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

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. class RouteAnnotationEventListener implements EventSubscriberInterface
  26. {
  27.     /**
  28.      * @var RouterInterface
  29.      */
  30.     protected $router;
  31.     /**
  32.      * @var EventDispatcherInterface
  33.      */
  34.     private $dispatcher;
  35.     /**
  36.      * @var string
  37.      */
  38.     private $defaultSection;
  39.     public function __construct(
  40.         RouterInterface $router,
  41.         EventDispatcherInterface $eventDispatcher,
  42.         string $defaultSection
  43.     ) {
  44.         $this->router $router;
  45.         $this->dispatcher $eventDispatcher;
  46.         $this->defaultSection $defaultSection;
  47.     }
  48.     /**
  49.      * @inheritdoc
  50.      */
  51.     public static function getSubscribedEvents(): array
  52.     {
  53.         return [
  54.             SitemapPopulateEvent::class => ['registerRouteAnnotation'0],
  55.         ];
  56.     }
  57.     /**
  58.      * @param SitemapPopulateEvent $event
  59.      */
  60.     public function registerRouteAnnotation(SitemapPopulateEvent $event): void
  61.     {
  62.         $this->addUrlsFromRoutes($event->getUrlContainer(), $event->getSection());
  63.     }
  64.     /**
  65.      * @param UrlContainerInterface $container
  66.      * @param string|null           $section
  67.      *
  68.      * @throws \InvalidArgumentException
  69.      */
  70.     private function addUrlsFromRoutes(UrlContainerInterface $container, ?string $section): void
  71.     {
  72.         $collection $this->router->getRouteCollection();
  73.         foreach ($collection->all() as $name => $route) {
  74.             $options RouteOptionParser::parse($name$route);
  75.             if (!$options) {
  76.                 continue;
  77.             }
  78.             $routeSection $options['section'] ?? $this->defaultSection;
  79.             if ($section !== null && $routeSection !== $section) {
  80.                 continue;
  81.             }
  82.             $event = new SitemapAddUrlEvent($name$options$this->router);
  83.             $this->dispatcher->dispatch($eventSitemapAddUrlEvent::NAME);
  84.             if (!$event->shouldBeRegistered()) {
  85.                 continue;
  86.             }
  87.             $container->addUrl(
  88.                 $event->getUrl() ?? $this->getUrlConcrete($name$options),
  89.                 $routeSection
  90.             );
  91.         }
  92.     }
  93.     /**
  94.      * @param string               $name    Route name
  95.      * @param array<string, mixed> $options Node options
  96.      *
  97.      * @return UrlConcrete
  98.      * @throws \InvalidArgumentException
  99.      */
  100.     protected function getUrlConcrete(string $name, array $options): UrlConcrete
  101.     {
  102.         try {
  103.             return new UrlConcrete(
  104.                 $this->getRouteUri($name),
  105.                 $options['lastmod'],
  106.                 $options['changefreq'],
  107.                 $options['priority']
  108.             );
  109.         } catch (\Exception $e) {
  110.             throw new \InvalidArgumentException(
  111.                 sprintf(
  112.                     'Invalid argument for route "%s": %s',
  113.                     $name,
  114.                     $e->getMessage()
  115.                 ),
  116.                 0,
  117.                 $e
  118.             );
  119.         }
  120.     }
  121.     /**
  122.      * @param string               $name   Route name
  123.      * @param array<string, mixed> $params Route additional parameters
  124.      *
  125.      * @return string
  126.      * @throws \InvalidArgumentException
  127.      */
  128.     protected function getRouteUri(string $name, array $params = []): string
  129.     {
  130.         // If the route needs additional parameters, we can't add it
  131.         try {
  132.             return $this->router->generate($name$paramsUrlGeneratorInterface::ABSOLUTE_URL);
  133.         } catch (MissingMandatoryParametersException $e) {
  134.             throw new \InvalidArgumentException(
  135.                 sprintf(
  136.                     'The route "%s" cannot have the sitemap option because it requires parameters other than "%s"',
  137.                     $name,
  138.                     implode('", "'array_keys($params))
  139.                 ),
  140.                 0,
  141.                 $e
  142.             );
  143.         }
  144.     }
  145. }