vendor/presta/sitemap-bundle/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 <www.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\Route;
  21. use Symfony\Component\Routing\RouteCollection;
  22. use Symfony\Component\Routing\RouterInterface;
  23. use Symfony\Contracts\EventDispatcher\EventDispatcherInterface as ContractsEventDispatcherInterface;
  24. /**
  25.  * This listener iterate over configured routes, and register allowed URLs to sitemap.
  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()
  54.     {
  55.         return [
  56.             SitemapPopulateEvent::ON_SITEMAP_POPULATE => ['registerRouteAnnotation'0],
  57.         ];
  58.     }
  59.     /**
  60.      * @param SitemapPopulateEvent $event
  61.      */
  62.     public function registerRouteAnnotation(SitemapPopulateEvent $event)
  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)
  73.     {
  74.         $collection $this->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);
  85.             if ($this->dispatcher instanceof ContractsEventDispatcherInterface) {
  86.                 $this->dispatcher->dispatch($eventSitemapAddUrlEvent::NAME);
  87.             } else {
  88.                 $this->dispatcher->dispatch(SitemapAddUrlEvent::NAME$event);
  89.             }
  90.             if (!$event->shouldBeRegistered()) {
  91.                 continue;
  92.             }
  93.             $container->addUrl(
  94.                 $event->getUrl() ?? $this->getUrlConcrete($name$options),
  95.                 $routeSection
  96.             );
  97.         }
  98.     }
  99.     /**
  100.      * @return RouteCollection
  101.      */
  102.     protected function getRouteCollection()
  103.     {
  104.         return $this->router->getRouteCollection();
  105.     }
  106.     /**
  107.      * @deprecated since 2.3.0, use @link RouteOptionParser::parse instead
  108.      *
  109.      * @param string $name
  110.      * @param Route  $route
  111.      *
  112.      * @return array|null
  113.      * @throws \InvalidArgumentException
  114.      */
  115.     public function getOptions($nameRoute $route)
  116.     {
  117.         @trigger_error(
  118.             sprintf(
  119.                 '%s is deprecated since 2.3.0 and will be removed in 3.0.0, use %s::%s instead',
  120.                 __METHOD__,
  121.                 RouteOptionParser::class,
  122.                 'parse'
  123.             ),
  124.             E_USER_DEPRECATED
  125.         );
  126.         return RouteOptionParser::parse($name$route);
  127.     }
  128.     /**
  129.      * @param string $name    Route name
  130.      * @param array  $options Node options
  131.      *
  132.      * @return UrlConcrete
  133.      * @throws \InvalidArgumentException
  134.      */
  135.     protected function getUrlConcrete($name$options)
  136.     {
  137.         try {
  138.             return new UrlConcrete(
  139.                 $this->getRouteUri($name),
  140.                 $options['lastmod'],
  141.                 $options['changefreq'],
  142.                 $options['priority']
  143.             );
  144.         } catch (\Exception $e) {
  145.             throw new \InvalidArgumentException(
  146.                 sprintf(
  147.                     'Invalid argument for route "%s": %s',
  148.                     $name,
  149.                     $e->getMessage()
  150.                 ),
  151.                 0,
  152.                 $e
  153.             );
  154.         }
  155.     }
  156.     /**
  157.      * @param string $name   Route name
  158.      * @param array  $params Route additional parameters
  159.      *
  160.      * @return string
  161.      * @throws \InvalidArgumentException
  162.      */
  163.     protected function getRouteUri($name$params = [])
  164.     {
  165.         // If the route needs additional parameters, we can't add it
  166.         try {
  167.             return $this->router->generate($name$paramsUrlGeneratorInterface::ABSOLUTE_URL);
  168.         } catch (MissingMandatoryParametersException $e) {
  169.             throw new \InvalidArgumentException(
  170.                 sprintf(
  171.                     'The route "%s" cannot have the sitemap option because it requires parameters other than "%s"',
  172.                     $name,
  173.                     implode('", "'array_keys($params))
  174.                 ),
  175.                 0,
  176.                 $e
  177.             );
  178.         }
  179.     }
  180. }