diff --git a/composer.json b/composer.json index b21f42a..169dc21 100644 --- a/composer.json +++ b/composer.json @@ -27,10 +27,11 @@ } ], "require": { - "php": "^8.0", + "php": "^8.1", "symfony/framework-bundle": "^5.0 | ^6.0", "doctrine/common": "^2.13 || ^3.0", - "doctrine/event-manager": "^1.2 | ^2.0" + "doctrine/event-manager": "^1.2 | ^2.0", + "symfony/clock": "^6.3" }, "require-dev": { "ext-json": "*", diff --git a/src/DependencyInjection/Compiler/DoctrineEventSubscriberPass.php b/src/DependencyInjection/Compiler/DoctrineEventSubscriberPass.php index 3c3c8cd..7f3b770 100644 --- a/src/DependencyInjection/Compiler/DoctrineEventSubscriberPass.php +++ b/src/DependencyInjection/Compiler/DoctrineEventSubscriberPass.php @@ -5,6 +5,10 @@ namespace Andante\TimestampableBundle\DependencyInjection\Compiler; use Andante\TimestampableBundle\EventSubscriber\TimestampableEventSubscriber; +use Composer\InstalledVersions; +use Doctrine\ORM\Events; +use Psr\Clock\ClockInterface; +use Symfony\Component\Clock\Clock; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; @@ -12,15 +16,37 @@ class DoctrineEventSubscriberPass implements CompilerPassInterface { public const TIMESTAMPABLE_SUBSCRIBER_SERVICE_ID = 'andante_timestampable.doctrine.timestampable_subscriber'; + public const CLOCK_SERVICE_ID = 'andante_timestampable.clock'; public function process(ContainerBuilder $container): void { - $container + $subscriberDefinition = $container ->register( self::TIMESTAMPABLE_SUBSCRIBER_SERVICE_ID, TimestampableEventSubscriber::class ) ->addArgument(new Reference('andante_timestampable.configuration')) ->addTag('doctrine.event_subscriber'); + $symfonyDoctrineBridgeVersion = InstalledVersions::getVersion('symfony/doctrine-bridge'); + if (null !== $symfonyDoctrineBridgeVersion && \version_compare($symfonyDoctrineBridgeVersion, '6.3', '>=')) { + $subscriberDefinition->addTag('doctrine.event_listener', [ + 'event' => Events::prePersist, + ]); + $subscriberDefinition->addTag('doctrine.event_listener', [ + 'event' => Events::preUpdate, + ]); + $subscriberDefinition->addTag('doctrine.event_listener', [ + 'event' => Events::loadClassMetadata, + ]); + } else { + $subscriberDefinition->addTag('doctrine.event_subscriber'); + } + + if ($container->has(ClockInterface::class)) { + $subscriberDefinition->addArgument(new Reference(ClockInterface::class)); + } else { + $container->register(self::CLOCK_SERVICE_ID, Clock::class); + $subscriberDefinition->addArgument(new Reference(self::CLOCK_SERVICE_ID)); + } } } diff --git a/src/EventSubscriber/TimestampableEventSubscriber.php b/src/EventSubscriber/TimestampableEventSubscriber.php index 35004a9..56d64c8 100644 --- a/src/EventSubscriber/TimestampableEventSubscriber.php +++ b/src/EventSubscriber/TimestampableEventSubscriber.php @@ -12,14 +12,19 @@ use Doctrine\ORM\Event\LoadClassMetadataEventArgs; use Doctrine\ORM\Events; use Doctrine\Persistence\Event\LifecycleEventArgs; +use Psr\Clock\ClockInterface; class TimestampableEventSubscriber implements EventSubscriber { private Configuration $configuration; + private ClockInterface $clock; - public function __construct(Configuration $configuration) - { + public function __construct( + Configuration $configuration, + ClockInterface $clock + ) { $this->configuration = $configuration; + $this->clock = $clock; } public function getSubscribedEvents(): array @@ -35,7 +40,7 @@ public function prePersist(LifecycleEventArgs $onFlushEventArgs): void { $entity = $onFlushEventArgs->getObject(); if ($entity instanceof CreatedAtTimestampableInterface && null === $entity->getCreatedAt()) { - $entity->setCreatedAt(new \DateTimeImmutable()); + $entity->setCreatedAt($this->clock->now()); } } @@ -43,7 +48,7 @@ public function preUpdate(LifecycleEventArgs $onFlushEventArgs): void { $entity = $onFlushEventArgs->getObject(); if ($entity instanceof UpdatedAtTimestampableInterface) { - $entity->setUpdatedAt(new \DateTimeImmutable()); + $entity->setUpdatedAt($this->clock->now()); } }