Browse Source

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.
Justin Hileman 11 năm trước cách đây
mục cha
commit
7aee026403

+ 19 - 1
src/Mustache/Compiler.php

@@ -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
src/Mustache/Engine.php

@@ -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 - 0
src/Mustache/Parser.php

@@ -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 - 0
test/Mustache/Test/EngineTest.php

@@ -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()

+ 50 - 0
test/Mustache/Test/FiveThree/Functional/EngineTest.php

@@ -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, ''                   ),
+        );
+    }
+}