Merge branch 'release/2.6.1'
This commit is contained in:
@@ -77,7 +77,7 @@ SymfonyClassCollectionLoader::load(array(
|
||||
*/
|
||||
class SymfonyClassCollectionLoader
|
||||
{
|
||||
static private $loaded;
|
||||
private static $loaded;
|
||||
|
||||
const HEADER = <<<EOS
|
||||
<?php
|
||||
@@ -102,7 +102,7 @@ EOS;
|
||||
*
|
||||
* @throws InvalidArgumentException When class can't be loaded
|
||||
*/
|
||||
static public function load(array $classes, $cacheDir, $name, $extension = '.php')
|
||||
public static function load(array $classes, $cacheDir, $name, $extension = '.php')
|
||||
{
|
||||
// each $name can only be loaded once per PHP process
|
||||
if (isset(self::$loaded[$name])) {
|
||||
@@ -134,7 +134,7 @@ EOS;
|
||||
*
|
||||
* @throws RuntimeException when a cache file cannot be written
|
||||
*/
|
||||
static private function writeCacheFile($file, $content)
|
||||
private static function writeCacheFile($file, $content)
|
||||
{
|
||||
$tmpFile = tempnam(dirname($file), basename($file));
|
||||
if (false !== @file_put_contents($tmpFile, $content) && @rename($tmpFile, $file)) {
|
||||
@@ -156,7 +156,7 @@ EOS;
|
||||
*
|
||||
* @return string The PHP string with the comments removed
|
||||
*/
|
||||
static private function stripComments($source)
|
||||
private static function stripComments($source)
|
||||
{
|
||||
if (!function_exists('token_get_all')) {
|
||||
return $source;
|
||||
|
||||
+15
-10
@@ -24,7 +24,6 @@ USAGE
|
||||
|
||||
define('EXAMPLE_PATH', realpath(dirname(__FILE__) . '/../test/fixtures/examples'));
|
||||
|
||||
|
||||
/**
|
||||
* transform a string to lowercase using underlines.
|
||||
* Examples:
|
||||
@@ -37,7 +36,8 @@ define('EXAMPLE_PATH', realpath(dirname(__FILE__) . '/../test/fixtures/examples'
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function getLowerCaseName($name) {
|
||||
function getLowerCaseName($name)
|
||||
{
|
||||
return preg_replace_callback("/([A-Z])/", create_function (
|
||||
'$match',
|
||||
'return "_" . strtolower($match[1]);'
|
||||
@@ -56,14 +56,14 @@ function getLowerCaseName($name) {
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function getUpperCaseName($name) {
|
||||
function getUpperCaseName($name)
|
||||
{
|
||||
return preg_replace_callback("/_([a-z])/", create_function (
|
||||
'$match',
|
||||
'return strtoupper($match{1});'
|
||||
), ucfirst($name));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* return the given value and echo it out appending "\n"
|
||||
*
|
||||
@@ -71,8 +71,10 @@ function getUpperCaseName($name) {
|
||||
* @access public
|
||||
* @return mixed
|
||||
*/
|
||||
function out($value) {
|
||||
function out($value)
|
||||
{
|
||||
echo $value . "\n";
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
@@ -88,7 +90,8 @@ function out($value) {
|
||||
* @access public
|
||||
* @return string
|
||||
*/
|
||||
function buildPath($directory, $filename = null, $extension = null) {
|
||||
function buildPath($directory, $filename = null, $extension = null)
|
||||
{
|
||||
return out(EXAMPLE_PATH . '/' . $directory.
|
||||
($extension !== null && $filename !== null ? '/' . $filename. "." . $extension : ""));
|
||||
}
|
||||
@@ -101,7 +104,8 @@ function buildPath($directory, $filename = null, $extension = null) {
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function createDirectory($directory) {
|
||||
function createDirectory($directory)
|
||||
{
|
||||
if (!@mkdir(buildPath($directory))) {
|
||||
die("FAILED to create directory\n");
|
||||
}
|
||||
@@ -118,7 +122,8 @@ function createDirectory($directory) {
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function createFile($directory, $filename, $extension, $content = "") {
|
||||
function createFile($directory, $filename, $extension, $content = "")
|
||||
{
|
||||
$handle = @fopen(buildPath($directory, $filename, $extension), "w");
|
||||
if ($handle) {
|
||||
fwrite($handle, $content);
|
||||
@@ -128,7 +133,6 @@ function createFile($directory, $filename, $extension, $content = "") {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* routine to create the example directory and 3 files
|
||||
*
|
||||
@@ -142,7 +146,8 @@ function createFile($directory, $filename, $extension, $content = "") {
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function main($example_name) {
|
||||
function main($example_name)
|
||||
{
|
||||
$lowercase = getLowerCaseName($example_name);
|
||||
$uppercase = getUpperCaseName($example_name);
|
||||
createDirectory($lowercase);
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
*/
|
||||
class Mustache_Autoloader
|
||||
{
|
||||
|
||||
private $baseDir;
|
||||
|
||||
/**
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
*/
|
||||
class Mustache_Compiler
|
||||
{
|
||||
|
||||
private $sections;
|
||||
private $source;
|
||||
private $indentNextLine;
|
||||
|
||||
@@ -134,6 +134,9 @@ class Mustache_Context
|
||||
{
|
||||
for ($i = count($stack) - 1; $i >= 0; $i--) {
|
||||
if (is_object($stack[$i]) && !($stack[$i] instanceof Closure)) {
|
||||
|
||||
// Note that is_callable() *will not work here*
|
||||
// See https://github.com/bobthecow/mustache.php/wiki/Magic-Methods
|
||||
if (method_exists($stack[$i], $id)) {
|
||||
return $stack[$i]->$id();
|
||||
} elseif (isset($stack[$i]->$id)) {
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
*/
|
||||
class Mustache_Engine
|
||||
{
|
||||
const VERSION = '2.6.0';
|
||||
const VERSION = '2.6.1';
|
||||
const SPEC_VERSION = '1.1.2';
|
||||
|
||||
const PRAGMA_FILTERS = 'FILTERS';
|
||||
|
||||
@@ -27,7 +27,10 @@ class Mustache_HelperCollection
|
||||
*/
|
||||
public function __construct($helpers = null)
|
||||
{
|
||||
if ($helpers !== null) {
|
||||
if ($helpers === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!is_array($helpers) && !$helpers instanceof Traversable) {
|
||||
throw new Mustache_Exception_InvalidArgumentException('HelperCollection constructor expects an array of helpers');
|
||||
}
|
||||
@@ -36,7 +39,6 @@ class Mustache_HelperCollection
|
||||
$this->add($name, $helper);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic mutator.
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
*/
|
||||
interface Mustache_Loader
|
||||
{
|
||||
|
||||
/**
|
||||
* Load a Template by name.
|
||||
*
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
*/
|
||||
interface Mustache_Loader_MutableLoader
|
||||
{
|
||||
|
||||
/**
|
||||
* Set an associative array of Template sources for this loader.
|
||||
*
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
*/
|
||||
class Mustache_Loader_StringLoader implements Mustache_Loader
|
||||
{
|
||||
|
||||
/**
|
||||
* Load a Template by source.
|
||||
*
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
*/
|
||||
abstract class Mustache_Template
|
||||
{
|
||||
|
||||
/**
|
||||
* @var Mustache_Engine
|
||||
*/
|
||||
|
||||
+36
-15
@@ -16,7 +16,6 @@
|
||||
*/
|
||||
class Mustache_Tokenizer
|
||||
{
|
||||
|
||||
// Finite state machine states
|
||||
const IN_TEXT = 0;
|
||||
const IN_TAG_TYPE = 1;
|
||||
@@ -85,6 +84,8 @@ class Mustache_Tokenizer
|
||||
/**
|
||||
* Scan and tokenize template source.
|
||||
*
|
||||
* @throws Mustache_Exception_SyntaxException when mismatched section tags are encountered.
|
||||
*
|
||||
* @param string $text Mustache template source to tokenize
|
||||
* @param string $delimiters Optionally, pass initial opening and closing delimiters (default: null)
|
||||
*
|
||||
@@ -117,7 +118,7 @@ class Mustache_Tokenizer
|
||||
} else {
|
||||
$char = $text[$i];
|
||||
$this->buffer .= $char;
|
||||
if ($char == "\n") {
|
||||
if ($char === "\n") {
|
||||
$this->flushBuffer();
|
||||
$this->line++;
|
||||
}
|
||||
@@ -152,29 +153,49 @@ class Mustache_Tokenizer
|
||||
|
||||
default:
|
||||
if ($this->tagChange($this->ctag, $this->ctagLen, $text, $i)) {
|
||||
$this->tokens[] = array(
|
||||
$token = array(
|
||||
self::TYPE => $this->tagType,
|
||||
self::NAME => trim($this->buffer),
|
||||
self::OTAG => $this->otag,
|
||||
self::CTAG => $this->ctag,
|
||||
self::LINE => $this->line,
|
||||
self::INDEX => ($this->tagType == self::T_END_SECTION) ? $this->seenTag - $this->otagLen : $i + $this->ctagLen
|
||||
self::INDEX => ($this->tagType === self::T_END_SECTION) ? $this->seenTag - $this->otagLen : $i + $this->ctagLen
|
||||
);
|
||||
|
||||
if ($this->tagType === self::T_UNESCAPED) {
|
||||
// Clean up `{{{ tripleStache }}}` style tokens.
|
||||
if ($this->ctag === '}}') {
|
||||
if (($i + 2 < $len) && $text[$i + 2] === '}') {
|
||||
$i++;
|
||||
} else {
|
||||
$msg = sprintf(
|
||||
'Mismatched tag delimiters: %s on line %d',
|
||||
$token[self::NAME],
|
||||
$token[self::LINE]
|
||||
);
|
||||
|
||||
throw new Mustache_Exception_SyntaxException($msg, $token);
|
||||
}
|
||||
} else {
|
||||
$lastName = $token[self::NAME];
|
||||
if (substr($lastName, -1) === '}') {
|
||||
$token[self::NAME] = trim(substr($lastName, 0, -1));
|
||||
} else {
|
||||
$msg = sprintf(
|
||||
'Mismatched tag delimiters: %s on line %d',
|
||||
$token[self::NAME],
|
||||
$token[self::LINE]
|
||||
);
|
||||
|
||||
throw new Mustache_Exception_SyntaxException($msg, $token);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->buffer = '';
|
||||
$i += $this->ctagLen - 1;
|
||||
$this->state = self::IN_TEXT;
|
||||
if ($this->tagType == self::T_UNESCAPED) {
|
||||
if ($this->ctag == '}}') {
|
||||
$i++;
|
||||
} else {
|
||||
// Clean up `{{{ tripleStache }}}` style tokens.
|
||||
$lastName = $this->tokens[count($this->tokens) - 1][self::NAME];
|
||||
if (substr($lastName, -1) === '}') {
|
||||
$this->tokens[count($this->tokens) - 1][self::NAME] = trim(substr($lastName, 0, -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->tokens[] = $token;
|
||||
} else {
|
||||
$this->buffer .= $text[$i];
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ class Mustache_Test_Cache_FilesystemCacheTest extends Mustache_Test_FunctionalTe
|
||||
public function testCacheGetNone()
|
||||
{
|
||||
$key = 'some key';
|
||||
$cache = new Mustache_Cache_FilesystemCache(self::$tempDir);;
|
||||
$cache = new Mustache_Cache_FilesystemCache(self::$tempDir);
|
||||
$loaded = $cache->load($key);
|
||||
|
||||
$this->assertFalse($loaded);
|
||||
@@ -27,7 +27,7 @@ class Mustache_Test_Cache_FilesystemCacheTest extends Mustache_Test_FunctionalTe
|
||||
{
|
||||
$key = 'some key';
|
||||
$value = '<?php /* some value */';
|
||||
$cache = new Mustache_Cache_FilesystemCache(self::$tempDir);;
|
||||
$cache = new Mustache_Cache_FilesystemCache(self::$tempDir);
|
||||
$cache->cache($key, $value);
|
||||
$loaded = $cache->load($key);
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ class Mustache_Test_FiveThree_Functional_FiltersTest extends PHPUnit_Framework_T
|
||||
array(
|
||||
'{{% FILTERS }}{{ date | longdate }}',
|
||||
$helpers,
|
||||
(object) array('date' => new DateTime('1/1/2000')),
|
||||
(object) array('date' => new DateTime('1/1/2000', new DateTimeZone("UTC"))),
|
||||
'2000-01-01 12:01:00'
|
||||
),
|
||||
|
||||
@@ -72,7 +72,7 @@ class Mustache_Test_FiveThree_Functional_FiltersTest extends PHPUnit_Framework_T
|
||||
});
|
||||
|
||||
$foo = new \StdClass;
|
||||
$foo->date = new DateTime('1/1/2000');
|
||||
$foo->date = new DateTime('1/1/2000', new DateTimeZone("UTC"));
|
||||
|
||||
$this->assertEquals('[[2000-01-01 12:01:00]]', $tpl->render($foo));
|
||||
}
|
||||
|
||||
@@ -42,12 +42,12 @@ EOS;
|
||||
|
||||
$tpl = $m->loadTemplate($src);
|
||||
|
||||
$data = new Mustache_Test_Functional_ClassWithLambda();
|
||||
$data = new Mustache_Test_FiveThree_Functional_ClassWithLambda();
|
||||
$this->assertEquals($expected, $tpl->render($data));
|
||||
}
|
||||
}
|
||||
|
||||
class Mustache_Test_Functional_ClassWithLambda
|
||||
class Mustache_Test_FiveThree_Functional_ClassWithLambda
|
||||
{
|
||||
public function _t()
|
||||
{
|
||||
|
||||
@@ -24,6 +24,28 @@ class Mustache_Test_TokenizerTest extends PHPUnit_Framework_TestCase
|
||||
$this->assertSame($expected, $tokenizer->scan($text, $delimiters));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Mustache_Exception_SyntaxException
|
||||
*/
|
||||
public function testUnevenBracesThrowExceptions()
|
||||
{
|
||||
$tokenizer = new Mustache_Tokenizer;
|
||||
|
||||
$text = "{{{ name }}";
|
||||
$tokenizer->scan($text, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException Mustache_Exception_SyntaxException
|
||||
*/
|
||||
public function testUnevenBracesWithCustomDelimiterThrowExceptions()
|
||||
{
|
||||
$tokenizer = new Mustache_Tokenizer;
|
||||
|
||||
$text = "<%{ name %>";
|
||||
$tokenizer->scan($text, "<% %>");
|
||||
}
|
||||
|
||||
public function getTokens()
|
||||
{
|
||||
return array(
|
||||
@@ -188,6 +210,69 @@ class Mustache_Test_TokenizerTest extends PHPUnit_Framework_TestCase
|
||||
),
|
||||
)
|
||||
),
|
||||
|
||||
// custom delimiters don't swallow the next character, even if it is a }, }}}, or the same delimiter
|
||||
array(
|
||||
"<% a %>} <% b %>%> <% c %>}}}",
|
||||
"<% %>",
|
||||
array(
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
|
||||
Mustache_Tokenizer::NAME => 'a',
|
||||
Mustache_Tokenizer::OTAG => '<%',
|
||||
Mustache_Tokenizer::CTAG => '%>',
|
||||
Mustache_Tokenizer::LINE => 0,
|
||||
Mustache_Tokenizer::INDEX => 7,
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||
Mustache_Tokenizer::LINE => 0,
|
||||
Mustache_Tokenizer::VALUE => "} ",
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
|
||||
Mustache_Tokenizer::NAME => 'b',
|
||||
Mustache_Tokenizer::OTAG => '<%',
|
||||
Mustache_Tokenizer::CTAG => '%>',
|
||||
Mustache_Tokenizer::LINE => 0,
|
||||
Mustache_Tokenizer::INDEX => 16,
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||
Mustache_Tokenizer::LINE => 0,
|
||||
Mustache_Tokenizer::VALUE => "%> ",
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_ESCAPED,
|
||||
Mustache_Tokenizer::NAME => 'c',
|
||||
Mustache_Tokenizer::OTAG => '<%',
|
||||
Mustache_Tokenizer::CTAG => '%>',
|
||||
Mustache_Tokenizer::LINE => 0,
|
||||
Mustache_Tokenizer::INDEX => 26,
|
||||
),
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_TEXT,
|
||||
Mustache_Tokenizer::LINE => 0,
|
||||
Mustache_Tokenizer::VALUE => "}}}",
|
||||
),
|
||||
)
|
||||
),
|
||||
|
||||
// unescaped custom delimiters are properly parsed
|
||||
array(
|
||||
"<%{ a }%>",
|
||||
"<% %>",
|
||||
array(
|
||||
array(
|
||||
Mustache_Tokenizer::TYPE => Mustache_Tokenizer::T_UNESCAPED,
|
||||
Mustache_Tokenizer::NAME => 'a',
|
||||
Mustache_Tokenizer::OTAG => '<%',
|
||||
Mustache_Tokenizer::CTAG => '%>',
|
||||
Mustache_Tokenizer::LINE => 0,
|
||||
Mustache_Tokenizer::INDEX => 9,
|
||||
)
|
||||
)
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user