vendor/presta/sitemap-bundle/src/EventListener/StaticRoutesAlternateEventListener.php line 62

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\Sitemap\Url\GoogleMultilangUrlDecorator;
  13. use Presta\SitemapBundle\Sitemap\Url\UrlConcrete;
  14. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  15. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  16. /**
  17.  * Listen to "presta_sitemap.add_url" event.
  18.  * Decorate translatable Url with multi-lang alternatives.
  19.  * Support both Symfony translated routes & JMSI18nRoutingBundle.
  20.  */
  21. final class StaticRoutesAlternateEventListener implements EventSubscriberInterface
  22. {
  23.     private const TRANSLATED_ROUTE_NAME_STRATEGIES = [
  24.         'symfony' => '/^(?P<name>.+)\.(?P<locale>%locales%)$/',
  25.         'jms' => '/^(?P<locale>%locales%)__RG__(?P<name>.+)$/',
  26.     ];
  27.     /**
  28.      * @var UrlGeneratorInterface
  29.      */
  30.     private $router;
  31.     /**
  32.      * @var array<string, mixed>
  33.      */
  34.     private $options;
  35.     /**
  36.      * @param UrlGeneratorInterface $router
  37.      * @param array<string, mixed>  $options
  38.      */
  39.     public function __construct(UrlGeneratorInterface $router, array $options)
  40.     {
  41.         $this->router $router;
  42.         $this->options $options;
  43.     }
  44.     /**
  45.      * @inheritdoc
  46.      */
  47.     public static function getSubscribedEvents(): array
  48.     {
  49.         return [
  50.             SitemapAddUrlEvent::class => 'addAlternate',
  51.         ];
  52.     }
  53.     public function addAlternate(SitemapAddUrlEvent $event): void
  54.     {
  55.         $name $event->getRoute();
  56.         $options $event->getOptions();
  57.         $info $this->getTranslatedRouteInfo($name);
  58.         if ($info === null) {
  59.             return; // not a supported translated route
  60.         }
  61.         [$translatedName$locale] = $info;
  62.         if ($locale !== $this->options['default_locale']) {
  63.             // route is translated, but we are on the non default locale route, should be skipped
  64.             $event->preventRegistration();
  65.             return;
  66.         }
  67.         $url = new GoogleMultilangUrlDecorator(
  68.             new UrlConcrete(
  69.                 $this->generateTranslatedRouteUrl($translatedName$locale),
  70.                 $options['lastmod'],
  71.                 $options['changefreq'],
  72.                 $options['priority']
  73.             )
  74.         );
  75.         foreach ($this->options['locales'] as $alternate) {
  76.             $url->addLink($this->generateTranslatedRouteUrl($translatedName$alternate), $alternate);
  77.         }
  78.         $event->setUrl($url);
  79.     }
  80.     /**
  81.      * @param string $name
  82.      *
  83.      * @return array{0: string, 1: string}|null
  84.      */
  85.     private function getTranslatedRouteInfo(string $name): ?array
  86.     {
  87.         $pattern self::TRANSLATED_ROUTE_NAME_STRATEGIES[$this->options['i18n']] ?? '';
  88.         $pattern \str_replace('%locales%'\implode('|'$this->options['locales']), $pattern);
  89.         if (!\preg_match($pattern$name$matches)) {
  90.             return null// route name do not match translated route name pattern, skip
  91.         }
  92.         return [$matches['name'], $matches['locale']];
  93.     }
  94.     private function generateTranslatedRouteUrl(string $namestring $locale): string
  95.     {
  96.         return $this->router->generate($name, ['_locale' => $locale], UrlGeneratorInterface::ABSOLUTE_URL);
  97.     }
  98. }