From a78b3d3e3a6353a5cb0c6e83df39d9fd2afb8cf6 Mon Sep 17 00:00:00 2001 From: Ambroise Maupate Date: Thu, 15 Jun 2023 18:08:00 +0200 Subject: [PATCH] feat(Redirections): Added redirection look-up cache and CRUD events --- .../src/Controller/Controller.php | 4 +- .../src/Controller/RedirectionController.php | 10 +---- .../PostCreatedRedirectionEvent.php | 9 +++++ .../PostDeletedRedirectionEvent.php | 9 +++++ .../PostUpdatedRedirectionEvent.php | 9 +++++ .../Event/Redirection/RedirectionEvent.php | 39 ++++++++++++++++++ .../RedirectionCacheSubscriber.php | 40 +++++++++++++++++++ lib/RoadizCoreBundle/src/Node/NodeMover.php | 3 ++ .../src/Routing/RedirectionPathResolver.php | 24 +++++++---- .../src/Controller/Node/SeoController.php | 5 +++ .../Controllers/RedirectionsController.php | 28 +++++++++++++ 11 files changed, 161 insertions(+), 19 deletions(-) create mode 100644 lib/RoadizCoreBundle/src/Event/Redirection/PostCreatedRedirectionEvent.php create mode 100644 lib/RoadizCoreBundle/src/Event/Redirection/PostDeletedRedirectionEvent.php create mode 100644 lib/RoadizCoreBundle/src/Event/Redirection/PostUpdatedRedirectionEvent.php create mode 100644 lib/RoadizCoreBundle/src/Event/Redirection/RedirectionEvent.php create mode 100644 lib/RoadizCoreBundle/src/EventSubscriber/RedirectionCacheSubscriber.php diff --git a/lib/RoadizCompatBundle/src/Controller/Controller.php b/lib/RoadizCompatBundle/src/Controller/Controller.php index be7fa95a..7bab5523 100644 --- a/lib/RoadizCompatBundle/src/Controller/Controller.php +++ b/lib/RoadizCompatBundle/src/Controller/Controller.php @@ -48,7 +48,6 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; -use Symfony\Component\Security\Core\Exception\AccessDeniedException; use Symfony\Component\Security\Core\Security; use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface; @@ -70,6 +69,7 @@ public static function getSubscribedServices(): array 'dispatcher' => 'event_dispatcher', 'em' => EntityManagerInterface::class, 'event_dispatcher' => 'event_dispatcher', + EventDispatcherInterface::class => EventDispatcherInterface::class, 'kernel' => KernelInterface::class, 'logger' => LoggerInterface::class, 'nodeApi' => NodeApi::class, @@ -196,7 +196,7 @@ protected function getPreviewResolver(): PreviewResolverInterface protected function dispatchEvent($event) { /** @var EventDispatcherInterface $eventDispatcher */ # php-stan hint - $eventDispatcher = $this->get('event_dispatcher'); + $eventDispatcher = $this->get(EventDispatcherInterface::class); return $eventDispatcher->dispatch($event); } diff --git a/lib/RoadizCoreBundle/src/Controller/RedirectionController.php b/lib/RoadizCoreBundle/src/Controller/RedirectionController.php index bef839fc..8262e3be 100644 --- a/lib/RoadizCoreBundle/src/Controller/RedirectionController.php +++ b/lib/RoadizCoreBundle/src/Controller/RedirectionController.php @@ -4,7 +4,6 @@ namespace RZ\Roadiz\CoreBundle\Controller; -use Doctrine\Persistence\ManagerRegistry; use RZ\Roadiz\CoreBundle\Entity\Redirection; use Symfony\Cmf\Component\Routing\RouteObjectInterface; use Symfony\Component\HttpFoundation\RedirectResponse; @@ -16,12 +15,10 @@ final class RedirectionController { private UrlGeneratorInterface $urlGenerator; - private ManagerRegistry $managerRegistry; - public function __construct(UrlGeneratorInterface $urlGenerator, ManagerRegistry $managerRegistry) + public function __construct(UrlGeneratorInterface $urlGenerator) { $this->urlGenerator = $urlGenerator; - $this->managerRegistry = $managerRegistry; } /** @@ -32,9 +29,6 @@ public function __construct(UrlGeneratorInterface $urlGenerator, ManagerRegistry public function redirectAction(Request $request, Redirection $redirection): RedirectResponse { if (null !== $redirection->getRedirectNodeSource()) { - $redirection->incrementUseCount(); - $this->managerRegistry->getManagerForClass(Redirection::class)->flush(); - return new RedirectResponse( $this->urlGenerator->generate( RouteObjectInterface::OBJECT_BASED_ROUTE_NAME, @@ -48,8 +42,6 @@ public function redirectAction(Request $request, Redirection $redirection): Redi null !== $redirection->getRedirectUri() && strlen($redirection->getRedirectUri()) > 0 ) { - $redirection->incrementUseCount(); - $this->managerRegistry->getManagerForClass(Redirection::class)->flush(); return new RedirectResponse($redirection->getRedirectUri(), $redirection->getType()); } diff --git a/lib/RoadizCoreBundle/src/Event/Redirection/PostCreatedRedirectionEvent.php b/lib/RoadizCoreBundle/src/Event/Redirection/PostCreatedRedirectionEvent.php new file mode 100644 index 00000000..13014c4f --- /dev/null +++ b/lib/RoadizCoreBundle/src/Event/Redirection/PostCreatedRedirectionEvent.php @@ -0,0 +1,9 @@ +redirection = $redirection; + } + + /** + * @return Redirection|null + */ + public function getRedirection(): ?Redirection + { + return $this->redirection; + } + + /** + * @param Redirection|null $redirection + * @return RedirectionEvent + */ + public function setRedirection(?Redirection $redirection): RedirectionEvent + { + $this->redirection = $redirection; + return $this; + } +} diff --git a/lib/RoadizCoreBundle/src/EventSubscriber/RedirectionCacheSubscriber.php b/lib/RoadizCoreBundle/src/EventSubscriber/RedirectionCacheSubscriber.php new file mode 100644 index 00000000..49dece5c --- /dev/null +++ b/lib/RoadizCoreBundle/src/EventSubscriber/RedirectionCacheSubscriber.php @@ -0,0 +1,40 @@ +cacheAdapter = $cacheAdapter; + } + + /** + * @inheritDoc + */ + public static function getSubscribedEvents(): array + { + return [ + PostCreatedRedirectionEvent::class => 'clearCache', + PostDeletedRedirectionEvent::class => 'clearCache', + PostUpdatedRedirectionEvent::class => 'clearCache', + ]; + } + + public function clearCache(RedirectionEvent $event): void + { + $this->cacheAdapter->deleteItem(RedirectionPathResolver::CACHE_KEY); + } +} diff --git a/lib/RoadizCoreBundle/src/Node/NodeMover.php b/lib/RoadizCoreBundle/src/Node/NodeMover.php index 2e866db9..901559d3 100644 --- a/lib/RoadizCoreBundle/src/Node/NodeMover.php +++ b/lib/RoadizCoreBundle/src/Node/NodeMover.php @@ -14,6 +14,8 @@ use RZ\Roadiz\CoreBundle\Entity\Redirection; use RZ\Roadiz\Core\Handlers\HandlerFactoryInterface; use RZ\Roadiz\CoreBundle\EntityHandler\NodeHandler; +use RZ\Roadiz\CoreBundle\Event\Redirection\PostCreatedRedirectionEvent; +use RZ\Roadiz\CoreBundle\Event\Redirection\PostUpdatedRedirectionEvent; use RZ\Roadiz\CoreBundle\Repository\EntityRepository; use RZ\Roadiz\CoreBundle\Routing\NodeRouter; use RZ\Roadiz\CoreBundle\Node\Exception\SameNodeUrlException; @@ -219,6 +221,7 @@ protected function redirect(NodesSources $nodeSource, string $previousPath, bool } else { $existingRedirection->setType(Response::HTTP_FOUND); } + $this->dispatcher->dispatch(new PostUpdatedRedirectionEvent($existingRedirection)); } return $nodeSource; diff --git a/lib/RoadizCoreBundle/src/Routing/RedirectionPathResolver.php b/lib/RoadizCoreBundle/src/Routing/RedirectionPathResolver.php index 9f19da21..7842a60d 100644 --- a/lib/RoadizCoreBundle/src/Routing/RedirectionPathResolver.php +++ b/lib/RoadizCoreBundle/src/Routing/RedirectionPathResolver.php @@ -34,7 +34,7 @@ public function resolvePath( bool $allowRootPaths = false, bool $allowNonReachableNodes = true ): ResourceInfo { - $this->stopwatch->start('findRedirection', 'routing'); + $this->stopwatch->start('lookForRedirection', 'routing'); $cacheItem = $this->cacheAdapter->getItem(self::CACHE_KEY); if (!$cacheItem->isHit()) { // Populate cache item @@ -58,17 +58,25 @@ public function resolvePath( /** @var int|null $redirectionId */ $redirectionId = $redirections[$path] ?? null; - $this->stopwatch->stop('findRedirection'); + $this->stopwatch->stop('lookForRedirection'); if (null === $redirectionId) { throw new ResourceNotFoundException(); } + $this->stopwatch->start('findRedirection', 'routing'); + $redirection = $this->managerRegistry + ->getRepository(Redirection::class) + ->find($redirectionId); + $this->stopwatch->stop('findRedirection'); + if (null === $redirection) { + throw new ResourceNotFoundException(); + } - return (new ResourceInfo()) - ->setResource( - $this->managerRegistry - ->getRepository(Redirection::class) - ->find($redirectionId) - ); + $this->stopwatch->start('incrementRedirection', 'routing'); + $redirection->incrementUseCount(); + $this->managerRegistry->getManagerForClass(Redirection::class)->flush(); + $this->stopwatch->stop('incrementRedirection'); + + return (new ResourceInfo())->setResource($redirection); } } diff --git a/lib/RoadizRozierBundle/src/Controller/Node/SeoController.php b/lib/RoadizRozierBundle/src/Controller/Node/SeoController.php index 9c31bfc3..7d375791 100644 --- a/lib/RoadizRozierBundle/src/Controller/Node/SeoController.php +++ b/lib/RoadizRozierBundle/src/Controller/Node/SeoController.php @@ -10,6 +10,8 @@ use RZ\Roadiz\CoreBundle\Entity\Translation; use RZ\Roadiz\CoreBundle\Entity\UrlAlias; use RZ\Roadiz\CoreBundle\Event\NodesSources\NodesSourcesUpdatedEvent; +use RZ\Roadiz\CoreBundle\Event\Redirection\PostCreatedRedirectionEvent; +use RZ\Roadiz\CoreBundle\Event\Redirection\PostUpdatedRedirectionEvent; use RZ\Roadiz\CoreBundle\Event\UrlAlias\UrlAliasCreatedEvent; use RZ\Roadiz\CoreBundle\Event\UrlAlias\UrlAliasDeletedEvent; use RZ\Roadiz\CoreBundle\Event\UrlAlias\UrlAliasUpdatedEvent; @@ -301,6 +303,7 @@ private function handleAddRedirection(NodesSources $source, Request $request): ? if ($addForm->isSubmitted() && $addForm->isValid()) { $this->em()->persist($redirection); $this->em()->flush(); + $this->dispatchEvent(new PostCreatedRedirectionEvent($redirection)); /** @var Translation $translation */ $translation = $redirection->getRedirectNodeSource()->getTranslation(); @@ -345,6 +348,7 @@ private function handleSingleRedirection(Redirection $redirection, Request $requ $editForm->handleRequest($request); if ($editForm->isSubmitted() && $editForm->isValid()) { $this->em()->flush(); + $this->dispatchEvent(new PostUpdatedRedirectionEvent($redirection)); return $this->redirect($this->generateUrl( 'nodesEditSEOPage', [ @@ -359,6 +363,7 @@ private function handleSingleRedirection(Redirection $redirection, Request $requ if ($deleteForm->isSubmitted() && $deleteForm->isValid()) { $this->em()->remove($redirection); $this->em()->flush(); + $this->dispatchEvent(new PostCreatedRedirectionEvent($redirection)); return $this->redirect($this->generateUrl( 'nodesEditSEOPage', [ diff --git a/lib/Rozier/src/Controllers/RedirectionsController.php b/lib/Rozier/src/Controllers/RedirectionsController.php index cd787e20..dd5882d1 100644 --- a/lib/Rozier/src/Controllers/RedirectionsController.php +++ b/lib/Rozier/src/Controllers/RedirectionsController.php @@ -6,6 +6,10 @@ use RZ\Roadiz\Core\AbstractEntities\PersistableInterface; use RZ\Roadiz\CoreBundle\Entity\Redirection; +use RZ\Roadiz\CoreBundle\Event\Redirection\PostCreatedRedirectionEvent; +use RZ\Roadiz\CoreBundle\Event\Redirection\PostDeletedRedirectionEvent; +use RZ\Roadiz\CoreBundle\Event\Redirection\PostUpdatedRedirectionEvent; +use RZ\Roadiz\CoreBundle\Event\Redirection\RedirectionEvent; use Symfony\Component\HttpFoundation\Request; use Themes\Rozier\Forms\RedirectionType; @@ -101,4 +105,28 @@ protected function getDefaultOrder(Request $request): array { return ['query' => 'ASC']; } + + protected function createPostCreateEvent(PersistableInterface $item): RedirectionEvent + { + if (!($item instanceof Redirection)) { + throw new \InvalidArgumentException('Item should be instance of ' . Redirection::class); + } + return new PostCreatedRedirectionEvent($item); + } + + protected function createPostUpdateEvent(PersistableInterface $item): RedirectionEvent + { + if (!($item instanceof Redirection)) { + throw new \InvalidArgumentException('Item should be instance of ' . Redirection::class); + } + return new PostUpdatedRedirectionEvent($item); + } + + protected function createDeleteEvent(PersistableInterface $item): RedirectionEvent + { + if (!($item instanceof Redirection)) { + throw new \InvalidArgumentException('Item should be instance of ' . Redirection::class); + } + return new PostDeletedRedirectionEvent($item); + } }