_Url ??= '/newsletter/subscriptions/' . $this->User->Uuid; } // ******* // METHODS // ******* /** * @throws Exceptions\InvalidNewsletterSubscription * @throws Exceptions\NewsletterSubscriptionExistsException */ public function Create(?string $expectedCaptcha = null, ?string $receivedCaptcha = null): void{ $this->Validate($expectedCaptcha, $receivedCaptcha); // Do we need to create a `User`? try{ $this->User = User::GetByEmail($this->User->Email); } catch(Exceptions\UserNotFoundException){ // User doesn't exist, create the `User`. try{ $this->User->Create(); } catch(Exceptions\UserExistsException | Exceptions\InvalidUserException){ // `User` exists, pass. } } $this->UserId = $this->User->UserId; $this->Created = NOW; try{ Db::Query(' INSERT into NewsletterSubscriptions (UserId, IsConfirmed, IsSubscribedToNewsletter, IsSubscribedToSummary, Created) values (?, ?, ?, ?, ?) ', [$this->User->UserId, false, $this->IsSubscribedToNewsletter, $this->IsSubscribedToSummary, $this->Created]); } catch(Exceptions\DuplicateDatabaseKeyException){ throw new Exceptions\NewsletterSubscriptionExistsException(); } // Send the double opt-in confirmation email. $this->SendConfirmationEmail(); } /** * @throws Exceptions\InvalidNewsletterSubscription */ public function Save(): void{ $this->Validate(); Db::Query(' UPDATE NewsletterSubscriptions set IsConfirmed = ?, IsSubscribedToNewsletter = ?, IsSubscribedToSummary = ? where UserId = ? ', [$this->IsConfirmed, $this->IsSubscribedToNewsletter, $this->IsSubscribedToSummary, $this->UserId]); } public function SendConfirmationEmail(): void{ $em = new Email(true); $em->PostmarkStream = EMAIL_POSTMARK_STREAM_BROADCAST; $em->To = $this->User->Email ?? ''; if($this->User->Name !== null && $this->User->Name != ''){ $em->ToName = $this->User->Name; } $em->Subject = 'Action required: confirm your newsletter subscription'; $em->Body = Template::EmailNewsletterConfirmation(subscription: $this, isSubscribedToSummary: $this->IsSubscribedToSummary, isSubscribedToNewsletter: $this->IsSubscribedToNewsletter); $em->TextBody = Template::EmailNewsletterConfirmationText(subscription: $this, isSubscribedToSummary: $this->IsSubscribedToSummary, isSubscribedToNewsletter: $this->IsSubscribedToNewsletter); $em->Send(); } public function Confirm(): void{ Db::Query(' UPDATE NewsletterSubscriptions set IsConfirmed = true where UserId = ? ', [$this->UserId]); } public function Delete(): void{ Db::Query(' DELETE from NewsletterSubscriptions where UserId = ? ', [$this->UserId]); } /** * @throws Exceptions\InvalidNewsletterSubscription */ public function Validate(?string $expectedCaptcha = null, ?string $receivedCaptcha = null): void{ $error = new Exceptions\InvalidNewsletterSubscription(); if($this->User === null || $this->User->Email == '' || !filter_var($this->User->Email, FILTER_VALIDATE_EMAIL)){ $error->Add(new Exceptions\InvalidEmailException()); } if(!$this->IsSubscribedToSummary && !$this->IsSubscribedToNewsletter){ $error->Add(new Exceptions\NewsletterRequiredException()); } if($expectedCaptcha !== null){ if($expectedCaptcha === '' || mb_strtolower($expectedCaptcha) !== mb_strtolower($receivedCaptcha ?? '')){ $error->Add(new Exceptions\InvalidCaptchaException()); } } if($error->HasExceptions){ throw $error; } } // *********** // ORM METHODS // *********** /** * @throws Exceptions\NewsletterSubscriptionNotFoundException */ public static function Get(?string $uuid): NewsletterSubscription{ if($uuid === null){ throw new Exceptions\NewsletterSubscriptionNotFoundException(); } return Db::Query(' SELECT ns.* from NewsletterSubscriptions ns inner join Users u using(UserId) where u.Uuid = ? ', [$uuid], NewsletterSubscription::class)[0] ?? throw new Exceptions\NewsletterSubscriptionNotFoundException(); } /** * @throws Exceptions\NewsletterSubscriptionNotFoundException */ public static function GetByUserId(?int $userId): NewsletterSubscription{ if($userId === null){ throw new Exceptions\NewsletterSubscriptionNotFoundException(); } return Db::Query(' SELECT ns.* from NewsletterSubscriptions ns inner join Users u using(UserId) where u.UserId = ? ', [$userId], NewsletterSubscription::class)[0] ?? throw new Exceptions\NewsletterSubscriptionNotFoundException(); } }