feat: integrate with MailJet API for newsletter registration

This commit is contained in:
Björn Fromme
2026-03-19 09:42:00 +01:00
parent 66c55f0722
commit d1e2bf3e7d
26 changed files with 1537 additions and 47 deletions
@@ -9,10 +9,14 @@ use App\BusProNet\Exception\ApiClientException;
use App\BusProNet\Model\Notification;
use App\BusProNet\Model\PersonalData;
use App\Entity\User;
use App\Exception\NewsletterProviderException;
use App\Form\PersonalDataType;
use App\Repository\NewsletterOptInConfirmationRepository;
use App\Security\Crypt;
use App\Service\BookingEditDataLoaderService;
use App\Service\ProfileCompletenessChecker;
use App\Service\Newsletter\MailjetNewsletterService;
use App\Service\Newsletter\NewsletterDoubleOptInService;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
@@ -46,6 +50,9 @@ class PersonalDataController extends AbstractController
private readonly BookingEditDataLoaderService $dataLoader,
private readonly ProfileCompletenessChecker $completenessChecker,
private readonly EntityManagerInterface $entityManager,
private readonly MailjetNewsletterService $newsletterService,
private readonly NewsletterDoubleOptInService $doubleOptInService,
private readonly NewsletterOptInConfirmationRepository $newsletterConfirmationRepository,
private readonly LoggerInterface $logger,
) {
}
@@ -130,9 +137,27 @@ class PersonalDataController extends AbstractController
return $this->redirectToRoute('app_personal_data');
}
$newsletterSubscribed = false;
$newsletterPendingConfirmation = false;
try {
$newsletterSubscribed = $this->newsletterService->isSubscribed($email);
} catch (NewsletterProviderException $e) {
$this->logger->warning('Unable to read newsletter subscription status', [
'email' => $email,
'error' => $e->getMessage(),
]);
$this->addFlash('error', 'Der Newsletter-Status konnte gerade nicht geladen werden.');
}
if (!$newsletterSubscribed) {
$newsletterPendingConfirmation = null !== $this->newsletterConfirmationRepository->findPendingByEmail($email);
}
return $this->render('account/personal_data.html.twig', [
'personalData' => $personalData,
'personalDataForm' => $personalDataForm->createView(),
'newsletterSubscribed' => $newsletterSubscribed,
'newsletterPendingConfirmation' => $newsletterPendingConfirmation,
]);
}
@@ -149,43 +174,43 @@ class PersonalDataController extends AbstractController
*/
#[Route('/personal-data/newsletter', name: 'app_personal_data_newsletter', methods: ['POST'])]
#[IsGranted('ROLE_USER')]
public function newsletter(): Response
public function newsletter(Request $request): Response
{
/** @var User $user */
$user = $this->getUser();
$email = $user->getEmail();
$password = $this->crypt->decrypt($user->getPassword());
$shouldSubscribe = $request->request->getBoolean('subscribed');
try {
$personalData = $this
->apiClient
->getPersonalData($email, $password);
} catch (ApiClientException $e) {
$this->addFlash('error', 'Deine persönlichen Daten konnten nicht abgerufen werden');
if ($shouldSubscribe) {
if ($this->newsletterService->isSubscribed($email)) {
$this->addFlash('info', 'Du bist bereits zum Newsletter angemeldet.');
} else {
$hasPendingConfirmation = null !== $this->newsletterConfirmationRepository->findPendingByEmail($email);
$this->doubleOptInService->requestConfirmation($email);
if ($hasPendingConfirmation) {
$this->addFlash('success', 'Wir haben dir eine neue Bestätigungs-E-Mail gesendet.');
} else {
$this->addFlash('success', 'Bitte bestätige deine Newsletter-Anmeldung über den Link in der E-Mail.');
}
}
} else {
$this->newsletterService->unsubscribe($email);
$this->addFlash('success', 'Du wurdest vom Newsletter abgemeldet.');
}
return $this->redirectToRoute('app_personal_data');
}
if ($personalData instanceof Notification) {
$this->logger->error('Unable to fetch personal data', [
'code' => $personalData->code,
'error' => $personalData->message,
]);
$this->addFlash('error', 'Deine persönlichen Daten konnten nicht abgerufen werden');
return $this->redirectToRoute('app_personal_data');
}
$personalData->communication->newsletter = !$personalData->communication->newsletter;
try {
$this->apiClient->updateNewsletterRegistration($email, $password, $personalData);
$this->addFlash('success', 'Deine Anmeldung zum Newsletter wurde aktualisiert');
$this->logger->info('Updated newsletter registration', [
$this->logger->info('Updated newsletter registration intent', [
'email' => $user->getEmail(),
'subscribed' => $shouldSubscribe,
]);
} catch (NewsletterProviderException|\InvalidArgumentException $e) {
$this->addFlash('error', 'Die Newsletter-Aktion konnte gerade nicht verarbeitet werden. Bitte versuche es erneut.');
$this->logger->warning('Newsletter action failed', [
'email' => $email,
'subscribed' => $shouldSubscribe,
'error' => $e->getMessage(),
]);
} catch (ApiClientException $e) {
$this->addFlash('error', $e->getMessage());
}
return $this->redirectToRoute('app_personal_data');