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 $pragmas;
private $defaultPragmas = array();
private $sections; private $sections;
private $source; private $source;
private $indentNextLine; 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) 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->sections = array();
$this->source = $source; $this->source = $source;
$this->indentNextLine = true; $this->indentNextLine = true;
@@ -53,6 +54,23 @@ class Mustache_Compiler
return $this->writeCode($tree, $name); 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. * Helper function for walking the Mustache token parse tree.
* *
+39 -3
View File
@@ -28,6 +28,11 @@ class Mustache_Engine
const PRAGMA_FILTERS = 'FILTERS'; const PRAGMA_FILTERS = 'FILTERS';
// Known pragmas
private static $knownPragmas = array(
self::PRAGMA_FILTERS => true,
);
// Template cache // Template cache
private $templates = array(); private $templates = array();
@@ -44,6 +49,7 @@ class Mustache_Engine
private $charset = 'UTF-8'; private $charset = 'UTF-8';
private $logger; private $logger;
private $strictCallables = false; private $strictCallables = false;
private $pragmas = array();
// Services // Services
private $tokenizer; private $tokenizer;
@@ -110,6 +116,10 @@ class Mustache_Engine
* // helps protect against arbitrary code execution when user input is passed directly into the template. * // 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. * // This currently defaults to false, but will default to true in v3.0.
* 'strict_callables' => true, * '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. * @throws Mustache_Exception_InvalidArgumentException If `escape` option is not callable.
@@ -176,6 +186,15 @@ class Mustache_Engine
if (isset($options['strict_callables'])) { if (isset($options['strict_callables'])) {
$this->strictCallables = $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; 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. * Set the Mustache template Loader instance.
* *
@@ -563,12 +592,13 @@ class Mustache_Engine
public function getTemplateClassName($source) public function getTemplateClassName($source)
{ {
return $this->templateClassPrefix . md5(sprintf( 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, self::VERSION,
isset($this->escape) ? 'custom' : 'default', isset($this->escape) ? 'custom' : 'default',
$this->entityFlags, $this->entityFlags,
$this->charset, $this->charset,
$this->strictCallables ? 'true' : 'false', $this->strictCallables ? 'true' : 'false',
implode(' ', array_keys($this->pragmas)),
$source $source
)); ));
} }
@@ -705,7 +735,10 @@ class Mustache_Engine
*/ */
private function parse($source) 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) 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 $lineNum;
private $lineTokens; private $lineTokens;
private $pragmas;
private $defaultPragmas = array();
/** /**
* Process an array of Mustache tokens and convert them into a parse tree. * Process an array of Mustache tokens and convert them into a parse tree.
@@ -30,10 +32,28 @@ class Mustache_Parser
{ {
$this->lineNum = -1; $this->lineNum = -1;
$this->lineTokens = 0; $this->lineTokens = 0;
$this->pragmas = $this->defaultPragmas;
return $this->buildTree($tokens); 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. * Helper method for recursively building a parse tree.
* *
@@ -121,6 +141,9 @@ class Mustache_Parser
break; break;
case Mustache_Tokenizer::T_PRAGMA: case Mustache_Tokenizer::T_PRAGMA:
$this->pragmas[$token[Mustache_Tokenizer::NAME]] = true;
// no break
case Mustache_Tokenizer::T_COMMENT: case Mustache_Tokenizer::T_COMMENT:
$this->clearStandaloneLines($nodes, $tokens); $this->clearStandaloneLines($nodes, $tokens);
$nodes[] = $token; $nodes[] = $token;
+2
View File
@@ -36,6 +36,7 @@ class Mustache_Test_EngineTest extends Mustache_Test_FunctionalTestCase
'escape' => 'strtoupper', 'escape' => 'strtoupper',
'entity_flags' => ENT_QUOTES, 'entity_flags' => ENT_QUOTES,
'charset' => 'ISO-8859-1', 'charset' => 'ISO-8859-1',
'pragmas' => array(Mustache_Engine::PRAGMA_FILTERS),
)); ));
$this->assertSame($logger, $mustache->getLogger()); $this->assertSame($logger, $mustache->getLogger());
@@ -50,6 +51,7 @@ class Mustache_Test_EngineTest extends Mustache_Test_FunctionalTestCase
$this->assertTrue($mustache->hasHelper('bar')); $this->assertTrue($mustache->hasHelper('bar'));
$this->assertFalse($mustache->hasHelper('baz')); $this->assertFalse($mustache->hasHelper('baz'));
$this->assertInstanceOf('Mustache_Cache_FilesystemCache', $mustache->getCache()); $this->assertInstanceOf('Mustache_Cache_FilesystemCache', $mustache->getCache());
$this->assertEquals(array(Mustache_Engine::PRAGMA_FILTERS), $mustache->getPragmas());
} }
public static function getFoo() 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, '' ),
);
}
}