*/ class NewsletterOptInRequestRepository extends ServiceEntityRepository { public function __construct(ManagerRegistry $registry) { parent::__construct($registry, NewsletterOptInRequest::class); } public function findByTokenHash(string $tokenHash): ?NewsletterOptInRequest { return $this->findOneBy(['tokenHash' => $tokenHash]); } public function findPendingByEmail(string $email): ?NewsletterOptInRequest { return $this->createQueryBuilder('c') ->where('c.email = :email') ->andWhere('c.confirmedAt IS NULL') ->andWhere('c.expiresAt > :now') ->setParameters(new ArrayCollection([ new Parameter('email', mb_strtolower(trim($email))), new Parameter('now', new \DateTimeImmutable()), ])) ->orderBy('c.createdAt', 'DESC') ->setMaxResults(1) ->getQuery() ->getOneOrNullResult(); } public function deleteExpiredPendingByEmail(string $email): int { return (int) $this->createQueryBuilder('c') ->delete() ->where('c.email = :email') ->andWhere('c.confirmedAt IS NULL') ->andWhere('c.expiresAt <= :now') ->setParameters(new ArrayCollection([ new Parameter('email', mb_strtolower(trim($email))), new Parameter('now', new \DateTimeImmutable()), ])) ->getQuery() ->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(); return (int) $this->createQueryBuilder('c') ->delete() ->where('c.confirmedAt IS NULL') ->andWhere('c.expiresAt <= :threshold') ->setParameter('threshold', $threshold) ->getQuery() ->execute(); } }