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

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