@@ -194,6 +194,12 @@
|
||||
</route>
|
||||
<!-- end newsletter management -->
|
||||
|
||||
<!-- sitemap generator -->
|
||||
<route id="sitemap.process" path="/sitemap">
|
||||
<default key="_controller">Front\Controller\SitemapController::generateAction</default>
|
||||
</route>
|
||||
<!-- end sitemap generator -->
|
||||
|
||||
<!-- Default Route -->
|
||||
<route id="default" path="/{_view}">
|
||||
<default key="_controller">Thelia\Controller\Front\DefaultController::noAction</default>
|
||||
|
||||
157
local/modules/Front/Controller/SitemapController.php
Normal file
157
local/modules/Front/Controller/SitemapController.php
Normal file
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
/*************************************************************************************/
|
||||
/* This file is part of the Thelia package. */
|
||||
/* */
|
||||
/* Copyright (c) OpenStudio */
|
||||
/* email : dev@thelia.net */
|
||||
/* web : http://www.thelia.net */
|
||||
/* */
|
||||
/* For the full copyright and license information, please view the LICENSE.txt */
|
||||
/* file that was distributed with this source code. */
|
||||
/*************************************************************************************/
|
||||
|
||||
|
||||
namespace Front\Controller;
|
||||
|
||||
use Thelia\Controller\Front\BaseFrontController;
|
||||
use Thelia\Core\HttpFoundation\Request;
|
||||
use Thelia\Core\HttpFoundation\Response;
|
||||
use Thelia\Log\Tlog;
|
||||
use Thelia\Model\ConfigQuery;
|
||||
|
||||
/**
|
||||
* Controller uses to generate sitemap.xml
|
||||
*
|
||||
* 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
|
||||
* query parameter.
|
||||
*
|
||||
* @package Front\Controller
|
||||
* @author Julien Chanséaume <jchanseaume@openstudio.fr>
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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`);
|
||||
|
||||
|
||||
47
templates/frontOffice/default/sitemap.html
Normal file
47
templates/frontOffice/default/sitemap.html
Normal file
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0"?>
|
||||
<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}
|
||||
</urlset>
|
||||
Reference in New Issue
Block a user