vendor/presta/sitemap-bundle/src/Service/AbstractGenerator.php line 166

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\Service;
  11. use Presta\SitemapBundle\Event\SitemapPopulateEvent;
  12. use Presta\SitemapBundle\Sitemap\Sitemapindex;
  13. use Presta\SitemapBundle\Sitemap\Url\Url;
  14. use Presta\SitemapBundle\Sitemap\Url\UrlConcrete;
  15. use Presta\SitemapBundle\Sitemap\Url\UrlDecorator;
  16. use Presta\SitemapBundle\Sitemap\Urlset;
  17. use Symfony\Component\EventDispatcher\EventDispatcherInterface;
  18. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  19. /**
  20.  * Base class for all sitemap generators.
  21.  */
  22. abstract class AbstractGenerator implements UrlContainerInterface
  23. {
  24.     /**
  25.      * @var EventDispatcherInterface
  26.      */
  27.     protected $dispatcher;
  28.     /**
  29.      * @var Sitemapindex|null
  30.      */
  31.     protected $root;
  32.     /**
  33.      * @var Urlset[]
  34.      */
  35.     protected $urlsets = [];
  36.     /**
  37.      * The maximum number of item generated in a sitemap
  38.      * @var int
  39.      */
  40.     protected $itemsBySet;
  41.     /**
  42.      * @var UrlGeneratorInterface|null
  43.      */
  44.     protected $urlGenerator;
  45.     /**
  46.      * @var array<string, mixed>
  47.      */
  48.     private $defaults;
  49.     /**
  50.      * @param EventDispatcherInterface   $dispatcher
  51.      * @param int|null                   $itemsBySet
  52.      * @param UrlGeneratorInterface|null $urlGenerator
  53.      */
  54.     public function __construct(
  55.         EventDispatcherInterface $dispatcher,
  56.         int $itemsBySet null,
  57.         UrlGeneratorInterface $urlGenerator null
  58.     ) {
  59.         if (!$urlGenerator) {
  60.             @trigger_error(
  61.                 'Not injecting the $urlGenerator is deprecated and will be required in 4.0.',
  62.                 \E_USER_DEPRECATED
  63.             );
  64.         }
  65.         $this->dispatcher $dispatcher;
  66.         // We add one to LIMIT_ITEMS because it was used as an index, not a quantity
  67.         $this->itemsBySet = ($itemsBySet === null) ? Sitemapindex::LIMIT_ITEMS $itemsBySet;
  68.         $this->urlGenerator $urlGenerator;
  69.         $this->defaults = [
  70.             'priority' => 1,
  71.             'changefreq' => UrlConcrete::CHANGEFREQ_DAILY,
  72.             'lastmod' => 'now',
  73.         ];
  74.     }
  75.     /**
  76.      * @param array<string, mixed> $defaults
  77.      */
  78.     public function setDefaults(array $defaults): void
  79.     {
  80.         $this->defaults $defaults;
  81.     }
  82.     /**
  83.      * @inheritdoc
  84.      */
  85.     public function addUrl(Url $urlstring $section): void
  86.     {
  87.         $urlset $this->getUrlset($section);
  88.         // Compare the number of items in the urlset against the maximum
  89.         // allowed and check the maximum of 50k sitemap in sitemapindex
  90.         $i 0;
  91.         while ((count($urlset) >= $this->itemsBySet || $urlset->isFull()) && $i <= Sitemapindex::LIMIT_ITEMS) {
  92.             $urlset $this->getUrlset($section '_' $i);
  93.             $i++;
  94.         }
  95.         if (count($urlset) >= $this->itemsBySet || $urlset->isFull()) {
  96.             throw new \RuntimeException('The limit of sitemapindex has been exceeded');
  97.         }
  98.         $concreteUrl $this->getUrlConcrete($url);
  99.         if ($concreteUrl instanceof UrlConcrete) {
  100.             if (null === $concreteUrl->getLastmod() && null !== $this->defaults['lastmod']) {
  101.                 $concreteUrl->setLastmod(new \DateTimeImmutable($this->defaults['lastmod']));
  102.             }
  103.             if (null === $concreteUrl->getChangefreq()) {
  104.                 $concreteUrl->setChangefreq($this->defaults['changefreq']);
  105.             }
  106.             if (null === $concreteUrl->getPriority()) {
  107.                 $concreteUrl->setPriority($this->defaults['priority']);
  108.             }
  109.         }
  110.         $urlset->addUrl($url);
  111.     }
  112.     /**
  113.      * get or create urlset
  114.      *
  115.      * @param string $name
  116.      *
  117.      * @return Urlset
  118.      */
  119.     public function getUrlset(string $name): Urlset
  120.     {
  121.         if (!isset($this->urlsets[$name])) {
  122.             $this->urlsets[$name] = $this->newUrlset($name);
  123.         }
  124.         return $this->urlsets[$name];
  125.     }
  126.     /**
  127.      * Factory method for create Urlsets
  128.      *
  129.      * @param string                  $name
  130.      * @param \DateTimeInterface|null $lastmod
  131.      *
  132.      * @return Urlset
  133.      */
  134.     abstract protected function newUrlset(string $name\DateTimeInterface $lastmod null): Urlset;
  135.     /**
  136.      * Dispatches SitemapPopulate Event - the listeners should use it to add their URLs to the sitemap
  137.      *
  138.      * @param string|null $section
  139.      */
  140.     protected function populate(string $section null): void
  141.     {
  142.         $event = new SitemapPopulateEvent($this$section$this->urlGenerator);
  143.         $this->dispatcher->dispatch($eventSitemapPopulateEvent::ON_SITEMAP_POPULATE);
  144.     }
  145.     /**
  146.      * @return Sitemapindex
  147.      */
  148.     protected function getRoot(): Sitemapindex
  149.     {
  150.         if (null === $this->root) {
  151.             $this->root = new Sitemapindex();
  152.             foreach ($this->urlsets as $urlset) {
  153.                 $this->root->addSitemap($urlset);
  154.             }
  155.         }
  156.         return $this->root;
  157.     }
  158.     /**
  159.      * @param Url $url
  160.      *
  161.      * @return Url|null
  162.      */
  163.     private function getUrlConcrete(Url $url): ?Url
  164.     {
  165.         if ($url instanceof UrlConcrete) {
  166.             return $url;
  167.         }
  168.         if ($url instanceof UrlDecorator) {
  169.             return $this->getUrlConcrete($url->getUrlDecorated());
  170.         }
  171.         return null;
  172.     }
  173. }