sitemap can be generated according to a specific language and/or specific context (catalog, content)

This commit is contained in:
Julien Chanseaume
2014-05-03 07:04:28 +02:00
parent 24f738c4fe
commit 02e32d7871
2 changed files with 134 additions and 121 deletions

View File

@@ -13,11 +13,13 @@
namespace Front\Controller;
use Doctrine\Common\Cache\FilesystemCache;
use Thelia\Controller\Front\BaseFrontController;
use Thelia\Core\HttpFoundation\Request;
use Thelia\Core\HttpFoundation\Response;
use Thelia\Log\Tlog;
use Thelia\Model\ConfigQuery;
use Thelia\Model\LangQuery;
/**
* Controller uses to generate sitemap.xml
@@ -34,12 +36,12 @@ class SitemapController extends BaseFrontController {
/**
* Folder name for sitemap cache
*/
const SITEMAP_DIR = "sitemap";
const SITEMAP_CACHE_DIR = "sitemap";
/**
* Folder name for sitemap cache
* Key prefix for sitemap cache
*/
const SITEMAP_FILE = "sitemap";
const SITEMAP_CACHE_KEY = "sitemap";
/**
* @return Response
@@ -49,36 +51,48 @@ class SitemapController extends BaseFrontController {
/** @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());
// the locale : fr, en,
$lang = $request->query->get("lang", "");
if ("" !== $lang) {
if (! $this->checkLang($lang)){
$this->pageNotFound();
}
}
// specific content : product, category, cms
$context = $request->query->get("context", "");
if (! in_array($context, array("", "catalog", "content")) ){
$this->pageNotFound();
}
if (null === $cacheContent){
$flush = $request->query->get("flush", "");
// check if sitemap already in cache
$cacheContent = false;
$cacheDir = $this->getCacheDir();
$cacheKey = self::SITEMAP_CACHE_KEY . $lang . $context;
$cacheExpire = intval(ConfigQuery::read("sitemap_ttl", '7200')) ?: 7200;
$cacheDriver = new FilesystemCache($cacheDir);
if (!($this->checkAdmin() && "" !== $flush)){
$cacheContent = $cacheDriver->fetch($cacheKey);
} else {
$cacheDriver->delete($cacheKey);
}
// if not in cache
if (false === $cacheContent){
// render the view
$cacheContent = $this->renderRaw("sitemap");
$cacheContent = $this->renderRaw(
"sitemap",
array(
"_lang_" => $lang,
"_context_" => $context
)
);
// save cache
try {
$this->setCache($cacheFileURL, $cacheContent);
} catch (\RuntimeException $ex) {
// Problem loading cache, permission errors ?
Tlog::getInstance()->addAlert($ex->getMessage());
}
$cacheDriver->save($cacheKey, $cacheContent, $cacheExpire);
}
$response = new Response();
@@ -88,70 +102,45 @@ class SitemapController extends BaseFrontController {
return $response;
}
/**
* get the cache directory for sitemap
*
* @return mixed|string
*/
protected function getCacheDir()
{
$cacheDir = $this->container->getParameter("kernel.cache_dir");
$cacheDir = rtrim($cacheDir, '/');
$cacheDir .= '/' . self::SITEMAP_CACHE_DIR . '/';
return $cacheDir;
}
/**
* Check if current user has ADMIN role
*
* @return bool
*/
protected function checkAdmin(){
return $this->getSecurityContext()->isGranted(array("ADMIN"), array(), array(), array());
return $this->getSecurityContext()->hasAdminUser();
}
/**
* 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`
* Check if a lang is used
*
* @param $fileURL the path to the file
* @param $content the content of the file
* @throws \RuntimeException
* @param $lang The lang code. e.g.: fr
* @return bool true if the language is used, otherwise false
*/
protected function setCache($fileURL, $content)
private function checkLang($lang)
{
if (! @file_put_contents($fileURL, $content)){
throw new \RuntimeException(sprintf("Failed to save %s file in cache directory", $fileURL));
}
}
// load locals
$lang = LangQuery::create()
->findOneByCode($lang);
return (null !== $lang);
/**
* 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;
}
}