BUGFIX: static publisher for a site that resides in a subfolder of webroot

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@103745 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Saophalkun Ponlu 2010-04-29 05:48:48 +00:00 committed by Sam Minnee
parent 9b593dcae5
commit 9c4c3eef2e
2 changed files with 147 additions and 10 deletions

View File

@ -1,7 +1,11 @@
<?php
/**
* Usage: Object::add_extension("SiteTree", "FilesystemPublisher('../static-folder/')")
* Usage: Object::add_extension("SiteTree", "FilesystemPublisher('static-folder', 'html')");
*
* Usage: To work with Subsite module you need to:
* - Add FilesystemPublisher::$domain_based_caching = true; in mysite/_config.php
* - Added main site host mapping in subsites/host-map.php after everytime a new subsite is created or modified
*
* You may also have a method $page->pagesAffectedByUnpublishing() to return other URLS
* that should be de-cached if $page is unpublished.
@ -12,14 +16,27 @@
* @subpackage publishers
*/
class FilesystemPublisher extends StaticPublisher {
protected $destFolder;
/**
* @var String
*/
protected $destFolder = 'cache';
/**
* @var String
*/
protected $fileExtension = 'html';
/**
* @var String
*/
protected static $static_base_url = null;
/**
* Use domain based cacheing (put cache files into a domain subfolder)
* This must be true if you are using this with subsites.
* @var Boolean Use domain based cacheing (put cache files into a domain subfolder)
* This must be true if you are using this with the "subsites" module.
* Please note that this form of caching requires all URLs to be provided absolute
* (not relative to the webroot) via {@link SiteTree->AbsoluteLink()}.
*/
public static $domain_based_caching = false;
@ -32,25 +49,57 @@ class FilesystemPublisher extends StaticPublisher {
}
/**
* @param $destFolder The folder to save the cached site into
* @param $fileExtension The file extension to use, for example, 'html'. If omitted, then each page will be placed
* in its own directory, with the filename 'index.html'. If you set the extension to PHP, then a simple PHP script will
* be generated that can do appropriate cache & redirect header negotation
* @param $destFolder The folder to save the cached site into.
* This needs to be set in sapphire/static-main.php as well through the {@link $cacheBaseDir} variable.
* @param $fileExtension The file extension to use, e.g 'html'.
* If omitted, then each page will be placed in its own directory,
* with the filename 'index.html'. If you set the extension to PHP, then a simple PHP script will
* be generated that can do appropriate cache & redirect header negotation.
*/
function __construct($destFolder, $fileExtension = null) {
// Remove trailing slash from folder
if(substr($destFolder, -1) == '/') $destFolder = substr($destFolder, 0, -1);
$this->destFolder = $destFolder;
$this->fileExtension = $fileExtension;
parent::__construct();
}
/**
* Transforms relative or absolute URLs to their static path equivalent.
* This needs to be the same logic that's used to look up these paths through
* sapphire/static-main.php. Does not include the {@link $destFolder} prefix.
* Replaces various special characters in the resulting filename similar to {@link SiteTree::generateURLSegment()}.
*
* Examples (without $domain_based_caching):
* - http://mysite.com/mywebroot/ => /index.html (assuming your webroot is in a subfolder)
* - http://mysite.com/about-us => /about-us.html
* - http://mysite.com/parent/child => /parent/child.html
*
* Examples (with $domain_based_caching):
* - http://mysite.com/mywebroot/ => /mysite.com/index.html (assuming your webroot is in a subfolder)
* - http://mysite.com/about-us => /mysite.com/about-us.html
* - http://myothersite.com/about-us => /myothersite.com/about-us.html
* - http://subdomain.mysite.com/parent/child => /subdomain.mysite.com/parent/child.html
*
* @param Array $urls Absolute or relative URLs
* @return Array Map of original URLs to filesystem paths (relative to {@link $destFolder}).
*/
function urlsToPaths($urls) {
$mappedUrls = array();
foreach($urls as $url) {
$urlParts = @parse_url($url);
$urlParts['path'] = isset($urlParts['path']) ? $urlParts['path'] : '';
// Remove base folders from the URL if webroot is hosted in a subfolder (same as static-main.php)
$path = isset($urlParts['path']) ? $urlParts['path'] : '';
if(substr(strtolower($path), 0, strlen(BASE_URL)) == strtolower(BASE_URL)) {
$urlSegment = substr($path, strlen(BASE_URL));
} else {
$urlSegment = $path;
}
// perform similar transformations to SiteTree::generateURLSegment()
$urlSegment = $urlParts['path'];
$urlSegment = str_replace('&amp;','-and-',$urlSegment);
$urlSegment = str_replace('&','-and-',$urlSegment);
$urlSegment = ereg_replace('[^A-Za-z0-9\/-]+','-',$urlSegment);
@ -114,7 +163,9 @@ class FilesystemPublisher extends StaticPublisher {
$files = array();
$i = 0;
$totalURLs = sizeof($urls);
foreach($urls as $url => $path) {
if(self::$static_base_url) Director::setBaseURL(self::$static_base_url);
$i++;
@ -129,9 +180,14 @@ class FilesystemPublisher extends StaticPublisher {
}
Requirements::clear();
if(Director::is_relative_url($url)) $url = Director::absoluteURL($url);
$response = Director::test(str_replace('+', ' ', $url));
Requirements::clear();
singleton('DataObject')->flushCache();
// Generate file content

View File

@ -9,20 +9,101 @@ class FilesystemPublisherTest extends SapphireTest {
protected $usesDatabase = true;
protected $orig = array();
function setUp() {
parent::setUp();
Object::add_extension("SiteTree", "FilesystemPublisher('../FilesystemPublisherTest-static-folder/')");
SiteTree::$write_homepage_map = false;
$this->orig['domain_based_caching'] = FilesystemPublisher::$domain_based_caching;
FilesystemPublisher::$domain_based_caching = false;
}
function tearDown() {
Object::remove_extension("SiteTree", "FilesystemPublisher('../FilesystemPublisherTest-static-folder/')");
SiteTree::$write_homepage_map = true;
FilesystemPublisher::$domain_based_caching = $this->orig['domain_based_caching'];
parent::tearDown();
}
function testUrlsToPathsWithRelativeUrls() {
$fsp = new FilesystemPublisher('.', 'html');
$this->assertEquals(
$fsp->urlsToPaths(array('/')),
array('/' => './index.html'),
'Root URL path mapping'
);
$this->assertEquals(
$fsp->urlsToPaths(array('about-us')),
array('about-us' => './about-us.html'),
'URLsegment path mapping'
);
$this->assertEquals(
$fsp->urlsToPaths(array('parent/child')),
array('parent/child' => 'parent/child.html'),
'Nested URLsegment path mapping'
);
}
function testUrlsToPathsWithAbsoluteUrls() {
$fsp = new FilesystemPublisher('.', 'html');
$url = Director::absoluteBaseUrl();
$this->assertEquals(
$fsp->urlsToPaths(array($url)),
array($url => './index.html'),
'Root URL path mapping'
);
$url = Director::absoluteBaseUrl() . 'about-us';
$this->assertEquals(
$fsp->urlsToPaths(array($url)),
array($url => './about-us.html'),
'URLsegment path mapping'
);
$url = Director::absoluteBaseUrl() . 'parent/child';
$this->assertEquals(
$fsp->urlsToPaths(array($url)),
array($url => 'parent/child.html'),
'Nested URLsegment path mapping'
);
}
function testUrlsToPathsWithDomainBasedCaching() {
FilesystemPublisher::$domain_based_caching = true;
$fsp = new FilesystemPublisher('.', 'html');
$url = 'http://domain1.com/';
$this->assertEquals(
$fsp->urlsToPaths(array($url)),
array($url => 'domain1.com/index.html'),
'Root URL path mapping'
);
$url = 'http://domain1.com/about-us';
$this->assertEquals(
$fsp->urlsToPaths(array($url)),
array($url => 'domain1.com/about-us.html'),
'URLsegment path mapping'
);
$url = 'http://domain2.com/parent/child';
$this->assertEquals(
$fsp->urlsToPaths(array($url)),
array($url => 'domain2.com/parent/child.html'),
'Nested URLsegment path mapping'
);
}
/**
* Simple test to ensure that FileSystemPublisher::__construct()
* has called parent::__construct() by checking the class property.