Skip to content

Commit

Permalink
feat(Redirections): Added redirection look-up cache and CRUD events
Browse files Browse the repository at this point in the history
  • Loading branch information
ambroisemaupate committed Jun 15, 2023
1 parent 6da1c69 commit a78b3d3
Show file tree
Hide file tree
Showing 11 changed files with 161 additions and 19 deletions.
4 changes: 2 additions & 2 deletions lib/RoadizCompatBundle/src/Controller/Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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,
Expand Down Expand Up @@ -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);
}

Expand Down
10 changes: 1 addition & 9 deletions lib/RoadizCoreBundle/src/Controller/RedirectionController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
}

/**
Expand All @@ -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,
Expand All @@ -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());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace RZ\Roadiz\CoreBundle\Event\Redirection;

final class PostCreatedRedirectionEvent extends RedirectionEvent
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace RZ\Roadiz\CoreBundle\Event\Redirection;

final class PostDeletedRedirectionEvent extends RedirectionEvent
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace RZ\Roadiz\CoreBundle\Event\Redirection;

final class PostUpdatedRedirectionEvent extends RedirectionEvent
{
}
39 changes: 39 additions & 0 deletions lib/RoadizCoreBundle/src/Event/Redirection/RedirectionEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

declare(strict_types=1);

namespace RZ\Roadiz\CoreBundle\Event\Redirection;

use RZ\Roadiz\CoreBundle\Entity\Redirection;
use Symfony\Contracts\EventDispatcher\Event;

abstract class RedirectionEvent extends Event
{
protected ?Redirection $redirection;

/**
* @param Redirection|null $redirection
*/
public function __construct(?Redirection $redirection)
{
$this->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;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

declare(strict_types=1);

namespace RZ\Roadiz\CoreBundle\EventSubscriber;

use Psr\Cache\CacheItemPoolInterface;
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 RZ\Roadiz\CoreBundle\Routing\RedirectionPathResolver;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class RedirectionCacheSubscriber implements EventSubscriberInterface
{
private CacheItemPoolInterface $cacheAdapter;

public function __construct(CacheItemPoolInterface $cacheAdapter)
{
$this->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);
}
}
3 changes: 3 additions & 0 deletions lib/RoadizCoreBundle/src/Node/NodeMover.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
24 changes: 16 additions & 8 deletions lib/RoadizCoreBundle/src/Routing/RedirectionPathResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
}
}
5 changes: 5 additions & 0 deletions lib/RoadizRozierBundle/src/Controller/Node/SeoController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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',
[
Expand All @@ -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',
[
Expand Down
28 changes: 28 additions & 0 deletions lib/Rozier/src/Controllers/RedirectionsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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);
}
}

0 comments on commit a78b3d3

Please sign in to comment.