diff --git a/local/modules/Front/Config/front.xml b/local/modules/Front/Config/front.xml index 319d9b4c2..4f32372a3 100644 --- a/local/modules/Front/Config/front.xml +++ b/local/modules/Front/Config/front.xml @@ -194,6 +194,12 @@ + + + Front\Controller\SitemapController::generateAction + + + Thelia\Controller\Front\DefaultController::noAction diff --git a/local/modules/Front/Controller/SitemapController.php b/local/modules/Front/Controller/SitemapController.php new file mode 100644 index 000000000..422d4247f --- /dev/null +++ b/local/modules/Front/Controller/SitemapController.php @@ -0,0 +1,157 @@ + + */ +class SitemapController extends BaseFrontController { + + + /** + * Folder name for sitemap cache + */ + const SITEMAP_DIR = "sitemap"; + + /** + * Folder name for sitemap cache + */ + const SITEMAP_FILE = "sitemap"; + + /** + * @return Response + */ + public function generateAction() + { + + /** @var Request $request */ + $request = $this->getRequest(); + $flush = $request->query->get("flush", ""); + $expire = ConfigQuery::read("sitemap_ttl", '7200'); + + // check if sitemap already in cache + $cacheDir = $this->getCacheDir(); + $cacheFileURL = $cacheDir . self::SITEMAP_FILE . '.xml'; + $expire = intval($expire) ?: 7200; + $cacheContent = null; + + if (!($this->checkAdmin() && "" !== $flush)){ + try { + $cacheContent = $this->getCache($cacheFileURL, $expire); + } catch (\RuntimeException $ex) { + // Problem loading cache, permission errors ? + Tlog::getInstance()->addAlert($ex->getMessage()); + } + } + + if (null === $cacheContent){ + // render the view + $cacheContent = $this->renderRaw("sitemap"); + + // save cache + try { + $this->setCache($cacheFileURL, $cacheContent); + } catch (\RuntimeException $ex) { + // Problem loading cache, permission errors ? + Tlog::getInstance()->addAlert($ex->getMessage()); + } + + } + + $response = new Response(); + $response->setContent($cacheContent); + $response->headers->set('Content-Type', 'application/xml'); + + return $response; + } + + /** + * Check if current user has ADMIN role + * + * @return bool + */ + protected function checkAdmin(){ + return $this->getSecurityContext()->isGranted(array("ADMIN"), array(), array(), array()); + } + + /** + * Get the content of the file if it exists and not expired? + * + * @param $fileURL path to the file + * @param $expire TTL for the file + * @return null|string The content of the file if it exists and not expired + * @throws \RuntimeException + */ + protected function getCache($fileURL, $expire) + { + $content = null; + if (is_file($fileURL)){ + $mtime = filemtime($fileURL); + if ($mtime + $expire < time()){ + if (! @unlink($fileURL)){ + throw new \RuntimeException(sprintf("Failed to remove %s file in cache directory", $fileURL)); + } + } else { + $content = file_get_contents($fileURL); + } + } + return $content; + } + + /** + * Save content in the file specified by `$fileURL` + * + * @param $fileURL the path to the file + * @param $content the content of the file + * @throws \RuntimeException + */ + protected function setCache($fileURL, $content) + { + if (! @file_put_contents($fileURL, $content)){ + throw new \RuntimeException(sprintf("Failed to save %s file in cache directory", $fileURL)); + } + } + + /** + * Retrieve the cache dir used for sitemaps + * + * @return string the path to the cache dir + * @throws \RuntimeException + */ + protected function getCacheDir() + { + $cacheDir = $this->container->getParameter("kernel.cache_dir"); + $cacheDir = rtrim($cacheDir, '/'); + $cacheDir .= '/' . self::SITEMAP_DIR . '/'; + if (! is_dir($cacheDir)){ + if (! @mkdir($cacheDir, 0777, true)) { + throw new \RuntimeException(sprintf("Failed to create %s dir in cache directory", self::SITEMAP_DIR)); + } + } + return $cacheDir; + } + +} \ No newline at end of file diff --git a/setup/insert.sql b/setup/insert.sql index a8a1bb212..e751f8805 100644 --- a/setup/insert.sql +++ b/setup/insert.sql @@ -45,7 +45,8 @@ INSERT INTO `config` (`name`, `value`, `secured`, `hidden`, `created_at`, `updat ('thelia_release_version','1', 1, 1, NOW(), NOW()), ('thelia_extra_version','', 1, 1, NOW(), NOW()), ('front_cart_country_cookie_name','fcccn', 1, 1, NOW(), NOW()), -('front_cart_country_cookie_expires','2592000', 1, 1, NOW(), NOW()); +('front_cart_country_cookie_expires','2592000', 1, 1, NOW(), NOW()), +('sitemap_ttl','7200', 1, 1, NOW(), NOW()); INSERT INTO `config_i18n` (`id`, `locale`, `title`, `description`, `chapo`, `postscriptum`) VALUES diff --git a/setup/update/2.0.1.sql b/setup/update/2.0.1.sql index cc368353a..7b91f3232 100644 --- a/setup/update/2.0.1.sql +++ b/setup/update/2.0.1.sql @@ -10,6 +10,8 @@ INSERT INTO `config` (`name`, `value`, `secured`, `hidden`, `created_at`, `updat ('front_cart_country_cookie_name','fcccn', 1, 1, NOW(), NOW()); INSERT INTO `config` (`name`, `value`, `secured`, `hidden`, `created_at`, `updated_at`) VALUES ('front_cart_country_cookie_expires','2592000', 1, 1, NOW(), NOW()); +INSERT INTO `config` (`name`, `value`, `secured`, `hidden`, `created_at`, `updated_at`) VALUES +('sitemap_ttl','7200', 1, 1, NOW(), NOW()); ALTER TABLE `module` ADD INDEX `idx_module_activate` (`activate`); diff --git a/templates/frontOffice/default/sitemap.html b/templates/frontOffice/default/sitemap.html new file mode 100644 index 000000000..75d43920f --- /dev/null +++ b/templates/frontOffice/default/sitemap.html @@ -0,0 +1,47 @@ + + + + {url path="/"} + + +{loop type="lang" name="category_lang"} +{loop type="category" name="category" lang="$ID"} + + {$URL} + {format_date date=$UPDATE_DATE format="c"} + {* + You can also set priority and changefreq + 0.8 + weekly + *} + +{/loop} +{/loop} + +{loop type="lang" name="product_lang"} +{loop type="product" name="product" lang="$ID"} + + {$URL} + {format_date date=$UPDATE_DATE format="c"} + +{/loop} +{/loop} + +{loop type="lang" name="folder_lang"} +{loop type="folder" name="folder" lang="$ID"} + + {$URL} + {format_date date=$UPDATE_DATE format="c"} + +{/loop} +{/loop} + +{loop type="lang" name="content_lang"} +{loop type="content" name="content" lang="$ID"} + + {$URL} + {format_date date=$UPDATE_DATE format="c"} + +{/loop} +{/loop} + \ No newline at end of file