From f1ab64fb502569c1e64f83f185ce49df52b27689 Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Wed, 22 Jul 2009 22:57:02 +0000 Subject: [PATCH] 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 --- code/staticpublisher/FilesystemPublisher.php | 81 ++++++++++++++------ code/staticpublisher/StaticPublisher.php | 16 ++++ tasks/RebuildStaticCacheTask.php | 26 ++++++- 3 files changed, 96 insertions(+), 27 deletions(-) diff --git a/code/staticpublisher/FilesystemPublisher.php b/code/staticpublisher/FilesystemPublisher.php index b1774bdf..e47fddff 100644 --- a/code/staticpublisher/FilesystemPublisher.php +++ b/code/staticpublisher/FilesystemPublisher.php @@ -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; + } } ?> diff --git a/code/staticpublisher/StaticPublisher.php b/code/staticpublisher/StaticPublisher.php index 9afc4027..f043d67a 100644 --- a/code/staticpublisher/StaticPublisher.php +++ b/code/staticpublisher/StaticPublisher.php @@ -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, diff --git a/tasks/RebuildStaticCacheTask.php b/tasks/RebuildStaticCacheTask.php index b0260e23..2af0bb5f 100644 --- a/tasks/RebuildStaticCacheTask.php +++ b/tasks/RebuildStaticCacheTask.php @@ -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! =="; }