vendor/presta/sitemap-bundle/src/EventListener/RouteAnnotationEventListener.php line 71

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the PrestaSitemapBundle package.
  4.  *
  5.  * (c) PrestaConcept <https://prestaconcept.net>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Presta\SitemapBundle\EventListener;
  11. use Presta\SitemapBundle\Event\SitemapAddUrlEvent;
  12. use Presta\SitemapBundle\Event\SitemapPopulateEvent;
  13. use Presta\SitemapBundle\Routing\RouteOptionParser;
  14. use Presta\SitemapBundle\Service\UrlContainerInterface;
  15. use Presta\SitemapBundle\Sitemap\Url\UrlConcrete;
  16. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  17. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  18. use Symfony\Component\Routing\Exception\MissingMandatoryParametersException;
  19. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  20. use Symfony\Component\Routing\RouterInterface;
  21. /**
  22.  * Listen to "presta_sitemap.populate" event.
  23.  * Populate sitemap with configured static routes.
  24.  *
  25.  * @phpstan-import-type RouteOptions from RouteOptionParser
  26.  */
  27. class RouteAnnotationEventListener implements EventSubscriberInterface
  28. {
  29.     /**
  30.      * @var RouterInterface
  31.      */
  32.     protected $router;
  33.     /**
  34.      * @var EventDispatcherInterface
  35.      */
  36.     private $dispatcher;
  37.     /**
  38.      * @var string
  39.      */
  40.     private $defaultSection;
  41.     public function __construct(
  42.         RouterInterface $router,
  43.         EventDispatcherInterface $eventDispatcher,
  44.         string $defaultSection
  45.     ) {
  46.         $this->router $router;
  47.         $this->dispatcher $eventDispatcher;
  48.         $this->defaultSection $defaultSection;
  49.     }
  50.     /**
  51.      * @inheritdoc
  52.      */
  53.     public static function getSubscribedEvents(): array
  54.     {
  55.         return [
  56.             SitemapPopulateEvent::class => ['registerRouteAnnotation'0],
  57.         ];
  58.     }
  59.     /**
  60.      * @param SitemapPopulateEvent $event
  61.      */
  62.     public function registerRouteAnnotation(SitemapPopulateEvent $event): void
  63.     {
  64.         $this->addUrlsFromRoutes($event->getUrlContainer(), $event->getSection());
  65.     }
  66.     /**
  67.      * @param UrlContainerInterface $container
  68.      * @param string|null           $section
  69.      *
  70.      * @throws \InvalidArgumentException
  71.      */
  72.     private function addUrlsFromRoutes(UrlContainerInterface $container, ?string $section): void
  73.     {
  74.         $collection $this->router->getRouteCollection();
  75.         foreach ($collection->all() as $name => $route) {
  76.             $options RouteOptionParser::parse($name$route);
  77.             if (!$options) {
  78.                 continue;
  79.             }
  80.             $routeSection $options['section'] ?? $this->defaultSection;
  81.             if ($section !== null && $routeSection !== $section) {
  82.                 continue;
  83.             }
  84.             $event = new SitemapAddUrlEvent($name$options$this->router);
  85.             $this->dispatcher->dispatch($eventSitemapAddUrlEvent::NAME);
  86.             if (!$event->shouldBeRegistered()) {
  87.                 continue;
  88.             }
  89.             $container->addUrl(
  90.                 $event->getUrl() ?? $this->getUrlConcrete($name$options),
  91.                 $routeSection
  92.             );
  93.         }
  94.     }
  95.     /**
  96.      * @param string       $name    Route name
  97.      * @param RouteOptions $options Node options
  98.      *
  99.      * @return UrlConcrete
  100.      * @throws \InvalidArgumentException
  101.      */
  102.     protected function getUrlConcrete(string $name, array $options): UrlConcrete
  103.     {
  104.         try {
  105.             return new UrlConcrete(
  106.                 $this->getRouteUri($name),
  107.                 $options['lastmod'],
  108.                 $options['changefreq'],
  109.                 $options['priority']
  110.             );
  111.         } catch (\Exception $e) {
  112.             throw new \InvalidArgumentException(
  113.                 sprintf(
  114.                     'Invalid argument for route "%s": %s',
  115.                     $name,
  116.                     $e->getMessage()
  117.                 ),
  118.                 0,
  119.                 $e
  120.             );
  121.         }
  122.     }
  123.     /**
  124.      * @param string               $name   Route name
  125.      * @param array<string, mixed> $params Route additional parameters
  126.      *
  127.      * @return string
  128.      * @throws \InvalidArgumentException
  129.      */
  130.     protected function getRouteUri(string $name, array $params = []): string
  131.     {
  132.         // If the route needs additional parameters, we can't add it
  133.         try {
  134.             return $this->router->generate($name$paramsUrlGeneratorInterface::ABSOLUTE_URL);
  135.         } catch (MissingMandatoryParametersException $e) {
  136.             throw new \InvalidArgumentException(
  137.                 sprintf(
  138.                     'The route "%s" cannot have the sitemap option because it requires parameters other than "%s"',
  139.                     $name,
  140.                     implode('", "'array_keys($params))
  141.                 ),
  142.                 0,
  143.                 $e
  144.             );
  145.         }
  146.     }
  147. }