From 3d7b1ca79960f018694b16f42277eb71c4d3b1c3 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Tue, 26 Mar 2024 23:26:44 +0100 Subject: [PATCH] Move from preFlush to onFlush + postFlush --- config/autoload/entity-manager.global.php | 7 +++---- module/Core/config/dependencies.config.php | 2 +- ...ner.php => ShortUrlVisitsCountTracker.php} | 21 +++++++++++++++---- .../Repository/ShortUrlListRepositoryTest.php | 21 +++++++------------ 4 files changed, 29 insertions(+), 22 deletions(-) rename module/Core/src/Visit/Listener/{ShortUrlVisitsCountPreFlushListener.php => ShortUrlVisitsCountTracker.php} (88%) diff --git a/config/autoload/entity-manager.global.php b/config/autoload/entity-manager.global.php index fef50b56..84233915 100644 --- a/config/autoload/entity-manager.global.php +++ b/config/autoload/entity-manager.global.php @@ -5,7 +5,7 @@ declare(strict_types=1); use Doctrine\ORM\Events; use Happyr\DoctrineSpecification\Repository\EntitySpecificationRepository; use Shlinkio\Shlink\Core\Config\EnvVars; -use Shlinkio\Shlink\Core\Visit\Listener\ShortUrlVisitsCountPreFlushListener; +use Shlinkio\Shlink\Core\Visit\Listener\ShortUrlVisitsCountTracker; use function Shlinkio\Shlink\Core\ArrayUtils\contains; @@ -63,9 +63,8 @@ return (static function (): array { 'load_mappings_using_functional_style' => true, 'default_repository_classname' => EntitySpecificationRepository::class, 'listeners' => [ - Events::preFlush => [ - ShortUrlVisitsCountPreFlushListener::class, - ], + Events::onFlush => [ShortUrlVisitsCountTracker::class], + Events::postFlush => [ShortUrlVisitsCountTracker::class], ], ], 'connection' => $resolveConnection(), diff --git a/module/Core/config/dependencies.config.php b/module/Core/config/dependencies.config.php index 7d3bf763..951c7b52 100644 --- a/module/Core/config/dependencies.config.php +++ b/module/Core/config/dependencies.config.php @@ -76,7 +76,7 @@ return [ EntityRepositoryFactory::class, Visit\Entity\Visit::class, ], - Visit\Listener\ShortUrlVisitsCountPreFlushListener::class => InvokableFactory::class, + Visit\Listener\ShortUrlVisitsCountTracker::class => InvokableFactory::class, Util\DoctrineBatchHelper::class => ConfigAbstractFactory::class, Util\RedirectResponseHelper::class => ConfigAbstractFactory::class, diff --git a/module/Core/src/Visit/Listener/ShortUrlVisitsCountPreFlushListener.php b/module/Core/src/Visit/Listener/ShortUrlVisitsCountTracker.php similarity index 88% rename from module/Core/src/Visit/Listener/ShortUrlVisitsCountPreFlushListener.php rename to module/Core/src/Visit/Listener/ShortUrlVisitsCountTracker.php index 74812e44..8d79c330 100644 --- a/module/Core/src/Visit/Listener/ShortUrlVisitsCountPreFlushListener.php +++ b/module/Core/src/Visit/Listener/ShortUrlVisitsCountTracker.php @@ -10,20 +10,33 @@ use Doctrine\DBAL\Platforms\PostgreSQLPlatform; use Doctrine\DBAL\Platforms\SQLitePlatform; use Doctrine\DBAL\Platforms\SQLServerPlatform; use Doctrine\ORM\EntityManagerInterface; -use Doctrine\ORM\Event\PreFlushEventArgs; +use Doctrine\ORM\Event\OnFlushEventArgs; +use Doctrine\ORM\Event\PostFlushEventArgs; use Shlinkio\Shlink\Core\Visit\Entity\Visit; use function rand; -final readonly class ShortUrlVisitsCountPreFlushListener +final class ShortUrlVisitsCountTracker { + /** @var object[] */ + private array $entitiesToBeCreated = []; + + public function onFlush(OnFlushEventArgs $args): void + { + // Track entities that are going to be created during this flush operation + $this->entitiesToBeCreated = $args->getObjectManager()->getUnitOfWork()->getScheduledEntityInsertions(); + } + /** * @throws Exception */ - public function preFlush(PreFlushEventArgs $args): void + public function postFlush(PostFlushEventArgs $args): void { $em = $args->getObjectManager(); - $entitiesToBeCreated = $em->getUnitOfWork()->getScheduledEntityInsertions(); + $entitiesToBeCreated = $this->entitiesToBeCreated; + + // Reset tracked entities until next flush operation + $this->entitiesToBeCreated = []; foreach ($entitiesToBeCreated as $entity) { $this->trackVisitCount($em, $entity); diff --git a/module/Core/test-db/ShortUrl/Repository/ShortUrlListRepositoryTest.php b/module/Core/test-db/ShortUrl/Repository/ShortUrlListRepositoryTest.php index 91e15737..cad0569d 100644 --- a/module/Core/test-db/ShortUrl/Repository/ShortUrlListRepositoryTest.php +++ b/module/Core/test-db/ShortUrl/Repository/ShortUrlListRepositoryTest.php @@ -62,18 +62,6 @@ class ShortUrlListRepositoryTest extends DatabaseTestCase $this->getEntityManager()->persist($foo); $bar = ShortUrl::withLongUrl('https://bar'); - $this->getEntityManager()->persist($bar); - - $foo2 = ShortUrl::withLongUrl('https://foo_2'); - $ref = new ReflectionObject($foo2); - $dateProp = $ref->getProperty('dateCreated'); - $dateProp->setAccessible(true); - $dateProp->setValue($foo2, Chronos::now()->subDays(5)); - $this->getEntityManager()->persist($foo2); - - // Flush short URLs first - $this->getEntityManager()->flush(); - $visits = array_map(function () use ($bar) { $visit = Visit::forValidShortUrl($bar, Visitor::botInstance()); $this->getEntityManager()->persist($visit); @@ -81,6 +69,9 @@ class ShortUrlListRepositoryTest extends DatabaseTestCase return $visit; }, range(0, 5)); $bar->setVisits(new ArrayCollection($visits)); + $this->getEntityManager()->persist($bar); + + $foo2 = ShortUrl::withLongUrl('https://foo_2'); $visits2 = array_map(function () use ($foo2) { $visit = Visit::forValidShortUrl($foo2, Visitor::emptyInstance()); $this->getEntityManager()->persist($visit); @@ -88,8 +79,12 @@ class ShortUrlListRepositoryTest extends DatabaseTestCase return $visit; }, range(0, 3)); $foo2->setVisits(new ArrayCollection($visits2)); + $ref = new ReflectionObject($foo2); + $dateProp = $ref->getProperty('dateCreated'); + $dateProp->setAccessible(true); + $dateProp->setValue($foo2, Chronos::now()->subDays(5)); + $this->getEntityManager()->persist($foo2); - // Flush visits afterwards $this->getEntityManager()->flush(); $result = $this->repo->findList(new ShortUrlsListFiltering(searchTerm: 'foo', tags: ['bar']));