vendor/sulu/sulu/src/Sulu/Bundle/WebsiteBundle/Controller/SitemapController.php line 90

  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\WebsiteBundle\Controller;
  11. use Sulu\Bundle\HttpCacheBundle\Cache\SuluHttpCache;
  12. use Sulu\Bundle\WebsiteBundle\Sitemap\SitemapProviderPoolInterface;
  13. use Sulu\Bundle\WebsiteBundle\Sitemap\XmlSitemapDumperInterface;
  14. use Sulu\Bundle\WebsiteBundle\Sitemap\XmlSitemapRendererInterface;
  15. use Symfony\Component\Filesystem\Filesystem;
  16. use Symfony\Component\HttpFoundation\BinaryFileResponse;
  17. use Symfony\Component\HttpFoundation\RedirectResponse;
  18. use Symfony\Component\HttpFoundation\Request;
  19. use Symfony\Component\HttpFoundation\Response;
  20. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  21. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  22. /**
  23.  * Renders a xml sitemap.
  24.  */
  25. class SitemapController
  26. {
  27.     /**
  28.      * @var XmlSitemapRendererInterface
  29.      */
  30.     private $xmlSitemapRenderer;
  31.     /**
  32.      * @var SitemapProviderPoolInterface
  33.      */
  34.     private $sitemapProviderPool;
  35.     /**
  36.      * @var XmlSitemapDumperInterface
  37.      */
  38.     private $xmlSitemapDumper;
  39.     /**
  40.      * @var Filesystem
  41.      */
  42.     private $filesystem;
  43.     /**
  44.      * @var UrlGeneratorInterface
  45.      */
  46.     private $router;
  47.     /**
  48.      * @var int
  49.      */
  50.     private $cacheLifeTime;
  51.     /**
  52.      * @var bool
  53.      */
  54.     private $debug;
  55.     public function __construct(
  56.         XmlSitemapRendererInterface $xmlSitemapRenderer,
  57.         SitemapProviderPoolInterface $sitemapProviderPool,
  58.         XmlSitemapDumperInterface $xmlSitemapDumper,
  59.         Filesystem $filesystem,
  60.         UrlGeneratorInterface $router,
  61.         int $cacheLifeTime,
  62.         bool $debug false
  63.     ) {
  64.         $this->xmlSitemapRenderer $xmlSitemapRenderer;
  65.         $this->sitemapProviderPool $sitemapProviderPool;
  66.         $this->xmlSitemapDumper $xmlSitemapDumper;
  67.         $this->filesystem $filesystem;
  68.         $this->router $router;
  69.         $this->cacheLifeTime $cacheLifeTime;
  70.         $this->debug $debug;
  71.     }
  72.     /**
  73.      * Render sitemap-index of all available sitemap.xml files.
  74.      * If only one provider exists this provider will be rendered directly.
  75.      *
  76.      * @return Response
  77.      */
  78.     public function indexAction(Request $request)
  79.     {
  80.         $response $this->getDumpedIndexResponse($request);
  81.         if (!$response) {
  82.             $sitemap $this->xmlSitemapRenderer->renderIndex($request->getScheme(), $request->getHost());
  83.             if (!$sitemap) {
  84.                 $sitemapAlias null;
  85.                 foreach ($this->sitemapProviderPool->getProviders() as $sitemapAlias => $provider) {
  86.                     if ($provider->getMaxPage($request->getScheme(), $request->getHost()) > 0) {
  87.                         $sitemapAlias $provider->getAlias();
  88.                         break;
  89.                     }
  90.                 }
  91.                 if (!$sitemapAlias) {
  92.                     throw new NotFoundHttpException(\sprintf(
  93.                         'No sitemaps found for "%s".',
  94.                         $request->getHttpHost()
  95.                     ));
  96.                 }
  97.                 return $this->sitemapPaginatedAction($request$sitemapAlias1);
  98.             }
  99.             $response = new Response($sitemap);
  100.         }
  101.         $response->headers->set('Content-Type''application/xml');
  102.         return $this->setCacheLifetime($response);
  103.     }
  104.     /**
  105.      * Returns index-response if dumped file exists.
  106.      *
  107.      * @return null|BinaryFileResponse
  108.      */
  109.     private function getDumpedIndexResponse(Request $request)
  110.     {
  111.         $path $this->xmlSitemapDumper->getIndexDumpPath(
  112.             $request->getScheme(),
  113.             $request->getHost()
  114.         );
  115.         if (!$this->filesystem->exists($path)) {
  116.             return;
  117.         }
  118.         return $this->createBinaryFileResponse($path);
  119.     }
  120.     /**
  121.      * Redirect to the first page of a single sitemap provider.
  122.      *
  123.      * @param string $alias
  124.      *
  125.      * @return Response
  126.      */
  127.     public function sitemapAction($alias)
  128.     {
  129.         if (!$this->sitemapProviderPool->hasProvider($alias)) {
  130.             return new Response(null404);
  131.         }
  132.         return new RedirectResponse(
  133.             $this->router->generate(
  134.                 'sulu_website.paginated_sitemap',
  135.                 ['alias' => $alias'page' => 1]
  136.             ),
  137.             301
  138.         );
  139.     }
  140.     /**
  141.      * Render a single page for a single sitemap.xml provider.
  142.      *
  143.      * @param string $alias
  144.      * @param int $page
  145.      *
  146.      * @return Response
  147.      */
  148.     public function sitemapPaginatedAction(Request $request$alias$page)
  149.     {
  150.         $response $this->getDumpedSitemapResponse($request$alias$page);
  151.         if (!$response) {
  152.             $sitemap $this->xmlSitemapRenderer->renderSitemap(
  153.                 $alias,
  154.                 $page,
  155.                 $request->getScheme(),
  156.                 $request->getHost()
  157.             );
  158.             if (!$sitemap) {
  159.                 return new Response(null404);
  160.             }
  161.             $response = new Response($sitemap);
  162.         }
  163.         $response->headers->set('Content-Type''application/xml');
  164.         return $this->setCacheLifetime($response);
  165.     }
  166.     /**
  167.      * Returns index-response if dumped file exists.
  168.      *
  169.      * @param string $alias
  170.      * @param int $page
  171.      *
  172.      * @return null|BinaryFileResponse
  173.      */
  174.     private function getDumpedSitemapResponse(Request $request$alias$page)
  175.     {
  176.         $path $this->xmlSitemapDumper->getDumpPath(
  177.             $request->getScheme(),
  178.             $request->getHttpHost(),
  179.             $alias,
  180.             $page
  181.         );
  182.         if (!$this->filesystem->exists($path)) {
  183.             return;
  184.         }
  185.         return $this->createBinaryFileResponse($path);
  186.     }
  187.     /**
  188.      * Set cache headers.
  189.      *
  190.      * @return Response
  191.      */
  192.     private function setCacheLifetime(Response $response)
  193.     {
  194.         $response->headers->set(
  195.             SuluHttpCache::HEADER_REVERSE_PROXY_TTL,
  196.             $response->getAge() + $this->cacheLifeTime
  197.         );
  198.         if ($this->debug) {
  199.             return $response;
  200.         }
  201.         return $response->setMaxAge(240)
  202.             ->setSharedMaxAge(960);
  203.     }
  204.     /**
  205.      * Create a binary file response.
  206.      *
  207.      * @param string $file
  208.      *
  209.      * @return BinaryFileResponse
  210.      */
  211.     private function createBinaryFileResponse($file)
  212.     {
  213.         $response = new BinaryFileResponse($file);
  214.         $response->headers->addCacheControlDirective('no-store'true);
  215.         return $response;
  216.     }
  217. }