sitemap can be generated according to a specific language and/or specific context (catalog, content)
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,47 +1,71 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
generated on : {$smarty.now|date_format:'%Y-%m-%d %H:%M:%S'}
|
||||
{if $_lang_ != "" }lang : {$_lang_}{/if}
|
||||
{if $_context_ != "" }context : {$_context_}{/if}
|
||||
-->
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
<url>
|
||||
<loc>{url path="/"}</loc>
|
||||
</url>
|
||||
<!-- categories -->
|
||||
{loop type="lang" name="category_lang"}
|
||||
{loop type="category" name="category" lang="$ID"}
|
||||
<url>
|
||||
<loc>{$URL}</loc>
|
||||
<lastmod>{format_date date=$UPDATE_DATE format="c"}</lastmod>
|
||||
{*
|
||||
You can also set priority and changefreq
|
||||
<priority>0.8</priority>
|
||||
<changefreq>weekly</changefreq>
|
||||
*}
|
||||
</url>
|
||||
{/loop}
|
||||
{/loop}
|
||||
<!-- products -->
|
||||
{loop type="lang" name="product_lang"}
|
||||
{loop type="product" name="product" lang="$ID"}
|
||||
<url>
|
||||
<loc>{$URL}</loc>
|
||||
<lastmod>{format_date date=$UPDATE_DATE format="c"}</lastmod>
|
||||
</url>
|
||||
{/loop}
|
||||
{/loop}
|
||||
<!-- folders -->
|
||||
{loop type="lang" name="folder_lang"}
|
||||
{loop type="folder" name="folder" lang="$ID"}
|
||||
<url>
|
||||
<loc>{$URL}</loc>
|
||||
<lastmod>{format_date date=$UPDATE_DATE format="c"}</lastmod>
|
||||
</url>
|
||||
{/loop}
|
||||
{/loop}
|
||||
<!-- contents -->
|
||||
{loop type="lang" name="content_lang"}
|
||||
{loop type="content" name="content" lang="$ID"}
|
||||
<url>
|
||||
<loc>{$URL}</loc>
|
||||
<lastmod>{format_date date=$UPDATE_DATE format="c"}</lastmod>
|
||||
</url>
|
||||
{/loop}
|
||||
{/loop}
|
||||
<url>
|
||||
<loc>{url path="/"}</loc>
|
||||
{*
|
||||
You can also set priority and changefreq
|
||||
<priority>0.8</priority>
|
||||
<changefreq>weekly</changefreq>
|
||||
*}
|
||||
</url>
|
||||
|
||||
{if $_context_ == "" || $_context_ == "catalog" }
|
||||
|
||||
<!-- categories -->
|
||||
{loop type="lang" name="category_lang"}
|
||||
{if $_lang_ == "" || $_lang_ == $CODE }
|
||||
{loop type="category" name="category" lang="$ID"}
|
||||
<url>
|
||||
<loc>{$URL}</loc>
|
||||
<lastmod>{format_date date=$UPDATE_DATE format="c"}</lastmod>
|
||||
</url>
|
||||
{/loop}
|
||||
{/if}
|
||||
{/loop}
|
||||
|
||||
<!-- products -->
|
||||
{loop type="lang" name="product_lang"}
|
||||
{if $_lang_ == "" || $_lang_ == $CODE }
|
||||
{loop type="product" name="product" lang="$ID"}
|
||||
<url>
|
||||
<loc>{$URL}</loc>
|
||||
<lastmod>{format_date date=$UPDATE_DATE format="c"}</lastmod>
|
||||
</url>
|
||||
{/loop}
|
||||
{/if}
|
||||
{/loop}
|
||||
|
||||
{/if}
|
||||
|
||||
{if $_context_ == "" || $_context_ == "content" }
|
||||
<!-- folders -->
|
||||
{loop type="lang" name="folder_lang"}
|
||||
{if $_lang_ == "" || $_lang_ == $CODE }
|
||||
{loop type="folder" name="folder" lang="$ID"}
|
||||
<url>
|
||||
<loc>{$URL}</loc>
|
||||
<lastmod>{format_date date=$UPDATE_DATE format="c"}</lastmod>
|
||||
</url>
|
||||
{/loop}
|
||||
{/if}
|
||||
{/loop}
|
||||
|
||||
<!-- contents -->
|
||||
{loop type="lang" name="content_lang"}
|
||||
{if $_lang_ == "" || $_lang_ == $CODE }
|
||||
{loop type="content" name="content" lang="$ID"}
|
||||
<url>
|
||||
<loc>{$URL}</loc>
|
||||
<lastmod>{format_date date=$UPDATE_DATE format="c"}</lastmod>
|
||||
</url>
|
||||
{/loop}
|
||||
{/if}
|
||||
{/loop}
|
||||
{/if}
|
||||
|
||||
</urlset>
|
||||
Reference in New Issue
Block a user