brand, $request->email)->exists()) { throw new ApiErrorException(ApiError::singleOptinCustomerExists()); } /** @var \App\Models\SingleOptin */ $singleOptin = SingleOptin::query()->where('email', $request->email) ->whereHas('brand', function ($q) use ($service) { $q->where('id', $service->brand->id); })->firstOrNew(); if (!$this->changeOptin($service, $request, \boolval($request->opt_in), $singleOptin)) { // @codeCoverageIgnoreStart throw new CrmException('Api failed to update single optin.'); // @codeCoverageIgnoreEnd } return response()->json(); } /** * Creates a new Single optin or destroys it if exists using hashcode * * @param \App\Http\Requests\Api\V2\SingleOptinRemoveWithHashcodeRequest $request * @param \App\Models\Service $service * @return \Illuminate\Http\JsonResponse * @throws \App\Exceptions\Api\V2\CrmException If the single optin could not be removed. */ public function optoutWithHashcode(SingleOptinRemoveWithHashcodeRequest $request, Service $service) { /** @var \App\Models\SingleOptin */ $singleOptin = SingleOptin::query()->where('hashcode', $request->hashcode) ->whereHas('brand', function ($q) use ($service) { $q->whereId($service->brand->id); })->firstOrFail(); if ($singleOptin and !$this->changeOptin($service, $request, \boolval($request->opt_in), $singleOptin)) { // @codeCoverageIgnoreStart throw new CrmException('Api failed to update single optin.'); // @codeCoverageIgnoreEnd } return response()->json(); } /** * Changes the optin state * * @param \App\Models\Service $service * @param \App\Http\Requests\Api\V2\BaseApiRequest $request * @param boolean $optin * @param \App\Models\SingleOptin $singleOptin * @return boolean Returns false in case of failure. */ private function changeOptin(Service $service, BaseApiRequest $request, bool $optin, SingleOptin $singleOptin): bool { if ($optin) { $singleOptin->fill($request->validated()); $singleOptin->brand()->associate($service->brand); return $singleOptin->save(); } return $singleOptin->delete() !== false; } }