ENHANCEMENT FilesystemPublisher no longer wipes out the whole cache, but removes pages that are not on the live site, but rebuilds the files one by one. It also now hooks into onAfterUnpublish() to remove files from the cache when they are removed from the CMS. If for some reason this fails, it will be picked up when a /dev/buildcache is done.

CHANGE default fileextension is now html (was null)

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/trunk@82470 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Tom Rix 2009-07-22 22:57:02 +00:00
parent f7566166fb
commit f1ab64fb50
3 changed files with 96 additions and 27 deletions

View File

@ -3,6 +3,9 @@
/**
* Usage: Object::add_extension("SiteTree", "FilesystemPublisher('../static-folder/')")
*
* You may also have a method $page->pagesAffectedByUnpublishing() to return other URLS
* that should be de-cached if $page is unpublished.
*
* @see http://doc.silverstripe.com/doku.php?id=staticpublisher
*
* @package cms
@ -10,7 +13,7 @@
*/
class FilesystemPublisher extends StaticPublisher {
protected $destFolder;
protected $fileExtension;
protected $fileExtension = 'html';
protected static $static_base_url = null;
@ -41,21 +44,62 @@ class FilesystemPublisher extends StaticPublisher {
parent::__construct();
}
function publishPages($urls) {
function urlsToPaths($urls) {
$mappedUrls = array();
foreach($urls as $url) {
$urlParts = @parse_url($url);
$urlParts['path'] = isset($urlParts['path']) ? $urlParts['path'] : '';
$urlSegment = preg_replace('/[^a-zA-Z0-9]/si', '_', trim($urlParts['path'], '/'));
$filename = $urlSegment ? "$urlSegment.$this->fileExtension" : "index.$this->fileExtension";
if (self::$domain_based_caching) {
if (!$urlParts) continue; // seriously malformed url here...
$filename = $urlParts['host'] . '/' . $filename;
}
$mappedUrls[$url] = ((dirname($filename) == '/') ? '' : (dirname($filename).'/')).basename($filename);
}
return $mappedUrls;
}
function unpublishPages($urls) {
// Do we need to map these?
// Detect a numerically indexed arrays
if (is_numeric(join('', array_keys($urls)))) $urls = $this->urlsToPaths($urls);
// This can be quite memory hungry and time-consuming
// @todo - Make a more memory efficient publisher
increase_time_limit_to();
increase_memory_limit_to();
//$base = Director::absoluteURL($this->destFolder);
//$base = preg_replace('/\/[^\/]+\/\.\./','',$base) . '/';
$cacheBaseDir = $this->getDestDir();
foreach($urls as $url => $path) {
if (file_exists($cacheBaseDir.'/'.$path)) {
@unlink($cacheBaseDir.'/'.$path);
}
}
}
function publishPages($urls) {
// Do we need to map these?
// Detect a numerically indexed arrays
if (is_numeric(join('', array_keys($urls)))) $urls = $this->urlsToPaths($urls);
// This can be quite memory hungry and time-consuming
// @todo - Make a more memory efficient publisher
increase_time_limit_to();
increase_memory_limit_to();
$currentBaseURL = Director::baseURL();
if(self::$static_base_url) Director::setBaseURL(self::$static_base_url);
$files = array();
$i = 0;
$totalURLs = sizeof($urls);
foreach($urls as $url) {
foreach($urls as $url => $path) {
$i++;
if($url && !is_string($url)) {
@ -101,23 +145,10 @@ class FilesystemPublisher extends StaticPublisher {
}
}
$urlParts = @parse_url($url);
$urlParts['path'] = isset($urlParts['path']) ? $urlParts['path'] : '';
$url = preg_replace('/[^a-zA-Z0-9]/si', '_', trim($urlParts['path'], '/'));
if($this->fileExtension) $filename = $url ? "$url.$this->fileExtension" : "index.$this->fileExtension";
else $filename = $url ? "$url/index.html" : "index.html";
if (self::$domain_based_caching) {
if (!$urlParts) continue; // seriously malformed url here...
$filename = $urlParts['host'] . '/' . $filename;
}
$files[$filename] = array(
$files[] = array(
'Content' => $content,
'Folder' => (dirname($filename) == '/') ? '' : (dirname($filename).'/'),
'Filename' => basename($filename),
'Folder' => dirname($path).'/',
'Filename' => basename($path),
);
// Add externals
@ -147,8 +178,8 @@ class FilesystemPublisher extends StaticPublisher {
}*/
}
if(self::$static_base_url) Director::setBaseURL(null);
if(self::$static_base_url) Director::setBaseURL($currentBaseURL);
$base = "../$this->destFolder";
foreach($files as $file) {
Filesystem::makeFolder("$base/$file[Folder]");
@ -183,6 +214,10 @@ class FilesystemPublisher extends StaticPublisher {
array($destination),
$template);
}
public function getDestDir() {
return '../'.$this->destFolder;
}
}
?>

View File

@ -12,6 +12,7 @@ abstract class StaticPublisher extends DataObjectDecorator {
static $echo_progress = false;
abstract function publishPages($pages);
abstract function unpublishPages($pages);
static function echo_progress() {
return (boolean)self::$echo_progress;
@ -52,6 +53,21 @@ abstract class StaticPublisher extends DataObjectDecorator {
$this->publishPages($urls);
}
/**
* On after unpublish, get changes and hook into underlying
* functionality
*/
function onAfterUnpublish($page) {
if($this->owner->hasMethod('pagesAffectedByUnpublishing')) {
$urls = $this->owner->pagesAffectedByUnpublishing();
$urls = array_unique($urls);
} else {
$urls = array($this->owner->AbsoluteLink());
}
$this->unpublishPages($urls);
}
/**
* Get all external references to CSS, JS,

View File

@ -55,6 +55,8 @@ class RebuildStaticCacheTask extends Controller {
$urls = array_unique($urls);
sort($urls);
$mappedUrls = $page->urlsToPaths($urls);
$start = isset($_GET['start']) ? $_GET['start'] : 0;
$count = isset($_GET['count']) ? $_GET['count'] : sizeof($urls);
if(($start + $count) > sizeof($urls)) $count = sizeof($urls) - $start;
@ -62,13 +64,29 @@ class RebuildStaticCacheTask extends Controller {
$urls = array_slice($urls, $start, $count);
if(!isset($_GET['urls']) && $start == 0 && file_exists("../cache")) {
echo "Removing old cache... \n";
echo "Removing stale cache files... \n";
flush();
Filesystem::removeFolder("../cache", true);
$cacheBaseDir = $page->getDestDir();
if (FilesystemPublisher::$domain_based_caching) {
// Glob each dir, then glob each one of those
foreach(glob('../cache/*', GLOB_ONLYDIR) as $cacheDir) {
foreach(glob($cacheDir.'/*') as $cacheFile) {
$searchCacheFile = trim(str_replace($cacheBaseDir, '', $cacheFile), '\/');
if (!in_array($searchCacheFile, $mappedUrls)) {
echo " * Deleting $cacheFile\n";
@unlink($cacheFile);
}
}
}
} else {
}
echo "done.\n\n";
}
echo "Republishing " . sizeof($urls) . " urls...\n\n";
$page->publishPages($urls);
echo "Rebuilding cache from " . sizeof($mappedUrls) . " urls...\n\n";
$page->publishPages($mappedUrls);
echo "\n\n== Done! ==";
}