diff --git a/lib/DI/ContainerConfigurator.php b/lib/DI/ContainerConfigurator.php index c6fef13891..44d9d38c71 100644 --- a/lib/DI/ContainerConfigurator.php +++ b/lib/DI/ContainerConfigurator.php @@ -123,6 +123,7 @@ class ContainerConfigurator implements IContainerConfigurator { ->setFactory([new Reference(\MailPoet\Doctrine\EntityManagerFactory::class), 'createEntityManager']) ->setPublic(true); $container->autowire(\MailPoet\Doctrine\EventListeners\EmojiEncodingListener::class)->setPublic(true); + $container->autowire(\MailPoet\Doctrine\EventListeners\LastSubscribedAtListener::class); $container->autowire(\MailPoet\Doctrine\EventListeners\TimestampListener::class); $container->autowire(\MailPoet\Doctrine\EventListeners\ValidationListener::class); $container->autowire(\MailPoet\Doctrine\Validator\ValidatorFactory::class); diff --git a/lib/Doctrine/EntityManagerFactory.php b/lib/Doctrine/EntityManagerFactory.php index 225e6b62dc..23ba3b5abb 100644 --- a/lib/Doctrine/EntityManagerFactory.php +++ b/lib/Doctrine/EntityManagerFactory.php @@ -3,6 +3,7 @@ namespace MailPoet\Doctrine; use MailPoet\Doctrine\EventListeners\EmojiEncodingListener; +use MailPoet\Doctrine\EventListeners\LastSubscribedAtListener; use MailPoet\Doctrine\EventListeners\TimestampListener; use MailPoet\Doctrine\EventListeners\ValidationListener; use MailPoet\Tracy\DoctrinePanel\DoctrinePanel; @@ -29,18 +30,23 @@ class EntityManagerFactory { /** @var EmojiEncodingListener */ private $emojiEncodingListener; + /** @var LastSubscribedAtListener */ + private $lastSubscribedAtListener; + public function __construct( Connection $connection, Configuration $configuration, TimestampListener $timestampListener, ValidationListener $validationListener, - EmojiEncodingListener $emojiEncodingListener + EmojiEncodingListener $emojiEncodingListener, + LastSubscribedAtListener $lastSubscribedAtListener ) { $this->connection = $connection; $this->configuration = $configuration; $this->timestampListener = $timestampListener; $this->validationListener = $validationListener; $this->emojiEncodingListener = $emojiEncodingListener; + $this->lastSubscribedAtListener = $lastSubscribedAtListener; } public function createEntityManager() { @@ -67,5 +73,10 @@ class EntityManagerFactory { [Events::prePersist, Events::preUpdate], $this->emojiEncodingListener ); + + $entityManager->getEventManager()->addEventListener( + [Events::prePersist, Events::preUpdate], + $this->lastSubscribedAtListener + ); } } diff --git a/lib/Doctrine/EventListeners/LastSubscribedAtListener.php b/lib/Doctrine/EventListeners/LastSubscribedAtListener.php new file mode 100644 index 0000000000..cba270634a --- /dev/null +++ b/lib/Doctrine/EventListeners/LastSubscribedAtListener.php @@ -0,0 +1,44 @@ +now = Carbon::createFromTimestamp($wp->currentTime('timestamp')); + } + + public function prePersist(LifecycleEventArgs $eventArgs): void { + $entity = $eventArgs->getEntity(); + + if ($entity instanceof SubscriberEntity && $entity->getStatus() === SubscriberEntity::STATUS_SUBSCRIBED) { + $entity->setLastSubscribedAt($this->now); + } + } + + public function preUpdate(LifecycleEventArgs $eventArgs): void { + $entity = $eventArgs->getEntity(); + if (!$entity instanceof SubscriberEntity) { + return; + } + + $unitOfWork = $eventArgs->getEntityManager()->getUnitOfWork(); + $changeSet = $unitOfWork->getEntityChangeSet($entity); + if (!isset($changeSet['status'])) { + return; + } + + [$oldStatus, $newStatus] = $changeSet['status']; + // Update last_subscribed_at when status changes to subscribed + if ($oldStatus !== SubscriberEntity::STATUS_SUBSCRIBED && $newStatus === SubscriberEntity::STATUS_SUBSCRIBED) { + $entity->setLastSubscribedAt($this->now); + } + } +} diff --git a/tests/integration/Doctrine/EventListeners/TimestampListenerTest.php b/tests/integration/Doctrine/EventListeners/TimestampListenerTest.php index 8ef4a59fa9..d88eecbf3b 100644 --- a/tests/integration/Doctrine/EventListeners/TimestampListenerTest.php +++ b/tests/integration/Doctrine/EventListeners/TimestampListenerTest.php @@ -6,6 +6,7 @@ use MailPoet\Doctrine\Annotations\AnnotationReaderProvider; use MailPoet\Doctrine\ConfigurationFactory; use MailPoet\Doctrine\EntityManagerFactory; use MailPoet\Doctrine\EventListeners\EmojiEncodingListener; +use MailPoet\Doctrine\EventListeners\LastSubscribedAtListener; use MailPoet\Doctrine\EventListeners\TimestampListener; use MailPoet\Doctrine\EventListeners\ValidationListener; use MailPoet\Doctrine\Validator\ValidatorFactory; @@ -94,7 +95,15 @@ class TimestampListenerTest extends \MailPoetTest { $timestampListener = new TimestampListener($this->wp); $validationListener = new ValidationListener($validatorFactory->createValidator()); $emojiEncodingListener = new EmojiEncodingListener(new Emoji($this->wp)); - $entityManagerFactory = new EntityManagerFactory($this->connection, $configuration, $timestampListener, $validationListener, $emojiEncodingListener); + $lastSubscribedAtListener = new LastSubscribedAtListener($this->wp); + $entityManagerFactory = new EntityManagerFactory( + $this->connection, + $configuration, + $timestampListener, + $validationListener, + $emojiEncodingListener, + $lastSubscribedAtListener + ); return $entityManagerFactory->createEntityManager(); } } diff --git a/tests/integration/Doctrine/EventListeners/ValidationTest.php b/tests/integration/Doctrine/EventListeners/ValidationTest.php index 3799f426e5..856970b8d9 100644 --- a/tests/integration/Doctrine/EventListeners/ValidationTest.php +++ b/tests/integration/Doctrine/EventListeners/ValidationTest.php @@ -6,6 +6,7 @@ use MailPoet\Doctrine\Annotations\AnnotationReaderProvider; use MailPoet\Doctrine\ConfigurationFactory; use MailPoet\Doctrine\EntityManagerFactory; use MailPoet\Doctrine\EventListeners\EmojiEncodingListener; +use MailPoet\Doctrine\EventListeners\LastSubscribedAtListener; use MailPoet\Doctrine\EventListeners\TimestampListener; use MailPoet\Doctrine\EventListeners\ValidationListener; use MailPoet\Doctrine\Validator\ValidationException; @@ -78,7 +79,15 @@ class ValidationTest extends \MailPoetTest { $timestampListener = new TimestampListener($this->wp); $validationListener = new ValidationListener($validatorFactory->createValidator()); $emojiEncodingListener = new EmojiEncodingListener(new Emoji($this->wp)); - $entityManagerFactory = new EntityManagerFactory($this->connection, $configuration, $timestampListener, $validationListener, $emojiEncodingListener); + $lastSubscribedAtListener = new LastSubscribedAtListener($this->wp); + $entityManagerFactory = new EntityManagerFactory( + $this->connection, + $configuration, + $timestampListener, + $validationListener, + $emojiEncodingListener, + $lastSubscribedAtListener + ); return $entityManagerFactory->createEntityManager(); } } diff --git a/tests/integration/Doctrine/Types/JsonTypesTest.php b/tests/integration/Doctrine/Types/JsonTypesTest.php index e8e2b92ada..d472640504 100644 --- a/tests/integration/Doctrine/Types/JsonTypesTest.php +++ b/tests/integration/Doctrine/Types/JsonTypesTest.php @@ -7,6 +7,7 @@ use MailPoet\Doctrine\Annotations\AnnotationReaderProvider; use MailPoet\Doctrine\ConfigurationFactory; use MailPoet\Doctrine\EntityManagerFactory; use MailPoet\Doctrine\EventListeners\EmojiEncodingListener; +use MailPoet\Doctrine\EventListeners\LastSubscribedAtListener; use MailPoet\Doctrine\EventListeners\TimestampListener; use MailPoet\Doctrine\EventListeners\ValidationListener; use MailPoet\Doctrine\Validator\ValidatorFactory; @@ -186,7 +187,15 @@ class JsonTypesTest extends \MailPoetTest { $timestampListener = new TimestampListener($this->wp); $validationListener = new ValidationListener($validatorFactory->createValidator()); $emojiEncodingListener = new EmojiEncodingListener(new Emoji($this->wp)); - $entityManagerFactory = new EntityManagerFactory($this->connection, $configuration, $timestampListener, $validationListener, $emojiEncodingListener); + $lastSubscribedAtListener = new LastSubscribedAtListener($this->wp); + $entityManagerFactory = new EntityManagerFactory( + $this->connection, + $configuration, + $timestampListener, + $validationListener, + $emojiEncodingListener, + $lastSubscribedAtListener + ); return $entityManagerFactory->createEntityManager(); } }