local/modules/Front/Controller/SitemapController.php line 52

  1. <?php
  2. /*
  3.  * This file is part of the Thelia package.
  4.  * http://www.thelia.net
  5.  *
  6.  * (c) OpenStudio <info@thelia.net>
  7.  *
  8.  * For the full copyright and license information, please view the LICENSE
  9.  * file that was distributed with this source code.
  10.  */
  11. namespace Front\Controller;
  12. use Symfony\Component\Cache\Adapter\AdapterInterface;
  13. use Thelia\Controller\Front\BaseFrontController;
  14. use Thelia\Core\HttpFoundation\Request;
  15. use Thelia\Core\HttpFoundation\Response;
  16. use Thelia\Model\ConfigQuery;
  17. use Thelia\Model\LangQuery;
  18. /**
  19.  * Controller uses to generate sitemap.xml.
  20.  *
  21.  * A default cache of 2 hours is used to avoid attack. You can flush cache if you have `ADMIN` role and pass flush=1 in
  22.  * query string parameter.
  23.  *
  24.  * You can generate sitemap according to specific language and/or specific context (catalog/content). You have to
  25.  * use ```lang``` and ```context``` query string parameters to do so. If a language is not used in website or if the
  26.  * context is not supported the page not found is displayed.
  27.  *
  28.  * {url}/sitemap?lang=fr&context=catalog will generate a sitemap for catalog (categories and products)
  29.  * for french language.
  30.  *
  31.  * @author Julien Chanséaume <jchanseaume@openstudio.fr>
  32.  */
  33. class SitemapController extends BaseFrontController
  34. {
  35.     /**
  36.      * Folder name for sitemap cache.
  37.      */
  38.     public const SITEMAP_CACHE_DIR 'sitemap';
  39.     /**
  40.      * Key prefix for sitemap cache.
  41.      */
  42.     public const SITEMAP_CACHE_KEY 'sitemap';
  43.     /**
  44.      * @return Response
  45.      */
  46.     public function generateAction()
  47.     {
  48.         /** @var Request $request */
  49.         $request $this->getRequest();
  50.         // the locale : fr, en,
  51.         $lang $request->query->get('lang''');
  52.         if ('' !== $lang) {
  53.             if (!$this->checkLang($lang)) {
  54.                 $this->pageNotFound();
  55.             }
  56.         }
  57.         // specific content : product, category, cms
  58.         $context $request->query->get('context''');
  59.         if (!\in_array($context, ['''catalog''content'])) {
  60.             $this->pageNotFound();
  61.         }
  62.         $flush $request->query->get('flush''');
  63.         /** @var AdapterInterface $cacheAdapter */
  64.         $cacheAdapter $this->container->get('thelia.cache');
  65.         $cacheKey self::SITEMAP_CACHE_KEY.$lang.$context;
  66.         $cacheItem $cacheAdapter->getItem($cacheKey);
  67.         if (!$cacheItem->isHit() || $flush) {
  68.             $cacheExpire = (int) (ConfigQuery::read('sitemap_ttl''7200')) ?: 7200;
  69.             // Render the view. Compression causes problems and is deactivated.
  70.             $cacheContent $this->getParser(null)->render(
  71.                 'sitemap.html',
  72.                 [
  73.                     '_lang_' => $lang,
  74.                     '_context_' => $context,
  75.                 ],
  76.                 false
  77.             );
  78.             $cacheItem->expiresAfter($cacheExpire);
  79.             $cacheItem->set($cacheContent);
  80.             $cacheAdapter->save($cacheItem);
  81.         }
  82.         $response = new Response();
  83.         $response->setContent($cacheItem->get());
  84.         $response->headers->set('Content-Type''application/xml');
  85.         return $response;
  86.     }
  87.     /**
  88.      * get the cache directory for sitemap.
  89.      *
  90.      * @return mixed|string
  91.      */
  92.     protected function getCacheDir()
  93.     {
  94.         $cacheDir $this->container->getParameter('kernel.cache_dir');
  95.         $cacheDir rtrim($cacheDir'/');
  96.         $cacheDir .= '/'.self::SITEMAP_CACHE_DIR.'/';
  97.         return $cacheDir;
  98.     }
  99.     /**
  100.      * Check if current user has ADMIN role.
  101.      *
  102.      * @return bool
  103.      */
  104.     protected function checkAdmin()
  105.     {
  106.         return $this->getSecurityContext()->hasAdminUser();
  107.     }
  108.     /**
  109.      * Check if a lang is used.
  110.      *
  111.      * @param $lang The lang code. e.g.: fr
  112.      *
  113.      * @return bool true if the language is used, otherwise false
  114.      */
  115.     private function checkLang($lang)
  116.     {
  117.         // load locals
  118.         $lang LangQuery::create()
  119.             ->findOneByCode($lang);
  120.         return null !== $lang;
  121.     }
  122. }