mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
API CHANGE: Allow cached blocks within control and if blocks, as long as that control or if block is contained within an uncached block, not a cached block (from r101833)
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@112042 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
5e204bc6e0
commit
c5c7dee5f0
@ -694,33 +694,21 @@ class SSViewer_PartialParser {
|
||||
/xS';
|
||||
|
||||
static function process($template, $content) {
|
||||
$parser = new SSViewer_PartialParser($template, $content, 0, array(), 'if', 'false');
|
||||
$parser = new SSViewer_PartialParser($template, $content, 0);
|
||||
$parser->parse();
|
||||
return $parser->generate();
|
||||
}
|
||||
|
||||
function __construct($template, $content, $offset, $keyparts, $conditional, $condition) {
|
||||
function __construct($template, $content, $offset) {
|
||||
$this->template = $template;
|
||||
$this->content = $content;
|
||||
$this->offset = $offset;
|
||||
|
||||
$this->keyparts = $keyparts;
|
||||
$this->conditional = $conditional;
|
||||
$this->condition = $condition;
|
||||
|
||||
$this->blocks = array();
|
||||
}
|
||||
|
||||
function controlcheck($text) {
|
||||
$ifs = preg_match_all('/<'.'% +if +/', $text, $matches);
|
||||
$end_ifs = preg_match_all('/<'.'% +end_if +/', $text, $matches);
|
||||
|
||||
if ($ifs != $end_ifs) throw new Exception('You can\'t have cached or uncached blocks within condition structures');
|
||||
|
||||
$controls = preg_match_all('/<'.'% +control +/', $text, $matches);
|
||||
$end_controls = preg_match_all('/<'.'% +end_control +/', $text, $matches);
|
||||
|
||||
if ($controls != $end_controls) throw new Exception('You can\'t have cached or uncached blocks within control structures');
|
||||
// NOP - hook for Cached_PartialParser
|
||||
}
|
||||
|
||||
function parse() {
|
||||
@ -743,12 +731,12 @@ class SSViewer_PartialParser {
|
||||
|
||||
if ($tag == 'cached' || $tag == 'cacheblock') {
|
||||
list($keyparts, $conditional, $condition) = $this->parseargs(@$matches[2][0]);
|
||||
$parser = new SSViewer_Cached_PartialParser($this->template, $this->content, $endpos, $keyparts, $conditional, $condition);
|
||||
}
|
||||
else {
|
||||
$keyparts = array(); $conditional = 'if'; $condition = 'false';
|
||||
$parser = new SSViewer_PartialParser($this->template, $this->content, $endpos);
|
||||
}
|
||||
|
||||
$parser = new SSViewer_PartialParser($this->template, $this->content, $endpos, $keyparts, $conditional, $condition);
|
||||
$parser->parse();
|
||||
$this->blocks[] = $parser;
|
||||
$this->offset = $parser->offset;
|
||||
@ -832,13 +820,49 @@ class SSViewer_PartialParser {
|
||||
return array($parts, $conditional, $condition);
|
||||
}
|
||||
|
||||
function generate() {
|
||||
$res = array();
|
||||
|
||||
foreach ($this->blocks as $i => $block) {
|
||||
if ($block instanceof SSViewer_PartialParser)
|
||||
$res[] = $block->generate();
|
||||
else {
|
||||
$res[] = $block;
|
||||
}
|
||||
}
|
||||
|
||||
return implode('', $res);
|
||||
}
|
||||
}
|
||||
|
||||
class SSViewer_Cached_PartialParser extends SSViewer_PartialParser {
|
||||
|
||||
function __construct($template, $content, $offset, $keyparts, $conditional, $condition) {
|
||||
$this->keyparts = $keyparts;
|
||||
$this->conditional = $conditional;
|
||||
$this->condition = $condition;
|
||||
|
||||
parent::__construct($template, $content, $offset);
|
||||
}
|
||||
|
||||
function controlcheck($text) {
|
||||
$ifs = preg_match_all('/<'.'% +if +/', $text, $matches);
|
||||
$end_ifs = preg_match_all('/<'.'% +end_if +/', $text, $matches);
|
||||
|
||||
if ($ifs != $end_ifs) throw new Exception('You can\'t have cached or uncached blocks within condition structures');
|
||||
|
||||
$controls = preg_match_all('/<'.'% +control +/', $text, $matches);
|
||||
$end_controls = preg_match_all('/<'.'% +end_control +/', $text, $matches);
|
||||
|
||||
if ($controls != $end_controls) throw new Exception('You can\'t have cached or uncached blocks within control structures');
|
||||
}
|
||||
|
||||
function key() {
|
||||
if (empty($this->keyparts)) return "''";
|
||||
return 'sha1(' . implode(".'_'.", $this->keyparts) . ')';
|
||||
}
|
||||
|
||||
function generate() {
|
||||
|
||||
$res = array();
|
||||
$key = $this->key();
|
||||
|
||||
@ -863,26 +887,15 @@ class SSViewer_PartialParser {
|
||||
// of cache blocks, and invalidation of the cache when the template changes
|
||||
$partialkey = "'".sha1($this->template . $block)."_'.$key.'_$i'";
|
||||
|
||||
$knownUncached = array(
|
||||
'if' => array('false', '0'),
|
||||
'unless' => array('true', '1')
|
||||
);
|
||||
// Try to load from cache
|
||||
$res[] = "<?\n".'if ('.$condition.' ($partial = $cache->load('.$partialkey.'))) $val .= $partial;'."\n";
|
||||
|
||||
// Optimized version if we know condition is false
|
||||
if ($this->conditional && in_array($this->condition, $knownUncached[$this->conditional])) {
|
||||
$res[] = $block;
|
||||
}
|
||||
else {
|
||||
// Try to load from cache
|
||||
$res[] = "<?\n".'if ('.$condition.' ($partial = $cache->load('.$partialkey.'))) $val .= $partial;'."\n";
|
||||
|
||||
// Cache miss - regenerate
|
||||
$res[] = "else {\n";
|
||||
$res[] = '$oldval = $val; $val = "";'."\n";
|
||||
$res[] = "\n?>" . $block . "<?\n";
|
||||
$res[] = $condition . ' $cache->save($val); $val = $oldval . $val ;'."\n";
|
||||
$res[] = "}\n?>";
|
||||
}
|
||||
// Cache miss - regenerate
|
||||
$res[] = "else {\n";
|
||||
$res[] = '$oldval = $val; $val = "";'."\n";
|
||||
$res[] = "\n?>" . $block . "<?\n";
|
||||
$res[] = $condition . ' $cache->save($val); $val = $oldval . $val ;'."\n";
|
||||
$res[] = "}\n?>";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -189,17 +189,22 @@ class SSViewerCacheBlockTest extends SapphireTest {
|
||||
/**
|
||||
* @expectedException Exception
|
||||
*/
|
||||
function testErrorMessageForCacheWithinControl() {
|
||||
function testErrorMessageForCachedWithinControlWithinCached() {
|
||||
$this->_reset(true);
|
||||
$this->_runtemplate('<% control Foo %><% cached %>$Bar<% end_cached %><% end_control %>');
|
||||
$this->_runtemplate('<% cached %><% control Foo %><% cached %>$Bar<% end_cached %><% end_control %><% end_cached %>');
|
||||
}
|
||||
|
||||
function testNoErrorMessageForCachedWithinControlWithinUncached() {
|
||||
$this->_reset(true);
|
||||
$this->_runtemplate('<% uncached %><% control Foo %><% cached %>$Bar<% end_cached %><% end_control %><% end_uncached %>');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Exception
|
||||
*/
|
||||
function testErrorMessageForCacheWithinIf() {
|
||||
function testErrorMessageForCachedWithinIf() {
|
||||
$this->_reset(true);
|
||||
$this->_runtemplate('<% if Foo %><% cached %>$Bar<% end_cached %><% end_if %>');
|
||||
$this->_runtemplate('<% cached %><% if Foo %><% cached %>$Bar<% end_cached %><% end_if %><% end_cached %>');
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user