Add default pragma option to Mustache_Engine.

Pragmas specified in the Mustache_Engine constructor will be enabled in all templates, regardless of the presence of pragma tags in individual templates.
This commit is contained in:
Justin Hileman
2014-06-26 22:45:23 -07:00
parent 4c4c6f156b
commit 7aee026403
5 changed files with 133 additions and 4 deletions
+19 -1
View File
@@ -18,6 +18,7 @@ class Mustache_Compiler
{
private $pragmas;
private $defaultPragmas = array();
private $sections;
private $source;
private $indentNextLine;
@@ -41,7 +42,7 @@ class Mustache_Compiler
*/
public function compile($source, array $tree, $name, $customEscape = false, $charset = 'UTF-8', $strictCallables = false, $entityFlags = ENT_COMPAT)
{
$this->pragmas = array();
$this->pragmas = $this->defaultPragmas;
$this->sections = array();
$this->source = $source;
$this->indentNextLine = true;
@@ -53,6 +54,23 @@ class Mustache_Compiler
return $this->writeCode($tree, $name);
}
/**
* Enable pragmas across all templates, regardless of the presence of pragma
* tags in the individual templates.
*
* @internal Users should set global pragmas in Mustache_Engine, not here :)
*
* @param array $pragmas
*/
public function setPragmas(array $pragmas)
{
$this->pragmas = array();
foreach ($pragmas as $pragma) {
$this->pragmas[$pragma] = true;
}
$this->defaultPragmas = $this->pragmas;
}
/**
* Helper function for walking the Mustache token parse tree.
*
+39 -3
View File
@@ -28,6 +28,11 @@ class Mustache_Engine
const PRAGMA_FILTERS = 'FILTERS';
// Known pragmas
private static $knownPragmas = array(
self::PRAGMA_FILTERS => true,
);
// Template cache
private $templates = array();
@@ -44,6 +49,7 @@ class Mustache_Engine
private $charset = 'UTF-8';
private $logger;
private $strictCallables = false;
private $pragmas = array();
// Services
private $tokenizer;
@@ -110,6 +116,10 @@ class Mustache_Engine
* // helps protect against arbitrary code execution when user input is passed directly into the template.
* // This currently defaults to false, but will default to true in v3.0.
* 'strict_callables' => true,
*
* // Enable pragmas across all templates, regardless of the presence of pragma tags in the individual
* // templates.
* 'pragmas' => [Mustache_Engine::PRAGMA_FILTERS],
* );
*
* @throws Mustache_Exception_InvalidArgumentException If `escape` option is not callable.
@@ -176,6 +186,15 @@ class Mustache_Engine
if (isset($options['strict_callables'])) {
$this->strictCallables = $options['strict_callables'];
}
if (isset($options['pragmas'])) {
foreach ($options['pragmas'] as $pragma) {
if (!isset(self::$knownPragmas[$pragma])) {
throw new Mustache_Exception_InvalidArgumentException(sprintf('Unknown pragma: "%s".', $pragma));
}
$this->pragmas[$pragma] = true;
}
}
}
/**
@@ -226,6 +245,16 @@ class Mustache_Engine
return $this->charset;
}
/**
* Get the current globally enabled pragmas.
*
* @return array
*/
public function getPragmas()
{
return array_keys($this->pragmas);
}
/**
* Set the Mustache template Loader instance.
*
@@ -563,12 +592,13 @@ class Mustache_Engine
public function getTemplateClassName($source)
{
return $this->templateClassPrefix . md5(sprintf(
'version:%s,escape:%s,entity_flags:%i,charset:%s,strict_callables:%s,source:%s',
'version:%s,escape:%s,entity_flags:%i,charset:%s,strict_callables:%s,pragmas:%s,source:%s',
self::VERSION,
isset($this->escape) ? 'custom' : 'default',
$this->entityFlags,
$this->charset,
$this->strictCallables ? 'true' : 'false',
implode(' ', array_keys($this->pragmas)),
$source
));
}
@@ -705,7 +735,10 @@ class Mustache_Engine
*/
private function parse($source)
{
return $this->getParser()->parse($this->tokenize($source));
$parser = $this->getParser();
$parser->setPragmas($this->getPragmas());
return $parser->parse($this->tokenize($source));
}
/**
@@ -728,7 +761,10 @@ class Mustache_Engine
array('className' => $name)
);
return $this->getCompiler()->compile($source, $tree, $name, isset($this->escape), $this->charset, $this->strictCallables, $this->entityFlags);
$compiler = $this->getCompiler();
$compiler->setPragmas($this->getPragmas());
return $compiler->compile($source, $tree, $name, isset($this->escape), $this->charset, $this->strictCallables, $this->entityFlags);
}
/**
+23
View File
@@ -18,6 +18,8 @@ class Mustache_Parser
{
private $lineNum;
private $lineTokens;
private $pragmas;
private $defaultPragmas = array();
/**
* Process an array of Mustache tokens and convert them into a parse tree.
@@ -30,10 +32,28 @@ class Mustache_Parser
{
$this->lineNum = -1;
$this->lineTokens = 0;
$this->pragmas = $this->defaultPragmas;
return $this->buildTree($tokens);
}
/**
* Enable pragmas across all templates, regardless of the presence of pragma
* tags in the individual templates.
*
* @internal Users should set global pragmas in Mustache_Engine, not here :)
*
* @param array $pragmas
*/
public function setPragmas(array $pragmas)
{
$this->pragmas = array();
foreach ($pragmas as $pragma) {
$this->pragmas[$pragma] = true;
}
$this->defaultPragmas = $this->pragmas;
}
/**
* Helper method for recursively building a parse tree.
*
@@ -121,6 +141,9 @@ class Mustache_Parser
break;
case Mustache_Tokenizer::T_PRAGMA:
$this->pragmas[$token[Mustache_Tokenizer::NAME]] = true;
// no break
case Mustache_Tokenizer::T_COMMENT:
$this->clearStandaloneLines($nodes, $tokens);
$nodes[] = $token;
+2
View File
@@ -36,6 +36,7 @@ class Mustache_Test_EngineTest extends Mustache_Test_FunctionalTestCase
'escape' => 'strtoupper',
'entity_flags' => ENT_QUOTES,
'charset' => 'ISO-8859-1',
'pragmas' => array(Mustache_Engine::PRAGMA_FILTERS),
));
$this->assertSame($logger, $mustache->getLogger());
@@ -50,6 +51,7 @@ class Mustache_Test_EngineTest extends Mustache_Test_FunctionalTestCase
$this->assertTrue($mustache->hasHelper('bar'));
$this->assertFalse($mustache->hasHelper('baz'));
$this->assertInstanceOf('Mustache_Cache_FilesystemCache', $mustache->getCache());
$this->assertEquals(array(Mustache_Engine::PRAGMA_FILTERS), $mustache->getPragmas());
}
public static function getFoo()
@@ -0,0 +1,50 @@
<?php
/*
* This file is part of Mustache.php.
*
* (c) 2010-2014 Justin Hileman
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
/**
* @group pragmas
* @group functional
*/
class Mustache_Test_FiveThree_Functional_EngineTest extends PHPUnit_Framework_TestCase
{
/**
* @dataProvider pragmaData
*/
public function testPragmasConstructorOption($pragmas, $helpers, $data, $tpl, $expect)
{
$mustache = new Mustache_Engine(array(
'pragmas' => $pragmas,
'helpers' => $helpers,
));
$this->assertEquals($expect, $mustache->render($tpl, $data));
}
public function pragmaData()
{
$helpers = array(
'longdate' => function (\DateTime $value) {
return $value->format('Y-m-d h:m:s');
}
);
$data = array(
'date' => new DateTime('1/1/2000', new DateTimeZone('UTC')),
);
$tpl = '{{ date | longdate }}';
return array(
array(array(Mustache_Engine::PRAGMA_FILTERS), $helpers, $data, $tpl, '2000-01-01 12:01:00'),
array(array(), $helpers, $data, $tpl, '' ),
);
}
}