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

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\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 \Symfony\Component\HttpFoundation\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, $sitemapAlias, 1);
  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(null, 404);
  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(null, 404);
  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. }