vendor/sulu/article-bundle/Sitemap/ArticleSitemapProvider.php line 198

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of Sulu.
  4.  *
  5.  * (c) Sulu GmbH
  6.  *
  7.  * This source file is subject to the MIT license that is bundled
  8.  * with this source code in the file LICENSE.
  9.  */
  10. namespace Sulu\Bundle\ArticleBundle\Sitemap;
  11. use ONGR\ElasticsearchBundle\Result\DocumentIterator;
  12. use ONGR\ElasticsearchBundle\Service\Manager;
  13. use ONGR\ElasticsearchBundle\Service\Repository;
  14. use ONGR\ElasticsearchDSL\Query\Compound\BoolQuery;
  15. use ONGR\ElasticsearchDSL\Query\TermLevel\TermQuery;
  16. use Sulu\Bundle\ArticleBundle\Document\ArticleViewDocumentInterface;
  17. use Sulu\Bundle\ArticleBundle\Document\Index\DocumentFactoryInterface;
  18. use Sulu\Bundle\WebsiteBundle\Sitemap\Sitemap;
  19. use Sulu\Bundle\WebsiteBundle\Sitemap\SitemapAlternateLink;
  20. use Sulu\Bundle\WebsiteBundle\Sitemap\SitemapProviderInterface;
  21. use Sulu\Bundle\WebsiteBundle\Sitemap\SitemapUrl;
  22. use Sulu\Component\Webspace\Manager\WebspaceManagerInterface;
  23. /**
  24.  * Integrates articles into sitemap.
  25.  */
  26. class ArticleSitemapProvider implements SitemapProviderInterface
  27. {
  28.     /**
  29.      * @var Manager
  30.      */
  31.     private $manager;
  32.     /**
  33.      * @var DocumentFactoryInterface
  34.      */
  35.     private $documentFactory;
  36.     /**
  37.      * @var WebspaceManagerInterface
  38.      */
  39.     private $webspaceManager;
  40.     public function __construct(
  41.         Manager $manager,
  42.         DocumentFactoryInterface $documentFactory,
  43.         WebspaceManagerInterface $webspaceManager
  44.     ) {
  45.         $this->manager $manager;
  46.         $this->documentFactory $documentFactory;
  47.         $this->webspaceManager $webspaceManager;
  48.     }
  49.     public function build($page$scheme$host)
  50.     {
  51.         $repository $this->manager->getRepository($this->documentFactory->getClass('article'));
  52.         $webspaceKeys $this->getWebspaceKeysByHost($host);
  53.         $result = [];
  54.         $from 0;
  55.         $size 1000;
  56.         do {
  57.             $bulk $this->getBulk($repository$webspaceKeys$from$size);
  58.             /** @var SitemapUrl[] $sitemapUrlListByUuid */
  59.             $sitemapUrlListByUuid = [];
  60.             /** @var ArticleViewDocumentInterface $item */
  61.             foreach ($bulk as $item) {
  62.                 // Get all webspace keys which are for the current document and current selected webspaces
  63.                 $itemWebspaceKeys = \array_intersect(
  64.                     \array_merge([$item->getMainWebspace()], $item->getAdditionalWebspaces()),
  65.                     $webspaceKeys
  66.                 );
  67.                 foreach ($itemWebspaceKeys as $itemWebspaceKey) {
  68.                     $url $this->buildUrl($item$scheme$host$itemWebspaceKey);
  69.                     $result[] = $url;
  70.                     $alternativeUrlsKey $itemWebspaceKey '__' $item->getUuid();
  71.                     if (!isset($sitemapUrlListByUuid[$alternativeUrlsKey])) {
  72.                         $sitemapUrlListByUuid[$alternativeUrlsKey] = [];
  73.                     }
  74.                     $sitemapUrlListByUuid[$alternativeUrlsKey] = $this->setAlternatives(
  75.                         $sitemapUrlListByUuid[$alternativeUrlsKey],
  76.                         $url
  77.                     );
  78.                 }
  79.             }
  80.             $from += $size;
  81.         } while ($bulk->count() > $from && $from < static::PAGE_SIZE);
  82.         return $result;
  83.     }
  84.     protected function buildUrl(
  85.         ArticleViewDocumentInterface $articleView,
  86.         string $scheme,
  87.         string $host,
  88.         string $webspaceKey
  89.     ): SitemapUrl {
  90.         return new SitemapUrl(
  91.             $this->findUrl($articleView$scheme$host$webspaceKey),
  92.             $articleView->getLocale(),
  93.             $articleView->getChanged()
  94.         );
  95.     }
  96.     private function findUrl(
  97.         ArticleViewDocumentInterface $articleView,
  98.         string $scheme,
  99.         string $host,
  100.         string $webspaceKey
  101.     ): string {
  102.         return $this->webspaceManager->findUrlByResourceLocator(
  103.             $articleView->getRoutePath(),
  104.             null,
  105.             $articleView->getLocale(),
  106.             $webspaceKey,
  107.             $host,
  108.             $scheme
  109.         );
  110.     }
  111.     /**
  112.      * Set alternatives to sitemap url.
  113.      *
  114.      * @param SitemapUrl[] $sitemapUrlList
  115.      *
  116.      * @return SitemapUrl[]
  117.      */
  118.     private function setAlternatives(array $sitemapUrlListSitemapUrl $sitemapUrl): array
  119.     {
  120.         foreach ($sitemapUrlList as $sitemapUrlFromList) {
  121.             // Add current as alternative to exist.
  122.             $sitemapUrlFromList->addAlternateLink(
  123.                 new SitemapAlternateLink($sitemapUrl->getLoc(), $sitemapUrl->getLocale())
  124.             );
  125.             // Add others as alternative to current.
  126.             $sitemapUrl->addAlternateLink(
  127.                 new SitemapAlternateLink($sitemapUrlFromList->getLoc(), $sitemapUrlFromList->getLocale())
  128.             );
  129.         }
  130.         $sitemapUrlList[] = $sitemapUrl;
  131.         return $sitemapUrlList;
  132.     }
  133.     private function getBulk(Repository $repository, array $webspaceKeysint $fromint $size): DocumentIterator
  134.     {
  135.         $search $repository->createSearch()
  136.             ->addQuery(new TermQuery('seo.hide_in_sitemap''false'))
  137.             ->setFrom($from)
  138.             ->setSize($size);
  139.         $webspaceQuery = new BoolQuery();
  140.         foreach ($webspaceKeys as $webspaceKey) {
  141.             $webspaceQuery->add(new TermQuery('main_webspace'$webspaceKey), BoolQuery::SHOULD);
  142.             $webspaceQuery->add(new TermQuery('additional_webspaces'$webspaceKey), BoolQuery::SHOULD);
  143.         }
  144.         $search->addQuery($webspaceQuery);
  145.         if (\method_exists($search'setTrackTotalHits')) {
  146.             $search->setTrackTotalHits(true);
  147.         }
  148.         return $repository->findDocuments($search);
  149.     }
  150.     public function createSitemap($scheme$host)
  151.     {
  152.         return new Sitemap($this->getAlias(), $this->getMaxPage($scheme$host));
  153.     }
  154.     public function getMaxPage($schema$host)
  155.     {
  156.         $repository $this->manager->getRepository($this->documentFactory->getClass('article'));
  157.         $search $repository->createSearch()
  158.             ->addQuery(new TermQuery('seo.hide_in_sitemap''false'));
  159.         $webspaceKeys $this->getWebspaceKeysByHost($host);
  160.         $webspaceQuery = new BoolQuery();
  161.         foreach ($webspaceKeys as $webspaceKey) {
  162.             $webspaceQuery->add(new TermQuery('main_webspace'$webspaceKey), BoolQuery::SHOULD);
  163.             $webspaceQuery->add(new TermQuery('additional_webspaces'$webspaceKey), BoolQuery::SHOULD);
  164.         }
  165.         return \ceil($repository->count($search) / static::PAGE_SIZE);
  166.     }
  167.     /**
  168.      * @return string[]
  169.      */
  170.     private function getWebspaceKeysByHost(string $host): array
  171.     {
  172.         $portalInformations $this->webspaceManager->findPortalInformationsByHostIncludingSubdomains($host);
  173.         $webspaceKeys = [];
  174.         foreach ($portalInformations as $portalInformation) {
  175.             $webspaceKeys[] = $portalInformation->getWebspaceKey();
  176.         }
  177.         return $webspaceKeys;
  178.     }
  179.     public function getAlias()
  180.     {
  181.         return 'articles';
  182.     }
  183. }