Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
OptinController
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
3 / 3
8
100.00% covered (success)
100.00%
1 / 1
 optin
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
3
 optoutWithHashcode
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
 changeOptin
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3namespace App\Http\Controllers\Api\V2;
4
5use App\Enums\ApiError;
6use App\Exceptions\Api\V2\ApiErrorException;
7use App\Exceptions\Api\V2\CrmException;
8use App\Http\Controllers\Controller;
9use App\Http\Requests\Api\V2\BaseApiRequest;
10use App\Http\Requests\Api\V2\SingleOptinRequest;
11use App\Http\Requests\Api\V2\SingleOptinRemoveWithHashcodeRequest;
12use App\Models\CustomerInfo;
13use App\Models\Service;
14use Illuminate\Http\JsonResponse;
15use App\Models\SingleOptin;
16
17class OptinController extends Controller
18{
19    /**
20     * Creates a new Single optin or destroys it if exists
21     *
22     * @param \App\Http\Requests\Api\V2\SingleOptinRequest $request
23     * @param \App\Models\Service                          $service
24     * @return \Illuminate\Http\JsonResponse
25     * @throws \App\Exceptions\Api\V2\ApiErrorException With ApiError::singleOptinCustomerExists
26     *                                                  if this email already has a full account.
27     * @throws \App\Exceptions\Api\V2\CrmException If the single optin could not be added or removed.
28     */
29    public function optin(SingleOptinRequest $request, Service $service): JsonResponse
30    {
31        if (CustomerInfo::getFromEmail($service->brand, $request->email)->exists()) {
32            throw new ApiErrorException(ApiError::singleOptinCustomerExists());
33        }
34
35        /** @var \App\Models\SingleOptin */
36        $singleOptin = SingleOptin::query()->where('email', $request->email)
37            ->whereHas('brand', function ($q) use ($service) {
38                $q->where('id', $service->brand->id);
39            })->firstOrNew();
40
41        if (!$this->changeOptin($service, $request, \boolval($request->opt_in), $singleOptin)) {
42            // @codeCoverageIgnoreStart
43            throw new CrmException('Api failed to update single optin.');
44            // @codeCoverageIgnoreEnd
45        }
46
47        return response()->json();
48    }
49
50    /**
51     * Creates a new Single optin or destroys it if exists using hashcode
52     *
53     * @param \App\Http\Requests\Api\V2\SingleOptinRemoveWithHashcodeRequest $request
54     * @param \App\Models\Service                                            $service
55     * @return \Illuminate\Http\JsonResponse
56     * @throws \App\Exceptions\Api\V2\CrmException If the single optin could not be removed.
57     */
58    public function optoutWithHashcode(SingleOptinRemoveWithHashcodeRequest $request, Service $service)
59    {
60        /** @var \App\Models\SingleOptin */
61        $singleOptin = SingleOptin::query()->where('hashcode', $request->hashcode)
62            ->whereHas('brand', function ($q) use ($service) {
63                $q->whereId($service->brand->id);
64            })->firstOrFail();
65
66        if ($singleOptin and !$this->changeOptin($service, $request, \boolval($request->opt_in), $singleOptin)) {
67            // @codeCoverageIgnoreStart
68            throw new CrmException('Api failed to update single optin.');
69            // @codeCoverageIgnoreEnd
70        }
71
72        return response()->json();
73    }
74
75    /**
76     * Changes the optin state
77     *
78     * @param \App\Models\Service                      $service
79     * @param \App\Http\Requests\Api\V2\BaseApiRequest $request
80     * @param boolean                                  $optin
81     * @param \App\Models\SingleOptin                  $singleOptin
82     * @return boolean Returns false in case of failure.
83     */
84    private function changeOptin(Service $service, BaseApiRequest $request, bool $optin, SingleOptin $singleOptin): bool
85    {
86        if ($optin) {
87            $singleOptin->fill($request->validated());
88            $singleOptin->brand()->associate($service->brand);
89            return $singleOptin->save();
90        }
91        return $singleOptin->delete() !== false;
92    }
93}