feat: MailJet list handling with DOI, webhook receiver and API endpoint

addresses #869cut134
This commit is contained in:
Björn Fromme
2026-04-29 09:51:57 +02:00
parent df7885ca1c
commit e4ef2f7adc
46 changed files with 3389 additions and 322 deletions
@@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
namespace App\Repository;
use App\Entity\NewsletterConsent;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
/**
* @extends ServiceEntityRepository<NewsletterConsent>
*/
class NewsletterConsentRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, NewsletterConsent::class);
}
public function findActiveByEmail(string $email): ?NewsletterConsent
{
return $this->createQueryBuilder('c')
->where('c.email = :email')
->andWhere('c.confirmedAt IS NOT NULL')
->andWhere('c.revokedAt IS NULL')
->setParameter('email', mb_strtolower(trim($email)))
->orderBy('c.confirmedAt', 'DESC')
->setMaxResults(1)
->getQuery()
->getOneOrNullResult();
}
public function findOneByEmailAndListId(string $email, int $mailjetListId): ?NewsletterConsent
{
return $this->findOneBy([
'email' => mb_strtolower(trim($email)),
'mailjetListId' => $mailjetListId,
]);
}
}
@@ -4,26 +4,26 @@ declare(strict_types=1);
namespace App\Repository;
use App\Entity\NewsletterOptInConfirmation;
use App\Entity\NewsletterOptInRequest;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
/**
* @extends ServiceEntityRepository<NewsletterOptInConfirmation>
* @extends ServiceEntityRepository<NewsletterOptInRequest>
*/
class NewsletterOptInConfirmationRepository extends ServiceEntityRepository
class NewsletterOptInRequestRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, NewsletterOptInConfirmation::class);
parent::__construct($registry, NewsletterOptInRequest::class);
}
public function findByTokenHash(string $tokenHash): ?NewsletterOptInConfirmation
public function findByTokenHash(string $tokenHash): ?NewsletterOptInRequest
{
return $this->findOneBy(['tokenHash' => $tokenHash]);
}
public function findPendingByEmail(string $email): ?NewsletterOptInConfirmation
public function findPendingByEmail(string $email): ?NewsletterOptInRequest
{
return $this->createQueryBuilder('c')
->where('c.email = :email')
@@ -50,6 +50,17 @@ class NewsletterOptInConfirmationRepository extends ServiceEntityRepository
->execute();
}
public function deletePendingByEmail(string $email): int
{
return (int) $this->createQueryBuilder('c')
->delete()
->where('c.email = :email')
->andWhere('c.confirmedAt IS NULL')
->setParameter('email', mb_strtolower(trim($email)))
->getQuery()
->execute();
}
public function deleteExpiredPending(): int
{
$threshold = new \DateTimeImmutable();