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
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/branches/2.4@101833 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
cfe081dd8b
commit
04299df886
@ -686,33 +686,21 @@ class SSViewer_PartialParser {
|
|||||||
/xS';
|
/xS';
|
||||||
|
|
||||||
static function process($template, $content) {
|
static function process($template, $content) {
|
||||||
$parser = new SSViewer_PartialParser($template, $content, 0, array(), 'if', 'false');
|
$parser = new SSViewer_PartialParser($template, $content, 0);
|
||||||
$parser->parse();
|
$parser->parse();
|
||||||
return $parser->generate();
|
return $parser->generate();
|
||||||
}
|
}
|
||||||
|
|
||||||
function __construct($template, $content, $offset, $keyparts, $conditional, $condition) {
|
function __construct($template, $content, $offset) {
|
||||||
$this->template = $template;
|
$this->template = $template;
|
||||||
$this->content = $content;
|
$this->content = $content;
|
||||||
$this->offset = $offset;
|
$this->offset = $offset;
|
||||||
|
|
||||||
$this->keyparts = $keyparts;
|
|
||||||
$this->conditional = $conditional;
|
|
||||||
$this->condition = $condition;
|
|
||||||
|
|
||||||
$this->blocks = array();
|
$this->blocks = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
function controlcheck($text) {
|
function controlcheck($text) {
|
||||||
$ifs = preg_match_all('/<'.'% +if +/', $text, $matches);
|
// NOP - hook for Cached_PartialParser
|
||||||
$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 parse() {
|
function parse() {
|
||||||
@ -735,12 +723,12 @@ class SSViewer_PartialParser {
|
|||||||
|
|
||||||
if ($tag == 'cached' || $tag == 'cacheblock') {
|
if ($tag == 'cached' || $tag == 'cacheblock') {
|
||||||
list($keyparts, $conditional, $condition) = $this->parseargs(@$matches[2][0]);
|
list($keyparts, $conditional, $condition) = $this->parseargs(@$matches[2][0]);
|
||||||
|
$parser = new SSViewer_Cached_PartialParser($this->template, $this->content, $endpos, $keyparts, $conditional, $condition);
|
||||||
}
|
}
|
||||||
else {
|
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();
|
$parser->parse();
|
||||||
$this->blocks[] = $parser;
|
$this->blocks[] = $parser;
|
||||||
$this->offset = $parser->offset;
|
$this->offset = $parser->offset;
|
||||||
@ -824,13 +812,49 @@ class SSViewer_PartialParser {
|
|||||||
return array($parts, $conditional, $condition);
|
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() {
|
function key() {
|
||||||
if (empty($this->keyparts)) return "''";
|
if (empty($this->keyparts)) return "''";
|
||||||
return 'sha1(' . implode(".'_'.", $this->keyparts) . ')';
|
return 'sha1(' . implode(".'_'.", $this->keyparts) . ')';
|
||||||
}
|
}
|
||||||
|
|
||||||
function generate() {
|
function generate() {
|
||||||
|
|
||||||
$res = array();
|
$res = array();
|
||||||
$key = $this->key();
|
$key = $this->key();
|
||||||
|
|
||||||
@ -855,16 +879,6 @@ class SSViewer_PartialParser {
|
|||||||
// of cache blocks, and invalidation of the cache when the template changes
|
// of cache blocks, and invalidation of the cache when the template changes
|
||||||
$partialkey = "'".sha1($this->template . $block)."_'.$key.'_$i'";
|
$partialkey = "'".sha1($this->template . $block)."_'.$key.'_$i'";
|
||||||
|
|
||||||
$knownUncached = array(
|
|
||||||
'if' => array('false', '0'),
|
|
||||||
'unless' => array('true', '1')
|
|
||||||
);
|
|
||||||
|
|
||||||
// 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
|
// Try to load from cache
|
||||||
$res[] = "<?\n".'if ('.$condition.' ($partial = $cache->load('.$partialkey.'))) $val .= $partial;'."\n";
|
$res[] = "<?\n".'if ('.$condition.' ($partial = $cache->load('.$partialkey.'))) $val .= $partial;'."\n";
|
||||||
|
|
||||||
@ -876,7 +890,6 @@ class SSViewer_PartialParser {
|
|||||||
$res[] = "}\n?>";
|
$res[] = "}\n?>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return implode('', $res);
|
return implode('', $res);
|
||||||
}
|
}
|
||||||
|
@ -189,17 +189,22 @@ class SSViewerCacheBlockTest extends SapphireTest {
|
|||||||
/**
|
/**
|
||||||
* @expectedException Exception
|
* @expectedException Exception
|
||||||
*/
|
*/
|
||||||
function testErrorMessageForCacheWithinControl() {
|
function testErrorMessageForCachedWithinControlWithinCached() {
|
||||||
$this->_reset(true);
|
$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
|
* @expectedException Exception
|
||||||
*/
|
*/
|
||||||
function testErrorMessageForCacheWithinIf() {
|
function testErrorMessageForCachedWithinIf() {
|
||||||
$this->_reset(true);
|
$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