if (!isset($argv[1]))
{
- die('You must provide the version (1.0.0)');
+ die('You must provide the version (1.0.0)');
}
if (!isset($argv[2]))
{
- die('You must provide the stability (alpha, beta, or stable)');
+ die('You must provide the stability (alpha, beta, or stable)');
}
$context = array(
- 'date' => date('Y-m-d'),
- 'time' => date('H:m:00'),
- 'version' => $argv[1],
- 'api_version' => $argv[1],
- 'stability' => $argv[2],
- 'api_stability' => $argv[2],
+ 'date' => date('Y-m-d'),
+ 'time' => date('H:m:00'),
+ 'version' => $argv[1],
+ 'api_version' => $argv[1],
+ 'stability' => $argv[2],
+ 'api_stability' => $argv[2],
);
$context['files'] = '';
$path = realpath(dirname(__FILE__).'/../lib/Twig');
foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::LEAVES_ONLY) as $file)
{
- if (preg_match('/\.php$/', $file))
- {
- $name = str_replace($path.'/', '', $file);
- $context['files'] .= ' <file install-as="Twig/'.$name.'" name="'.$name.'" role="php" />'."\n";
- }
+ if (preg_match('/\.php$/', $file))
+ {
+ $name = str_replace($path.'/', '', $file);
+ $context['files'] .= ' <file install-as="Twig/'.$name.'" name="'.$name.'" role="php" />'."\n";
+ }
}
$template = file_get_contents(dirname(__FILE__).'/../package.xml.tpl');
function replace_parameters($matches)
{
- global $context;
+ global $context;
- return isset($context[$matches[1]]) ? $context[$matches[1]] : null;
+ return isset($context[$matches[1]]) ? $context[$matches[1]] : null;
}
*/
class Twig_Autoloader
{
- /**
- * Registers Twig_Autoloader as an SPL autoloader.
- */
- static public function register()
- {
- ini_set('unserialize_callback_func', 'spl_autoload_call');
- spl_autoload_register(array(new self, 'autoload'));
- }
-
- /**
- * Handles autoloading of classes.
- *
- * @param string $class A class name.
- *
- * @return boolean Returns true if the class has been loaded
- */
- static public function autoload($class)
- {
- if (0 !== strpos($class, 'Twig'))
+ /**
+ * Registers Twig_Autoloader as an SPL autoloader.
+ */
+ static public function register()
{
- return false;
+ ini_set('unserialize_callback_func', 'spl_autoload_call');
+ spl_autoload_register(array(new self, 'autoload'));
}
- require dirname(__FILE__).'/../'.str_replace('_', '/', $class).'.php';
+ /**
+ * Handles autoloading of classes.
+ *
+ * @param string $class A class name.
+ *
+ * @return boolean Returns true if the class has been loaded
+ */
+ static public function autoload($class)
+ {
+ if (0 !== strpos($class, 'Twig')) {
+ return false;
+ }
+
+ require dirname(__FILE__).'/../'.str_replace('_', '/', $class).'.php';
- return true;
- }
+ return true;
+ }
}
*/
class Twig_Compiler implements Twig_CompilerInterface
{
- protected $lastLine;
- protected $source;
- protected $indentation;
- protected $env;
-
- /**
- * Constructor.
- *
- * @param Twig_Environment $env The twig environment instance
- */
- public function __construct(Twig_Environment $env = null)
- {
- $this->env = $env;
- }
-
- public function setEnvironment(Twig_Environment $env)
- {
- $this->env = $env;
- }
-
- /**
- * Gets the current PHP code after compilation.
- *
- * @return string The PHP code
- */
- public function getSource()
- {
- return $this->source;
- }
-
- /**
- * Compiles a node.
- *
- * @param Twig_Node $node The node to compile
- *
- * @return Twig_Compiler The current compiler instance
- */
- public function compile(Twig_Node $node)
- {
- $this->lastLine = null;
- $this->source = '';
- $this->indentation = 0;
-
- $node->compile($this);
-
- return $this;
- }
-
- public function subcompile(Twig_Node $node)
- {
- $node->compile($this);
-
- return $this;
- }
-
- /**
- * Adds a raw string to the compiled code.
- *
- * @param string $string The string
- *
- * @return Twig_Compiler The current compiler instance
- */
- public function raw($string)
- {
- $this->source .= $string;
-
- return $this;
- }
-
- /**
- * Writes a string to the compiled code by adding indentation.
- *
- * @return Twig_Compiler The current compiler instance
- */
- public function write()
- {
- $strings = func_get_args();
- foreach ($strings as $string)
- {
- $this->source .= str_repeat(' ', $this->indentation * 2).$string;
- }
-
- return $this;
- }
-
- /**
- * Adds a quoted string to the compiled code.
- *
- * @param string $string The string
- *
- * @return Twig_Compiler The current compiler instance
- */
- public function string($value)
- {
- $this->source .= sprintf('"%s"', addcslashes($value, "\t\"\$\\"));
-
- return $this;
- }
-
- /**
- * Returns a PHP representation of a given value.
- *
- * @param mixed $value The value to convert
- *
- * @return Twig_Compiler The current compiler instance
- */
- public function repr($value)
- {
- if (is_int($value) || is_float($value))
- {
- $this->raw($value);
- }
- else if (is_null($value))
- {
- $this->raw('null');
- }
- else if (is_bool($value))
- {
- $this->raw($value ? 'true' : 'false');
- }
- else if (is_array($value))
- {
- $this->raw('array(');
- $i = 0;
- foreach ($value as $key => $value)
- {
- if ($i++)
- {
- $this->raw(', ');
+ protected $lastLine;
+ protected $source;
+ protected $indentation;
+ protected $env;
+
+ /**
+ * Constructor.
+ *
+ * @param Twig_Environment $env The twig environment instance
+ */
+ public function __construct(Twig_Environment $env = null)
+ {
+ $this->env = $env;
+ }
+
+ public function setEnvironment(Twig_Environment $env)
+ {
+ $this->env = $env;
+ }
+
+ /**
+ * Gets the current PHP code after compilation.
+ *
+ * @return string The PHP code
+ */
+ public function getSource()
+ {
+ return $this->source;
+ }
+
+ /**
+ * Compiles a node.
+ *
+ * @param Twig_Node $node The node to compile
+ *
+ * @return Twig_Compiler The current compiler instance
+ */
+ public function compile(Twig_Node $node)
+ {
+ $this->lastLine = null;
+ $this->source = '';
+ $this->indentation = 0;
+
+ $node->compile($this);
+
+ return $this;
+ }
+
+ public function subcompile(Twig_Node $node)
+ {
+ $node->compile($this);
+
+ return $this;
+ }
+
+ /**
+ * Adds a raw string to the compiled code.
+ *
+ * @param string $string The string
+ *
+ * @return Twig_Compiler The current compiler instance
+ */
+ public function raw($string)
+ {
+ $this->source .= $string;
+
+ return $this;
+ }
+
+ /**
+ * Writes a string to the compiled code by adding indentation.
+ *
+ * @return Twig_Compiler The current compiler instance
+ */
+ public function write()
+ {
+ $strings = func_get_args();
+ foreach ($strings as $string) {
+ $this->source .= str_repeat(' ', $this->indentation * 2).$string;
}
- $this->repr($key);
- $this->raw(' => ');
- $this->repr($value);
- }
- $this->raw(')');
- }
- else
- {
- $this->string($value);
- }
-
- return $this;
- }
-
- /**
- * Pushes the current context on the stack.
- *
- * @return Twig_Compiler The current compiler instance
- */
- public function pushContext()
- {
- // the (array) cast bypasses a PHP 5.2.6 bug
- $this->write('$context[\'_parent\'] = (array) $context;'."\n");
-
- return $this;
- }
-
- /**
- * Pops a context from the stack.
- *
- * @return Twig_Compiler The current compiler instance
- */
- public function popContext()
- {
- $this->write('$context = $context[\'_parent\'];'."\n");
-
- return $this;
- }
-
- /**
- * Adds debugging information.
- *
- * @param Twig_Node $node The related twig node
- *
- * @return Twig_Compiler The current compiler instance
- */
- public function addDebugInfo(Twig_Node $node)
- {
- if ($node->getLine() != $this->lastLine)
- {
- $this->lastLine = $node->getLine();
- $this->write("// line {$node->getLine()}\n");
- }
-
- return $this;
- }
-
- /**
- * Indents the generated code.
- *
- * @param integer $indent The number of indentation to add
- *
- * @return Twig_Compiler The current compiler instance
- */
- public function indent($step = 1)
- {
- $this->indentation += $step;
-
- return $this;
- }
-
- /**
- * Outdents the generated code.
- *
- * @param integer $indent The number of indentation to remove
- *
- * @return Twig_Compiler The current compiler instance
- */
- public function outdent($step = 1)
- {
- $this->indentation -= $step;
-
- return $this;
- }
-
- /**
- * Returns the environment instance related to this compiler.
- *
- * @return Twig_Environment The environment instance
- */
- public function getEnvironment()
- {
- return $this->env;
- }
-
- public function getTemplateClass($name)
- {
- return $this->getEnvironment()->getTemplateClass($name);
- }
+
+ return $this;
+ }
+
+ /**
+ * Adds a quoted string to the compiled code.
+ *
+ * @param string $string The string
+ *
+ * @return Twig_Compiler The current compiler instance
+ */
+ public function string($value)
+ {
+ $this->source .= sprintf('"%s"', addcslashes($value, "\t\"\$\\"));
+
+ return $this;
+ }
+
+ /**
+ * Returns a PHP representation of a given value.
+ *
+ * @param mixed $value The value to convert
+ *
+ * @return Twig_Compiler The current compiler instance
+ */
+ public function repr($value)
+ {
+ if (is_int($value) || is_float($value)) {
+ $this->raw($value);
+ } else if (is_null($value)) {
+ $this->raw('null');
+ } else if (is_bool($value)) {
+ $this->raw($value ? 'true' : 'false');
+ } else if (is_array($value)) {
+ $this->raw('array(');
+ $i = 0;
+ foreach ($value as $key => $value) {
+ if ($i++) {
+ $this->raw(', ');
+ }
+ $this->repr($key);
+ $this->raw(' => ');
+ $this->repr($value);
+ }
+ $this->raw(')');
+ } else {
+ $this->string($value);
+ }
+
+ return $this;
+ }
+
+ /**
+ * Pushes the current context on the stack.
+ *
+ * @return Twig_Compiler The current compiler instance
+ */
+ public function pushContext()
+ {
+ // the (array) cast bypasses a PHP 5.2.6 bug
+ $this->write('$context[\'_parent\'] = (array) $context;'."\n");
+
+ return $this;
+ }
+
+ /**
+ * Pops a context from the stack.
+ *
+ * @return Twig_Compiler The current compiler instance
+ */
+ public function popContext()
+ {
+ $this->write('$context = $context[\'_parent\'];'."\n");
+
+ return $this;
+ }
+
+ /**
+ * Adds debugging information.
+ *
+ * @param Twig_Node $node The related twig node
+ *
+ * @return Twig_Compiler The current compiler instance
+ */
+ public function addDebugInfo(Twig_Node $node)
+ {
+ if ($node->getLine() != $this->lastLine) {
+ $this->lastLine = $node->getLine();
+ $this->write("// line {$node->getLine()}\n");
+ }
+
+ return $this;
+ }
+
+ /**
+ * Indents the generated code.
+ *
+ * @param integer $indent The number of indentation to add
+ *
+ * @return Twig_Compiler The current compiler instance
+ */
+ public function indent($step = 1)
+ {
+ $this->indentation += $step;
+
+ return $this;
+ }
+
+ /**
+ * Outdents the generated code.
+ *
+ * @param integer $indent The number of indentation to remove
+ *
+ * @return Twig_Compiler The current compiler instance
+ */
+ public function outdent($step = 1)
+ {
+ $this->indentation -= $step;
+
+ return $this;
+ }
+
+ /**
+ * Returns the environment instance related to this compiler.
+ *
+ * @return Twig_Environment The environment instance
+ */
+ public function getEnvironment()
+ {
+ return $this->env;
+ }
+
+ public function getTemplateClass($name)
+ {
+ return $this->getEnvironment()->getTemplateClass($name);
+ }
}
*/
interface Twig_CompilerInterface
{
- /**
- * Compiles a node.
- *
- * @param Twig_Node $node The node to compile
- *
- * @return Twig_Compiler The current compiler instance
- */
- public function compile(Twig_Node $node);
+ /**
+ * Compiles a node.
+ *
+ * @param Twig_Node $node The node to compile
+ *
+ * @return Twig_Compiler The current compiler instance
+ */
+ public function compile(Twig_Node $node);
- /**
- * Gets the current PHP code after compilation.
- *
- * @return string The PHP code
- */
- public function getSource();
+ /**
+ * Gets the current PHP code after compilation.
+ *
+ * @return string The PHP code
+ */
+ public function getSource();
}
class Twig_Environment
{
- const VERSION = '0.9.6-DEV';
-
- protected $charset;
- protected $loader;
- protected $trimBlocks;
- protected $debug;
- protected $autoReload;
- protected $cache;
- protected $lexer;
- protected $parser;
- protected $compiler;
- protected $baseTemplateClass;
- protected $extensions;
- protected $parsers;
- protected $visitors;
- protected $filters;
- protected $runtimeInitialized;
- protected $loadedTemplates;
-
- /**
- * Constructor.
- *
- * Available options:
- *
- * * debug: When set to `true`, the generated templates have a __toString()
- * method that you can use to display the generated nodes (default to
- * false).
- *
- * * trim_blocks: Mimicks the behavior of PHP by removing the newline that
- * follows instructions if present (default to false).
- *
- * * charset: The charset used by the templates (default to utf-8).
- *
- * * base_template_class: The base template class to use for generated
- * templates (default to Twig_Template).
- *
- * * cache: Can be one of three values:
- * * null (the default): Twig will create a sub-directory under the system tmp directory
- * (not recommended as templates from two projects with the same name will share the cache)
- * * false: disable the compile cache altogether
- * * An absolute path where to store the compiled templates
- *
- * * auto_reload: Whether to reload the template is the original source changed.
- * If you don't provide the auto_reload option, it will be
- * determined automatically base on the debug value.
- */
- public function __construct(Twig_LoaderInterface $loader = null, $options = array())
- {
- if (null !== $loader)
- {
- $this->setLoader($loader);
- }
-
- $this->debug = isset($options['debug']) ? (bool) $options['debug'] : false;
- $this->trimBlocks = isset($options['trim_blocks']) ? (bool) $options['trim_blocks'] : false;
- $this->charset = isset($options['charset']) ? $options['charset'] : 'UTF-8';
- $this->baseTemplateClass = isset($options['base_template_class']) ? $options['base_template_class'] : 'Twig_Template';
- $this->autoReload = isset($options['auto_reload']) ? (bool) $options['auto_reload'] : $this->debug;
- $this->extensions = array('core' => new Twig_Extension_Core());
- $this->runtimeInitialized = false;
- $this->setCache(isset($options['cache']) ? $options['cache'] : null);
- }
-
- public function getBaseTemplateClass()
- {
- return $this->baseTemplateClass;
- }
-
- public function setBaseTemplateClass($class)
- {
- $this->baseTemplateClass = $class;
- }
-
- public function enableDebug()
- {
- $this->debug = true;
- }
-
- public function disableDebug()
- {
- $this->debug = false;
- }
-
- public function isDebug()
- {
- return $this->debug;
- }
-
- public function isAutoReload()
- {
- return $this->autoReload;
- }
-
- public function setAutoReload($autoReload)
- {
- $this->autoReload = (Boolean) $autoReload;
- }
-
- public function getCache()
- {
- return $this->cache;
- }
-
- public function setCache($cache)
- {
- $this->cache = null === $cache ? sys_get_temp_dir().DIRECTORY_SEPARATOR.'twig_'.md5(dirname(__FILE__)) : $cache;
-
- if (false !== $this->cache && !is_dir($this->cache))
- {
- mkdir($this->cache, 0755, true);
- }
- }
-
- public function getCacheFilename($name)
- {
- return $this->getCache() ? $this->getCache().'/'.$this->getTemplateClass($name).'.php' : false;
- }
-
- public function getTrimBlocks()
- {
- return $this->trimBlocks;
- }
-
- public function setTrimBlocks($bool)
- {
- $this->trimBlocks = (bool) $bool;
- }
-
- /**
- * Gets the template class associated with the given string.
- *
- * @param string $name The name for which to calculate the template class name
- *
- * @return string The template class name
- */
- public function getTemplateClass($name)
- {
- return '__TwigTemplate_'.md5($this->loader->getCacheKey($name));
- }
-
- /**
- * Loads a template by name.
- *
- * @param string $name The template name
- *
- * @return Twig_TemplateInterface A template instance representing the given template name
- */
- public function loadTemplate($name)
- {
- $cls = $this->getTemplateClass($name);
-
- if (isset($this->loadedTemplates[$cls]))
- {
- return $this->loadedTemplates[$cls];
- }
-
- if (!class_exists($cls, false))
- {
- if (false === $cache = $this->getCacheFilename($name))
- {
- eval('?>'.$this->compileSource($this->loader->getSource($name), $name));
- }
- else
- {
- if (!file_exists($cache) || ($this->isAutoReload() && !$this->loader->isFresh($name, filemtime($cache))))
- {
- $content = $this->compileSource($this->loader->getSource($name), $name);
-
- if (false === file_put_contents($cache, $content, LOCK_EX))
- {
- eval('?>'.$content);
- }
- else
- {
- require_once $cache;
- }
- }
- else
- {
- require_once $cache;
+ const VERSION = '0.9.6-DEV';
+
+ protected $charset;
+ protected $loader;
+ protected $trimBlocks;
+ protected $debug;
+ protected $autoReload;
+ protected $cache;
+ protected $lexer;
+ protected $parser;
+ protected $compiler;
+ protected $baseTemplateClass;
+ protected $extensions;
+ protected $parsers;
+ protected $visitors;
+ protected $filters;
+ protected $runtimeInitialized;
+ protected $loadedTemplates;
+
+ /**
+ * Constructor.
+ *
+ * Available options:
+ *
+ * * debug: When set to `true`, the generated templates have a __toString()
+ * method that you can use to display the generated nodes (default to
+ * false).
+ *
+ * * trim_blocks: Mimicks the behavior of PHP by removing the newline that
+ * follows instructions if present (default to false).
+ *
+ * * charset: The charset used by the templates (default to utf-8).
+ *
+ * * base_template_class: The base template class to use for generated
+ * templates (default to Twig_Template).
+ *
+ * * cache: Can be one of three values:
+ * * null (the default): Twig will create a sub-directory under the system tmp directory
+ * (not recommended as templates from two projects with the same name will share the cache)
+ * * false: disable the compile cache altogether
+ * * An absolute path where to store the compiled templates
+ *
+ * * auto_reload: Whether to reload the template is the original source changed.
+ * If you don't provide the auto_reload option, it will be
+ * determined automatically base on the debug value.
+ */
+ public function __construct(Twig_LoaderInterface $loader = null, $options = array())
+ {
+ if (null !== $loader) {
+ $this->setLoader($loader);
}
- }
+
+ $this->debug = isset($options['debug']) ? (bool) $options['debug'] : false;
+ $this->trimBlocks = isset($options['trim_blocks']) ? (bool) $options['trim_blocks'] : false;
+ $this->charset = isset($options['charset']) ? $options['charset'] : 'UTF-8';
+ $this->baseTemplateClass = isset($options['base_template_class']) ? $options['base_template_class'] : 'Twig_Template';
+ $this->autoReload = isset($options['auto_reload']) ? (bool) $options['auto_reload'] : $this->debug;
+ $this->extensions = array('core' => new Twig_Extension_Core());
+ $this->runtimeInitialized = false;
+ $this->setCache(isset($options['cache']) ? $options['cache'] : null);
+ }
+
+ public function getBaseTemplateClass()
+ {
+ return $this->baseTemplateClass;
+ }
+
+ public function setBaseTemplateClass($class)
+ {
+ $this->baseTemplateClass = $class;
+ }
+
+ public function enableDebug()
+ {
+ $this->debug = true;
+ }
+
+ public function disableDebug()
+ {
+ $this->debug = false;
+ }
+
+ public function isDebug()
+ {
+ return $this->debug;
+ }
+
+ public function isAutoReload()
+ {
+ return $this->autoReload;
+ }
+
+ public function setAutoReload($autoReload)
+ {
+ $this->autoReload = (Boolean) $autoReload;
+ }
+
+ public function getCache()
+ {
+ return $this->cache;
}
- if (!$this->runtimeInitialized)
+ public function setCache($cache)
{
- $this->initRuntime();
+ $this->cache = null === $cache ? sys_get_temp_dir().DIRECTORY_SEPARATOR.'twig_'.md5(dirname(__FILE__)) : $cache;
- $this->runtimeInitialized = true;
+ if (false !== $this->cache && !is_dir($this->cache)) {
+ mkdir($this->cache, 0755, true);
+ }
}
- return $this->loadedTemplates[$cls] = new $cls($this);
- }
+ public function getCacheFilename($name)
+ {
+ return $this->getCache() ? $this->getCache().'/'.$this->getTemplateClass($name).'.php' : false;
+ }
- public function clearTemplateCache()
- {
- $this->loadedTemplates = array();
- }
+ public function getTrimBlocks()
+ {
+ return $this->trimBlocks;
+ }
- public function getLexer()
- {
- if (null === $this->lexer)
+ public function setTrimBlocks($bool)
{
- $this->lexer = new Twig_Lexer($this);
+ $this->trimBlocks = (bool) $bool;
}
- return $this->lexer;
- }
+ /**
+ * Gets the template class associated with the given string.
+ *
+ * @param string $name The name for which to calculate the template class name
+ *
+ * @return string The template class name
+ */
+ public function getTemplateClass($name)
+ {
+ return '__TwigTemplate_'.md5($this->loader->getCacheKey($name));
+ }
- public function setLexer(Twig_LexerInterface $lexer)
- {
- $this->lexer = $lexer;
- $lexer->setEnvironment($this);
- }
+ /**
+ * Loads a template by name.
+ *
+ * @param string $name The template name
+ *
+ * @return Twig_TemplateInterface A template instance representing the given template name
+ */
+ public function loadTemplate($name)
+ {
+ $cls = $this->getTemplateClass($name);
- public function tokenize($source, $name)
- {
- return $this->getLexer()->tokenize($source, $name);
- }
+ if (isset($this->loadedTemplates[$cls])) {
+ return $this->loadedTemplates[$cls];
+ }
+
+ if (!class_exists($cls, false)) {
+ if (false === $cache = $this->getCacheFilename($name)) {
+ eval('?>'.$this->compileSource($this->loader->getSource($name), $name));
+ } else {
+ if (!file_exists($cache) || ($this->isAutoReload() && !$this->loader->isFresh($name, filemtime($cache)))) {
+ $content = $this->compileSource($this->loader->getSource($name), $name);
+
+ if (false === file_put_contents($cache, $content, LOCK_EX)) {
+ eval('?>'.$content);
+ } else {
+ require_once $cache;
+ }
+ } else {
+ require_once $cache;
+ }
+ }
+ }
+
+ if (!$this->runtimeInitialized) {
+ $this->initRuntime();
+
+ $this->runtimeInitialized = true;
+ }
- public function getParser()
- {
- if (null === $this->parser)
+ return $this->loadedTemplates[$cls] = new $cls($this);
+ }
+
+ public function clearTemplateCache()
{
- $this->parser = new Twig_Parser($this);
+ $this->loadedTemplates = array();
}
- return $this->parser;
- }
+ public function getLexer()
+ {
+ if (null === $this->lexer) {
+ $this->lexer = new Twig_Lexer($this);
+ }
+
+ return $this->lexer;
+ }
- public function setParser(Twig_ParserInterface $parser)
- {
- $this->parser = $parser;
- $parser->setEnvironment($this);
- }
+ public function setLexer(Twig_LexerInterface $lexer)
+ {
+ $this->lexer = $lexer;
+ $lexer->setEnvironment($this);
+ }
- public function parse(Twig_TokenStream $tokens)
- {
- return $this->getParser()->parse($tokens);
- }
+ public function tokenize($source, $name)
+ {
+ return $this->getLexer()->tokenize($source, $name);
+ }
- public function getCompiler()
- {
- if (null === $this->compiler)
+ public function getParser()
{
- $this->compiler = new Twig_Compiler($this);
+ if (null === $this->parser) {
+ $this->parser = new Twig_Parser($this);
+ }
+
+ return $this->parser;
}
- return $this->compiler;
- }
+ public function setParser(Twig_ParserInterface $parser)
+ {
+ $this->parser = $parser;
+ $parser->setEnvironment($this);
+ }
- public function setCompiler(Twig_CompilerInterface $compiler)
- {
- $this->compiler = $compiler;
- $compiler->setEnvironment($this);
- }
+ public function parse(Twig_TokenStream $tokens)
+ {
+ return $this->getParser()->parse($tokens);
+ }
- public function compile(Twig_Node $node)
- {
- return $this->getCompiler()->compile($node)->getSource();
- }
+ public function getCompiler()
+ {
+ if (null === $this->compiler) {
+ $this->compiler = new Twig_Compiler($this);
+ }
- public function compileSource($source, $name)
- {
- return $this->compile($this->parse($this->tokenize($source, $name)));
- }
+ return $this->compiler;
+ }
- public function setLoader(Twig_LoaderInterface $loader)
- {
- $this->loader = $loader;
- }
+ public function setCompiler(Twig_CompilerInterface $compiler)
+ {
+ $this->compiler = $compiler;
+ $compiler->setEnvironment($this);
+ }
- public function getLoader()
- {
- return $this->loader;
- }
+ public function compile(Twig_Node $node)
+ {
+ return $this->getCompiler()->compile($node)->getSource();
+ }
- public function setCharset($charset)
- {
- $this->charset = $charset;
- }
+ public function compileSource($source, $name)
+ {
+ return $this->compile($this->parse($this->tokenize($source, $name)));
+ }
- public function getCharset()
- {
- return $this->charset;
- }
+ public function setLoader(Twig_LoaderInterface $loader)
+ {
+ $this->loader = $loader;
+ }
- public function initRuntime()
- {
- foreach ($this->getExtensions() as $extension)
+ public function getLoader()
{
- $extension->initRuntime();
+ return $this->loader;
}
- }
- public function hasExtension($name)
- {
- return isset($this->extensions[$name]);
- }
+ public function setCharset($charset)
+ {
+ $this->charset = $charset;
+ }
- public function getExtension($name)
- {
- return $this->extensions[$name];
- }
+ public function getCharset()
+ {
+ return $this->charset;
+ }
- public function addExtension(Twig_ExtensionInterface $extension)
- {
- $this->extensions[$extension->getName()] = $extension;
- }
+ public function initRuntime()
+ {
+ foreach ($this->getExtensions() as $extension) {
+ $extension->initRuntime();
+ }
+ }
- public function removeExtension($name)
- {
- unset($this->extensions[$name]);
- }
+ public function hasExtension($name)
+ {
+ return isset($this->extensions[$name]);
+ }
- public function setExtensions(array $extensions)
- {
- foreach ($extensions as $extension)
+ public function getExtension($name)
{
- $this->addExtension($extension);
+ return $this->extensions[$name];
}
- }
- public function getExtensions()
- {
- return $this->extensions;
- }
+ public function addExtension(Twig_ExtensionInterface $extension)
+ {
+ $this->extensions[$extension->getName()] = $extension;
+ }
- public function getTokenParsers()
- {
- if (null === $this->parsers)
+ public function removeExtension($name)
{
- $this->parsers = array();
- foreach ($this->getExtensions() as $extension)
- {
- $this->parsers = array_merge($this->parsers, $extension->getTokenParsers());
- }
+ unset($this->extensions[$name]);
}
- return $this->parsers;
- }
+ public function setExtensions(array $extensions)
+ {
+ foreach ($extensions as $extension) {
+ $this->addExtension($extension);
+ }
+ }
- public function getNodeVisitors()
- {
- if (null === $this->visitors)
+ public function getExtensions()
{
- $this->visitors = array();
- foreach ($this->getExtensions() as $extension)
- {
- $this->visitors = array_merge($this->visitors, $extension->getNodeVisitors());
- }
+ return $this->extensions;
}
- return $this->visitors;
- }
+ public function getTokenParsers()
+ {
+ if (null === $this->parsers) {
+ $this->parsers = array();
+ foreach ($this->getExtensions() as $extension) {
+ $this->parsers = array_merge($this->parsers, $extension->getTokenParsers());
+ }
+ }
+
+ return $this->parsers;
+ }
- public function getFilters()
- {
- if (null === $this->filters)
+ public function getNodeVisitors()
{
- $this->filters = array();
- foreach ($this->getExtensions() as $extension)
- {
- $this->filters = array_merge($this->filters, $extension->getFilters());
- }
+ if (null === $this->visitors) {
+ $this->visitors = array();
+ foreach ($this->getExtensions() as $extension) {
+ $this->visitors = array_merge($this->visitors, $extension->getNodeVisitors());
+ }
+ }
+
+ return $this->visitors;
}
- return $this->filters;
- }
+ public function getFilters()
+ {
+ if (null === $this->filters) {
+ $this->filters = array();
+ foreach ($this->getExtensions() as $extension) {
+ $this->filters = array_merge($this->filters, $extension->getFilters());
+ }
+ }
+
+ return $this->filters;
+ }
}
*/
class Twig_ExpressionParser
{
- protected $parser;
-
- public function __construct(Twig_Parser $parser)
- {
- $this->parser = $parser;
- }
-
- public function parseExpression()
- {
- return $this->parseConditionalExpression();
- }
-
- public function parseConditionalExpression()
- {
- $lineno = $this->parser->getCurrentToken()->getLine();
- $expr1 = $this->parseOrExpression();
- while ($this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, '?'))
- {
- $this->parser->getStream()->next();
- $expr2 = $this->parseOrExpression();
- $this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, ':');
- $expr3 = $this->parseConditionalExpression();
- $expr1 = new Twig_Node_Expression_Conditional($expr1, $expr2, $expr3, $lineno);
- $lineno = $this->parser->getCurrentToken()->getLine();
- }
-
- return $expr1;
- }
+ protected $parser;
- public function parseOrExpression()
- {
- $lineno = $this->parser->getCurrentToken()->getLine();
- $left = $this->parseAndExpression();
- while ($this->parser->getStream()->test('or'))
+ public function __construct(Twig_Parser $parser)
{
- $this->parser->getStream()->next();
- $right = $this->parseAndExpression();
- $left = new Twig_Node_Expression_Binary_Or($left, $right, $lineno);
- $lineno = $this->parser->getCurrentToken()->getLine();
+ $this->parser = $parser;
}
- return $left;
- }
-
- public function parseAndExpression()
- {
- $lineno = $this->parser->getCurrentToken()->getLine();
- $left = $this->parseCompareExpression();
- while ($this->parser->getStream()->test('and'))
+ public function parseExpression()
{
- $this->parser->getStream()->next();
- $right = $this->parseCompareExpression();
- $left = new Twig_Node_Expression_Binary_And($left, $right, $lineno);
- $lineno = $this->parser->getCurrentToken()->getLine();
+ return $this->parseConditionalExpression();
}
- return $left;
- }
-
- public function parseCompareExpression()
- {
- static $operators = array('==', '!=', '<', '>', '>=', '<=');
- $lineno = $this->parser->getCurrentToken()->getLine();
- $expr = $this->parseAddExpression();
- $ops = array();
- while (
- $this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, $operators)
- ||
- $this->parser->getStream()->test(Twig_Token::NAME_TYPE, 'in')
- )
+ public function parseConditionalExpression()
{
- $ops[] = array($this->parser->getStream()->next()->getValue(), $this->parseAddExpression());
+ $lineno = $this->parser->getCurrentToken()->getLine();
+ $expr1 = $this->parseOrExpression();
+ while ($this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, '?')) {
+ $this->parser->getStream()->next();
+ $expr2 = $this->parseOrExpression();
+ $this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, ':');
+ $expr3 = $this->parseConditionalExpression();
+ $expr1 = new Twig_Node_Expression_Conditional($expr1, $expr2, $expr3, $lineno);
+ $lineno = $this->parser->getCurrentToken()->getLine();
+ }
+
+ return $expr1;
}
- if (empty($ops))
+ public function parseOrExpression()
{
- return $expr;
- }
+ $lineno = $this->parser->getCurrentToken()->getLine();
+ $left = $this->parseAndExpression();
+ while ($this->parser->getStream()->test('or')) {
+ $this->parser->getStream()->next();
+ $right = $this->parseAndExpression();
+ $left = new Twig_Node_Expression_Binary_Or($left, $right, $lineno);
+ $lineno = $this->parser->getCurrentToken()->getLine();
+ }
- return new Twig_Node_Expression_Compare($expr, $ops, $lineno);
- }
+ return $left;
+ }
- public function parseAddExpression()
- {
- $lineno = $this->parser->getCurrentToken()->getLine();
- $left = $this->parseSubExpression();
- while ($this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, '+'))
+ public function parseAndExpression()
{
- $this->parser->getStream()->next();
- $right = $this->parseSubExpression();
- $left = new Twig_Node_Expression_Binary_Add($left, $right, $lineno);
- $lineno = $this->parser->getCurrentToken()->getLine();
- }
+ $lineno = $this->parser->getCurrentToken()->getLine();
+ $left = $this->parseCompareExpression();
+ while ($this->parser->getStream()->test('and')) {
+ $this->parser->getStream()->next();
+ $right = $this->parseCompareExpression();
+ $left = new Twig_Node_Expression_Binary_And($left, $right, $lineno);
+ $lineno = $this->parser->getCurrentToken()->getLine();
+ }
- return $left;
- }
+ return $left;
+ }
- public function parseSubExpression()
- {
- $lineno = $this->parser->getCurrentToken()->getLine();
- $left = $this->parseConcatExpression();
- while ($this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, '-'))
+ public function parseCompareExpression()
{
- $this->parser->getStream()->next();
- $right = $this->parseConcatExpression();
- $left = new Twig_Node_Expression_Binary_Sub($left, $right, $lineno);
- $lineno = $this->parser->getCurrentToken()->getLine();
- }
+ static $operators = array('==', '!=', '<', '>', '>=', '<=');
+ $lineno = $this->parser->getCurrentToken()->getLine();
+ $expr = $this->parseAddExpression();
+ $ops = array();
+ while (
+ $this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, $operators)
+ ||
+ $this->parser->getStream()->test(Twig_Token::NAME_TYPE, 'in')
+ ) {
+ $ops[] = array($this->parser->getStream()->next()->getValue(), $this->parseAddExpression());
+ }
- return $left;
- }
+ if (empty($ops)) {
+ return $expr;
+ }
- public function parseConcatExpression()
- {
- $lineno = $this->parser->getCurrentToken()->getLine();
- $left = $this->parseMulExpression();
- while ($this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, '~'))
- {
- $this->parser->getStream()->next();
- $right = $this->parseMulExpression();
- $left = new Twig_Node_Expression_Binary_Concat($left, $right, $lineno);
- $lineno = $this->parser->getCurrentToken()->getLine();
+ return new Twig_Node_Expression_Compare($expr, $ops, $lineno);
}
- return $left;
- }
-
- public function parseMulExpression()
- {
- $lineno = $this->parser->getCurrentToken()->getLine();
- $left = $this->parseDivExpression();
- while ($this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, '*'))
+ public function parseAddExpression()
{
- $this->parser->getStream()->next();
- $right = $this->parseDivExpression();
- $left = new Twig_Node_Expression_Binary_Mul($left, $right, $lineno);
- $lineno = $this->parser->getCurrentToken()->getLine();
- }
+ $lineno = $this->parser->getCurrentToken()->getLine();
+ $left = $this->parseSubExpression();
+ while ($this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, '+')) {
+ $this->parser->getStream()->next();
+ $right = $this->parseSubExpression();
+ $left = new Twig_Node_Expression_Binary_Add($left, $right, $lineno);
+ $lineno = $this->parser->getCurrentToken()->getLine();
+ }
- return $left;
- }
+ return $left;
+ }
- public function parseDivExpression()
- {
- $lineno = $this->parser->getCurrentToken()->getLine();
- $left = $this->parseFloorDivExpression();
- while ($this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, '/'))
+ public function parseSubExpression()
{
- $this->parser->getStream()->next();
- $right = $this->parseModExpression();
- $left = new Twig_Node_Expression_Binary_Div($left, $right, $lineno);
- $lineno = $this->parser->getCurrentToken()->getLine();
- }
+ $lineno = $this->parser->getCurrentToken()->getLine();
+ $left = $this->parseConcatExpression();
+ while ($this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, '-')) {
+ $this->parser->getStream()->next();
+ $right = $this->parseConcatExpression();
+ $left = new Twig_Node_Expression_Binary_Sub($left, $right, $lineno);
+ $lineno = $this->parser->getCurrentToken()->getLine();
+ }
- return $left;
- }
+ return $left;
+ }
- public function parseFloorDivExpression()
- {
- $lineno = $this->parser->getCurrentToken()->getLine();
- $left = $this->parseModExpression();
- while ($this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, '//'))
+ public function parseConcatExpression()
{
- $this->parser->getStream()->next();
- $right = $this->parseModExpression();
- $left = new Twig_Node_Expression_Binary_FloorDiv($left, $right, $lineno);
- $lineno = $this->parser->getCurrentToken()->getLine();
- }
+ $lineno = $this->parser->getCurrentToken()->getLine();
+ $left = $this->parseMulExpression();
+ while ($this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, '~')) {
+ $this->parser->getStream()->next();
+ $right = $this->parseMulExpression();
+ $left = new Twig_Node_Expression_Binary_Concat($left, $right, $lineno);
+ $lineno = $this->parser->getCurrentToken()->getLine();
+ }
- return $left;
- }
+ return $left;
+ }
- public function parseModExpression()
- {
- $lineno = $this->parser->getCurrentToken()->getLine();
- $left = $this->parseUnaryExpression();
- while ($this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, '%'))
+ public function parseMulExpression()
{
- $this->parser->getStream()->next();
- $right = $this->parseUnaryExpression();
- $left = new Twig_Node_Expression_Binary_Mod($left, $right, $lineno);
- $lineno = $this->parser->getCurrentToken()->getLine();
- }
+ $lineno = $this->parser->getCurrentToken()->getLine();
+ $left = $this->parseDivExpression();
+ while ($this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, '*')) {
+ $this->parser->getStream()->next();
+ $right = $this->parseDivExpression();
+ $left = new Twig_Node_Expression_Binary_Mul($left, $right, $lineno);
+ $lineno = $this->parser->getCurrentToken()->getLine();
+ }
- return $left;
- }
+ return $left;
+ }
- public function parseUnaryExpression()
- {
- if ($this->parser->getStream()->test('not'))
+ public function parseDivExpression()
{
- return $this->parseNotExpression();
+ $lineno = $this->parser->getCurrentToken()->getLine();
+ $left = $this->parseFloorDivExpression();
+ while ($this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, '/')) {
+ $this->parser->getStream()->next();
+ $right = $this->parseModExpression();
+ $left = new Twig_Node_Expression_Binary_Div($left, $right, $lineno);
+ $lineno = $this->parser->getCurrentToken()->getLine();
+ }
+
+ return $left;
}
- if ($this->parser->getCurrentToken()->getType() == Twig_Token::OPERATOR_TYPE)
+
+ public function parseFloorDivExpression()
{
- switch ($this->parser->getCurrentToken()->getValue())
- {
- case '-':
- return $this->parseNegExpression();
- case '+':
- return $this->parsePosExpression();
- }
- }
+ $lineno = $this->parser->getCurrentToken()->getLine();
+ $left = $this->parseModExpression();
+ while ($this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, '//')) {
+ $this->parser->getStream()->next();
+ $right = $this->parseModExpression();
+ $left = new Twig_Node_Expression_Binary_FloorDiv($left, $right, $lineno);
+ $lineno = $this->parser->getCurrentToken()->getLine();
+ }
- return $this->parsePrimaryExpression();
- }
+ return $left;
+ }
- public function parseNotExpression()
- {
- $token = $this->parser->getStream()->next();
- $node = $this->parseUnaryExpression();
+ public function parseModExpression()
+ {
+ $lineno = $this->parser->getCurrentToken()->getLine();
+ $left = $this->parseUnaryExpression();
+ while ($this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, '%')) {
+ $this->parser->getStream()->next();
+ $right = $this->parseUnaryExpression();
+ $left = new Twig_Node_Expression_Binary_Mod($left, $right, $lineno);
+ $lineno = $this->parser->getCurrentToken()->getLine();
+ }
- return new Twig_Node_Expression_Unary_Not($node, $token->getLine());
- }
+ return $left;
+ }
- public function parseNegExpression()
- {
- $token = $this->parser->getStream()->next();
- $node = $this->parseUnaryExpression();
+ public function parseUnaryExpression()
+ {
+ if ($this->parser->getStream()->test('not')) {
+ return $this->parseNotExpression();
+ }
+ if ($this->parser->getCurrentToken()->getType() == Twig_Token::OPERATOR_TYPE) {
+ switch ($this->parser->getCurrentToken()->getValue()) {
+ case '-':
+ return $this->parseNegExpression();
+ case '+':
+ return $this->parsePosExpression();
+ }
+ }
- return new Twig_Node_Expression_Unary_Neg($node, $token->getLine());
- }
+ return $this->parsePrimaryExpression();
+ }
- public function parsePosExpression()
- {
- $token = $this->parser->getStream()->next();
- $node = $this->parseUnaryExpression();
+ public function parseNotExpression()
+ {
+ $token = $this->parser->getStream()->next();
+ $node = $this->parseUnaryExpression();
- return new Twig_Node_Expression_Unary_Pos($node, $token->getLine());
- }
+ return new Twig_Node_Expression_Unary_Not($node, $token->getLine());
+ }
- public function parsePrimaryExpression($assignment = false)
- {
- $token = $this->parser->getCurrentToken();
- switch ($token->getType())
+ public function parseNegExpression()
{
- case Twig_Token::NAME_TYPE:
- $this->parser->getStream()->next();
- switch ($token->getValue())
- {
- case 'true':
- $node = new Twig_Node_Expression_Constant(true, $token->getLine());
- break;
-
- case 'false':
- $node = new Twig_Node_Expression_Constant(false, $token->getLine());
- break;
-
- case 'none':
- $node = new Twig_Node_Expression_Constant(null, $token->getLine());
- break;
-
- default:
- $cls = $assignment ? 'Twig_Node_Expression_AssignName' : 'Twig_Node_Expression_Name';
- $node = new $cls($token->getValue(), $token->getLine());
- }
- break;
+ $token = $this->parser->getStream()->next();
+ $node = $this->parseUnaryExpression();
- case Twig_Token::NUMBER_TYPE:
- case Twig_Token::STRING_TYPE:
- $this->parser->getStream()->next();
- $node = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine());
- break;
-
- default:
- if ($token->test(Twig_Token::OPERATOR_TYPE, '['))
- {
- $this->parser->getStream()->next();
- $node = $this->parseArrayExpression();
- $this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, ']');
- }
- elseif ($token->test(Twig_Token::OPERATOR_TYPE, '('))
- {
- $this->parser->getStream()->next();
- $node = $this->parseExpression();
- $this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, ')');
- }
- else
- {
- throw new Twig_SyntaxError(sprintf('Unexpected token "%s"', $token->getValue()), $token->getLine());
- }
+ return new Twig_Node_Expression_Unary_Neg($node, $token->getLine());
}
- if (!$assignment)
+
+ public function parsePosExpression()
{
- $node = $this->parsePostfixExpression($node);
- }
+ $token = $this->parser->getStream()->next();
+ $node = $this->parseUnaryExpression();
- return $node;
- }
+ return new Twig_Node_Expression_Unary_Pos($node, $token->getLine());
+ }
- public function parseArrayExpression()
- {
- $elements = array();
- while (!$this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, ']'))
+ public function parsePrimaryExpression($assignment = false)
{
- if (!empty($elements))
- {
- $this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, ',');
-
- // trailing ,?
- if ($this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, ']'))
- {
- return new Twig_Node_Expression_Array($elements, $this->parser->getCurrentToken()->getLine());
+ $token = $this->parser->getCurrentToken();
+ switch ($token->getType()) {
+ case Twig_Token::NAME_TYPE:
+ $this->parser->getStream()->next();
+ switch ($token->getValue()) {
+ case 'true':
+ $node = new Twig_Node_Expression_Constant(true, $token->getLine());
+ break;
+
+ case 'false':
+ $node = new Twig_Node_Expression_Constant(false, $token->getLine());
+ break;
+
+ case 'none':
+ $node = new Twig_Node_Expression_Constant(null, $token->getLine());
+ break;
+
+ default:
+ $cls = $assignment ? 'Twig_Node_Expression_AssignName' : 'Twig_Node_Expression_Name';
+ $node = new $cls($token->getValue(), $token->getLine());
+ }
+ break;
+
+ case Twig_Token::NUMBER_TYPE:
+ case Twig_Token::STRING_TYPE:
+ $this->parser->getStream()->next();
+ $node = new Twig_Node_Expression_Constant($token->getValue(), $token->getLine());
+ break;
+
+ default:
+ if ($token->test(Twig_Token::OPERATOR_TYPE, '[')) {
+ $this->parser->getStream()->next();
+ $node = $this->parseArrayExpression();
+ $this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, ']');
+ } elseif ($token->test(Twig_Token::OPERATOR_TYPE, '(')) {
+ $this->parser->getStream()->next();
+ $node = $this->parseExpression();
+ $this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, ')');
+ } else {
+ throw new Twig_SyntaxError(sprintf('Unexpected token "%s"', $token->getValue()), $token->getLine());
+ }
}
- }
-
- // hash or array element?
- if (
- $this->parser->getStream()->test(Twig_Token::STRING_TYPE)
- ||
- $this->parser->getStream()->test(Twig_Token::NUMBER_TYPE)
- )
- {
- if ($this->parser->getStream()->look()->test(Twig_Token::OPERATOR_TYPE, ':'))
- {
- // hash
- $key = $this->parser->getStream()->next()->getValue();
- $this->parser->getStream()->next();
-
- $elements[$key] = $this->parseExpression();
-
- continue;
+ if (!$assignment) {
+ $node = $this->parsePostfixExpression($node);
}
- $this->parser->getStream()->rewind();
- }
- $elements[] = $this->parseExpression();
+ return $node;
}
- return new Twig_Node_Expression_Array($elements, $this->parser->getCurrentToken()->getLine());
- }
-
- public function parsePostfixExpression($node)
- {
- $stop = false;
- while (!$stop && $this->parser->getCurrentToken()->getType() == Twig_Token::OPERATOR_TYPE)
+ public function parseArrayExpression()
{
- switch ($this->parser->getCurrentToken()->getValue())
- {
- case '..':
- $node = $this->parseRangeExpression($node);
- break;
-
- case '.':
- case '[':
- $node = $this->parseSubscriptExpression($node);
- break;
-
- case '|':
- $node = $this->parseFilterExpression($node);
- break;
-
- default:
- $stop = true;
- break;
- }
+ $elements = array();
+ while (!$this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, ']')) {
+ if (!empty($elements)) {
+ $this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, ',');
+
+ // trailing ,?
+ if ($this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, ']')) {
+ return new Twig_Node_Expression_Array($elements, $this->parser->getCurrentToken()->getLine());
+ }
+ }
+
+ // hash or array element?
+ if (
+ $this->parser->getStream()->test(Twig_Token::STRING_TYPE)
+ ||
+ $this->parser->getStream()->test(Twig_Token::NUMBER_TYPE)
+ )
+ {
+ if ($this->parser->getStream()->look()->test(Twig_Token::OPERATOR_TYPE, ':')) {
+ // hash
+ $key = $this->parser->getStream()->next()->getValue();
+ $this->parser->getStream()->next();
+
+ $elements[$key] = $this->parseExpression();
+
+ continue;
+ }
+ $this->parser->getStream()->rewind();
+ }
+
+ $elements[] = $this->parseExpression();
+ }
+
+ return new Twig_Node_Expression_Array($elements, $this->parser->getCurrentToken()->getLine());
}
- return $node;
- }
+ public function parsePostfixExpression($node)
+ {
+ $stop = false;
+ while (!$stop && $this->parser->getCurrentToken()->getType() == Twig_Token::OPERATOR_TYPE) {
+ switch ($this->parser->getCurrentToken()->getValue()) {
+ case '..':
+ $node = $this->parseRangeExpression($node);
+ break;
+
+ case '.':
+ case '[':
+ $node = $this->parseSubscriptExpression($node);
+ break;
+
+ case '|':
+ $node = $this->parseFilterExpression($node);
+ break;
+
+ default:
+ $stop = true;
+ break;
+ }
+ }
- public function parseRangeExpression($node)
- {
- $token = $this->parser->getStream()->next();
- $lineno = $token->getLine();
+ return $node;
+ }
- $end = $this->parseExpression();
+ public function parseRangeExpression($node)
+ {
+ $token = $this->parser->getStream()->next();
+ $lineno = $token->getLine();
- return new Twig_Node_Expression_Filter($node, array(array('range', array($end))), $lineno);
- }
+ $end = $this->parseExpression();
- public function parseSubscriptExpression($node)
- {
- $token = $this->parser->getStream()->next();
- $lineno = $token->getLine();
- $arguments = array();
- if ($token->getValue() == '.')
- {
- $token = $this->parser->getStream()->next();
- if ($token->getType() == Twig_Token::NAME_TYPE || $token->getType() == Twig_Token::NUMBER_TYPE)
- {
- $arg = new Twig_Node_Expression_Constant($token->getValue(), $lineno);
-
- $arguments = $this->parseArguments();
- }
- else
- {
- throw new Twig_SyntaxError('Expected name or number', $lineno);
- }
+ return new Twig_Node_Expression_Filter($node, array(array('range', array($end))), $lineno);
}
- else
+
+ public function parseSubscriptExpression($node)
{
- $arg = $this->parseExpression();
- $this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, ']');
- }
+ $token = $this->parser->getStream()->next();
+ $lineno = $token->getLine();
+ $arguments = array();
+ if ($token->getValue() == '.') {
+ $token = $this->parser->getStream()->next();
+ if ($token->getType() == Twig_Token::NAME_TYPE || $token->getType() == Twig_Token::NUMBER_TYPE) {
+ $arg = new Twig_Node_Expression_Constant($token->getValue(), $lineno);
+
+ $arguments = $this->parseArguments();
+ } else {
+ throw new Twig_SyntaxError('Expected name or number', $lineno);
+ }
+ } else {
+ $arg = $this->parseExpression();
+ $this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, ']');
+ }
- return new Twig_Node_Expression_GetAttr($node, $arg, $arguments, $lineno, $token->getValue());
- }
+ return new Twig_Node_Expression_GetAttr($node, $arg, $arguments, $lineno, $token->getValue());
+ }
- public function parseFilterExpression($node)
- {
- $lineno = $this->parser->getCurrentToken()->getLine();
+ public function parseFilterExpression($node)
+ {
+ $lineno = $this->parser->getCurrentToken()->getLine();
- $this->parser->getStream()->next();
+ $this->parser->getStream()->next();
- return new Twig_Node_Expression_Filter($node, $this->parseFilterExpressionRaw(), $lineno);
- }
+ return new Twig_Node_Expression_Filter($node, $this->parseFilterExpressionRaw(), $lineno);
+ }
- public function parseFilterExpressionRaw()
- {
- $filters = array();
- while (true)
+ public function parseFilterExpressionRaw()
{
- $token = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE);
-
- $filters[] = array($token->getValue(), $this->parseArguments());
+ $filters = array();
+ while (true) {
+ $token = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE);
- if (!$this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, '|'))
- {
- break;
- }
+ $filters[] = array($token->getValue(), $this->parseArguments());
- $this->parser->getStream()->next();
- }
+ if (!$this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, '|')) {
+ break;
+ }
- return $filters;
- }
+ $this->parser->getStream()->next();
+ }
- public function parseArguments()
- {
- if (!$this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, '('))
- {
- return array();
+ return $filters;
}
- $args = array();
- $this->parser->getStream()->next();
- while (!$this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, ')'))
+ public function parseArguments()
{
- if (!empty($args))
- {
- $this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, ',');
- }
- $args[] = $this->parseExpression();
- }
- $this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, ')');
+ if (!$this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, '(')) {
+ return array();
+ }
- return $args;
- }
+ $args = array();
+ $this->parser->getStream()->next();
+ while (!$this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, ')')) {
+ if (!empty($args)) {
+ $this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, ',');
+ }
+ $args[] = $this->parseExpression();
+ }
+ $this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, ')');
- public function parseAssignmentExpression()
- {
- $lineno = $this->parser->getCurrentToken()->getLine();
- $targets = array();
- $is_multitarget = false;
- while (true)
- {
- if (!empty($targets))
- {
- $this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, ',');
- }
- if ($this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, ')') ||
- $this->parser->getStream()->test(Twig_Token::VAR_END_TYPE) ||
- $this->parser->getStream()->test(Twig_Token::BLOCK_END_TYPE) ||
- $this->parser->getStream()->test('in'))
- {
- break;
- }
- $targets[] = $this->parsePrimaryExpression(true);
- if (!$this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, ','))
- {
- break;
- }
- $is_multitarget = true;
+ return $args;
}
- if (!$is_multitarget && count($targets) == 1)
- {
- return array(false, $targets[0]);
- }
-
- return array(true, $targets);
- }
- public function parseMultitargetExpression()
- {
- $lineno = $this->parser->getCurrentToken()->getLine();
- $targets = array();
- $is_multitarget = false;
- while (true)
+ public function parseAssignmentExpression()
{
- if (!empty($targets))
- {
- $this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, ',');
- }
- if ($this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, ')') ||
- $this->parser->getStream()->test(Twig_Token::VAR_END_TYPE) ||
- $this->parser->getStream()->test(Twig_Token::BLOCK_END_TYPE))
- {
- break;
- }
- $targets[] = $this->parseExpression();
- if (!$this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, ','))
- {
- break;
- }
- $is_multitarget = true;
+ $lineno = $this->parser->getCurrentToken()->getLine();
+ $targets = array();
+ $is_multitarget = false;
+ while (true) {
+ if (!empty($targets)) {
+ $this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, ',');
+ }
+ if ($this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, ')') ||
+ $this->parser->getStream()->test(Twig_Token::VAR_END_TYPE) ||
+ $this->parser->getStream()->test(Twig_Token::BLOCK_END_TYPE) ||
+ $this->parser->getStream()->test('in'))
+ {
+ break;
+ }
+ $targets[] = $this->parsePrimaryExpression(true);
+ if (!$this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, ',')) {
+ break;
+ }
+ $is_multitarget = true;
+ }
+ if (!$is_multitarget && count($targets) == 1) {
+ return array(false, $targets[0]);
+ }
+
+ return array(true, $targets);
}
- if (!$is_multitarget && count($targets) == 1)
+
+ public function parseMultitargetExpression()
{
- return array(false, $targets[0]);
- }
+ $lineno = $this->parser->getCurrentToken()->getLine();
+ $targets = array();
+ $is_multitarget = false;
+ while (true) {
+ if (!empty($targets)) {
+ $this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, ',');
+ }
+ if ($this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, ')') ||
+ $this->parser->getStream()->test(Twig_Token::VAR_END_TYPE) ||
+ $this->parser->getStream()->test(Twig_Token::BLOCK_END_TYPE))
+ {
+ break;
+ }
+ $targets[] = $this->parseExpression();
+ if (!$this->parser->getStream()->test(Twig_Token::OPERATOR_TYPE, ',')) {
+ break;
+ }
+ $is_multitarget = true;
+ }
+ if (!$is_multitarget && count($targets) == 1) {
+ return array(false, $targets[0]);
+ }
- return array(true, $targets);
- }
+ return array(true, $targets);
+ }
}
*/
abstract class Twig_Extension implements Twig_ExtensionInterface
{
- /**
- * Initializes the runtime environment.
- *
- * This is where you can load some file that contains filter functions for instance.
- */
- public function initRuntime()
- {
- }
+ /**
+ * Initializes the runtime environment.
+ *
+ * This is where you can load some file that contains filter functions for instance.
+ */
+ public function initRuntime()
+ {
+ }
- /**
- * Returns the token parser instances to add to the existing list.
- *
- * @return array An array of Twig_TokenParser instances
- */
- public function getTokenParsers()
- {
- return array();
- }
+ /**
+ * Returns the token parser instances to add to the existing list.
+ *
+ * @return array An array of Twig_TokenParser instances
+ */
+ public function getTokenParsers()
+ {
+ return array();
+ }
- /**
- * Returns the node visitor instances to add to the existing list.
- *
- * @return array An array of Twig_NodeVisitorInterface instances
- */
- public function getNodeVisitors()
- {
- return array();
- }
+ /**
+ * Returns the node visitor instances to add to the existing list.
+ *
+ * @return array An array of Twig_NodeVisitorInterface instances
+ */
+ public function getNodeVisitors()
+ {
+ return array();
+ }
- /**
- * Returns a list of filters to add to the existing list.
- *
- * @return array An array of filters
- */
- public function getFilters()
- {
- return array();
- }
+ /**
+ * Returns a list of filters to add to the existing list.
+ *
+ * @return array An array of filters
+ */
+ public function getFilters()
+ {
+ return array();
+ }
}
*/
class Twig_Extension_Core extends Twig_Extension
{
- /**
- * Returns the token parser instance to add to the existing list.
- *
- * @return array An array of Twig_TokenParser instances
- */
- public function getTokenParsers()
- {
- return array(
- new Twig_TokenParser_For(),
- new Twig_TokenParser_If(),
- new Twig_TokenParser_Extends(),
- new Twig_TokenParser_Include(),
- new Twig_TokenParser_Block(),
- new Twig_TokenParser_Parent(),
- new Twig_TokenParser_Display(),
- new Twig_TokenParser_Filter(),
- new Twig_TokenParser_Macro(),
- new Twig_TokenParser_Import(),
- new Twig_TokenParser_Set(),
- new Twig_TokenParser_Debug(),
- );
- }
-
- /**
- * Returns the node visitor instances to add to the existing list.
- *
- * @return array An array of Twig_NodeVisitorInterface instances
- */
- public function getNodeVisitors()
- {
- return array(new Twig_NodeVisitor_Filter());
- }
-
- /**
- * Returns a list of filters to add to the existing list.
- *
- * @return array An array of filters
- */
- public function getFilters()
- {
- $filters = array(
- // formatting filters
- 'date' => new Twig_Filter_Function('twig_date_format_filter'),
- 'format' => new Twig_Filter_Function('sprintf'),
-
- // numbers
- 'even' => new Twig_Filter_Function('twig_is_even_filter'),
- 'odd' => new Twig_Filter_Function('twig_is_odd_filter'),
-
- // encoding
- 'urlencode' => new Twig_Filter_Function('twig_urlencode_filter', array('is_escaper' => true)),
-
- // string filters
- 'title' => new Twig_Filter_Function('twig_title_string_filter', array('needs_environment' => true)),
- 'capitalize' => new Twig_Filter_Function('twig_capitalize_string_filter', array('needs_environment' => true)),
- 'upper' => new Twig_Filter_Function('strtoupper'),
- 'lower' => new Twig_Filter_Function('strtolower'),
- 'striptags' => new Twig_Filter_Function('strip_tags'),
-
- // array helpers
- 'join' => new Twig_Filter_Function('twig_join_filter'),
- 'reverse' => new Twig_Filter_Function('twig_reverse_filter'),
- 'length' => new Twig_Filter_Function('twig_length_filter', array('needs_environment' => true)),
- 'sort' => new Twig_Filter_Function('twig_sort_filter'),
- 'in' => new Twig_Filter_Function('twig_in_filter'),
- 'range' => new Twig_Filter_Function('twig_range_filter'),
- 'cycle' => new Twig_Filter_Function('twig_cycle_filter'),
-
- // iteration and runtime
- 'default' => new Twig_Filter_Function('twig_default_filter'),
- 'keys' => new Twig_Filter_Function('twig_get_array_keys_filter'),
- 'items' => new Twig_Filter_Function('twig_get_array_items_filter'),
-
- // escaping
- 'escape' => new Twig_Filter_Function('twig_escape_filter', array('needs_environment' => true, 'is_escaper' => true)),
- 'e' => new Twig_Filter_Function('twig_escape_filter', array('needs_environment' => true, 'is_escaper' => true)),
- );
-
- if (function_exists('mb_get_info'))
+ /**
+ * Returns the token parser instance to add to the existing list.
+ *
+ * @return array An array of Twig_TokenParser instances
+ */
+ public function getTokenParsers()
{
- $filters['upper'] = new Twig_Filter_Function('twig_upper_filter', array('needs_environment' => true));
- $filters['lower'] = new Twig_Filter_Function('twig_lower_filter', array('needs_environment' => true));
+ return array(
+ new Twig_TokenParser_For(),
+ new Twig_TokenParser_If(),
+ new Twig_TokenParser_Extends(),
+ new Twig_TokenParser_Include(),
+ new Twig_TokenParser_Block(),
+ new Twig_TokenParser_Parent(),
+ new Twig_TokenParser_Display(),
+ new Twig_TokenParser_Filter(),
+ new Twig_TokenParser_Macro(),
+ new Twig_TokenParser_Import(),
+ new Twig_TokenParser_Set(),
+ new Twig_TokenParser_Debug(),
+ );
}
- return $filters;
- }
-
- /**
- * Returns the name of the extension.
- *
- * @return string The extension name
- */
- public function getName()
- {
- return 'core';
- }
+ /**
+ * Returns the node visitor instances to add to the existing list.
+ *
+ * @return array An array of Twig_NodeVisitorInterface instances
+ */
+ public function getNodeVisitors()
+ {
+ return array(new Twig_NodeVisitor_Filter());
+ }
+
+ /**
+ * Returns a list of filters to add to the existing list.
+ *
+ * @return array An array of filters
+ */
+ public function getFilters()
+ {
+ $filters = array(
+ // formatting filters
+ 'date' => new Twig_Filter_Function('twig_date_format_filter'),
+ 'format' => new Twig_Filter_Function('sprintf'),
+
+ // numbers
+ 'even' => new Twig_Filter_Function('twig_is_even_filter'),
+ 'odd' => new Twig_Filter_Function('twig_is_odd_filter'),
+
+ // encoding
+ 'urlencode' => new Twig_Filter_Function('twig_urlencode_filter', array('is_escaper' => true)),
+
+ // string filters
+ 'title' => new Twig_Filter_Function('twig_title_string_filter', array('needs_environment' => true)),
+ 'capitalize' => new Twig_Filter_Function('twig_capitalize_string_filter', array('needs_environment' => true)),
+ 'upper' => new Twig_Filter_Function('strtoupper'),
+ 'lower' => new Twig_Filter_Function('strtolower'),
+ 'striptags' => new Twig_Filter_Function('strip_tags'),
+
+ // array helpers
+ 'join' => new Twig_Filter_Function('twig_join_filter'),
+ 'reverse' => new Twig_Filter_Function('twig_reverse_filter'),
+ 'length' => new Twig_Filter_Function('twig_length_filter', array('needs_environment' => true)),
+ 'sort' => new Twig_Filter_Function('twig_sort_filter'),
+ 'in' => new Twig_Filter_Function('twig_in_filter'),
+ 'range' => new Twig_Filter_Function('twig_range_filter'),
+ 'cycle' => new Twig_Filter_Function('twig_cycle_filter'),
+
+ // iteration and runtime
+ 'default' => new Twig_Filter_Function('twig_default_filter'),
+ 'keys' => new Twig_Filter_Function('twig_get_array_keys_filter'),
+ 'items' => new Twig_Filter_Function('twig_get_array_items_filter'),
+
+ // escaping
+ 'escape' => new Twig_Filter_Function('twig_escape_filter', array('needs_environment' => true, 'is_escaper' => true)),
+ 'e' => new Twig_Filter_Function('twig_escape_filter', array('needs_environment' => true, 'is_escaper' => true)),
+ );
+
+ if (function_exists('mb_get_info')) {
+ $filters['upper'] = new Twig_Filter_Function('twig_upper_filter', array('needs_environment' => true));
+ $filters['lower'] = new Twig_Filter_Function('twig_lower_filter', array('needs_environment' => true));
+ }
+
+ return $filters;
+ }
+
+ /**
+ * Returns the name of the extension.
+ *
+ * @return string The extension name
+ */
+ public function getName()
+ {
+ return 'core';
+ }
}
function twig_date_format_filter($timestamp, $format = 'F j, Y H:i')
{
- return $timestamp instanceof DateTime ? $timestamp->format($format) : date($format, $timestamp);
+ return $timestamp instanceof DateTime ? $timestamp->format($format) : date($format, $timestamp);
}
function twig_urlencode_filter($url, $raw = false)
{
- if ($raw)
- {
- return rawurlencode($url);
- }
+ if ($raw) {
+ return rawurlencode($url);
+ }
- return urlencode($url);
+ return urlencode($url);
}
function twig_join_filter($value, $glue = '')
{
- return implode($glue, (array) $value);
+ return implode($glue, (array) $value);
}
function twig_default_filter($value, $default = '')
{
- return is_null($value) ? $default : $value;
+ return is_null($value) ? $default : $value;
}
function twig_get_array_keys_filter($array)
{
- if (is_object($array) && $array instanceof Traversable)
- {
- return array_keys(iterator_to_array($array));
- }
+ if (is_object($array) && $array instanceof Traversable) {
+ return array_keys(iterator_to_array($array));
+ }
- if (!is_array($array))
- {
- return array();
- }
+ if (!is_array($array)) {
+ return array();
+ }
- return array_keys($array);
+ return array_keys($array);
}
function twig_reverse_filter($array)
{
- if (is_object($array) && $array instanceof Traversable)
- {
- return array_reverse(iterator_to_array($array));
- }
+ if (is_object($array) && $array instanceof Traversable) {
+ return array_reverse(iterator_to_array($array));
+ }
- if (!is_array($array))
- {
- return array();
- }
+ if (!is_array($array)) {
+ return array();
+ }
- return array_reverse($array);
+ return array_reverse($array);
}
function twig_is_even_filter($value)
{
- return $value % 2 == 0;
+ return $value % 2 == 0;
}
function twig_is_odd_filter($value)
{
- return $value % 2 == 1;
+ return $value % 2 == 1;
}
function twig_sort_filter($array)
{
- asort($array);
+ asort($array);
- return $array;
+ return $array;
}
function twig_in_filter($value, $compare)
{
- if (is_array($compare))
- {
- return in_array($value, $compare);
- }
- elseif (is_string($compare))
- {
- return false !== strpos($compare, (string) $value);
- }
- elseif (is_object($compare) && $compare instanceof Traversable)
- {
- return in_array($value, iterator_to_array($compare));
- }
-
- return false;
+ if (is_array($compare)) {
+ return in_array($value, $compare);
+ } elseif (is_string($compare)) {
+ return false !== strpos($compare, (string) $value);
+ } elseif (is_object($compare) && $compare instanceof Traversable) {
+ return in_array($value, iterator_to_array($compare));
+ }
+
+ return false;
}
function twig_range_filter($start, $end, $step = 1)
{
- return range($start, $end, $step);
+ return range($start, $end, $step);
}
function twig_cycle_filter($values, $i)
{
- if (!is_array($values) && !$values instanceof ArrayAccess)
- {
- return $values;
- }
+ if (!is_array($values) && !$values instanceof ArrayAccess) {
+ return $values;
+ }
- return $values[$i % count($values)];
+ return $values[$i % count($values)];
}
/*
*/
function twig_escape_filter(Twig_Environment $env, $string, $type = 'html')
{
- if (!is_string($string))
- {
- return $string;
- }
-
- switch ($type)
- {
- case 'js':
- // a function the c-escapes a string, making it suitable to be placed in a JavaScript string
- return str_replace(array("\\" , "\n" , "\r" , "\"" , "'"),
- array("\\\\", "\\n" , "\\r", "\\\"", "\\'"),
- $string);
- case 'html':
- default:
- return htmlspecialchars($string, ENT_QUOTES, $env->getCharset());
- }
+ if (!is_string($string)) {
+ return $string;
+ }
+
+ switch ($type) {
+ case 'js':
+ // a function the c-escapes a string, making it suitable to be placed in a JavaScript string
+ return str_replace(array("\\" , "\n" , "\r" , "\"" , "'"),
+ array("\\\\", "\\n" , "\\r", "\\\"", "\\'"),
+ $string);
+ case 'html':
+ default:
+ return htmlspecialchars($string, ENT_QUOTES, $env->getCharset());
+ }
}
// add multibyte extensions if possible
-if (function_exists('mb_get_info'))
-{
- function twig_length_filter(Twig_Environment $env, $thing)
- {
- return is_string($thing) ? mb_strlen($thing, $env->getCharset()) : count($thing);
- }
-
- function twig_upper_filter(Twig_Environment $env, $string)
- {
- if (!is_null($env->getCharset()))
+if (function_exists('mb_get_info')) {
+ function twig_length_filter(Twig_Environment $env, $thing)
{
- return mb_strtoupper($string, $env->getCharset());
+ return is_string($thing) ? mb_strlen($thing, $env->getCharset()) : count($thing);
}
- return strtoupper($string);
- }
-
- function twig_lower_filter(Twig_Environment $env, $string)
- {
- if (!is_null($env->getCharset()))
+ function twig_upper_filter(Twig_Environment $env, $string)
{
- return mb_strtolower($string, $env->getCharset());
- }
+ if (!is_null($env->getCharset())) {
+ return mb_strtoupper($string, $env->getCharset());
+ }
- return strtolower($string);
- }
+ return strtoupper($string);
+ }
- function twig_title_string_filter(Twig_Environment $env, $string)
- {
- if (is_null($env->getCharset()))
+ function twig_lower_filter(Twig_Environment $env, $string)
{
- return ucwords(strtolower($string));
- }
+ if (!is_null($env->getCharset())) {
+ return mb_strtolower($string, $env->getCharset());
+ }
- return mb_convert_case($string, MB_CASE_TITLE, $env->getCharset());
- }
+ return strtolower($string);
+ }
- function twig_capitalize_string_filter(Twig_Environment $env, $string)
- {
- if (is_null($env->getCharset()))
+ function twig_title_string_filter(Twig_Environment $env, $string)
{
- return ucfirst(strtolower($string));
+ if (is_null($env->getCharset())) {
+ return ucwords(strtolower($string));
+ }
+
+ return mb_convert_case($string, MB_CASE_TITLE, $env->getCharset());
}
- return mb_strtoupper(mb_substr($string, 0, 1, $env->getCharset())).
- mb_strtolower(mb_substr($string, 1, mb_strlen($string), $env->getCharset()), $env->getCharset());
- }
+ function twig_capitalize_string_filter(Twig_Environment $env, $string)
+ {
+ if (is_null($env->getCharset())) {
+ return ucfirst(strtolower($string));
+ }
+
+ return mb_strtoupper(mb_substr($string, 0, 1, $env->getCharset())).
+ mb_strtolower(mb_substr($string, 1, mb_strlen($string), $env->getCharset()), $env->getCharset());
+ }
}
// and byte fallback
else
{
- function twig_length_filter(Twig_Environment $env, $thing)
- {
- return is_string($thing) ? strlen($thing) : count($thing);
- }
-
- function twig_title_string_filter(Twig_Environment $env, $string)
- {
- return ucwords(strtolower($string));
- }
-
- function twig_capitalize_string_filter(Twig_Environment $env, $string)
- {
- return ucfirst(strtolower($string));
- }
+ function twig_length_filter(Twig_Environment $env, $thing)
+ {
+ return is_string($thing) ? strlen($thing) : count($thing);
+ }
+
+ function twig_title_string_filter(Twig_Environment $env, $string)
+ {
+ return ucwords(strtolower($string));
+ }
+
+ function twig_capitalize_string_filter(Twig_Environment $env, $string)
+ {
+ return ucfirst(strtolower($string));
+ }
}
function twig_iterator_to_array($seq)
{
- if (is_array($seq))
- {
- return $seq;
- }
- elseif (is_object($seq) && $seq instanceof Traversable)
- {
- return $seq instanceof Countable ? $seq : iterator_to_array($seq);
- }
- else
- {
- return array();
- }
+ if (is_array($seq)) {
+ return $seq;
+ } elseif (is_object($seq) && $seq instanceof Traversable) {
+ return $seq instanceof Countable ? $seq : iterator_to_array($seq);
+ } else {
+ return array();
+ }
}
// only for backward compatibility
function twig_get_array_items_filter($array)
{
- // noop
- return $array;
+ // noop
+ return $array;
}
*/
class Twig_Extension_Escaper extends Twig_Extension
{
- protected $autoescape;
+ protected $autoescape;
- public function __construct($autoescape = true)
- {
- $this->autoescape = $autoescape;
- }
+ public function __construct($autoescape = true)
+ {
+ $this->autoescape = $autoescape;
+ }
- /**
- * Returns the token parser instance to add to the existing list.
- *
- * @return array An array of Twig_TokenParser instances
- */
- public function getTokenParsers()
- {
- return array(new Twig_TokenParser_AutoEscape());
- }
+ /**
+ * Returns the token parser instance to add to the existing list.
+ *
+ * @return array An array of Twig_TokenParser instances
+ */
+ public function getTokenParsers()
+ {
+ return array(new Twig_TokenParser_AutoEscape());
+ }
- /**
- * Returns the node visitor instances to add to the existing list.
- *
- * @return array An array of Twig_NodeVisitorInterface instances
- */
- public function getNodeVisitors()
- {
- return array(new Twig_NodeVisitor_Escaper());
- }
+ /**
+ * Returns the node visitor instances to add to the existing list.
+ *
+ * @return array An array of Twig_NodeVisitorInterface instances
+ */
+ public function getNodeVisitors()
+ {
+ return array(new Twig_NodeVisitor_Escaper());
+ }
- /**
- * Returns a list of filters to add to the existing list.
- *
- * @return array An array of filters
- */
- public function getFilters()
- {
- return array(
- 'safe' => new Twig_Filter_Function('twig_safe_filter', array('is_escaper' => true)),
- );
- }
+ /**
+ * Returns a list of filters to add to the existing list.
+ *
+ * @return array An array of filters
+ */
+ public function getFilters()
+ {
+ return array(
+ 'safe' => new Twig_Filter_Function('twig_safe_filter', array('is_escaper' => true)),
+ );
+ }
- public function isGlobal()
- {
- return $this->autoescape;
- }
+ public function isGlobal()
+ {
+ return $this->autoescape;
+ }
- /**
- * Returns the name of the extension.
- *
- * @return string The extension name
- */
- public function getName()
- {
- return 'escaper';
- }
+ /**
+ * Returns the name of the extension.
+ *
+ * @return string The extension name
+ */
+ public function getName()
+ {
+ return 'escaper';
+ }
}
// tells the escaper node visitor that the string is safe
function twig_safe_filter($string)
{
- return $string;
+ return $string;
}
*/
class Twig_Extension_I18n extends Twig_Extension
{
- /**
- * Returns the token parser instance to add to the existing list.
- *
- * @return array An array of Twig_TokenParser instances
- */
- public function getTokenParsers()
- {
- return array(new Twig_TokenParser_Trans());
- }
+ /**
+ * Returns the token parser instance to add to the existing list.
+ *
+ * @return array An array of Twig_TokenParser instances
+ */
+ public function getTokenParsers()
+ {
+ return array(new Twig_TokenParser_Trans());
+ }
- /**
- * Returns the name of the extension.
- *
- * @return string The extension name
- */
- public function getName()
- {
- return 'i18n';
- }
+ /**
+ * Returns the name of the extension.
+ *
+ * @return string The extension name
+ */
+ public function getName()
+ {
+ return 'i18n';
+ }
}
*/
class Twig_Extension_Sandbox extends Twig_Extension
{
- protected $sandboxedGlobally;
- protected $sandboxed;
- protected $policy;
+ protected $sandboxedGlobally;
+ protected $sandboxed;
+ protected $policy;
- public function __construct(Twig_Sandbox_SecurityPolicyInterface $policy, $sandboxed = false)
- {
- $this->policy = $policy;
- $this->sandboxedGlobally = $sandboxed;
- }
+ public function __construct(Twig_Sandbox_SecurityPolicyInterface $policy, $sandboxed = false)
+ {
+ $this->policy = $policy;
+ $this->sandboxedGlobally = $sandboxed;
+ }
- /**
- * Returns the node visitor instances to add to the existing list.
- *
- * @return array An array of Twig_NodeVisitorInterface instances
- */
- public function getNodeVisitors()
- {
- return array(new Twig_NodeVisitor_Sandbox());
- }
+ /**
+ * Returns the node visitor instances to add to the existing list.
+ *
+ * @return array An array of Twig_NodeVisitorInterface instances
+ */
+ public function getNodeVisitors()
+ {
+ return array(new Twig_NodeVisitor_Sandbox());
+ }
- public function enableSandbox()
- {
- $this->sandboxed = true;
- }
+ public function enableSandbox()
+ {
+ $this->sandboxed = true;
+ }
- public function disableSandbox()
- {
- $this->sandboxed = false;
- }
+ public function disableSandbox()
+ {
+ $this->sandboxed = false;
+ }
- public function isSandboxed()
- {
- return $this->sandboxedGlobally || $this->sandboxed;
- }
+ public function isSandboxed()
+ {
+ return $this->sandboxedGlobally || $this->sandboxed;
+ }
- public function isSandboxedGlobally()
- {
- return $this->sandboxedGlobally;
- }
+ public function isSandboxedGlobally()
+ {
+ return $this->sandboxedGlobally;
+ }
- public function setSecurityPolicy(Twig_Sandbox_SecurityPolicyInterface $policy)
- {
- $this->policy = $policy;
- }
+ public function setSecurityPolicy(Twig_Sandbox_SecurityPolicyInterface $policy)
+ {
+ $this->policy = $policy;
+ }
- public function getSecurityPolicy()
- {
- return $this->policy;
- }
+ public function getSecurityPolicy()
+ {
+ return $this->policy;
+ }
- public function checkSecurity($tags, $filters)
- {
- if ($this->isSandboxed())
+ public function checkSecurity($tags, $filters)
{
- $this->policy->checkSecurity($tags, $filters);
+ if ($this->isSandboxed()) {
+ $this->policy->checkSecurity($tags, $filters);
+ }
}
- }
- public function checkMethodAllowed($obj, $method)
- {
- if ($this->isSandboxed())
+ public function checkMethodAllowed($obj, $method)
{
- $this->policy->checkMethodAllowed($obj, $method);
+ if ($this->isSandboxed()) {
+ $this->policy->checkMethodAllowed($obj, $method);
+ }
}
- }
- public function checkPropertyAllowed($obj, $method)
- {
- if ($this->isSandboxed())
+ public function checkPropertyAllowed($obj, $method)
{
- $this->policy->checkPropertyAllowed($obj, $method);
+ if ($this->isSandboxed()) {
+ $this->policy->checkPropertyAllowed($obj, $method);
+ }
}
- }
- /**
- * Returns the name of the extension.
- *
- * @return string The extension name
- */
- public function getName()
- {
- return 'sandbox';
- }
+ /**
+ * Returns the name of the extension.
+ *
+ * @return string The extension name
+ */
+ public function getName()
+ {
+ return 'sandbox';
+ }
}
*/
interface Twig_ExtensionInterface
{
- /**
- * Initializes the runtime environment.
- *
- * This is where you can load some file that contains filter functions for instance.
- */
- public function initRuntime();
+ /**
+ * Initializes the runtime environment.
+ *
+ * This is where you can load some file that contains filter functions for instance.
+ */
+ public function initRuntime();
- /**
- * Returns the token parser instances to add to the existing list.
- *
- * @return array An array of Twig_TokenParser instances
- */
- public function getTokenParsers();
+ /**
+ * Returns the token parser instances to add to the existing list.
+ *
+ * @return array An array of Twig_TokenParser instances
+ */
+ public function getTokenParsers();
- /**
- * Returns the node visitor instances to add to the existing list.
- *
- * @return array An array of Twig_NodeVisitorInterface instances
- */
- public function getNodeVisitors();
+ /**
+ * Returns the node visitor instances to add to the existing list.
+ *
+ * @return array An array of Twig_NodeVisitorInterface instances
+ */
+ public function getNodeVisitors();
- /**
- * Returns a list of filters to add to the existing list.
- *
- * @return array An array of filters
- */
- public function getFilters();
+ /**
+ * Returns a list of filters to add to the existing list.
+ *
+ * @return array An array of filters
+ */
+ public function getFilters();
- /**
- * Returns the name of the extension.
- *
- * @return string The extension name
- */
- public function getName();
+ /**
+ * Returns the name of the extension.
+ *
+ * @return string The extension name
+ */
+ public function getName();
}
*/
abstract class Twig_Filter
{
- protected $options;
+ protected $options;
- public function __construct(array $options = array())
- {
- $this->options = array_merge(array(
- 'needs_environment' => false,
- 'is_escaper' => false,
- ), $options);
- }
+ public function __construct(array $options = array())
+ {
+ $this->options = array_merge(array(
+ 'needs_environment' => false,
+ 'is_escaper' => false,
+ ), $options);
+ }
- abstract public function compile();
+ abstract public function compile();
- public function needsEnvironment()
- {
- return $this->options['needs_environment'];
- }
+ public function needsEnvironment()
+ {
+ return $this->options['needs_environment'];
+ }
- public function isEscaper()
- {
- return $this->options['is_escaper'];
- }
+ public function isEscaper()
+ {
+ return $this->options['is_escaper'];
+ }
}
*/
class Twig_Filter_Function extends Twig_Filter
{
- protected $function;
+ protected $function;
- public function __construct($function, array $options = array())
- {
- parent::__construct($options);
+ public function __construct($function, array $options = array())
+ {
+ parent::__construct($options);
- $this->function = $function;
- }
+ $this->function = $function;
+ }
- public function compile()
- {
- return $this->function;
- }
+ public function compile()
+ {
+ return $this->function;
+ }
}
*/
class Twig_Filter_Method extends Twig_Filter
{
- protected $extension, $method;
+ protected $extension, $method;
- public function __construct(Twig_ExtensionInterface $extension, $method, array $options = array())
- {
- parent::__construct($options);
+ public function __construct(Twig_ExtensionInterface $extension, $method, array $options = array())
+ {
+ parent::__construct($options);
- $this->extension = $extension;
- $this->method = $method;
- }
+ $this->extension = $extension;
+ $this->method = $method;
+ }
- public function compile()
- {
- return sprintf('$this->getEnvironment()->getExtension(\'%s\')->%s', $this->extension->getName(), $this->method);
- }
+ public function compile()
+ {
+ return sprintf('$this->getEnvironment()->getExtension(\'%s\')->%s', $this->extension->getName(), $this->method);
+ }
}
*/
class Twig_Lexer implements Twig_LexerInterface
{
- protected $cursor;
- protected $position;
- protected $end;
- protected $pushedBack;
- protected $code;
- protected $lineno;
- protected $filename;
- protected $env;
- protected $options;
-
- const POSITION_DATA = 0;
- const POSITION_BLOCK = 1;
- const POSITION_VAR = 2;
-
- const REGEX_NAME = '/[A-Za-z_][A-Za-z0-9_]*/A';
- const REGEX_NUMBER = '/[0-9]+(?:\.[0-9]+)?/A';
- const REGEX_STRING = '/(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\')/Asm';
- const REGEX_OPERATOR = '/<=? | >=? | [!=]= | \/\/ | \.\. | [(){}.,%*\/+~|-] | \[ | \] | \? | \:/Ax';
-
- public function __construct(Twig_Environment $env = null, array $options = array())
- {
- $this->env = $env;
-
- $this->options = array_merge(array(
- 'tag_comment' => array('{#', '#}'),
- 'tag_block' => array('{%', '%}'),
- 'tag_variable' => array('{{', '}}'),
- ), $options);
- }
-
- /**
- * Tokenizes a source code.
- *
- * @param string $code The source code
- * @param string $filename A unique identifier for the source code
- *
- * @return Twig_TokenStream A token stream instance
- */
- public function tokenize($code, $filename = 'n/a')
- {
- if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2)
+ protected $cursor;
+ protected $position;
+ protected $end;
+ protected $pushedBack;
+ protected $code;
+ protected $lineno;
+ protected $filename;
+ protected $env;
+ protected $options;
+
+ const POSITION_DATA = 0;
+ const POSITION_BLOCK = 1;
+ const POSITION_VAR = 2;
+
+ const REGEX_NAME = '/[A-Za-z_][A-Za-z0-9_]*/A';
+ const REGEX_NUMBER = '/[0-9]+(?:\.[0-9]+)?/A';
+ const REGEX_STRING = '/(?:"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"|\'([^\'\\\\]*(?:\\\\.[^\'\\\\]*)*)\')/Asm';
+ const REGEX_OPERATOR = '/<=? | >=? | [!=]= | \/\/ | \.\. | [(){}.,%*\/+~|-] | \[ | \] | \? | \:/Ax';
+
+ public function __construct(Twig_Environment $env = null, array $options = array())
{
- $mbEncoding = mb_internal_encoding();
- mb_internal_encoding('ASCII');
+ $this->env = $env;
+
+ $this->options = array_merge(array(
+ 'tag_comment' => array('{#', '#}'),
+ 'tag_block' => array('{%', '%}'),
+ 'tag_variable' => array('{{', '}}'),
+ ), $options);
}
- $this->code = str_replace(array("\r\n", "\r"), "\n", $code);
- $this->filename = $filename;
- $this->cursor = 0;
- $this->lineno = 1;
- $this->pushedBack = array();
- $this->end = strlen($this->code);
- $this->position = self::POSITION_DATA;
-
- $tokens = array();
- $end = false;
- while (!$end)
+ /**
+ * Tokenizes a source code.
+ *
+ * @param string $code The source code
+ * @param string $filename A unique identifier for the source code
+ *
+ * @return Twig_TokenStream A token stream instance
+ */
+ public function tokenize($code, $filename = 'n/a')
{
- $token = $this->nextToken();
+ if (function_exists('mb_internal_encoding') && ((int) ini_get('mbstring.func_overload')) & 2) {
+ $mbEncoding = mb_internal_encoding();
+ mb_internal_encoding('ASCII');
+ }
- $tokens[] = $token;
+ $this->code = str_replace(array("\r\n", "\r"), "\n", $code);
+ $this->filename = $filename;
+ $this->cursor = 0;
+ $this->lineno = 1;
+ $this->pushedBack = array();
+ $this->end = strlen($this->code);
+ $this->position = self::POSITION_DATA;
- $end = $token->getType() === Twig_Token::EOF_TYPE;
- }
+ $tokens = array();
+ $end = false;
+ while (!$end) {
+ $token = $this->nextToken();
- if (isset($mbEncoding))
- {
- mb_internal_encoding($mbEncoding);
- }
+ $tokens[] = $token;
- return new Twig_TokenStream($tokens, $this->filename, $this->env->getTrimBlocks());
- }
-
- public function setEnvironment(Twig_Environment $env)
- {
- $this->env = $env;
- }
-
- /**
- * Parses the next token and returns it.
- */
- protected function nextToken()
- {
- // do we have tokens pushed back? get one
- if (!empty($this->pushedBack))
- {
- return array_shift($this->pushedBack);
+ $end = $token->getType() === Twig_Token::EOF_TYPE;
+ }
+
+ if (isset($mbEncoding)) {
+ mb_internal_encoding($mbEncoding);
+ }
+
+ return new Twig_TokenStream($tokens, $this->filename, $this->env->getTrimBlocks());
}
- // have we reached the end of the code?
- if ($this->cursor >= $this->end)
+ public function setEnvironment(Twig_Environment $env)
{
- return new Twig_Token(Twig_Token::EOF_TYPE, '', $this->lineno);
+ $this->env = $env;
}
- // otherwise dispatch to the lexing functions depending
- // on our current position in the code.
- switch ($this->position)
+ /**
+ * Parses the next token and returns it.
+ */
+ protected function nextToken()
{
- case self::POSITION_DATA:
- $tokens = $this->lexData();
- break;
+ // do we have tokens pushed back? get one
+ if (!empty($this->pushedBack)) {
+ return array_shift($this->pushedBack);
+ }
- case self::POSITION_BLOCK:
- $tokens = $this->lexBlock();
- break;
+ // have we reached the end of the code?
+ if ($this->cursor >= $this->end) {
+ return new Twig_Token(Twig_Token::EOF_TYPE, '', $this->lineno);
+ }
- case self::POSITION_VAR:
- $tokens = $this->lexVar();
- break;
- }
+ // otherwise dispatch to the lexing functions depending
+ // on our current position in the code.
+ switch ($this->position) {
+ case self::POSITION_DATA:
+ $tokens = $this->lexData();
+ break;
- // if the return value is not an array it's a token
- if (!is_array($tokens))
- {
- return $tokens;
- }
- // empty array, call again
- else if (empty($tokens))
- {
- return $this->nextToken();
- }
- // if we have multiple items we push them to the buffer
- else if (count($tokens) > 1)
- {
- $first = array_shift($tokens);
- $this->pushedBack = $tokens;
+ case self::POSITION_BLOCK:
+ $tokens = $this->lexBlock();
+ break;
- return $first;
+ case self::POSITION_VAR:
+ $tokens = $this->lexVar();
+ break;
+ }
+
+ // if the return value is not an array it's a token
+ if (!is_array($tokens)) {
+ return $tokens;
+ }
+ // empty array, call again
+ else if (empty($tokens)) {
+ return $this->nextToken();
+ }
+ // if we have multiple items we push them to the buffer
+ else if (count($tokens) > 1) {
+ $first = array_shift($tokens);
+ $this->pushedBack = $tokens;
+
+ return $first;
+ }
+ // otherwise return the first item of the array.
+ else {
+ return $tokens[0];
+ }
}
- // otherwise return the first item of the array.
- else
+
+ protected function lexData()
{
- return $tokens[0];
- }
- }
+ $match = null;
- protected function lexData()
- {
- $match = null;
+ $pos1 = strpos($this->code, $this->options['tag_comment'][0], $this->cursor);
+ $pos2 = strpos($this->code, $this->options['tag_variable'][0], $this->cursor);
+ $pos3 = strpos($this->code, $this->options['tag_block'][0], $this->cursor);
- $pos1 = strpos($this->code, $this->options['tag_comment'][0], $this->cursor);
- $pos2 = strpos($this->code, $this->options['tag_variable'][0], $this->cursor);
- $pos3 = strpos($this->code, $this->options['tag_block'][0], $this->cursor);
+ // if no matches are left we return the rest of the template
+ // as simple text token
+ if (false === $pos1 && false === $pos2 && false === $pos3) {
+ $rv = new Twig_Token(Twig_Token::TEXT_TYPE, substr($this->code, $this->cursor), $this->lineno);
+ $this->cursor = $this->end;
- // if no matches are left we return the rest of the template
- // as simple text token
- if (false === $pos1 && false === $pos2 && false === $pos3)
- {
- $rv = new Twig_Token(Twig_Token::TEXT_TYPE, substr($this->code, $this->cursor), $this->lineno);
- $this->cursor = $this->end;
+ return $rv;
+ }
- return $rv;
- }
+ // min
+ $pos = -log(0);
+ if (false !== $pos1 && $pos1 < $pos) {
+ $pos = $pos1;
+ $token = $this->options['tag_comment'][0];
+ }
+ if (false !== $pos2 && $pos2 < $pos) {
+ $pos = $pos2;
+ $token = $this->options['tag_variable'][0];
+ }
+ if (false !== $pos3 && $pos3 < $pos) {
+ $pos = $pos3;
+ $token = $this->options['tag_block'][0];
+ }
- // min
- $pos = -log(0);
- if (false !== $pos1 && $pos1 < $pos)
- {
- $pos = $pos1;
- $token = $this->options['tag_comment'][0];
- }
- if (false !== $pos2 && $pos2 < $pos)
- {
- $pos = $pos2;
- $token = $this->options['tag_variable'][0];
- }
- if (false !== $pos3 && $pos3 < $pos)
- {
- $pos = $pos3;
- $token = $this->options['tag_block'][0];
- }
+ // update the lineno on the instance
+ $lineno = $this->lineno;
- // update the lineno on the instance
- $lineno = $this->lineno;
+ $text = substr($this->code, $this->cursor, $pos - $this->cursor);
+ $this->moveCursor($text.$token);
+ $this->moveLineNo($text.$token);
- $text = substr($this->code, $this->cursor, $pos - $this->cursor);
- $this->moveCursor($text.$token);
- $this->moveLineNo($text.$token);
+ // array of tokens
+ $result = array();
- // array of tokens
- $result = array();
+ // push the template text first
+ if (!empty($text)) {
+ $result[] = new Twig_Token(Twig_Token::TEXT_TYPE, $text, $lineno);
+ $lineno += substr_count($text, "\n");
+ }
- // push the template text first
- if (!empty($text))
- {
- $result[] = new Twig_Token(Twig_Token::TEXT_TYPE, $text, $lineno);
- $lineno += substr_count($text, "\n");
+ switch ($token) {
+ case $this->options['tag_comment'][0]:
+ if (!preg_match('/(.*?)'.preg_quote($this->options['tag_comment'][1], '/').'/As', $this->code, $match, null, $this->cursor)) {
+ throw new Twig_SyntaxError('unclosed comment', $this->lineno, $this->filename);
+ }
+ $this->moveCursor($match[0]);
+ $this->moveLineNo($match[0]);
+ break;
+
+ case $this->options['tag_block'][0]:
+ // raw data?
+ if (preg_match('/\s*raw\s*'.preg_quote($this->options['tag_block'][1], '/').'(.*?)'.preg_quote($this->options['tag_block'][0], '/').'\s*endraw\s*'.preg_quote($this->options['tag_block'][1], '/').'/As', $this->code, $match, null, $this->cursor)) {
+ $result[] = new Twig_Token(Twig_Token::TEXT_TYPE, $match[1], $lineno);
+ $this->moveCursor($match[0]);
+ $this->moveLineNo($match[0]);
+ $this->position = self::POSITION_DATA;
+ } else {
+ $result[] = new Twig_Token(Twig_Token::BLOCK_START_TYPE, '', $lineno);
+ $this->position = self::POSITION_BLOCK;
+ }
+ break;
+
+ case $this->options['tag_variable'][0]:
+ $result[] = new Twig_Token(Twig_Token::VAR_START_TYPE, '', $lineno);
+ $this->position = self::POSITION_VAR;
+ break;
+ }
+
+ return $result;
}
- switch ($token)
+ protected function lexBlock()
{
- case $this->options['tag_comment'][0]:
- if (!preg_match('/(.*?)'.preg_quote($this->options['tag_comment'][1], '/').'/As', $this->code, $match, null, $this->cursor))
- {
- throw new Twig_SyntaxError('unclosed comment', $this->lineno, $this->filename);
- }
- $this->moveCursor($match[0]);
- $this->moveLineNo($match[0]);
- break;
-
- case $this->options['tag_block'][0]:
- // raw data?
- if (preg_match('/\s*raw\s*'.preg_quote($this->options['tag_block'][1], '/').'(.*?)'.preg_quote($this->options['tag_block'][0], '/').'\s*endraw\s*'.preg_quote($this->options['tag_block'][1], '/').'/As', $this->code, $match, null, $this->cursor))
- {
- $result[] = new Twig_Token(Twig_Token::TEXT_TYPE, $match[1], $lineno);
- $this->moveCursor($match[0]);
- $this->moveLineNo($match[0]);
- $this->position = self::POSITION_DATA;
- }
- else
- {
- $result[] = new Twig_Token(Twig_Token::BLOCK_START_TYPE, '', $lineno);
- $this->position = self::POSITION_BLOCK;
+ if (preg_match('/\s*'.preg_quote($this->options['tag_block'][1], '/').'/As', $this->code, $match, null, $this->cursor)) {
+ $lineno = $this->lineno;
+ $this->moveCursor($match[0]);
+ $this->moveLineNo($match[0]);
+ $this->position = self::POSITION_DATA;
+
+ return new Twig_Token(Twig_Token::BLOCK_END_TYPE, '', $lineno);
}
- break;
- case $this->options['tag_variable'][0]:
- $result[] = new Twig_Token(Twig_Token::VAR_START_TYPE, '', $lineno);
- $this->position = self::POSITION_VAR;
- break;
+ return $this->lexExpression();
}
- return $result;
- }
-
- protected function lexBlock()
- {
- if (preg_match('/\s*'.preg_quote($this->options['tag_block'][1], '/').'/As', $this->code, $match, null, $this->cursor))
+ protected function lexVar()
{
- $lineno = $this->lineno;
- $this->moveCursor($match[0]);
- $this->moveLineNo($match[0]);
- $this->position = self::POSITION_DATA;
+ if (preg_match('/\s*'.preg_quote($this->options['tag_variable'][1], '/').'/As', $this->code, $match, null, $this->cursor)) {
+ $lineno = $this->lineno;
+ $this->moveCursor($match[0]);
+ $this->moveLineNo($match[0]);
+ $this->position = self::POSITION_DATA;
- return new Twig_Token(Twig_Token::BLOCK_END_TYPE, '', $lineno);
- }
+ return new Twig_Token(Twig_Token::VAR_END_TYPE, '', $lineno);
+ }
- return $this->lexExpression();
- }
+ return $this->lexExpression();
+ }
- protected function lexVar()
- {
- if (preg_match('/\s*'.preg_quote($this->options['tag_variable'][1], '/').'/As', $this->code, $match, null, $this->cursor))
+ protected function lexExpression()
{
- $lineno = $this->lineno;
- $this->moveCursor($match[0]);
- $this->moveLineNo($match[0]);
- $this->position = self::POSITION_DATA;
+ $match = null;
- return new Twig_Token(Twig_Token::VAR_END_TYPE, '', $lineno);
- }
+ // whitespace
+ while (preg_match('/\s+/As', $this->code, $match, null, $this->cursor)) {
+ $this->moveCursor($match[0]);
+ $this->moveLineNo($match[0]);
+ }
- return $this->lexExpression();
- }
+ // sanity check
+ if ($this->cursor >= $this->end) {
+ throw new Twig_SyntaxError('Unexpected end of stream', $this->lineno, $this->filename);
+ }
- protected function lexExpression()
- {
- $match = null;
+ // first parse operators
+ if (preg_match(self::REGEX_OPERATOR, $this->code, $match, null, $this->cursor)) {
+ $this->moveCursor($match[0]);
- // whitespace
- while (preg_match('/\s+/As', $this->code, $match, null, $this->cursor))
- {
- $this->moveCursor($match[0]);
- $this->moveLineNo($match[0]);
- }
+ return new Twig_Token(Twig_Token::OPERATOR_TYPE, $match[0], $this->lineno);
+ }
+ // now names
+ else if (preg_match(self::REGEX_NAME, $this->code, $match, null, $this->cursor)) {
+ $this->moveCursor($match[0]);
- // sanity check
- if ($this->cursor >= $this->end)
- {
- throw new Twig_SyntaxError('Unexpected end of stream', $this->lineno, $this->filename);
- }
+ return new Twig_Token(Twig_Token::NAME_TYPE, $match[0], $this->lineno);
+ }
+ // then numbers
+ else if (preg_match(self::REGEX_NUMBER, $this->code, $match, null, $this->cursor)) {
+ $this->moveCursor($match[0]);
+ $value = (float)$match[0];
+ if ((int)$value === $value) {
+ $value = (int)$value;
+ }
+
+ return new Twig_Token(Twig_Token::NUMBER_TYPE, $value, $this->lineno);
+ }
+ // and finally strings
+ else if (preg_match(self::REGEX_STRING, $this->code, $match, null, $this->cursor)) {
+ $this->moveCursor($match[0]);
+ $this->moveLineNo($match[0]);
+ $value = stripcslashes(substr($match[0], 1, strlen($match[0]) - 2));
- // first parse operators
- if (preg_match(self::REGEX_OPERATOR, $this->code, $match, null, $this->cursor))
- {
- $this->moveCursor($match[0]);
+ return new Twig_Token(Twig_Token::STRING_TYPE, $value, $this->lineno);
+ }
- return new Twig_Token(Twig_Token::OPERATOR_TYPE, $match[0], $this->lineno);
+ // unlexable
+ throw new Twig_SyntaxError(sprintf("Unexpected character '%s'", $this->code[$this->cursor]), $this->lineno, $this->filename);
}
- // now names
- else if (preg_match(self::REGEX_NAME, $this->code, $match, null, $this->cursor))
- {
- $this->moveCursor($match[0]);
- return new Twig_Token(Twig_Token::NAME_TYPE, $match[0], $this->lineno);
- }
- // then numbers
- else if (preg_match(self::REGEX_NUMBER, $this->code, $match, null, $this->cursor))
+ protected function moveLineNo($text)
{
- $this->moveCursor($match[0]);
- $value = (float)$match[0];
- if ((int)$value === $value)
- {
- $value = (int)$value;
- }
-
- return new Twig_Token(Twig_Token::NUMBER_TYPE, $value, $this->lineno);
+ $this->lineno += substr_count($text, "\n");
}
- // and finally strings
- else if (preg_match(self::REGEX_STRING, $this->code, $match, null, $this->cursor))
- {
- $this->moveCursor($match[0]);
- $this->moveLineNo($match[0]);
- $value = stripcslashes(substr($match[0], 1, strlen($match[0]) - 2));
- return new Twig_Token(Twig_Token::STRING_TYPE, $value, $this->lineno);
+ protected function moveCursor($text)
+ {
+ $this->cursor += strlen($text);
}
- // unlexable
- throw new Twig_SyntaxError(sprintf("Unexpected character '%s'", $this->code[$this->cursor]), $this->lineno, $this->filename);
- }
-
- protected function moveLineNo($text)
- {
- $this->lineno += substr_count($text, "\n");
- }
-
- protected function moveCursor($text)
- {
- $this->cursor += strlen($text);
- }
-
}
*/
interface Twig_LexerInterface
{
- /**
- * Tokenizes a source code.
- *
- * @param string $code The source code
- * @param string $filename A unique identifier for the source code
- *
- * @return Twig_TokenStream A token stream instance
- */
- public function tokenize($code, $filename = 'n/a');
+ /**
+ * Tokenizes a source code.
+ *
+ * @param string $code The source code
+ * @param string $filename A unique identifier for the source code
+ *
+ * @return Twig_TokenStream A token stream instance
+ */
+ public function tokenize($code, $filename = 'n/a');
}
*/
class Twig_Loader_Array implements Twig_LoaderInterface
{
- protected $templates;
+ protected $templates;
- /**
- * Constructor.
- *
- * @param array $templates An array of templates (keys are the names, and values are the source code)
- *
- * @see Twig_Loader
- */
- public function __construct(array $templates)
- {
- $this->templates = array();
- foreach ($templates as $name => $template)
+ /**
+ * Constructor.
+ *
+ * @param array $templates An array of templates (keys are the names, and values are the source code)
+ *
+ * @see Twig_Loader
+ */
+ public function __construct(array $templates)
{
- $this->templates[$name] = $template;
+ $this->templates = array();
+ foreach ($templates as $name => $template) {
+ $this->templates[$name] = $template;
+ }
}
- }
- /**
- * Gets the source code of a template, given its name.
- *
- * @param string $name string The name of the template to load
- *
- * @return string The template source code
- */
- public function getSource($name)
- {
- if (!isset($this->templates[$name]))
+ /**
+ * Gets the source code of a template, given its name.
+ *
+ * @param string $name string The name of the template to load
+ *
+ * @return string The template source code
+ */
+ public function getSource($name)
{
- throw new LogicException(sprintf('Template "%s" is not defined.', $name));
- }
+ if (!isset($this->templates[$name])) {
+ throw new LogicException(sprintf('Template "%s" is not defined.', $name));
+ }
- return $this->templates[$name];
- }
+ return $this->templates[$name];
+ }
- /**
- * Gets the cache key to use for the cache for a given template name.
- *
- * @param string $name string The name of the template to load
- *
- * @return string The cache key
- */
- public function getCacheKey($name)
- {
- if (!isset($this->templates[$name]))
+ /**
+ * Gets the cache key to use for the cache for a given template name.
+ *
+ * @param string $name string The name of the template to load
+ *
+ * @return string The cache key
+ */
+ public function getCacheKey($name)
{
- throw new LogicException(sprintf('Template "%s" is not defined.', $name));
- }
+ if (!isset($this->templates[$name])) {
+ throw new LogicException(sprintf('Template "%s" is not defined.', $name));
+ }
- return $this->templates[$name];
- }
+ return $this->templates[$name];
+ }
- /**
- * Returns true if the template is still fresh.
- *
- * @param string $name The template name
- * @param timestamp $time The last modification time of the cached template
- */
- public function isFresh($name, $time)
- {
- return true;
- }
+ /**
+ * Returns true if the template is still fresh.
+ *
+ * @param string $name The template name
+ * @param timestamp $time The last modification time of the cached template
+ */
+ public function isFresh($name, $time)
+ {
+ return true;
+ }
}
*/
class Twig_Loader_Filesystem implements Twig_LoaderInterface
{
- protected $paths;
- protected $cache;
-
- /**
- * Constructor.
- *
- * @param string|array $paths A path or an array of paths where to look for templates
- */
- public function __construct($paths)
- {
- $this->setPaths($paths);
- }
-
- /**
- * Returns the paths to the templates.
- *
- * @return array The array of paths where to look for templates
- */
- public function getPaths()
- {
- return $this->paths;
- }
-
- /**
- * Sets the paths where templates are stored.
- *
- * @param string|array $paths A path or an array of paths where to look for templates
- */
- public function setPaths($paths)
- {
- // invalidate the cache
- $this->cache = array();
-
- if (!is_array($paths))
+ protected $paths;
+ protected $cache;
+
+ /**
+ * Constructor.
+ *
+ * @param string|array $paths A path or an array of paths where to look for templates
+ */
+ public function __construct($paths)
{
- $paths = array($paths);
+ $this->setPaths($paths);
}
- $this->paths = array();
- foreach ($paths as $path)
+ /**
+ * Returns the paths to the templates.
+ *
+ * @return array The array of paths where to look for templates
+ */
+ public function getPaths()
{
- if (!is_dir($path))
- {
- throw new InvalidArgumentException(sprintf('The "%s" directory does not exist.', $path));
- }
+ return $this->paths;
+ }
+
+ /**
+ * Sets the paths where templates are stored.
+ *
+ * @param string|array $paths A path or an array of paths where to look for templates
+ */
+ public function setPaths($paths)
+ {
+ // invalidate the cache
+ $this->cache = array();
+
+ if (!is_array($paths)) {
+ $paths = array($paths);
+ }
- $this->paths[] = realpath($path);
+ $this->paths = array();
+ foreach ($paths as $path) {
+ if (!is_dir($path)) {
+ throw new InvalidArgumentException(sprintf('The "%s" directory does not exist.', $path));
+ }
+
+ $this->paths[] = realpath($path);
+ }
}
- }
-
- /**
- * Gets the source code of a template, given its name.
- *
- * @param string $name string The name of the template to load
- *
- * @return string The template source code
- */
- public function getSource($name)
- {
- return file_get_contents($this->findTemplate($name));
- }
-
- /**
- * Gets the cache key to use for the cache for a given template name.
- *
- * @param string $name string The name of the template to load
- *
- * @return string The cache key
- */
- public function getCacheKey($name)
- {
- return $this->findTemplate($name);
- }
-
- /**
- * Returns true if the template is still fresh.
- *
- * @param string $name The template name
- * @param timestamp $time The last modification time of the cached template
- */
- public function isFresh($name, $time)
- {
- return filemtime($this->findTemplate($name)) < $time;
- }
-
- protected function findTemplate($name)
- {
- if (isset($this->cache[$name]))
+
+ /**
+ * Gets the source code of a template, given its name.
+ *
+ * @param string $name string The name of the template to load
+ *
+ * @return string The template source code
+ */
+ public function getSource($name)
{
- return $this->cache[$name];
+ return file_get_contents($this->findTemplate($name));
}
- foreach ($this->paths as $path)
+ /**
+ * Gets the cache key to use for the cache for a given template name.
+ *
+ * @param string $name string The name of the template to load
+ *
+ * @return string The cache key
+ */
+ public function getCacheKey($name)
{
- if (!file_exists($path.DIRECTORY_SEPARATOR.$name))
- {
- continue;
- }
+ return $this->findTemplate($name);
+ }
- $file = realpath($path.DIRECTORY_SEPARATOR.$name);
+ /**
+ * Returns true if the template is still fresh.
+ *
+ * @param string $name The template name
+ * @param timestamp $time The last modification time of the cached template
+ */
+ public function isFresh($name, $time)
+ {
+ return filemtime($this->findTemplate($name)) < $time;
+ }
+
+ protected function findTemplate($name)
+ {
+ if (isset($this->cache[$name])) {
+ return $this->cache[$name];
+ }
- // simple security check
- if (0 !== strpos($file, $path))
- {
- throw new RuntimeException('Looks like you try to load a template outside configured directories.');
- }
+ foreach ($this->paths as $path) {
+ if (!file_exists($path.DIRECTORY_SEPARATOR.$name)) {
+ continue;
+ }
- return $this->cache[$name] = $file;
- }
+ $file = realpath($path.DIRECTORY_SEPARATOR.$name);
- throw new RuntimeException(sprintf('Unable to find template "%s" (looked into: %s).', $name, implode(', ', $this->paths)));
- }
+ // simple security check
+ if (0 !== strpos($file, $path)) {
+ throw new RuntimeException('Looks like you try to load a template outside configured directories.');
+ }
+
+ return $this->cache[$name] = $file;
+ }
+
+ throw new RuntimeException(sprintf('Unable to find template "%s" (looked into: %s).', $name, implode(', ', $this->paths)));
+ }
}
*/
class Twig_Loader_String implements Twig_LoaderInterface
{
- /**
- * Gets the source code of a template, given its name.
- *
- * @param string $name string The name of the template to load
- *
- * @return string The template source code
- */
- public function getSource($name)
- {
- return $name;
- }
+ /**
+ * Gets the source code of a template, given its name.
+ *
+ * @param string $name string The name of the template to load
+ *
+ * @return string The template source code
+ */
+ public function getSource($name)
+ {
+ return $name;
+ }
- /**
- * Gets the cache key to use for the cache for a given template name.
- *
- * @param string $name string The name of the template to load
- *
- * @return string The cache key
- */
- public function getCacheKey($name)
- {
- return $name;
- }
+ /**
+ * Gets the cache key to use for the cache for a given template name.
+ *
+ * @param string $name string The name of the template to load
+ *
+ * @return string The cache key
+ */
+ public function getCacheKey($name)
+ {
+ return $name;
+ }
- /**
- * Returns true if the template is still fresh.
- *
- * @param string $name The template name
- * @param timestamp $time The last modification time of the cached template
- */
- public function isFresh($name, $time)
- {
- return true;
- }
+ /**
+ * Returns true if the template is still fresh.
+ *
+ * @param string $name The template name
+ * @param timestamp $time The last modification time of the cached template
+ */
+ public function isFresh($name, $time)
+ {
+ return true;
+ }
}
*/
interface Twig_LoaderInterface
{
- /**
- * Gets the source code of a template, given its name.
- *
- * @param string $name string The name of the template to load
- *
- * @return string The template source code
- */
- public function getSource($name);
+ /**
+ * Gets the source code of a template, given its name.
+ *
+ * @param string $name string The name of the template to load
+ *
+ * @return string The template source code
+ */
+ public function getSource($name);
- /**
- * Gets the cache key to use for the cache for a given template name.
- *
- * @param string $name string The name of the template to load
- *
- * @return string The cache key
- */
- public function getCacheKey($name);
+ /**
+ * Gets the cache key to use for the cache for a given template name.
+ *
+ * @param string $name string The name of the template to load
+ *
+ * @return string The cache key
+ */
+ public function getCacheKey($name);
- /**
- * Returns true if the template is still fresh.
- *
- * @param string $name The template name
- * @param timestamp $time The last modification time of the cached template
- */
- public function isFresh($name, $time);
+ /**
+ * Returns true if the template is still fresh.
+ *
+ * @param string $name The template name
+ * @param timestamp $time The last modification time of the cached template
+ */
+ public function isFresh($name, $time);
}
*/
abstract class Twig_Node
{
- protected $lineno;
- protected $tag;
+ protected $lineno;
+ protected $tag;
- public function __construct($lineno, $tag = null)
- {
- $this->lineno = $lineno;
- $this->tag = $tag;
- }
+ public function __construct($lineno, $tag = null)
+ {
+ $this->lineno = $lineno;
+ $this->tag = $tag;
+ }
- public function __toString()
- {
- return get_class($this).'()';
- }
+ public function __toString()
+ {
+ return get_class($this).'()';
+ }
- abstract public function compile($compiler);
+ abstract public function compile($compiler);
- public function getLine()
- {
- return $this->lineno;
- }
+ public function getLine()
+ {
+ return $this->lineno;
+ }
- public function getTag()
- {
- return $this->tag;
- }
+ public function getTag()
+ {
+ return $this->tag;
+ }
}
*/
class Twig_Node_AutoEscape extends Twig_Node implements Twig_NodeListInterface
{
- protected $value;
- protected $body;
+ protected $value;
+ protected $body;
- public function __construct($value, Twig_NodeList $body, $lineno, $tag = null)
- {
- parent::__construct($lineno, $tag);
- $this->value = $value;
- $this->body = $body;
- }
-
- public function __toString()
- {
- $repr = array(get_class($this).'('.($this->value ? 'on' : 'off'));
- foreach (explode("\n", $this->body) as $line)
+ public function __construct($value, Twig_NodeList $body, $lineno, $tag = null)
{
- $repr[] = ' '.$line;
+ parent::__construct($lineno, $tag);
+ $this->value = $value;
+ $this->body = $body;
}
- $repr[] = ')';
- return implode("\n", $repr);
- }
+ public function __toString()
+ {
+ $repr = array(get_class($this).'('.($this->value ? 'on' : 'off'));
+ foreach (explode("\n", $this->body) as $line) {
+ $repr[] = ' '.$line;
+ }
+ $repr[] = ')';
+
+ return implode("\n", $repr);
+ }
- public function getNodes()
- {
- return $this->body->getNodes();
- }
+ public function getNodes()
+ {
+ return $this->body->getNodes();
+ }
- public function setNodes(array $nodes)
- {
- $this->body = new Twig_NodeList($nodes, $this->lineno);
- }
+ public function setNodes(array $nodes)
+ {
+ $this->body = new Twig_NodeList($nodes, $this->lineno);
+ }
- public function compile($compiler)
- {
- $compiler->subcompile($this->body);
- }
+ public function compile($compiler)
+ {
+ $compiler->subcompile($this->body);
+ }
- public function getValue()
- {
- return $this->value;
- }
+ public function getValue()
+ {
+ return $this->value;
+ }
}
*/
class Twig_Node_Block extends Twig_Node implements Twig_NodeListInterface
{
- protected $name;
- protected $body;
- protected $parent;
+ protected $name;
+ protected $body;
+ protected $parent;
- public function __construct($name, Twig_NodeList $body, $lineno, $parent = null, $tag = null)
- {
- parent::__construct($lineno, $tag);
- $this->name = $name;
- $this->body = $body;
- $this->parent = $parent;
- }
-
- public function __toString()
- {
- $repr = array(get_class($this).' '.$this->name.'(');
- foreach ($this->body->getNodes() as $node)
+ public function __construct($name, Twig_NodeList $body, $lineno, $parent = null, $tag = null)
{
- foreach (explode("\n", $node->__toString()) as $line)
- {
- $repr[] = ' '.$line;
- }
+ parent::__construct($lineno, $tag);
+ $this->name = $name;
+ $this->body = $body;
+ $this->parent = $parent;
}
- $repr[] = ')';
- return implode("\n", $repr);
- }
+ public function __toString()
+ {
+ $repr = array(get_class($this).' '.$this->name.'(');
+ foreach ($this->body->getNodes() as $node) {
+ foreach (explode("\n", $node->__toString()) as $line) {
+ $repr[] = ' '.$line;
+ }
+ }
+ $repr[] = ')';
- public function getNodes()
- {
- return $this->body->getNodes();
- }
+ return implode("\n", $repr);
+ }
- public function setNodes(array $nodes)
- {
- $this->body = new Twig_NodeList($nodes, $this->lineno);
- }
+ public function getNodes()
+ {
+ return $this->body->getNodes();
+ }
- public function replace($other)
- {
- $this->body = $other->body;
- }
+ public function setNodes(array $nodes)
+ {
+ $this->body = new Twig_NodeList($nodes, $this->lineno);
+ }
+
+ public function replace($other)
+ {
+ $this->body = $other->body;
+ }
- public function compile($compiler)
- {
- $compiler
- ->addDebugInfo($this)
- ->write(sprintf("public function block_%s(\$context)\n", $this->name), "{\n")
- ->indent()
- ;
+ public function compile($compiler)
+ {
+ $compiler
+ ->addDebugInfo($this)
+ ->write(sprintf("public function block_%s(\$context)\n", $this->name), "{\n")
+ ->indent()
+ ;
- $compiler
- ->subcompile($this->body)
- ->outdent()
- ->write("}\n\n")
- ;
- }
+ $compiler
+ ->subcompile($this->body)
+ ->outdent()
+ ->write("}\n\n")
+ ;
+ }
- public function getName()
- {
- return $this->name;
- }
+ public function getName()
+ {
+ return $this->name;
+ }
- public function getParent()
- {
- return $this->parent;
- }
+ public function getParent()
+ {
+ return $this->parent;
+ }
- public function setParent($parent)
- {
- $this->parent = $parent;
- }
+ public function setParent($parent)
+ {
+ $this->parent = $parent;
+ }
}
*/
class Twig_Node_BlockReference extends Twig_Node
{
- protected $name;
+ protected $name;
- public function __construct($name, $lineno, $tag = null)
- {
- parent::__construct($lineno, $tag);
- $this->name = $name;
- }
+ public function __construct($name, $lineno, $tag = null)
+ {
+ parent::__construct($lineno, $tag);
+ $this->name = $name;
+ }
- public function __toString()
- {
- return get_class($this).'('.$this->name.')';
- }
+ public function __toString()
+ {
+ return get_class($this).'('.$this->name.')';
+ }
- public function compile($compiler)
- {
- $compiler
- ->addDebugInfo($this)
- ->write(sprintf('$this->block_%s($context);'."\n", $this->name))
- ;
- }
+ public function compile($compiler)
+ {
+ $compiler
+ ->addDebugInfo($this)
+ ->write(sprintf('$this->block_%s($context);'."\n", $this->name))
+ ;
+ }
- public function getName()
- {
- return $this->name;
- }
+ public function getName()
+ {
+ return $this->name;
+ }
}
class Twig_Node_Debug extends Twig_Node
{
- protected $expr;
+ protected $expr;
- public function __construct(Twig_Node_Expression $expr = null, $lineno, $tag = null)
- {
- parent::__construct($lineno, $tag);
+ public function __construct(Twig_Node_Expression $expr = null, $lineno, $tag = null)
+ {
+ parent::__construct($lineno, $tag);
- $this->expr = $expr;
- }
+ $this->expr = $expr;
+ }
- public function compile($compiler)
- {
- $compiler->addDebugInfo($this);
+ public function compile($compiler)
+ {
+ $compiler->addDebugInfo($this);
- $compiler
- ->write("if (\$this->env->isDebug())\n", "{\n")
- ->indent()
- ->write('var_export(')
- ;
+ $compiler
+ ->write("if (\$this->env->isDebug())\n", "{\n")
+ ->indent()
+ ->write('var_export(')
+ ;
- if (null === $this->expr)
- {
- $compiler->raw('$context');
- }
- else
- {
- $compiler->subcompile($this->expr);
- }
+ if (null === $this->expr) {
+ $compiler->raw('$context');
+ } else {
+ $compiler->subcompile($this->expr);
+ }
- $compiler
- ->raw(");\n")
- ->outdent()
- ->write("}\n")
- ;
- }
+ $compiler
+ ->raw(");\n")
+ ->outdent()
+ ->write("}\n")
+ ;
+ }
}
*/
class Twig_Node_Expression_Array extends Twig_Node_Expression implements Twig_NodeListInterface
{
- protected $elements;
+ protected $elements;
- public function __construct($elements, $lineno)
- {
- parent::__construct($lineno);
+ public function __construct($elements, $lineno)
+ {
+ parent::__construct($lineno);
- $this->elements = $elements;
- }
+ $this->elements = $elements;
+ }
- public function __toString()
- {
- $repr = array(get_class($this).'(');
- foreach ($this->elements as $name => $node)
+ public function __toString()
{
- foreach (explode("\n", ' '.$name.' => '.$node) as $line)
- {
- $repr[] = ' '.$line;
- }
- }
- $repr[] = ')';
+ $repr = array(get_class($this).'(');
+ foreach ($this->elements as $name => $node) {
+ foreach (explode("\n", ' '.$name.' => '.$node) as $line) {
+ $repr[] = ' '.$line;
+ }
+ }
+ $repr[] = ')';
- return implode("\n", $repr);
- }
+ return implode("\n", $repr);
+ }
- public function getNodes()
- {
- return $this->elements;
- }
+ public function getNodes()
+ {
+ return $this->elements;
+ }
- public function setNodes(array $nodes)
- {
- $this->elements = $nodes;
- }
+ public function setNodes(array $nodes)
+ {
+ $this->elements = $nodes;
+ }
- public function compile($compiler)
- {
- $compiler->raw('array(');
- $first = true;
- foreach ($this->elements as $name => $node)
+ public function compile($compiler)
{
- if (!$first)
- {
- $compiler->raw(', ');
- }
- $first = false;
+ $compiler->raw('array(');
+ $first = true;
+ foreach ($this->elements as $name => $node) {
+ if (!$first) {
+ $compiler->raw(', ');
+ }
+ $first = false;
- $compiler
- ->repr($name)
- ->raw(' => ')
- ->subcompile($node)
- ;
+ $compiler
+ ->repr($name)
+ ->raw(' => ')
+ ->subcompile($node)
+ ;
+ }
+ $compiler->raw(')');
}
- $compiler->raw(')');
- }
- public function getElements()
- {
- return $this->elements;
- }
+ public function getElements()
+ {
+ return $this->elements;
+ }
}
class Twig_Node_Expression_AssignName extends Twig_Node_Expression_Name
{
- public function compile($compiler)
- {
- $compiler->raw(sprintf('$context[\'%s\']', $this->name));
- }
+ public function compile($compiler)
+ {
+ $compiler->raw(sprintf('$context[\'%s\']', $this->name));
+ }
}
*/
abstract class Twig_Node_Expression_Binary extends Twig_Node_Expression
{
- protected $left;
- protected $right;
+ protected $left;
+ protected $right;
- public function __construct(Twig_Node $left, Twig_Node $right, $lineno)
- {
- parent::__construct($lineno);
- $this->left = $left;
- $this->right = $right;
- }
-
- public function __toString()
- {
- $repr = array(get_class($this).'(');
-
- foreach (explode("\n", $this->left->__toString()) as $line)
+ public function __construct(Twig_Node $left, Twig_Node $right, $lineno)
{
- $repr[] = ' '.$line;
+ parent::__construct($lineno);
+ $this->left = $left;
+ $this->right = $right;
}
- $repr[] = ', ';
+ public function __toString()
+ {
+ $repr = array(get_class($this).'(');
+
+ foreach (explode("\n", $this->left->__toString()) as $line) {
+ $repr[] = ' '.$line;
+ }
+
+ $repr[] = ', ';
+
+ foreach (explode("\n", $this->right->__toString()) as $line) {
+ $repr[] = ' '.$line;
+ }
+
+ $repr[] = ')';
+
+ return implode("\n", $repr);
+ }
- foreach (explode("\n", $this->right->__toString()) as $line)
+ public function compile($compiler)
{
- $repr[] = ' '.$line;
+ $compiler
+ ->raw('(')
+ ->subcompile($this->left)
+ ->raw(') ')
+ ;
+ $this->operator($compiler);
+ $compiler
+ ->raw(' (')
+ ->subcompile($this->right)
+ ->raw(')')
+ ;
}
- $repr[] = ')';
-
- return implode("\n", $repr);
- }
-
- public function compile($compiler)
- {
- $compiler
- ->raw('(')
- ->subcompile($this->left)
- ->raw(') ')
- ;
- $this->operator($compiler);
- $compiler
- ->raw(' (')
- ->subcompile($this->right)
- ->raw(')')
- ;
- }
-
- abstract public function operator($compiler);
+ abstract public function operator($compiler);
}
*/
class Twig_Node_Expression_Binary_Add extends Twig_Node_Expression_Binary
{
- public function operator($compiler)
- {
- return $compiler->raw('+');
- }
+ public function operator($compiler)
+ {
+ return $compiler->raw('+');
+ }
}
*/
class Twig_Node_Expression_Binary_And extends Twig_Node_Expression_Binary
{
- public function operator($compiler)
- {
- return $compiler->raw('&&');
- }
+ public function operator($compiler)
+ {
+ return $compiler->raw('&&');
+ }
}
*/
class Twig_Node_Expression_Binary_Concat extends Twig_Node_Expression_Binary
{
- public function operator($compiler)
- {
- return $compiler->raw('.');
- }
+ public function operator($compiler)
+ {
+ return $compiler->raw('.');
+ }
}
*/
class Twig_Node_Expression_Binary_Div extends Twig_Node_Expression_Binary
{
- public function operator($compiler)
- {
- return $compiler->raw('/');
- }
+ public function operator($compiler)
+ {
+ return $compiler->raw('/');
+ }
}
*/
class Twig_Node_Expression_Binary_FloorDiv extends Twig_Node_Expression_Binary
{
- public function compile($compiler)
- {
- $compiler
- ->raw('floor(')
- ->subcompile($this->left)
- ->raw(' / ')
- ->subcompile($this->right)
- ->raw(')')
- ;
- }
+ public function compile($compiler)
+ {
+ $compiler
+ ->raw('floor(')
+ ->subcompile($this->left)
+ ->raw(' / ')
+ ->subcompile($this->right)
+ ->raw(')')
+ ;
+ }
- public function operator($compiler)
- {
- return;
- }
+ public function operator($compiler)
+ {
+ return;
+ }
}
*/
class Twig_Node_Expression_Binary_Mod extends Twig_Node_Expression_Binary
{
- public function operator($compiler)
- {
- return $compiler->raw('%');
- }
+ public function operator($compiler)
+ {
+ return $compiler->raw('%');
+ }
}
*/
class Twig_Node_Expression_Binary_Mul extends Twig_Node_Expression_Binary
{
- public function operator($compiler)
- {
- return $compiler->raw('*');
- }
+ public function operator($compiler)
+ {
+ return $compiler->raw('*');
+ }
}
*/
class Twig_Node_Expression_Binary_Or extends Twig_Node_Expression_Binary
{
- public function operator($compiler)
- {
- return $compiler->raw('||');
- }
+ public function operator($compiler)
+ {
+ return $compiler->raw('||');
+ }
}
*/
class Twig_Node_Expression_Binary_Sub extends Twig_Node_Expression_Binary
{
- public function operator($compiler)
- {
- return $compiler->raw('-');
- }
+ public function operator($compiler)
+ {
+ return $compiler->raw('-');
+ }
}
*/
class Twig_Node_Expression_Compare extends Twig_Node_Expression
{
- protected $expr;
- protected $ops;
+ protected $expr;
+ protected $ops;
- public function __construct(Twig_Node_Expression $expr, $ops, $lineno)
- {
- parent::__construct($lineno);
- $this->expr = $expr;
- $this->ops = $ops;
- }
-
- public function compile($compiler)
- {
- $nbOps = count($this->ops) > 1;
- if ('in' === $this->ops[0][0])
+ public function __construct(Twig_Node_Expression $expr, $ops, $lineno)
{
- return $this->compileIn($compiler);
+ parent::__construct($lineno);
+ $this->expr = $expr;
+ $this->ops = $ops;
}
- $this->expr->compile($compiler);
- $i = 0;
- foreach ($this->ops as $op)
+ public function compile($compiler)
{
- if ($i)
- {
- $compiler->raw(' && ($tmp'.$i);
- }
- list($op, $node) = $op;
- $compiler->raw(' '.$op.' ');
+ $nbOps = count($this->ops) > 1;
+ if ('in' === $this->ops[0][0]) {
+ return $this->compileIn($compiler);
+ }
- if ($nbOps)
- {
- $compiler
- ->raw('($tmp'.++$i.' = ')
- ->subcompile($node)
- ->raw(')')
- ;
- }
- else
- {
- $compiler->subcompile($node);
- }
+ $this->expr->compile($compiler);
+ $i = 0;
+ foreach ($this->ops as $op) {
+ if ($i) {
+ $compiler->raw(' && ($tmp'.$i);
+ }
+ list($op, $node) = $op;
+ $compiler->raw(' '.$op.' ');
+
+ if ($nbOps) {
+ $compiler
+ ->raw('($tmp'.++$i.' = ')
+ ->subcompile($node)
+ ->raw(')')
+ ;
+ } else {
+ $compiler->subcompile($node);
+ }
+ }
+
+ for ($j = 1; $j < $i; $j++) {
+ $compiler->raw(')');
+ }
}
- for ($j = 1; $j < $i; $j++)
+ protected function compileIn($compiler)
{
- $compiler->raw(')');
+ $compiler
+ ->raw('twig_in_filter(')
+ ->subcompile($this->expr)
+ ->raw(', ')
+ ->subcompile($this->ops[0][1])
+ ->raw(')')
+ ;
}
- }
-
- protected function compileIn($compiler)
- {
- $compiler
- ->raw('twig_in_filter(')
- ->subcompile($this->expr)
- ->raw(', ')
- ->subcompile($this->ops[0][1])
- ->raw(')')
- ;
- }
}
*/
class Twig_Node_Expression_Conditional extends Twig_Node_Expression
{
- protected $expr1;
- protected $expr2;
- protected $expr3;
+ protected $expr1;
+ protected $expr2;
+ protected $expr3;
- public function __construct(Twig_Node_Expression $expr1, Twig_Node_Expression $expr2, Twig_Node_Expression $expr3, $lineno)
- {
- parent::__construct($lineno);
- $this->expr1 = $expr1;
- $this->expr2 = $expr2;
- $this->expr3 = $expr3;
- }
+ public function __construct(Twig_Node_Expression $expr1, Twig_Node_Expression $expr2, Twig_Node_Expression $expr3, $lineno)
+ {
+ parent::__construct($lineno);
+ $this->expr1 = $expr1;
+ $this->expr2 = $expr2;
+ $this->expr3 = $expr3;
+ }
- public function compile($compiler)
- {
- $compiler
- ->raw('(')
- ->subcompile($this->expr1)
- ->raw(') ? (')
- ->subcompile($this->expr2)
- ->raw(') : (')
- ->subcompile($this->expr3)
- ->raw(')')
- ;
- }
+ public function compile($compiler)
+ {
+ $compiler
+ ->raw('(')
+ ->subcompile($this->expr1)
+ ->raw(') ? (')
+ ->subcompile($this->expr2)
+ ->raw(') : (')
+ ->subcompile($this->expr3)
+ ->raw(')')
+ ;
+ }
}
*/
class Twig_Node_Expression_Constant extends Twig_Node_Expression
{
- protected $value;
+ protected $value;
- public function __construct($value, $lineno)
- {
- parent::__construct($lineno);
- $this->value = $value;
- }
+ public function __construct($value, $lineno)
+ {
+ parent::__construct($lineno);
+ $this->value = $value;
+ }
- public function __toString()
- {
- return get_class($this).'('.$this->value.')';
- }
+ public function __toString()
+ {
+ return get_class($this).'('.$this->value.')';
+ }
- public function compile($compiler)
- {
- $compiler->repr($this->value);
- }
+ public function compile($compiler)
+ {
+ $compiler->repr($this->value);
+ }
- public function getValue()
- {
- return $this->value;
- }
+ public function getValue()
+ {
+ return $this->value;
+ }
}
*/
class Twig_Node_Expression_Filter extends Twig_Node_Expression implements Twig_NodeListInterface
{
- protected $node;
- protected $filters;
+ protected $node;
+ protected $filters;
- public function __construct(Twig_Node $node, array $filters, $lineno, $tag = null)
- {
- parent::__construct($lineno, $tag);
+ public function __construct(Twig_Node $node, array $filters, $lineno, $tag = null)
+ {
+ parent::__construct($lineno, $tag);
- $this->node = $node;
- $this->filters = $filters;
- }
+ $this->node = $node;
+ $this->filters = $filters;
+ }
- public function __toString()
- {
- $filters = array();
- foreach ($this->filters as $filter)
+ public function __toString()
{
- $filters[] = $filter[0].'('.implode(', ', $filter[1]).')';
- }
+ $filters = array();
+ foreach ($this->filters as $filter) {
+ $filters[] = $filter[0].'('.implode(', ', $filter[1]).')';
+ }
- $repr = array(get_class($this).'('.implode(', ', $filters));
+ $repr = array(get_class($this).'('.implode(', ', $filters));
- foreach (explode("\n", $this->node->__toString()) as $line)
- {
- $repr[] = ' '.$line;
+ foreach (explode("\n", $this->node->__toString()) as $line) {
+ $repr[] = ' '.$line;
+ }
+
+ $repr[] = ')';
+
+ return implode("\n", $repr);
}
- $repr[] = ')';
+ public function getNodes()
+ {
+ return array($this->node);
+ }
- return implode("\n", $repr);
- }
+ public function setNodes(array $nodes)
+ {
+ $this->node = $nodes[0];
+ }
- public function getNodes()
- {
- return array($this->node);
- }
+ public function compile($compiler)
+ {
+ $filterMap = $compiler->getEnvironment()->getFilters();
+
+ $postponed = array();
+ for ($i = count($this->filters) - 1; $i >= 0; --$i) {
+ list($name, $attrs) = $this->filters[$i];
+ if (!isset($filterMap[$name])) {
+ $compiler
+ ->raw('$this->resolveMissingFilter(')
+ ->repr($name)
+ ->raw(', ')
+ ;
+ } else {
+ $compiler->raw($filterMap[$name]->compile().($filterMap[$name]->needsEnvironment() ? '($this->getEnvironment(), ' : '('));
+ }
+ $postponed[] = $attrs;
+ }
+ $this->node->compile($compiler);
+ foreach (array_reverse($postponed) as $attributes) {
+ foreach ($attributes as $node) {
+ $compiler
+ ->raw(', ')
+ ->subcompile($node)
+ ;
+ }
+ $compiler->raw(')');
+ }
+ }
- public function setNodes(array $nodes)
- {
- $this->node = $nodes[0];
- }
+ public function getFilters()
+ {
+ return $this->filters;
+ }
- public function compile($compiler)
- {
- $filterMap = $compiler->getEnvironment()->getFilters();
+ public function setFilters(array $filters)
+ {
+ $this->filters = $filters;
+ }
- $postponed = array();
- for ($i = count($this->filters) - 1; $i >= 0; --$i)
+ public function prependFilter($filter)
{
- list($name, $attrs) = $this->filters[$i];
- if (!isset($filterMap[$name]))
- {
- $compiler
- ->raw('$this->resolveMissingFilter(')
- ->repr($name)
- ->raw(', ')
- ;
- }
- else
- {
- $compiler->raw($filterMap[$name]->compile().($filterMap[$name]->needsEnvironment() ? '($this->getEnvironment(), ' : '('));
- }
- $postponed[] = $attrs;
+ $this->filters = array_merge(array($filter), $this->filters);
}
- $this->node->compile($compiler);
- foreach (array_reverse($postponed) as $attributes)
+
+ public function appendFilter($filter)
{
- foreach ($attributes as $node)
- {
- $compiler
- ->raw(', ')
- ->subcompile($node)
- ;
- }
- $compiler->raw(')');
+ $this->filters[] = $filter;
}
- }
-
- public function getFilters()
- {
- return $this->filters;
- }
-
- public function setFilters(array $filters)
- {
- $this->filters = $filters;
- }
-
- public function prependFilter($filter)
- {
- $this->filters = array_merge(array($filter), $this->filters);
- }
-
- public function appendFilter($filter)
- {
- $this->filters[] = $filter;
- }
-
- public function appendFilters(array $filters)
- {
- $this->filters = array_merge($this->filters, $filters);
- }
-
- public function hasFilter($name)
- {
- foreach ($this->filters as $filter)
+
+ public function appendFilters(array $filters)
{
- if ($name == $filter[0])
- {
- return true;
- }
+ $this->filters = array_merge($this->filters, $filters);
}
- return false;
- }
+ public function hasFilter($name)
+ {
+ foreach ($this->filters as $filter) {
+ if ($name == $filter[0]) {
+ return true;
+ }
+ }
+
+ return false;
+ }
}
*/
class Twig_Node_Expression_GetAttr extends Twig_Node_Expression implements Twig_NodeListInterface
{
- protected $node;
- protected $attr;
- protected $arguments;
+ protected $node;
+ protected $attr;
+ protected $arguments;
- public function __construct(Twig_Node $node, $attr, $arguments, $lineno, $token_value)
- {
- parent::__construct($lineno);
- $this->node = $node;
- $this->attr = $attr;
- $this->arguments = $arguments;
- $this->token_value = $token_value;
- }
-
- public function __toString()
- {
- return get_class($this).'('.$this->node.', '.$this->attr.')';
- }
-
- public function getNode()
- {
- return $this->node;
- }
-
- public function getNodes()
- {
- return array($this->node);
- }
-
- public function setNodes(array $nodes)
- {
- $this->node = $nodes[0];
- }
+ public function __construct(Twig_Node $node, $attr, $arguments, $lineno, $token_value)
+ {
+ parent::__construct($lineno);
+ $this->node = $node;
+ $this->attr = $attr;
+ $this->arguments = $arguments;
+ $this->token_value = $token_value;
+ }
- public function compile($compiler)
- {
- $compiler
- ->raw('$this->getAttribute(')
- ->subcompile($this->node)
- ->raw(', ')
- ->subcompile($this->attr)
- ->raw(', array(')
- ;
+ public function __toString()
+ {
+ return get_class($this).'('.$this->node.', '.$this->attr.')';
+ }
- foreach ($this->arguments as $node)
+ public function getNode()
{
- $compiler
- ->subcompile($node)
- ->raw(', ')
- ;
+ return $this->node;
}
- $compiler->raw(')');
+ public function getNodes()
+ {
+ return array($this->node);
+ }
- if ('[' == $this->token_value) // Don't look for functions if they're using foo[bar]
+ public function setNodes(array $nodes)
{
- $compiler->raw(', true');
+ $this->node = $nodes[0];
}
- $compiler->raw(')');
- }
+ public function compile($compiler)
+ {
+ $compiler
+ ->raw('$this->getAttribute(')
+ ->subcompile($this->node)
+ ->raw(', ')
+ ->subcompile($this->attr)
+ ->raw(', array(')
+ ;
+
+ foreach ($this->arguments as $node) {
+ $compiler
+ ->subcompile($node)
+ ->raw(', ')
+ ;
+ }
+
+ $compiler->raw(')');
+
+ // Don't look for functions if they're using foo[bar]
+ if ('[' == $this->token_value) {
+ $compiler->raw(', true');
+ }
+
+ $compiler->raw(')');
+ }
}
*/
class Twig_Node_Expression_Name extends Twig_Node_Expression
{
- protected $name;
+ protected $name;
- public function __construct($name, $lineno)
- {
- parent::__construct($lineno);
- $this->name = $name;
- }
+ public function __construct($name, $lineno)
+ {
+ parent::__construct($lineno);
+ $this->name = $name;
+ }
- public function __toString()
- {
- return get_class($this).'('.$this->name.')';
- }
+ public function __toString()
+ {
+ return get_class($this).'('.$this->name.')';
+ }
- public function compile($compiler)
- {
- $compiler->raw(sprintf('(isset($context[\'%s\']) ? $context[\'%s\'] : null)', $this->name, $this->name));
- }
+ public function compile($compiler)
+ {
+ $compiler->raw(sprintf('(isset($context[\'%s\']) ? $context[\'%s\'] : null)', $this->name, $this->name));
+ }
- public function getName()
- {
- return $this->name;
- }
+ public function getName()
+ {
+ return $this->name;
+ }
}
*/
abstract class Twig_Node_Expression_Unary extends Twig_Node_Expression
{
- protected $node;
+ protected $node;
- public function __construct(Twig_Node $node, $lineno)
- {
- parent::__construct($lineno);
- $this->node = $node;
- }
-
- public function __toString()
- {
- $repr = array(get_class($this).'(');
-
- foreach (explode("\n", $this->node->__toString()) as $line)
+ public function __construct(Twig_Node $node, $lineno)
{
- $repr[] = ' '.$line;
+ parent::__construct($lineno);
+ $this->node = $node;
}
- $repr[] = ')';
+ public function __toString()
+ {
+ $repr = array(get_class($this).'(');
+
+ foreach (explode("\n", $this->node->__toString()) as $line) {
+ $repr[] = ' '.$line;
+ }
- return implode("\n", $repr);
- }
- public function compile($compiler)
- {
- $compiler->raw('(');
- $this->operator($compiler);
- $this->node->compile($compiler);
- $compiler->raw(')');
- }
+ $repr[] = ')';
+
+ return implode("\n", $repr);
+ }
+ public function compile($compiler)
+ {
+ $compiler->raw('(');
+ $this->operator($compiler);
+ $this->node->compile($compiler);
+ $compiler->raw(')');
+ }
- abstract public function operator($compiler);
+ abstract public function operator($compiler);
}
*/
class Twig_Node_Expression_Unary_Neg extends Twig_Node_Expression_Unary
{
- public function operator($compiler)
- {
- $compiler->raw('-');
- }
+ public function operator($compiler)
+ {
+ $compiler->raw('-');
+ }
}
*/
class Twig_Node_Expression_Unary_Not extends Twig_Node_Expression_Unary
{
- public function operator($compiler)
- {
- $compiler->raw('!');
- }
+ public function operator($compiler)
+ {
+ $compiler->raw('!');
+ }
}
*/
class Twig_Node_Expression_Unary_Pos extends Twig_Node_Expression_Unary
{
- public function operator($compiler)
- {
- $compiler->raw('+');
- }
+ public function operator($compiler)
+ {
+ $compiler->raw('+');
+ }
}
*/
class Twig_Node_Filter extends Twig_Node implements Twig_NodeListInterface
{
- protected $filters;
- protected $body;
+ protected $filters;
+ protected $body;
- public function __construct($filters, Twig_NodeList $body, $lineno, $tag = null)
- {
- parent::__construct($lineno, $tag);
- $this->filters = $filters;
- $this->body = $body;
- }
-
- public function __toString()
- {
- $filters = array();
- foreach ($this->filters as $filter)
+ public function __construct($filters, Twig_NodeList $body, $lineno, $tag = null)
{
- $filters[] = $filter[0].'('.implode(', ', $filter[1]).')';
+ parent::__construct($lineno, $tag);
+ $this->filters = $filters;
+ $this->body = $body;
}
- $repr = array(get_class($this).'('.implode(', ', $filters));
-
- foreach (explode("\n", $this->body->__toString()) as $line)
+ public function __toString()
{
- $repr[] = ' '.$line;
- }
+ $filters = array();
+ foreach ($this->filters as $filter) {
+ $filters[] = $filter[0].'('.implode(', ', $filter[1]).')';
+ }
+
+ $repr = array(get_class($this).'('.implode(', ', $filters));
- $repr[] = ')';
+ foreach (explode("\n", $this->body->__toString()) as $line) {
+ $repr[] = ' '.$line;
+ }
- return implode("\n", $repr);
- }
+ $repr[] = ')';
- public function getNodes()
- {
- return $this->body->getNodes();
- }
+ return implode("\n", $repr);
+ }
+
+ public function getNodes()
+ {
+ return $this->body->getNodes();
+ }
- public function setNodes(array $nodes)
- {
- $this->body = new Twig_NodeList($nodes, $this->lineno);
- }
+ public function setNodes(array $nodes)
+ {
+ $this->body = new Twig_NodeList($nodes, $this->lineno);
+ }
- public function compile($compiler)
- {
- $compiler->subcompile($this->body);
- }
+ public function compile($compiler)
+ {
+ $compiler->subcompile($this->body);
+ }
- public function getFilters()
- {
- return $this->filters;
- }
+ public function getFilters()
+ {
+ return $this->filters;
+ }
}
*/
class Twig_Node_For extends Twig_Node implements Twig_NodeListInterface
{
- protected $isMultitarget;
- protected $item;
- protected $seq;
- protected $body;
- protected $else;
- protected $withLoop;
-
- public function __construct($isMultitarget, $item, $seq, Twig_NodeList $body, Twig_Node $else = null, $withLoop = false, $lineno, $tag = null)
- {
- parent::__construct($lineno, $tag);
- $this->isMultitarget = $isMultitarget;
- $this->item = $item;
- $this->seq = $seq;
- $this->body = $body;
- $this->else = $else;
- $this->withLoop = $withLoop;
- $this->lineno = $lineno;
- }
-
- public function getNodes()
- {
- return $this->body->getNodes();
- }
-
- public function setNodes(array $nodes)
- {
- $this->body = new Twig_NodeList($nodes, $this->lineno);
- }
-
- public function compile($compiler)
- {
- $compiler
- ->addDebugInfo($this)
- ->pushContext()
- ;
-
- if (!is_null($this->else))
+ protected $isMultitarget;
+ protected $item;
+ protected $seq;
+ protected $body;
+ protected $else;
+ protected $withLoop;
+
+ public function __construct($isMultitarget, $item, $seq, Twig_NodeList $body, Twig_Node $else = null, $withLoop = false, $lineno, $tag = null)
{
- $compiler->write("\$context['_iterated'] = false;\n");
+ parent::__construct($lineno, $tag);
+ $this->isMultitarget = $isMultitarget;
+ $this->item = $item;
+ $this->seq = $seq;
+ $this->body = $body;
+ $this->else = $else;
+ $this->withLoop = $withLoop;
+ $this->lineno = $lineno;
}
- if ($this->isMultitarget)
+ public function getNodes()
{
- $loopVars = array($this->item[0]->getName(), $this->item[1]->getName());
+ return $this->body->getNodes();
}
- else
- {
- $loopVars = array('_key', $this->item->getName());
- }
-
- $compiler
- ->write("\$context['_seq'] = twig_iterator_to_array(")
- ->subcompile($this->seq)
- ->raw(");\n")
- ;
- if ($this->withLoop)
+ public function setNodes(array $nodes)
{
- $compiler
- ->write("\$length = count(\$context['_seq']);\n")
-
- ->write("\$context['loop'] = array(\n")
- ->write(" 'parent' => \$context['_parent'],\n")
- ->write(" 'length' => \$length,\n")
- ->write(" 'index0' => 0,\n")
- ->write(" 'index' => 1,\n")
- ->write(" 'revindex0' => \$length - 1,\n")
- ->write(" 'revindex' => \$length,\n")
- ->write(" 'first' => true,\n")
- ->write(" 'last' => 1 === \$length,\n")
- ->write(");\n")
- ;
+ $this->body = new Twig_NodeList($nodes, $this->lineno);
}
- $compiler
- ->write("foreach (\$context['_seq'] as \$context[")
- ->repr($loopVars[0])
- ->raw("] => \$context[")
- ->repr($loopVars[1])
- ->raw("])\n")
- ->write("{\n")
- ->indent()
- ;
-
- if (!is_null($this->else))
+ public function compile($compiler)
{
- $compiler->write("\$context['_iterated'] = true;\n");
+ $compiler
+ ->addDebugInfo($this)
+ ->pushContext()
+ ;
+
+ if (!is_null($this->else)) {
+ $compiler->write("\$context['_iterated'] = false;\n");
+ }
+
+ if ($this->isMultitarget) {
+ $loopVars = array($this->item[0]->getName(), $this->item[1]->getName());
+ } else {
+ $loopVars = array('_key', $this->item->getName());
+ }
+
+ $compiler
+ ->write("\$context['_seq'] = twig_iterator_to_array(")
+ ->subcompile($this->seq)
+ ->raw(");\n")
+ ;
+
+ if ($this->withLoop) {
+ $compiler
+ ->write("\$length = count(\$context['_seq']);\n")
+
+ ->write("\$context['loop'] = array(\n")
+ ->write(" 'parent' => \$context['_parent'],\n")
+ ->write(" 'length' => \$length,\n")
+ ->write(" 'index0' => 0,\n")
+ ->write(" 'index' => 1,\n")
+ ->write(" 'revindex0' => \$length - 1,\n")
+ ->write(" 'revindex' => \$length,\n")
+ ->write(" 'first' => true,\n")
+ ->write(" 'last' => 1 === \$length,\n")
+ ->write(");\n")
+ ;
+ }
+
+ $compiler
+ ->write("foreach (\$context['_seq'] as \$context[")
+ ->repr($loopVars[0])
+ ->raw("] => \$context[")
+ ->repr($loopVars[1])
+ ->raw("])\n")
+ ->write("{\n")
+ ->indent()
+ ;
+
+ if (!is_null($this->else)) {
+ $compiler->write("\$context['_iterated'] = true;\n");
+ }
+
+ $compiler->subcompile($this->body);
+
+ if ($this->withLoop) {
+ $compiler
+ ->write("++\$context['loop']['index0'];\n")
+ ->write("++\$context['loop']['index'];\n")
+ ->write("--\$context['loop']['revindex0'];\n")
+ ->write("--\$context['loop']['revindex'];\n")
+ ->write("\$context['loop']['first'] = false;\n")
+ ->write("\$context['loop']['last'] = 0 === \$context['loop']['revindex0'];\n")
+ ;
+ }
+
+ $compiler
+ ->outdent()
+ ->write("}\n")
+ ;
+
+ if (!is_null($this->else)) {
+ $compiler
+ ->write("if (!\$context['_iterated'])\n")
+ ->write("{\n")
+ ->indent()
+ ->subcompile($this->else)
+ ->outdent()
+ ->write("}\n")
+ ;
+ }
+ $compiler->popContext();
}
- $compiler->subcompile($this->body);
-
- if ($this->withLoop)
+ public function setWithLoop($boolean)
{
- $compiler
- ->write("++\$context['loop']['index0'];\n")
- ->write("++\$context['loop']['index'];\n")
- ->write("--\$context['loop']['revindex0'];\n")
- ->write("--\$context['loop']['revindex'];\n")
- ->write("\$context['loop']['first'] = false;\n")
- ->write("\$context['loop']['last'] = 0 === \$context['loop']['revindex0'];\n")
- ;
+ $this->withLoop = (Boolean) $boolean;
}
-
- $compiler
- ->outdent()
- ->write("}\n")
- ;
-
- if (!is_null($this->else))
- {
- $compiler
- ->write("if (!\$context['_iterated'])\n")
- ->write("{\n")
- ->indent()
- ->subcompile($this->else)
- ->outdent()
- ->write("}\n")
- ;
- }
- $compiler->popContext();
- }
-
- public function setWithLoop($boolean)
- {
- $this->withLoop = (Boolean) $boolean;
- }
}
*/
class Twig_Node_If extends Twig_Node implements Twig_NodeListInterface
{
- protected $tests;
- protected $else;
+ protected $tests;
+ protected $else;
- public function __construct($tests, Twig_NodeList $else = null, $lineno, $tag = null)
- {
- parent::__construct($lineno, $tag);
- $this->tests = $tests;
- $this->else = $else;
- }
-
- public function __toString()
- {
- $repr = array(get_class($this).'(');
- foreach ($this->tests as $test)
+ public function __construct($tests, Twig_NodeList $else = null, $lineno, $tag = null)
{
- foreach (explode("\n", $test[0].' => '.$test[1]) as $line)
- {
- $repr[] = ' '.$line;
- }
+ parent::__construct($lineno, $tag);
+ $this->tests = $tests;
+ $this->else = $else;
}
- $repr[] = ')';
- if ($this->else)
+ public function __toString()
{
- foreach (explode("\n", $this->else) as $line)
- {
- $repr[] = ' '.$line;
- }
- }
+ $repr = array(get_class($this).'(');
+ foreach ($this->tests as $test) {
+ foreach (explode("\n", $test[0].' => '.$test[1]) as $line) {
+ $repr[] = ' '.$line;
+ }
+ }
+ $repr[] = ')';
- return implode("\n", $repr);
- }
+ if ($this->else) {
+ foreach (explode("\n", $this->else) as $line) {
+ $repr[] = ' '.$line;
+ }
+ }
- public function getNodes()
- {
- $nodes = array();
- foreach ($this->tests as $test)
- {
- $nodes[] = $test[1];
+ return implode("\n", $repr);
}
- if ($this->else)
+ public function getNodes()
{
- $nodes[] = $this->else;
- }
+ $nodes = array();
+ foreach ($this->tests as $test) {
+ $nodes[] = $test[1];
+ }
- return $nodes;
- }
+ if ($this->else) {
+ $nodes[] = $this->else;
+ }
- public function setNodes(array $nodes)
- {
- foreach ($this->tests as $i => $test)
- {
- $this->tests[$i][1] = $nodes[$i];
+ return $nodes;
}
- if ($this->else)
+ public function setNodes(array $nodes)
{
- $nodes = $nodes[count($nodes) - 1];
+ foreach ($this->tests as $i => $test) {
+ $this->tests[$i][1] = $nodes[$i];
+ }
+
+ if ($this->else) {
+ $nodes = $nodes[count($nodes) - 1];
+ }
}
- }
- public function compile($compiler)
- {
- $compiler->addDebugInfo($this);
- $idx = 0;
- foreach ($this->tests as $test)
+ public function compile($compiler)
{
- if ($idx++)
- {
- $compiler
- ->outdent()
- ->write("}\n", "elseif (")
- ;
- }
- else
- {
- $compiler
- ->write('if (')
- ;
- }
+ $compiler->addDebugInfo($this);
+ $idx = 0;
+ foreach ($this->tests as $test) {
+ if ($idx++) {
+ $compiler
+ ->outdent()
+ ->write("}\n", "elseif (")
+ ;
+ } else {
+ $compiler
+ ->write('if (')
+ ;
+ }
- $compiler
- ->subcompile($test[0])
- ->raw(")\n")
- ->write("{\n")
- ->indent()
- ->subcompile($test[1])
- ;
- }
- if (!is_null($this->else))
- {
- $compiler
- ->outdent()
- ->write("}\n", "else\n", "{\n")
- ->indent()
- ->subcompile($this->else)
- ;
- }
+ $compiler
+ ->subcompile($test[0])
+ ->raw(")\n")
+ ->write("{\n")
+ ->indent()
+ ->subcompile($test[1])
+ ;
+ }
+ if (!is_null($this->else)) {
+ $compiler
+ ->outdent()
+ ->write("}\n", "else\n", "{\n")
+ ->indent()
+ ->subcompile($this->else)
+ ;
+ }
- $compiler
- ->outdent()
- ->write("}\n");
- }
+ $compiler
+ ->outdent()
+ ->write("}\n");
+ }
}
*/
class Twig_Node_Import extends Twig_Node
{
- protected $macro;
- protected $var;
+ protected $macro;
+ protected $var;
- public function __construct($macro, $var, $lineno, $tag = null)
- {
- parent::__construct($lineno, $tag);
- $this->macro = $macro;
- $this->var = $var;
- }
+ public function __construct($macro, $var, $lineno, $tag = null)
+ {
+ parent::__construct($lineno, $tag);
+ $this->macro = $macro;
+ $this->var = $var;
+ }
- public function __toString()
- {
- return get_class($this).'('.$this->macro.', '.$this->var.')';
- }
+ public function __toString()
+ {
+ return get_class($this).'('.$this->macro.', '.$this->var.')';
+ }
- public function compile($compiler)
- {
- $compiler
- ->addDebugInfo($this)
- ->write('$this->env->loadTemplate(')
- ->string($this->macro)
- ->raw(");\n\n")
- ->write("if (!class_exists(")
- ->string($compiler->getTemplateClass($this->macro).'_Macro')
- ->raw("))\n")
- ->write("{\n")
- ->indent()
- ->write(sprintf("throw new InvalidArgumentException('There is no defined macros in template \"%s\".');\n", $this->macro))
- ->outdent()
- ->write("}\n")
- ->write(sprintf("\$context["))
- ->string($this->var)
- ->raw(sprintf("] = new %s_Macro(\$this->env);\n", $compiler->getTemplateClass($this->macro)))
- ;
- }
+ public function compile($compiler)
+ {
+ $compiler
+ ->addDebugInfo($this)
+ ->write('$this->env->loadTemplate(')
+ ->string($this->macro)
+ ->raw(");\n\n")
+ ->write("if (!class_exists(")
+ ->string($compiler->getTemplateClass($this->macro).'_Macro')
+ ->raw("))\n")
+ ->write("{\n")
+ ->indent()
+ ->write(sprintf("throw new InvalidArgumentException('There is no defined macros in template \"%s\".');\n", $this->macro))
+ ->outdent()
+ ->write("}\n")
+ ->write(sprintf("\$context["))
+ ->string($this->var)
+ ->raw(sprintf("] = new %s_Macro(\$this->env);\n", $compiler->getTemplateClass($this->macro)))
+ ;
+ }
- public function getMacro()
- {
- return $this->macro;
- }
+ public function getMacro()
+ {
+ return $this->macro;
+ }
- public function getVar()
- {
- return $this->var;
- }
+ public function getVar()
+ {
+ return $this->var;
+ }
}
*/
class Twig_Node_Include extends Twig_Node implements Twig_NodeListInterface
{
- protected $expr;
- protected $sandboxed;
- protected $variables;
-
- public function __construct(Twig_Node_Expression $expr, $sandboxed, $variables, $lineno, $tag = null)
- {
- parent::__construct($lineno, $tag);
-
- $this->expr = $expr;
- $this->sandboxed = $sandboxed;
- $this->variables = $variables;
- }
-
- public function __toString()
- {
- return get_class($this).'('.$this->expr.')';
- }
-
- public function getNodes()
- {
- if (null === $this->variables)
- {
- return array(new Twig_Node_Text('', -1));
- }
- else
+ protected $expr;
+ protected $sandboxed;
+ protected $variables;
+
+ public function __construct(Twig_Node_Expression $expr, $sandboxed, $variables, $lineno, $tag = null)
{
- return array($this->variables);
- }
+ parent::__construct($lineno, $tag);
- return $this->variables->getNodes();
- }
+ $this->expr = $expr;
+ $this->sandboxed = $sandboxed;
+ $this->variables = $variables;
+ }
- public function setNodes(array $nodes)
- {
- if (isset($nodes[0]) && -1 === $nodes[0]->getLine())
+ public function __toString()
{
- $this->variables = null;
+ return get_class($this).'('.$this->expr.')';
}
- else
+
+ public function getNodes()
{
- $this->variables = $nodes[0];
+ if (null === $this->variables) {
+ return array(new Twig_Node_Text('', -1));
+ } else {
+ return array($this->variables);
+ }
+
+ return $this->variables->getNodes();
}
- }
-
- public function getIncludedFile()
- {
- return $this->expr;
- }
-
- public function isSandboxed()
- {
- return $this->sandboxed;
- }
-
- public function getVariables()
- {
- return $this->variables;
- }
-
- public function compile($compiler)
- {
- if (!$compiler->getEnvironment()->hasExtension('sandbox') && $this->sandboxed)
+
+ public function setNodes(array $nodes)
{
- throw new Twig_SyntaxError('Unable to use the sanboxed attribute on an include if the sandbox extension is not enabled.', $this->lineno);
+ if (isset($nodes[0]) && -1 === $nodes[0]->getLine()) {
+ $this->variables = null;
+ } else {
+ $this->variables = $nodes[0];
+ }
}
- $compiler->addDebugInfo($this);
-
- if ($this->sandboxed)
+ public function getIncludedFile()
{
- $compiler
- ->write("\$sandbox = \$this->env->getExtension('sandbox');\n")
- ->write("\$alreadySandboxed = \$sandbox->isSandboxed();\n")
- ->write("\$sandbox->enableSandbox();\n")
- ;
+ return $this->expr;
}
- $compiler
- ->write('$this->env->loadTemplate(')
- ->subcompile($this->expr)
- ->raw(')->display(')
- ;
-
- if (null === $this->variables)
+ public function isSandboxed()
{
- $compiler->raw('$context');
+ return $this->sandboxed;
}
- else
+
+ public function getVariables()
{
- $compiler->subcompile($this->variables);
+ return $this->variables;
}
- $compiler->raw(");\n");
-
- if ($this->sandboxed)
+ public function compile($compiler)
{
- $compiler
- ->write("if (!\$alreadySandboxed)\n", "{\n")
- ->indent()
- ->write("\$sandbox->disableSandbox();\n")
- ->outdent()
- ->write("}\n")
- ;
+ if (!$compiler->getEnvironment()->hasExtension('sandbox') && $this->sandboxed) {
+ throw new Twig_SyntaxError('Unable to use the sanboxed attribute on an include if the sandbox extension is not enabled.', $this->lineno);
+ }
+
+ $compiler->addDebugInfo($this);
+
+ if ($this->sandboxed) {
+ $compiler
+ ->write("\$sandbox = \$this->env->getExtension('sandbox');\n")
+ ->write("\$alreadySandboxed = \$sandbox->isSandboxed();\n")
+ ->write("\$sandbox->enableSandbox();\n")
+ ;
+ }
+
+ $compiler
+ ->write('$this->env->loadTemplate(')
+ ->subcompile($this->expr)
+ ->raw(')->display(')
+ ;
+
+ if (null === $this->variables) {
+ $compiler->raw('$context');
+ } else {
+ $compiler->subcompile($this->variables);
+ }
+
+ $compiler->raw(");\n");
+
+ if ($this->sandboxed) {
+ $compiler
+ ->write("if (!\$alreadySandboxed)\n", "{\n")
+ ->indent()
+ ->write("\$sandbox->disableSandbox();\n")
+ ->outdent()
+ ->write("}\n")
+ ;
+ }
}
- }
}
*/
class Twig_Node_Macro extends Twig_Node implements Twig_NodeListInterface
{
- protected $name;
- protected $body;
- protected $arguments;
+ protected $name;
+ protected $body;
+ protected $arguments;
- public function __construct($name, Twig_NodeList $body, $arguments, $lineno, $parent = null, $tag = null)
- {
- parent::__construct($lineno, $tag);
- $this->name = $name;
- $this->body = $body;
- $this->arguments = $arguments;
- }
-
- public function __toString()
- {
- $repr = array(get_class($this).' '.$this->name.'(');
- foreach ($this->body->getNodes() as $node)
+ public function __construct($name, Twig_NodeList $body, $arguments, $lineno, $parent = null, $tag = null)
{
- foreach (explode("\n", $node->__toString()) as $line)
- {
- $repr[] = ' '.$line;
- }
+ parent::__construct($lineno, $tag);
+ $this->name = $name;
+ $this->body = $body;
+ $this->arguments = $arguments;
}
- $repr[] = ')';
-
- return implode("\n", $repr);
- }
-
- public function getNodes()
- {
- return $this->body->getNodes();
- }
- public function setNodes(array $nodes)
- {
- $this->body = new Twig_NodeList($nodes, $this->lineno);
- }
+ public function __toString()
+ {
+ $repr = array(get_class($this).' '.$this->name.'(');
+ foreach ($this->body->getNodes() as $node) {
+ foreach (explode("\n", $node->__toString()) as $line) {
+ $repr[] = ' '.$line;
+ }
+ }
+ $repr[] = ')';
- public function replace($other)
- {
- $this->body = $other->body;
- }
+ return implode("\n", $repr);
+ }
- public function compile($compiler)
- {
- $arguments = array();
- foreach ($this->arguments as $argument)
+ public function getNodes()
{
- $arguments[] = '$'.$argument->getName().' = null';
+ return $this->body->getNodes();
}
- $compiler
- ->addDebugInfo($this)
- ->write(sprintf("public function get%s(%s)\n", $this->name, implode(', ', $arguments)), "{\n")
- ->indent()
- ->write("\$context = array(\n")
- ->indent()
- ;
+ public function setNodes(array $nodes)
+ {
+ $this->body = new Twig_NodeList($nodes, $this->lineno);
+ }
- foreach ($this->arguments as $argument)
+ public function replace($other)
{
- $compiler
- ->write('')
- ->string($argument->getName())
- ->raw(' => $'.$argument->getName())
- ->raw(",\n")
- ;
+ $this->body = $other->body;
}
- $compiler
- ->outdent()
- ->write(");\n\n")
- ->subcompile($this->body)
- ->outdent()
- ->write("}\n\n")
- ;
- }
+ public function compile($compiler)
+ {
+ $arguments = array();
+ foreach ($this->arguments as $argument) {
+ $arguments[] = '$'.$argument->getName().' = null';
+ }
+
+ $compiler
+ ->addDebugInfo($this)
+ ->write(sprintf("public function get%s(%s)\n", $this->name, implode(', ', $arguments)), "{\n")
+ ->indent()
+ ->write("\$context = array(\n")
+ ->indent()
+ ;
+
+ foreach ($this->arguments as $argument) {
+ $compiler
+ ->write('')
+ ->string($argument->getName())
+ ->raw(' => $'.$argument->getName())
+ ->raw(",\n")
+ ;
+ }
+
+ $compiler
+ ->outdent()
+ ->write(");\n\n")
+ ->subcompile($this->body)
+ ->outdent()
+ ->write("}\n\n")
+ ;
+ }
}
*/
class Twig_Node_Module extends Twig_Node implements Twig_NodeListInterface
{
- protected $body;
- protected $extends;
- protected $blocks;
- protected $macros;
- protected $filename;
- protected $usedFilters;
- protected $usedTags;
-
- public function __construct(Twig_NodeList $body, $extends, array $blocks, array $macros, $filename)
- {
- parent::__construct(1);
-
- $this->body = $body;
- $this->extends = $extends;
- $this->blocks = array_values($blocks);
- $this->macros = $macros;
- $this->filename = $filename;
- $this->usedFilters = array();
- $this->usedTags = array();
- }
-
- public function __toString()
- {
- $repr = array(get_class($this).'(', ' body:');
- foreach ($this->body->getNodes() as $node)
+ protected $body;
+ protected $extends;
+ protected $blocks;
+ protected $macros;
+ protected $filename;
+ protected $usedFilters;
+ protected $usedTags;
+
+ public function __construct(Twig_NodeList $body, $extends, array $blocks, array $macros, $filename)
{
- foreach (explode("\n", $node->__toString()) as $line)
- {
- $repr[] = ' '.$line;
- }
+ parent::__construct(1);
+
+ $this->body = $body;
+ $this->extends = $extends;
+ $this->blocks = array_values($blocks);
+ $this->macros = $macros;
+ $this->filename = $filename;
+ $this->usedFilters = array();
+ $this->usedTags = array();
}
- $repr[] = ' blocks: ';
- foreach ($this->blocks as $node)
+ public function __toString()
{
- foreach (explode("\n", $node->__toString()) as $line)
- {
- $repr[] = ' '.$line;
- }
- }
-
- $repr[] = ' macros: ';
- foreach ($this->macros as $node)
- {
- foreach (explode("\n", $node->__toString()) as $line)
- {
- $repr[] = ' '.$line;
- }
- }
-
- $repr[] = ')';
+ $repr = array(get_class($this).'(', ' body:');
+ foreach ($this->body->getNodes() as $node) {
+ foreach (explode("\n", $node->__toString()) as $line) {
+ $repr[] = ' '.$line;
+ }
+ }
- return implode("\n", $repr);
- }
+ $repr[] = ' blocks: ';
+ foreach ($this->blocks as $node) {
+ foreach (explode("\n", $node->__toString()) as $line) {
+ $repr[] = ' '.$line;
+ }
+ }
- public function getFilename()
- {
- return $this->filename;
- }
+ $repr[] = ' macros: ';
+ foreach ($this->macros as $node) {
+ foreach (explode("\n", $node->__toString()) as $line) {
+ $repr[] = ' '.$line;
+ }
+ }
- public function getBody()
- {
- return $this->body;
- }
+ $repr[] = ')';
- public function getNodes()
- {
- return array_merge(array($this->body), $this->blocks, $this->macros);
- }
+ return implode("\n", $repr);
+ }
- public function setNodes(array $nodes)
- {
- $this->body = array_shift($nodes);
- $this->blocks = array();
- $this->macros = array();
- foreach ($nodes as $node)
+ public function getFilename()
{
- if ($node instanceof Twig_Node_Macro)
- {
- $this->macros[] = $node;
- }
- else
- {
- $this->blocks[] = $node;
- }
+ return $this->filename;
}
- }
-
- public function setUsedFilters(array $filters)
- {
- $this->usedFilters = $filters;
- }
- public function setUsedTags(array $tags)
- {
- $this->usedTags = $tags;
- }
-
- public function compile($compiler)
- {
- $this->compileTemplate($compiler);
- $this->compileMacros($compiler);
- }
-
- protected function compileTemplate($compiler)
- {
- $sandboxed = $compiler->getEnvironment()->hasExtension('sandbox');
-
- $compiler->write("<?php\n\n");
-
- if (!is_null($this->extends))
+ public function getBody()
{
- $compiler
- ->write('$this->loadTemplate(')
- ->repr($this->extends)
- ->raw(");\n\n")
- ;
+ return $this->body;
}
- $compiler
- // if the filename contains */, add a blank to avoid a PHP parse error
- ->write("/* ".str_replace('*/', '* /', $this->filename)." */\n")
- ->write('class '.$compiler->getTemplateClass($this->filename))
- ;
-
- $parent = null === $this->extends ? $compiler->getEnvironment()->getBaseTemplateClass() : $compiler->getTemplateClass($this->extends);
-
- $compiler
- ->raw(" extends $parent\n")
- ->write("{\n")
- ->indent()
- ->write("public function display(array \$context)\n", "{\n")
- ->indent()
- ;
+ public function getNodes()
+ {
+ return array_merge(array($this->body), $this->blocks, $this->macros);
+ }
- if (null !== $this->extends)
+ public function setNodes(array $nodes)
{
- // remove all but import nodes
- $nodes = array();
- foreach ($this->body->getNodes() as $node)
- {
- if ($node instanceof Twig_Node_Import)
- {
- $nodes[] = $node;
+ $this->body = array_shift($nodes);
+ $this->blocks = array();
+ $this->macros = array();
+ foreach ($nodes as $node) {
+ if ($node instanceof Twig_Node_Macro) {
+ $this->macros[] = $node;
+ } else {
+ $this->blocks[] = $node;
+ }
}
- }
-
- $compiler
- ->subcompile(new Twig_NodeList($nodes))
- ->write("\n")
- ->write("parent::display(\$context);\n")
- ->outdent()
- ->write("}\n\n")
- ;
}
- else
+
+ public function setUsedFilters(array $filters)
{
- if ($sandboxed)
- {
- $compiler->write("\$this->checkSecurity();\n");
- }
-
- $compiler
- ->subcompile($this->body)
- ->outdent()
- ->write("}\n\n")
- ;
+ $this->usedFilters = $filters;
}
- // blocks
- foreach ($this->blocks as $node)
+ public function setUsedTags(array $tags)
{
- $compiler->subcompile($node);
+ $this->usedTags = $tags;
}
- if ($sandboxed)
+ public function compile($compiler)
{
- // sandbox information
- $compiler
- ->write("protected function checkSecurity()\n", "{\n")
- ->indent()
- ->write("\$this->env->getExtension('sandbox')->checkSecurity(\n")
- ->indent()
- ->write(!$this->usedTags ? "array(),\n" : "array('".implode('\', \'', $this->usedTags)."'),\n")
- ->write(!$this->usedFilters ? "array()\n" : "array('".implode('\', \'', $this->usedFilters)."')\n")
- ->outdent()
- ->write(");\n")
- ->outdent()
- ->write("}\n\n")
- ;
+ $this->compileTemplate($compiler);
+ $this->compileMacros($compiler);
}
- // debug information
- if ($compiler->getEnvironment()->isDebug())
+ protected function compileTemplate($compiler)
{
- $compiler
- ->write("public function __toString()\n", "{\n")
- ->indent()
- ->write('return ')
- ->string($this)
- ->raw(";\n")
- ->outdent()
- ->write("}\n\n")
- ;
+ $sandboxed = $compiler->getEnvironment()->hasExtension('sandbox');
+
+ $compiler->write("<?php\n\n");
+
+ if (!is_null($this->extends)) {
+ $compiler
+ ->write('$this->loadTemplate(')
+ ->repr($this->extends)
+ ->raw(");\n\n")
+ ;
+ }
+
+ $compiler
+ // if the filename contains */, add a blank to avoid a PHP parse error
+ ->write("/* ".str_replace('*/', '* /', $this->filename)." */\n")
+ ->write('class '.$compiler->getTemplateClass($this->filename))
+ ;
+
+ $parent = null === $this->extends ? $compiler->getEnvironment()->getBaseTemplateClass() : $compiler->getTemplateClass($this->extends);
+
+ $compiler
+ ->raw(" extends $parent\n")
+ ->write("{\n")
+ ->indent()
+ ->write("public function display(array \$context)\n", "{\n")
+ ->indent()
+ ;
+
+ if (null !== $this->extends) {
+ // remove all but import nodes
+ $nodes = array();
+ foreach ($this->body->getNodes() as $node) {
+ if ($node instanceof Twig_Node_Import) {
+ $nodes[] = $node;
+ }
+ }
+
+ $compiler
+ ->subcompile(new Twig_NodeList($nodes))
+ ->write("\n")
+ ->write("parent::display(\$context);\n")
+ ->outdent()
+ ->write("}\n\n")
+ ;
+ } else {
+ if ($sandboxed) {
+ $compiler->write("\$this->checkSecurity();\n");
+ }
+
+ $compiler
+ ->subcompile($this->body)
+ ->outdent()
+ ->write("}\n\n")
+ ;
+ }
+
+ // blocks
+ foreach ($this->blocks as $node) {
+ $compiler->subcompile($node);
+ }
+
+ if ($sandboxed) {
+ // sandbox information
+ $compiler
+ ->write("protected function checkSecurity()\n", "{\n")
+ ->indent()
+ ->write("\$this->env->getExtension('sandbox')->checkSecurity(\n")
+ ->indent()
+ ->write(!$this->usedTags ? "array(),\n" : "array('".implode('\', \'', $this->usedTags)."'),\n")
+ ->write(!$this->usedFilters ? "array()\n" : "array('".implode('\', \'', $this->usedFilters)."')\n")
+ ->outdent()
+ ->write(");\n")
+ ->outdent()
+ ->write("}\n\n")
+ ;
+ }
+
+ // debug information
+ if ($compiler->getEnvironment()->isDebug()) {
+ $compiler
+ ->write("public function __toString()\n", "{\n")
+ ->indent()
+ ->write('return ')
+ ->string($this)
+ ->raw(";\n")
+ ->outdent()
+ ->write("}\n\n")
+ ;
+ }
+
+ // original template name
+ $compiler
+ ->write("public function getName()\n", "{\n")
+ ->indent()
+ ->write('return ')
+ ->string($this->filename)
+ ->raw(";\n")
+ ->outdent()
+ ->write("}\n\n")
+ ;
+
+ $compiler
+ ->outdent()
+ ->write("}\n")
+ ;
}
- // original template name
- $compiler
- ->write("public function getName()\n", "{\n")
- ->indent()
- ->write('return ')
- ->string($this->filename)
- ->raw(";\n")
- ->outdent()
- ->write("}\n\n")
- ;
-
- $compiler
- ->outdent()
- ->write("}\n")
- ;
- }
-
- protected function compileMacros($compiler)
- {
- if (!$this->macros)
+ protected function compileMacros($compiler)
{
- return;
- }
+ if (!$this->macros) {
+ return;
+ }
- $compiler
- ->write("\n")
- ->write('class '.$compiler->getTemplateClass($this->filename).'_Macro extends Twig_Macro'."\n")
- ->write("{\n")
- ->indent()
- ;
+ $compiler
+ ->write("\n")
+ ->write('class '.$compiler->getTemplateClass($this->filename).'_Macro extends Twig_Macro'."\n")
+ ->write("{\n")
+ ->indent()
+ ;
- // macros
- foreach ($this->macros as $node)
- {
- $compiler->subcompile($node);
- }
+ // macros
+ foreach ($this->macros as $node) {
+ $compiler->subcompile($node);
+ }
- $compiler
- ->outdent()
- ->write("}\n")
- ;
- }
+ $compiler
+ ->outdent()
+ ->write("}\n")
+ ;
+ }
}
*/
class Twig_Node_Parent extends Twig_Node
{
- protected $blockName;
+ protected $blockName;
- public function __construct($blockName, $lineno, $tag = null)
- {
- parent::__construct($lineno, $tag);
- $this->blockName = $blockName;
- }
+ public function __construct($blockName, $lineno, $tag = null)
+ {
+ parent::__construct($lineno, $tag);
+ $this->blockName = $blockName;
+ }
- public function __toString()
- {
- return get_class($this).'('.$this->blockName.')';
- }
+ public function __toString()
+ {
+ return get_class($this).'('.$this->blockName.')';
+ }
- public function compile($compiler)
- {
- $compiler
- ->addDebugInfo($this)
- ->write('parent::block_'.$this->blockName.'($context);'."\n")
- ;
- }
+ public function compile($compiler)
+ {
+ $compiler
+ ->addDebugInfo($this)
+ ->write('parent::block_'.$this->blockName.'($context);'."\n")
+ ;
+ }
}
*/
class Twig_Node_Print extends Twig_Node implements Twig_NodeListInterface
{
- protected $expr;
+ protected $expr;
- public function __construct(Twig_Node_Expression $expr, $lineno, $tag = null)
- {
- parent::__construct($lineno, $tag);
- $this->expr = $expr;
- }
-
- public function __toString()
- {
- $repr = array(get_class($this).'(');
- foreach (explode("\n", $this->expr->__toString()) as $line)
+ public function __construct(Twig_Node_Expression $expr, $lineno, $tag = null)
{
- $repr[] = ' '.$line;
+ parent::__construct($lineno, $tag);
+ $this->expr = $expr;
}
- $repr[] = ')';
- return implode("\n", $repr);
- }
+ public function __toString()
+ {
+ $repr = array(get_class($this).'(');
+ foreach (explode("\n", $this->expr->__toString()) as $line) {
+ $repr[] = ' '.$line;
+ }
+ $repr[] = ')';
+
+ return implode("\n", $repr);
+ }
- public function getNodes()
- {
- return array($this->expr);
- }
+ public function getNodes()
+ {
+ return array($this->expr);
+ }
- public function setNodes(array $nodes)
- {
- $this->expr = $nodes[0];
- }
+ public function setNodes(array $nodes)
+ {
+ $this->expr = $nodes[0];
+ }
- public function compile($compiler)
- {
- $compiler
- ->addDebugInfo($this)
- ->write('echo ')
- ->subcompile($this->expr)
- ->raw(";\n")
- ;
- }
+ public function compile($compiler)
+ {
+ $compiler
+ ->addDebugInfo($this)
+ ->write('echo ')
+ ->subcompile($this->expr)
+ ->raw(";\n")
+ ;
+ }
- public function getExpression()
- {
- return $this->expr;
- }
+ public function getExpression()
+ {
+ return $this->expr;
+ }
}
*/
class Twig_Node_Set extends Twig_Node implements Twig_NodeListInterface
{
- protected $names;
- protected $values;
- protected $isMultitarget;
- protected $capture;
-
- public function __construct($isMultitarget, $capture, $names, $values, $lineno, $tag = null)
- {
- parent::__construct($lineno, $tag);
-
- $this->isMultitarget = $isMultitarget;
- $this->capture = $capture;
- $this->names = $names;
- $this->values = $values;
- }
-
- public function __toString()
- {
- $repr = array(get_class($this).'('.($this->isMultitarget ? implode(', ', $this->names) : $this->names).',');
- foreach ($this->isMultitarget ? $this->values : array($this->values) as $node)
- {
- foreach (explode("\n", $node->__toString()) as $line)
- {
- $repr[] = ' '.$line;
- }
- }
- $repr[] = ')';
-
- return implode("\n", $repr);
- }
+ protected $names;
+ protected $values;
+ protected $isMultitarget;
+ protected $capture;
- public function getNodes()
- {
- if ($this->isMultitarget)
- {
- return $this->values;
- }
- else
+ public function __construct($isMultitarget, $capture, $names, $values, $lineno, $tag = null)
{
- return array($this->values);
+ parent::__construct($lineno, $tag);
+
+ $this->isMultitarget = $isMultitarget;
+ $this->capture = $capture;
+ $this->names = $names;
+ $this->values = $values;
}
- }
- public function setNodes(array $nodes)
- {
- $this->values = $this->isMultitarget ? $nodes : $nodes[0];
- }
+ public function __toString()
+ {
+ $repr = array(get_class($this).'('.($this->isMultitarget ? implode(', ', $this->names) : $this->names).',');
+ foreach ($this->isMultitarget ? $this->values : array($this->values) as $node) {
+ foreach (explode("\n", $node->__toString()) as $line) {
+ $repr[] = ' '.$line;
+ }
+ }
+ $repr[] = ')';
- public function compile($compiler)
- {
- $compiler->addDebugInfo($this);
+ return implode("\n", $repr);
+ }
- if ($this->isMultitarget)
+ public function getNodes()
{
- $compiler->write('list(');
- foreach ($this->names as $idx => $node)
- {
- if ($idx)
- {
- $compiler->raw(', ');
+ if ($this->isMultitarget) {
+ return $this->values;
+ } else {
+ return array($this->values);
}
-
- $compiler
- ->raw('$context[')
- ->string($node->getName())
- ->raw(']')
- ;
- }
- $compiler->raw(')');
}
- else
+
+ public function setNodes(array $nodes)
{
- if ($this->capture)
- {
- $compiler
- ->write("ob_start();\n")
- ->subcompile($this->values)
- ;
- }
-
- $compiler
- ->write('$context[')
- ->string($this->names->getName())
- ->raw(']')
- ;
-
- if ($this->capture)
- {
- $compiler->raw(" = ob_get_clean()");
- }
+ $this->values = $this->isMultitarget ? $nodes : $nodes[0];
}
- if (!$this->capture)
+ public function compile($compiler)
{
- $compiler->raw(' = ');
-
- if ($this->isMultitarget)
- {
- $compiler->write('array(');
- foreach ($this->values as $idx => $value)
- {
- if ($idx)
- {
- $compiler->raw(', ');
- }
-
- $compiler->subcompile($value);
+ $compiler->addDebugInfo($this);
+
+ if ($this->isMultitarget) {
+ $compiler->write('list(');
+ foreach ($this->names as $idx => $node) {
+ if ($idx) {
+ $compiler->raw(', ');
+ }
+
+ $compiler
+ ->raw('$context[')
+ ->string($node->getName())
+ ->raw(']')
+ ;
+ }
+ $compiler->raw(')');
+ } else {
+ if ($this->capture) {
+ $compiler
+ ->write("ob_start();\n")
+ ->subcompile($this->values)
+ ;
+ }
+
+ $compiler
+ ->write('$context[')
+ ->string($this->names->getName())
+ ->raw(']')
+ ;
+
+ if ($this->capture) {
+ $compiler->raw(" = ob_get_clean()");
+ }
+ }
+
+ if (!$this->capture) {
+ $compiler->raw(' = ');
+
+ if ($this->isMultitarget) {
+ $compiler->write('array(');
+ foreach ($this->values as $idx => $value) {
+ if ($idx) {
+ $compiler->raw(', ');
+ }
+
+ $compiler->subcompile($value);
+ }
+ $compiler->raw(')');
+ } else {
+ $compiler->subcompile($this->values);
+ }
}
- $compiler->raw(')');
- }
- else
- {
- $compiler->subcompile($this->values);
- }
- }
- $compiler->raw(";\n");
- }
+ $compiler->raw(";\n");
+ }
- public function getNames()
- {
- return $this->names;
- }
+ public function getNames()
+ {
+ return $this->names;
+ }
}
*/
class Twig_Node_Text extends Twig_Node
{
- protected $data;
+ protected $data;
- public function __construct($data, $lineno)
- {
- parent::__construct($lineno);
- $this->data = $data;
- }
+ public function __construct($data, $lineno)
+ {
+ parent::__construct($lineno);
+ $this->data = $data;
+ }
- public function __toString()
- {
- return get_class($this).'('.$this->data.')';
- }
+ public function __toString()
+ {
+ return get_class($this).'('.$this->data.')';
+ }
- public function compile($compiler)
- {
- $compiler
- ->addDebugInfo($this)
- ->write('echo ')
- ->string($this->data)
- ->raw(";\n")
- ;
- }
+ public function compile($compiler)
+ {
+ $compiler
+ ->addDebugInfo($this)
+ ->write('echo ')
+ ->string($this->data)
+ ->raw(";\n")
+ ;
+ }
- public function getData()
- {
- return $this->data;
- }
+ public function getData()
+ {
+ return $this->data;
+ }
}
*/
class Twig_Node_Trans extends Twig_Node
{
- protected $count, $body, $plural;
+ protected $count, $body, $plural;
- public function __construct($count, Twig_NodeList $body, $plural, $lineno, $tag = null)
- {
- parent::__construct($lineno, $tag);
-
- $this->count = $count;
- $this->body = $body;
- $this->plural = $plural;
- }
-
- public function __toString()
- {
- return get_class($this).'('.$this->body.', '.$this->count.')';
- }
+ public function __construct($count, Twig_NodeList $body, $plural, $lineno, $tag = null)
+ {
+ parent::__construct($lineno, $tag);
- public function compile($compiler)
- {
- $compiler->addDebugInfo($this);
+ $this->count = $count;
+ $this->body = $body;
+ $this->plural = $plural;
+ }
- list($msg, $vars) = $this->compileString($this->body);
+ public function __toString()
+ {
+ return get_class($this).'('.$this->body.', '.$this->count.')';
+ }
- if (false !== $this->plural)
+ public function compile($compiler)
{
- list($msg1, $vars1) = $this->compileString($this->plural);
+ $compiler->addDebugInfo($this);
- $vars = array_merge($vars, $vars1);
- }
+ list($msg, $vars) = $this->compileString($this->body);
- $function = false === $this->plural ? 'gettext' : 'ngettext';
+ if (false !== $this->plural) {
+ list($msg1, $vars1) = $this->compileString($this->plural);
- if ($vars)
- {
- $compiler
- ->write('echo strtr('.$function.'(')
- ->string($msg)
- ;
-
- if (false !== $this->plural)
- {
- $compiler
- ->raw(', ')
- ->string($msg1)
- ->raw(', abs(')
- ->subcompile($this->count)
- ->raw(')')
- ;
- }
-
- $compiler->raw('), array(');
-
- foreach ($vars as $var)
- {
- if ('count' === $var->getName())
- {
- $compiler
- ->string('%count%')
- ->raw(' => abs(')
- ->subcompile($this->count)
- ->raw('), ')
- ;
+ $vars = array_merge($vars, $vars1);
}
- else
- {
- $compiler
- ->string('%'.$var->getName().'%')
- ->raw(' => ')
- ->subcompile($var)
- ->raw(', ')
- ;
+
+ $function = false === $this->plural ? 'gettext' : 'ngettext';
+
+ if ($vars) {
+ $compiler
+ ->write('echo strtr('.$function.'(')
+ ->string($msg)
+ ;
+
+ if (false !== $this->plural) {
+ $compiler
+ ->raw(', ')
+ ->string($msg1)
+ ->raw(', abs(')
+ ->subcompile($this->count)
+ ->raw(')')
+ ;
+ }
+
+ $compiler->raw('), array(');
+
+ foreach ($vars as $var) {
+ if ('count' === $var->getName()) {
+ $compiler
+ ->string('%count%')
+ ->raw(' => abs(')
+ ->subcompile($this->count)
+ ->raw('), ')
+ ;
+ } else {
+ $compiler
+ ->string('%'.$var->getName().'%')
+ ->raw(' => ')
+ ->subcompile($var)
+ ->raw(', ')
+ ;
+ }
+ }
+
+ $compiler->raw("));\n");
+ } else {
+ $compiler
+ ->write('echo '.$function.'(')
+ ->string($msg)
+ ->raw(");\n")
+ ;
}
- }
+ }
- $compiler->raw("));\n");
+ public function getBody()
+ {
+ return $this->body;
}
- else
+
+ public function getPlural()
{
- $compiler
- ->write('echo '.$function.'(')
- ->string($msg)
- ->raw(");\n")
- ;
+ return $this->plural;
}
- }
-
- public function getBody()
- {
- return $this->body;
- }
-
- public function getPlural()
- {
- return $this->plural;
- }
-
- public function getCount()
- {
- return $this->count;
- }
-
- protected function compileString(Twig_NodeList $body)
- {
- $msg = '';
- $vars = array();
- foreach ($body->getNodes() as $i => $node)
+
+ public function getCount()
{
- if ($node instanceof Twig_Node_Text)
- {
- $msg .= $node->getData();
- }
- elseif ($node instanceof Twig_Node_Print && $node->getExpression() instanceof Twig_Node_Expression_Name)
- {
- $msg .= sprintf('%%%s%%', $node->getExpression()->getName());
- $vars[] = $node->getExpression();
- }
- else
- {
- throw new Twig_SyntaxError(sprintf('The text to be translated with "trans" can only contain references to simple variable'), $this->lineno);
- }
+ return $this->count;
}
- return array(trim($msg), $vars);
- }
+ protected function compileString(Twig_NodeList $body)
+ {
+ $msg = '';
+ $vars = array();
+ foreach ($body->getNodes() as $i => $node) {
+ if ($node instanceof Twig_Node_Text) {
+ $msg .= $node->getData();
+ } elseif ($node instanceof Twig_Node_Print && $node->getExpression() instanceof Twig_Node_Expression_Name) {
+ $msg .= sprintf('%%%s%%', $node->getExpression()->getName());
+ $vars[] = $node->getExpression();
+ } else {
+ throw new Twig_SyntaxError(sprintf('The text to be translated with "trans" can only contain references to simple variable'), $this->lineno);
+ }
+ }
+
+ return array(trim($msg), $vars);
+ }
}
*/
class Twig_NodeList extends Twig_Node implements Twig_NodeListInterface
{
- protected $nodes;
+ protected $nodes;
- public function __construct(array $nodes, $lineno = 0)
- {
- parent::__construct($lineno);
+ public function __construct(array $nodes, $lineno = 0)
+ {
+ parent::__construct($lineno);
- $this->nodes = $nodes;
- }
+ $this->nodes = $nodes;
+ }
- public function __toString()
- {
- $repr = array(get_class($this).'(');
- foreach ($this->nodes as $node)
+ public function __toString()
{
- foreach (explode("\n", $node->__toString()) as $line)
- {
- $repr[] = ' '.$line;
- }
+ $repr = array(get_class($this).'(');
+ foreach ($this->nodes as $node) {
+ foreach (explode("\n", $node->__toString()) as $line) {
+ $repr[] = ' '.$line;
+ }
+ }
+
+ return implode("\n", $repr);
}
- return implode("\n", $repr);
- }
-
- public function compile($compiler)
- {
- foreach ($this->nodes as $node)
+ public function compile($compiler)
{
- $node->compile($compiler);
+ foreach ($this->nodes as $node) {
+ $node->compile($compiler);
+ }
}
- }
- public function getNodes()
- {
- return $this->nodes;
- }
+ public function getNodes()
+ {
+ return $this->nodes;
+ }
- public function setNodes(array $nodes)
- {
- $this->nodes = $nodes;
- }
+ public function setNodes(array $nodes)
+ {
+ $this->nodes = $nodes;
+ }
}
*/
interface Twig_NodeListInterface
{
- /**
- * Returns an array of embedded nodes
- */
- public function getNodes();
+ /**
+ * Returns an array of embedded nodes
+ */
+ public function getNodes();
- /**
- * Sets the array of embedded nodes
- */
- public function setNodes(array $nodes);
+ /**
+ * Sets the array of embedded nodes
+ */
+ public function setNodes(array $nodes);
}
*/
class Twig_NodeTraverser
{
- protected $env;
+ protected $env;
- public function __construct(Twig_Environment $env)
- {
- $this->env = $env;
- }
-
- public function traverse(Twig_Node $node, Twig_NodeVisitorInterface $visitor)
- {
- $node = $visitor->enterNode($node, $this->env);
+ public function __construct(Twig_Environment $env)
+ {
+ $this->env = $env;
+ }
- if ($node instanceof Twig_NodeListInterface)
+ public function traverse(Twig_Node $node, Twig_NodeVisitorInterface $visitor)
{
- $newNodes = array();
- foreach ($nodes = $node->getNodes() as $k => $n)
- {
- if (null !== $n = $this->traverse($n, $visitor))
- {
- $newNodes[$k] = $n;
+ $node = $visitor->enterNode($node, $this->env);
+
+ if ($node instanceof Twig_NodeListInterface) {
+ $newNodes = array();
+ foreach ($nodes = $node->getNodes() as $k => $n) {
+ if (null !== $n = $this->traverse($n, $visitor)) {
+ $newNodes[$k] = $n;
+ }
+ }
+ $node->setNodes($newNodes);
}
- }
- $node->setNodes($newNodes);
- }
- return $visitor->leaveNode($node, $this->env);
- }
+ return $visitor->leaveNode($node, $this->env);
+ }
}
*/
class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface
{
- protected $statusStack = array();
- protected $blocks = array();
+ protected $statusStack = array();
+ protected $blocks = array();
- public function enterNode(Twig_Node $node, Twig_Environment $env)
- {
- if ($node instanceof Twig_Node_AutoEscape)
+ public function enterNode(Twig_Node $node, Twig_Environment $env)
{
- $this->statusStack[] = $node->getValue();
- }
- elseif ($node instanceof Twig_Node_Print)
- {
- return $this->escapeNode($node, $env, $this->needEscaping($env));
- }
- elseif ($node instanceof Twig_Node_Block)
- {
- $this->statusStack[] = isset($this->blocks[$node->getName()]) ? $this->blocks[$node->getName()] : $this->needEscaping($env);
- }
-
- return $node;
- }
+ if ($node instanceof Twig_Node_AutoEscape) {
+ $this->statusStack[] = $node->getValue();
+ } elseif ($node instanceof Twig_Node_Print) {
+ return $this->escapeNode($node, $env, $this->needEscaping($env));
+ } elseif ($node instanceof Twig_Node_Block) {
+ $this->statusStack[] = isset($this->blocks[$node->getName()]) ? $this->blocks[$node->getName()] : $this->needEscaping($env);
+ }
- public function leaveNode(Twig_Node $node, Twig_Environment $env)
- {
- if ($node instanceof Twig_Node_AutoEscape || $node instanceof Twig_Node_Block)
- {
- array_pop($this->statusStack);
+ return $node;
}
- elseif ($node instanceof Twig_Node_BlockReference)
+
+ public function leaveNode(Twig_Node $node, Twig_Environment $env)
{
- $this->blocks[$node->getName()] = $this->needEscaping($env);
- }
+ if ($node instanceof Twig_Node_AutoEscape || $node instanceof Twig_Node_Block) {
+ array_pop($this->statusStack);
+ } elseif ($node instanceof Twig_Node_BlockReference) {
+ $this->blocks[$node->getName()] = $this->needEscaping($env);
+ }
- return $node;
- }
+ return $node;
+ }
- protected function escapeNode(Twig_Node $node, Twig_Environment $env, $type)
- {
- if (false === $type)
+ protected function escapeNode(Twig_Node $node, Twig_Environment $env, $type)
{
- return $node;
- }
+ if (false === $type) {
+ return $node;
+ }
- $expression = $node instanceof Twig_Node_Print ? $node->getExpression() : $node;
+ $expression = $node instanceof Twig_Node_Print ? $node->getExpression() : $node;
- if ($expression instanceof Twig_Node_Expression_Filter)
- {
- // don't escape if the primary node of the filter is not a variable
- $nodes = $expression->getNodes();
- if (!$nodes[0] instanceof Twig_Node_Expression_Name)
- {
- return $node;
- }
+ if ($expression instanceof Twig_Node_Expression_Filter) {
+ // don't escape if the primary node of the filter is not a variable
+ $nodes = $expression->getNodes();
+ if (!$nodes[0] instanceof Twig_Node_Expression_Name) {
+ return $node;
+ }
- // don't escape if there is already an "escaper" in the filter chain
- $filterMap = $env->getFilters();
- foreach ($expression->getFilters() as $filter)
- {
- if (isset($filterMap[$filter[0]]) && $filterMap[$filter[0]]->isEscaper())
- {
- return $node;
+ // don't escape if there is already an "escaper" in the filter chain
+ $filterMap = $env->getFilters();
+ foreach ($expression->getFilters() as $filter) {
+ if (isset($filterMap[$filter[0]]) && $filterMap[$filter[0]]->isEscaper()) {
+ return $node;
+ }
+ }
+ } elseif (!$expression instanceof Twig_Node_Expression_GetAttr && !$expression instanceof Twig_Node_Expression_Name) {
+ // don't escape if the node is not a variable
+ return $node;
}
- }
- }
- elseif (!$expression instanceof Twig_Node_Expression_GetAttr && !$expression instanceof Twig_Node_Expression_Name)
- {
- // don't escape if the node is not a variable
- return $node;
- }
- // escape
- if ($expression instanceof Twig_Node_Expression_Filter)
- {
- // escape all variables in filters arguments
- $filters = $expression->getFilters();
- foreach ($filters as $i => $filter)
- {
- foreach ($filter[1] as $j => $argument)
- {
- $filters[$i][1][$j] = $this->escapeNode($argument, $env, $type);
- }
- }
+ // escape
+ if ($expression instanceof Twig_Node_Expression_Filter) {
+ // escape all variables in filters arguments
+ $filters = $expression->getFilters();
+ foreach ($filters as $i => $filter) {
+ foreach ($filter[1] as $j => $argument) {
+ $filters[$i][1][$j] = $this->escapeNode($argument, $env, $type);
+ }
+ }
- $expression->setFilters($filters);
- $expression->prependFilter($this->getEscaperFilter($type));
+ $expression->setFilters($filters);
+ $expression->prependFilter($this->getEscaperFilter($type));
- return $node;
- }
- elseif ($node instanceof Twig_Node_Print)
- {
- return new Twig_Node_Print(
- new Twig_Node_Expression_Filter($expression, array($this->getEscaperFilter($type)), $node->getLine())
- , $node->getLine()
- );
- }
- else
- {
- return new Twig_Node_Expression_Filter($node, array($this->getEscaperFilter($type)), $node->getLine());
+ return $node;
+ } elseif ($node instanceof Twig_Node_Print) {
+ return new Twig_Node_Print(
+ new Twig_Node_Expression_Filter($expression, array($this->getEscaperFilter($type)), $node->getLine())
+ , $node->getLine()
+ );
+ } else {
+ return new Twig_Node_Expression_Filter($node, array($this->getEscaperFilter($type)), $node->getLine());
+ }
}
- }
- protected function needEscaping(Twig_Environment $env)
- {
- if (count($this->statusStack))
+ protected function needEscaping(Twig_Environment $env)
{
- return $this->statusStack[count($this->statusStack) - 1];
+ if (count($this->statusStack)) {
+ return $this->statusStack[count($this->statusStack) - 1];
+ } else {
+ return $env->hasExtension('escaper') ? $env->getExtension('escaper')->isGlobal() : false;
+ }
}
- else
+
+ protected function getEscaperFilter($type)
{
- return $env->hasExtension('escaper') ? $env->getExtension('escaper')->isGlobal() : false;
+ return array('escape', array(new Twig_Node_Expression_Constant((string) $type, -1)));
}
- }
-
- protected function getEscaperFilter($type)
- {
- return array('escape', array(new Twig_Node_Expression_Constant((string) $type, -1)));
- }
}
*/
class Twig_NodeVisitor_Filter implements Twig_NodeVisitorInterface
{
- protected $statusStack = array();
+ protected $statusStack = array();
- public function enterNode(Twig_Node $node, Twig_Environment $env)
- {
- if ($node instanceof Twig_Node_Filter)
+ public function enterNode(Twig_Node $node, Twig_Environment $env)
{
- $this->statusStack[] = $node->getFilters();
- }
- elseif ($node instanceof Twig_Node_Print || $node instanceof Twig_Node_Text)
- {
- return $this->applyFilters($node);
- }
-
- return $node;
- }
+ if ($node instanceof Twig_Node_Filter) {
+ $this->statusStack[] = $node->getFilters();
+ } elseif ($node instanceof Twig_Node_Print || $node instanceof Twig_Node_Text) {
+ return $this->applyFilters($node);
+ }
- public function leaveNode(Twig_Node $node, Twig_Environment $env)
- {
- if ($node instanceof Twig_Node_Filter)
- {
- array_pop($this->statusStack);
+ return $node;
}
- return $node;
- }
-
- protected function applyFilters(Twig_Node $node)
- {
- if (false === $filters = $this->getCurrentFilters())
+ public function leaveNode(Twig_Node $node, Twig_Environment $env)
{
- return $node;
- }
+ if ($node instanceof Twig_Node_Filter) {
+ array_pop($this->statusStack);
+ }
- if ($node instanceof Twig_Node_Text)
- {
- $expression = new Twig_Node_Expression_Constant($node->getData(), $node->getLine());
- }
- else
- {
- $expression = $node->getExpression();
+ return $node;
}
- // filters
- if ($expression instanceof Twig_Node_Expression_Filter)
+ protected function applyFilters(Twig_Node $node)
{
- $expression->appendFilters($filters);
+ if (false === $filters = $this->getCurrentFilters()) {
+ return $node;
+ }
+
+ if ($node instanceof Twig_Node_Text) {
+ $expression = new Twig_Node_Expression_Constant($node->getData(), $node->getLine());
+ } else {
+ $expression = $node->getExpression();
+ }
- return $node;
+ // filters
+ if ($expression instanceof Twig_Node_Expression_Filter) {
+ $expression->appendFilters($filters);
+
+ return $node;
+ } else {
+ return new Twig_Node_Print(
+ new Twig_Node_Expression_Filter($expression, $filters, $node->getLine())
+ , $node->getLine()
+ );
+ }
}
- else
+
+ protected function getCurrentFilters()
{
- return new Twig_Node_Print(
- new Twig_Node_Expression_Filter($expression, $filters, $node->getLine())
- , $node->getLine()
- );
+ return count($this->statusStack) ? $this->statusStack[count($this->statusStack) - 1] : false;
}
- }
-
- protected function getCurrentFilters()
- {
- return count($this->statusStack) ? $this->statusStack[count($this->statusStack) - 1] : false;
- }
}
*/
class Twig_NodeVisitor_Sandbox implements Twig_NodeVisitorInterface
{
- protected $inAModule = false;
- protected $tags;
- protected $filters;
+ protected $inAModule = false;
+ protected $tags;
+ protected $filters;
- public function enterNode(Twig_Node $node, Twig_Environment $env)
- {
- if ($node instanceof Twig_Node_Module)
+ public function enterNode(Twig_Node $node, Twig_Environment $env)
{
- $this->inAModule = true;
- $this->tags = array();
- $this->filters = array();
+ if ($node instanceof Twig_Node_Module) {
+ $this->inAModule = true;
+ $this->tags = array();
+ $this->filters = array();
- return $node;
- }
- elseif ($this->inAModule)
- {
- // look for tags
- if ($node->getTag())
- {
- $this->tags[$node->getTag()] = true;
- }
+ return $node;
+ } elseif ($this->inAModule) {
+ // look for tags
+ if ($node->getTag()) {
+ $this->tags[$node->getTag()] = true;
+ }
- // look for filters
- if ($node instanceof Twig_Node_Expression_Filter)
- {
- foreach ($node->getFilters() as $filter)
- {
- $this->filters[$filter[0]] = true;
+ // look for filters
+ if ($node instanceof Twig_Node_Expression_Filter) {
+ foreach ($node->getFilters() as $filter) {
+ $this->filters[$filter[0]] = true;
+ }
+ }
}
- }
- }
- return $node;
- }
+ return $node;
+ }
- public function leaveNode(Twig_Node $node, Twig_Environment $env)
- {
- if ($node instanceof Twig_Node_Module)
+ public function leaveNode(Twig_Node $node, Twig_Environment $env)
{
- $node->setUsedFilters(array_keys($this->filters));
- $node->setUsedTags(array_keys($this->tags));
- $this->inAModule = false;
- }
+ if ($node instanceof Twig_Node_Module) {
+ $node->setUsedFilters(array_keys($this->filters));
+ $node->setUsedTags(array_keys($this->tags));
+ $this->inAModule = false;
+ }
- return $node;
- }
+ return $node;
+ }
}
interface Twig_NodeVisitorInterface
{
- public function enterNode(Twig_Node $node, Twig_Environment $env);
+ public function enterNode(Twig_Node $node, Twig_Environment $env);
- public function leaveNode(Twig_Node $node, Twig_Environment $env);
+ public function leaveNode(Twig_Node $node, Twig_Environment $env);
}
*/
class Twig_Parser
{
- protected $stream;
- protected $extends;
- protected $handlers;
- protected $visitors;
- protected $expressionParser;
- protected $blocks;
- protected $blockStack;
- protected $macros;
- protected $env;
+ protected $stream;
+ protected $extends;
+ protected $handlers;
+ protected $visitors;
+ protected $expressionParser;
+ protected $blocks;
+ protected $blockStack;
+ protected $macros;
+ protected $env;
+
+ public function __construct(Twig_Environment $env = null)
+ {
+ $this->setEnvironment($env);
+ }
+
+ public function setEnvironment(Twig_Environment $env)
+ {
+ $this->env = $env;
+
+ $this->handlers = array();
+ $this->visitors = array();
- public function __construct(Twig_Environment $env = null)
- {
- $this->setEnvironment($env);
- }
+ // tag handlers
+ foreach ($this->env->getTokenParsers() as $handler) {
+ $handler->setParser($this);
- public function setEnvironment(Twig_Environment $env)
- {
- $this->env = $env;
+ $this->handlers[$handler->getTag()] = $handler;
+ }
- $this->handlers = array();
- $this->visitors = array();
+ // node visitors
+ $this->visitors = $env->getNodeVisitors();
+ }
- // tag handlers
- foreach ($this->env->getTokenParsers() as $handler)
+ /**
+ * Converts a token stream to a node tree.
+ *
+ * @param Twig_TokenStream $stream A token stream instance
+ *
+ * @return Twig_Node_Module A node tree
+ */
+ public function parse(Twig_TokenStream $stream)
{
- $handler->setParser($this);
+ if (null === $this->expressionParser) {
+ $this->expressionParser = new Twig_ExpressionParser($this);
+ }
+
+ $this->stream = $stream;
+ $this->extends = null;
+ $this->blocks = array();
+ $this->macros = array();
+ $this->blockStack = array();
+
+ try {
+ $body = $this->subparse(null);
+ } catch (Twig_SyntaxError $e) {
+ if (is_null($e->getFilename())) {
+ $e->setFilename($this->stream->getFilename());
+ }
+
+ throw $e;
+ }
+
+ if (!is_null($this->extends)) {
+ foreach ($this->blocks as $block) {
+ $block->setParent($this->extends);
+ }
+ }
- $this->handlers[$handler->getTag()] = $handler;
+ $node = new Twig_Node_Module($body, $this->extends, $this->blocks, $this->macros, $this->stream->getFilename());
+
+ $t = new Twig_NodeTraverser($this->env);
+ foreach ($this->visitors as $visitor) {
+ $node = $t->traverse($node, $visitor);
+ }
+
+ return $node;
}
- // node visitors
- $this->visitors = $env->getNodeVisitors();
- }
+ public function subparse($test, $drop_needle = false)
+ {
+ $lineno = $this->getCurrentToken()->getLine();
+ $rv = array();
+ while (!$this->stream->isEOF()) {
+ switch ($this->getCurrentToken()->getType()) {
+ case Twig_Token::TEXT_TYPE:
+ $token = $this->stream->next();
+ $rv[] = new Twig_Node_Text($token->getValue(), $token->getLine());
+ break;
+
+ case Twig_Token::VAR_START_TYPE:
+ $token = $this->stream->next();
+ $expr = $this->expressionParser->parseExpression();
+ $this->stream->expect(Twig_Token::VAR_END_TYPE);
+ $rv[] = new Twig_Node_Print($expr, $token->getLine());
+ break;
+
+ case Twig_Token::BLOCK_START_TYPE:
+ $this->stream->next();
+ $token = $this->getCurrentToken();
+
+ if ($token->getType() !== Twig_Token::NAME_TYPE) {
+ throw new Twig_SyntaxError('A block must start with a tag name', $token->getLine());
+ }
+
+ if (!is_null($test) && call_user_func($test, $token)) {
+ if ($drop_needle) {
+ $this->stream->next();
+ }
+
+ return new Twig_NodeList($rv, $lineno);
+ }
+
+ if (!isset($this->handlers[$token->getValue()])) {
+ throw new Twig_SyntaxError(sprintf('Unknown tag name "%s"', $token->getValue()), $token->getLine());
+ }
+
+ $this->stream->next();
+
+ $subparser = $this->handlers[$token->getValue()];
+ $node = $subparser->parse($token);
+ if (!is_null($node)) {
+ $rv[] = $node;
+ }
+ break;
+
+ default:
+ throw new LogicException('Lexer or parser ended up in unsupported state.');
+ }
+ }
- /**
- * Converts a token stream to a node tree.
- *
- * @param Twig_TokenStream $stream A token stream instance
- *
- * @return Twig_Node_Module A node tree
- */
- public function parse(Twig_TokenStream $stream)
- {
- if (null === $this->expressionParser)
+ return new Twig_NodeList($rv, $lineno);
+ }
+
+ public function addHandler($name, $class)
{
- $this->expressionParser = new Twig_ExpressionParser($this);
+ $this->handlers[$name] = $class;
}
- $this->stream = $stream;
- $this->extends = null;
- $this->blocks = array();
- $this->macros = array();
- $this->blockStack = array();
+ public function addNodeVisitor(Twig_NodeVisitorInterface $visitor)
+ {
+ $this->visitors[] = $visitor;
+ }
- try
+ public function getBlockStack()
{
- $body = $this->subparse(null);
+ return $this->blockStack;
}
- catch (Twig_SyntaxError $e)
+
+ public function peekBlockStack()
{
- if (is_null($e->getFilename()))
- {
- $e->setFilename($this->stream->getFilename());
- }
+ return $this->blockStack[count($this->blockStack) - 1];
+ }
- throw $e;
+ public function popBlockStack()
+ {
+ array_pop($this->blockStack);
}
- if (!is_null($this->extends))
+ public function pushBlockStack($name)
{
- foreach ($this->blocks as $block)
- {
- $block->setParent($this->extends);
- }
+ $this->blockStack[] = $name;
}
- $node = new Twig_Node_Module($body, $this->extends, $this->blocks, $this->macros, $this->stream->getFilename());
+ public function hasBlock($name)
+ {
+ return isset($this->blocks[$name]);
+ }
- $t = new Twig_NodeTraverser($this->env);
- foreach ($this->visitors as $visitor)
+ public function setBlock($name, $value)
{
- $node = $t->traverse($node, $visitor);
+ $this->blocks[$name] = $value;
}
- return $node;
- }
+ public function hasMacro($name)
+ {
+ return isset($this->macros[$name]);
+ }
- public function subparse($test, $drop_needle = false)
- {
- $lineno = $this->getCurrentToken()->getLine();
- $rv = array();
- while (!$this->stream->isEOF())
+ public function setMacro($name, $value)
{
- switch ($this->getCurrentToken()->getType())
- {
- case Twig_Token::TEXT_TYPE:
- $token = $this->stream->next();
- $rv[] = new Twig_Node_Text($token->getValue(), $token->getLine());
- break;
+ $this->macros[$name] = $value;
+ }
- case Twig_Token::VAR_START_TYPE:
- $token = $this->stream->next();
- $expr = $this->expressionParser->parseExpression();
- $this->stream->expect(Twig_Token::VAR_END_TYPE);
- $rv[] = new Twig_Node_Print($expr, $token->getLine());
- break;
+ public function getExpressionParser()
+ {
+ return $this->expressionParser;
+ }
- case Twig_Token::BLOCK_START_TYPE:
- $this->stream->next();
- $token = $this->getCurrentToken();
+ public function getParent()
+ {
+ return $this->extends;
+ }
- if ($token->getType() !== Twig_Token::NAME_TYPE)
- {
- throw new Twig_SyntaxError('A block must start with a tag name', $token->getLine());
- }
+ public function setParent($extends)
+ {
+ $this->extends = $extends;
+ }
- if (!is_null($test) && call_user_func($test, $token))
- {
- if ($drop_needle)
- {
- $this->stream->next();
- }
+ public function getStream()
+ {
+ return $this->stream;
+ }
- return new Twig_NodeList($rv, $lineno);
- }
-
- if (!isset($this->handlers[$token->getValue()]))
- {
- throw new Twig_SyntaxError(sprintf('Unknown tag name "%s"', $token->getValue()), $token->getLine());
- }
-
- $this->stream->next();
-
- $subparser = $this->handlers[$token->getValue()];
- $node = $subparser->parse($token);
- if (!is_null($node))
- {
- $rv[] = $node;
- }
- break;
-
- default:
- throw new LogicException('Lexer or parser ended up in unsupported state.');
- }
- }
-
- return new Twig_NodeList($rv, $lineno);
- }
-
- public function addHandler($name, $class)
- {
- $this->handlers[$name] = $class;
- }
-
- public function addNodeVisitor(Twig_NodeVisitorInterface $visitor)
- {
- $this->visitors[] = $visitor;
- }
-
- public function getBlockStack()
- {
- return $this->blockStack;
- }
-
- public function peekBlockStack()
- {
- return $this->blockStack[count($this->blockStack) - 1];
- }
-
- public function popBlockStack()
- {
- array_pop($this->blockStack);
- }
-
- public function pushBlockStack($name)
- {
- $this->blockStack[] = $name;
- }
-
- public function hasBlock($name)
- {
- return isset($this->blocks[$name]);
- }
-
- public function setBlock($name, $value)
- {
- $this->blocks[$name] = $value;
- }
-
- public function hasMacro($name)
- {
- return isset($this->macros[$name]);
- }
-
- public function setMacro($name, $value)
- {
- $this->macros[$name] = $value;
- }
-
- public function getExpressionParser()
- {
- return $this->expressionParser;
- }
-
- public function getParent()
- {
- return $this->extends;
- }
-
- public function setParent($extends)
- {
- $this->extends = $extends;
- }
-
- public function getStream()
- {
- return $this->stream;
- }
-
- public function getCurrentToken()
- {
- return $this->stream->getCurrent();
- }
+ public function getCurrentToken()
+ {
+ return $this->stream->getCurrent();
+ }
}
*/
interface Twig_ParserInterface
{
- /**
- * Converts a token stream to a node tree.
- *
- * @param Twig_TokenStream $stream A token stream instance
- *
- * @return Twig_Node_Module A node tree
- */
- public function parser(Twig_TokenStream $code);
+ /**
+ * Converts a token stream to a node tree.
+ *
+ * @param Twig_TokenStream $stream A token stream instance
+ *
+ * @return Twig_Node_Module A node tree
+ */
+ public function parser(Twig_TokenStream $code);
}
*/
abstract class Twig_Resource
{
- protected $env;
- protected $cache;
+ protected $env;
+ protected $cache;
- public function __construct(Twig_Environment $env)
- {
- $this->env = $env;
- $this->cache = array();
- }
-
- public function getEnvironment()
- {
- return $this->env;
- }
-
- protected function resolveMissingFilter($name)
- {
- throw new Twig_RuntimeError(sprintf('The filter "%s" does not exist', $name));
- }
-
- protected function getAttribute($object, $item, array $arguments = array(), $arrayOnly = false)
- {
- $item = (string) $item;
+ public function __construct(Twig_Environment $env)
+ {
+ $this->env = $env;
+ $this->cache = array();
+ }
- if ((is_array($object) || is_object($object) && $object instanceof ArrayAccess) && isset($object[$item]))
+ public function getEnvironment()
{
- return $object[$item];
+ return $this->env;
}
- if ($arrayOnly || !is_object($object))
+ protected function resolveMissingFilter($name)
{
- return null;
+ throw new Twig_RuntimeError(sprintf('The filter "%s" does not exist', $name));
}
- if (isset($object->$item))
+ protected function getAttribute($object, $item, array $arguments = array(), $arrayOnly = false)
{
- if ($this->env->hasExtension('sandbox'))
- {
- $this->env->getExtension('sandbox')->checkPropertyAllowed($object, $item);
- }
+ $item = (string) $item;
- return $object->$item;
- }
+ if ((is_array($object) || is_object($object) && $object instanceof ArrayAccess) && isset($object[$item])) {
+ return $object[$item];
+ }
- $class = get_class($object);
+ if ($arrayOnly || !is_object($object)) {
+ return null;
+ }
- if (!isset($this->cache[$class]))
- {
- $r = new ReflectionClass($class);
- $this->cache[$class] = array();
- foreach ($r->getMethods(ReflectionMethod::IS_STATIC | ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_FINAL) as $method)
- {
- $this->cache[$class][strtolower($method->getName())] = true;
- }
- }
+ if (isset($object->$item)) {
+ if ($this->env->hasExtension('sandbox')) {
+ $this->env->getExtension('sandbox')->checkPropertyAllowed($object, $item);
+ }
- $item = strtolower($item);
- if (isset($this->cache[$class][$item]))
- {
- $method = $item;
- }
- elseif (isset($this->cache[$class]['get'.$item]))
- {
- $method = 'get'.$item;
- }
- elseif (isset($this->cache[$class]['__call']))
- {
- $method = $item;
- }
- else
- {
- return null;
- }
+ return $object->$item;
+ }
- if ($this->env->hasExtension('sandbox'))
- {
- $this->env->getExtension('sandbox')->checkMethodAllowed($object, $method);
- }
+ $class = get_class($object);
+
+ if (!isset($this->cache[$class])) {
+ $r = new ReflectionClass($class);
+ $this->cache[$class] = array();
+ foreach ($r->getMethods(ReflectionMethod::IS_STATIC | ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_FINAL) as $method) {
+ $this->cache[$class][strtolower($method->getName())] = true;
+ }
+ }
+
+ $item = strtolower($item);
+ if (isset($this->cache[$class][$item])) {
+ $method = $item;
+ } elseif (isset($this->cache[$class]['get'.$item])) {
+ $method = 'get'.$item;
+ } elseif (isset($this->cache[$class]['__call'])) {
+ $method = $item;
+ } else {
+ return null;
+ }
- return call_user_func_array(array($object, $method), $arguments);
- }
+ if ($this->env->hasExtension('sandbox')) {
+ $this->env->getExtension('sandbox')->checkMethodAllowed($object, $method);
+ }
+
+ return call_user_func_array(array($object, $method), $arguments);
+ }
}
*/
class Twig_Sandbox_SecurityPolicy implements Twig_Sandbox_SecurityPolicyInterface
{
- protected $allowedTags;
- protected $allowedFilters;
- protected $allowedMethods;
- protected $allowedProperties;
+ protected $allowedTags;
+ protected $allowedFilters;
+ protected $allowedMethods;
+ protected $allowedProperties;
- public function __construct(array $allowedTags = array(), array $allowedFilters = array(), array $allowedMethods = array(), array $allowedProperties = array())
- {
- $this->allowedTags = $allowedTags;
- $this->allowedFilters = $allowedFilters;
- $this->allowedMethods = $allowedMethods;
- $this->allowedProperties = $allowedProperties;
- }
-
- public function setAllowedTags(array $tags)
- {
- $this->allowedTags = $tags;
- }
-
- public function setAllowedFilters(array $filters)
- {
- $this->allowedFilters = $filters;
- }
-
- public function setAllowedMethods(array $methods)
- {
- $this->allowedMethods = $methods;
- }
-
- public function setAllowedProperties(array $properties)
- {
- $this->allowedProperties = $properties;
- }
+ public function __construct(array $allowedTags = array(), array $allowedFilters = array(), array $allowedMethods = array(), array $allowedProperties = array())
+ {
+ $this->allowedTags = $allowedTags;
+ $this->allowedFilters = $allowedFilters;
+ $this->allowedMethods = $allowedMethods;
+ $this->allowedProperties = $allowedProperties;
+ }
- public function checkSecurity($tags, $filters)
- {
- foreach ($tags as $tag)
+ public function setAllowedTags(array $tags)
{
- if (!in_array($tag, $this->allowedTags))
- {
- throw new Twig_Sandbox_SecurityError(sprintf('Tag "%s" is not allowed.', $tag));
- }
+ $this->allowedTags = $tags;
}
- foreach ($filters as $filter)
+ public function setAllowedFilters(array $filters)
{
- if (!in_array($filter, $this->allowedFilters))
- {
- throw new Twig_Sandbox_SecurityError(sprintf('Filter "%s" is not allowed.', $filter));
- }
+ $this->allowedFilters = $filters;
}
- }
- public function checkMethodAllowed($obj, $method)
- {
- $allowed = false;
- foreach ($this->allowedMethods as $class => $methods)
+ public function setAllowedMethods(array $methods)
{
- if ($obj instanceof $class)
- {
- $allowed = in_array($method, is_array($methods) ? $methods : array($methods));
+ $this->allowedMethods = $methods;
+ }
- break;
- }
+ public function setAllowedProperties(array $properties)
+ {
+ $this->allowedProperties = $properties;
}
- if (!$allowed)
+ public function checkSecurity($tags, $filters)
{
- throw new Twig_Sandbox_SecurityError(sprintf('Calling "%s" method on a "%s" object is not allowed.', $method, get_class($obj)));
+ foreach ($tags as $tag) {
+ if (!in_array($tag, $this->allowedTags)) {
+ throw new Twig_Sandbox_SecurityError(sprintf('Tag "%s" is not allowed.', $tag));
+ }
+ }
+
+ foreach ($filters as $filter) {
+ if (!in_array($filter, $this->allowedFilters)) {
+ throw new Twig_Sandbox_SecurityError(sprintf('Filter "%s" is not allowed.', $filter));
+ }
+ }
}
- }
- public function checkPropertyAllowed($obj, $property)
- {
- $allowed = false;
- foreach ($this->allowedProperties as $class => $properties)
+ public function checkMethodAllowed($obj, $method)
{
- if ($obj instanceof $class)
- {
- $allowed = in_array($property, is_array($properties) ? $properties : array($properties));
+ $allowed = false;
+ foreach ($this->allowedMethods as $class => $methods) {
+ if ($obj instanceof $class) {
+ $allowed = in_array($method, is_array($methods) ? $methods : array($methods));
- break;
- }
+ break;
+ }
+ }
+
+ if (!$allowed) {
+ throw new Twig_Sandbox_SecurityError(sprintf('Calling "%s" method on a "%s" object is not allowed.', $method, get_class($obj)));
+ }
}
- if (!$allowed)
+ public function checkPropertyAllowed($obj, $property)
{
- throw new Twig_Sandbox_SecurityError(sprintf('Calling "%s" property on a "%s" object is not allowed.', $property, get_class($obj)));
+ $allowed = false;
+ foreach ($this->allowedProperties as $class => $properties) {
+ if ($obj instanceof $class) {
+ $allowed = in_array($property, is_array($properties) ? $properties : array($properties));
+
+ break;
+ }
+ }
+
+ if (!$allowed) {
+ throw new Twig_Sandbox_SecurityError(sprintf('Calling "%s" property on a "%s" object is not allowed.', $property, get_class($obj)));
+ }
}
- }
}
*/
interface Twig_Sandbox_SecurityPolicyInterface
{
- public function checkSecurity($tags, $filters);
+ public function checkSecurity($tags, $filters);
- public function checkMethodAllowed($obj, $method);
+ public function checkMethodAllowed($obj, $method);
- public function checkPropertyAllowed($obj, $method);
+ public function checkPropertyAllowed($obj, $method);
}
*/
class Twig_SyntaxError extends Twig_Error
{
- protected $lineno;
- protected $filename;
- protected $rawMessage;
+ protected $lineno;
+ protected $filename;
+ protected $rawMessage;
- public function __construct($message, $lineno, $filename = null)
- {
- $this->lineno = $lineno;
- $this->filename = $filename;
- $this->rawMessage = $message;
+ public function __construct($message, $lineno, $filename = null)
+ {
+ $this->lineno = $lineno;
+ $this->filename = $filename;
+ $this->rawMessage = $message;
- $this->updateRepr();
+ $this->updateRepr();
- parent::__construct($this->message, $lineno);
- }
+ parent::__construct($this->message, $lineno);
+ }
- public function getFilename()
- {
- return $this->filename;
- }
+ public function getFilename()
+ {
+ return $this->filename;
+ }
- public function setFilename($filename)
- {
- $this->filename = $filename;
+ public function setFilename($filename)
+ {
+ $this->filename = $filename;
- $this->updateRepr();
- }
+ $this->updateRepr();
+ }
- protected function updateRepr()
- {
- $this->message = $this->rawMessage.' in '.($this->filename ? $this->filename : 'n/a').' at line '.$this->lineno;
- }
+ protected function updateRepr()
+ {
+ $this->message = $this->rawMessage.' in '.($this->filename ? $this->filename : 'n/a').' at line '.$this->lineno;
+ }
}
*/
abstract class Twig_Template extends Twig_Resource implements Twig_TemplateInterface
{
- /**
- * Renders the template with the given context and returns it as string.
- *
- * @param array $context An array of parameters to pass to the template
- *
- * @return string The rendered template
- */
- public function render(array $context)
- {
- ob_start();
- try
+ /**
+ * Renders the template with the given context and returns it as string.
+ *
+ * @param array $context An array of parameters to pass to the template
+ *
+ * @return string The rendered template
+ */
+ public function render(array $context)
{
- $this->display($context);
- }
- catch (Exception $e)
- {
- ob_end_clean();
+ ob_start();
+ try {
+ $this->display($context);
+ } catch (Exception $e) {
+ ob_end_clean();
- throw $e;
- }
+ throw $e;
+ }
- return ob_get_clean();
- }
+ return ob_get_clean();
+ }
- abstract protected function getName();
+ abstract protected function getName();
}
*/
interface Twig_TemplateInterface
{
- /**
- * Renders the template with the given context and returns it as string.
- *
- * @param array $context An array of parameters to pass to the template
- *
- * @return string The rendered template
- */
- public function render(array $context);
+ /**
+ * Renders the template with the given context and returns it as string.
+ *
+ * @param array $context An array of parameters to pass to the template
+ *
+ * @return string The rendered template
+ */
+ public function render(array $context);
- /**
- * Displays the template with the given context.
- *
- * @param array $context An array of parameters to pass to the template
- */
- public function display(array $context);
+ /**
+ * Displays the template with the given context.
+ *
+ * @param array $context An array of parameters to pass to the template
+ */
+ public function display(array $context);
- /**
- * Returns the bound environment for this template.
- *
- * @return Twig_Environment The current environment
- */
- public function getEnvironment();
+ /**
+ * Returns the bound environment for this template.
+ *
+ * @return Twig_Environment The current environment
+ */
+ public function getEnvironment();
}
*/
class Twig_Token
{
- protected $value;
- protected $type;
- protected $lineno;
+ protected $value;
+ protected $type;
+ protected $lineno;
- const EOF_TYPE = -1;
- const TEXT_TYPE = 0;
- const BLOCK_START_TYPE = 1;
- const VAR_START_TYPE = 2;
- const BLOCK_END_TYPE = 3;
- const VAR_END_TYPE = 4;
- const NAME_TYPE = 5;
- const NUMBER_TYPE = 6;
- const STRING_TYPE = 7;
- const OPERATOR_TYPE = 8;
+ const EOF_TYPE = -1;
+ const TEXT_TYPE = 0;
+ const BLOCK_START_TYPE = 1;
+ const VAR_START_TYPE = 2;
+ const BLOCK_END_TYPE = 3;
+ const VAR_END_TYPE = 4;
+ const NAME_TYPE = 5;
+ const NUMBER_TYPE = 6;
+ const STRING_TYPE = 7;
+ const OPERATOR_TYPE = 8;
- public function __construct($type, $value, $lineno)
- {
- $this->type = $type;
- $this->value = $value;
- $this->lineno = $lineno;
- }
-
- public function __toString()
- {
- return sprintf('%s(%s)', self::getTypeAsString($this->type, true), $this->value);
- }
+ public function __construct($type, $value, $lineno)
+ {
+ $this->type = $type;
+ $this->value = $value;
+ $this->lineno = $lineno;
+ }
- /**
- * Test the current token for a type. The first argument is the type
- * of the token (if not given Twig_Token::NAME_NAME), the second the
- * value of the token (if not given value is not checked).
- * the token value can be an array if multiple checks shoudl be
- * performed.
- */
- public function test($type, $values = null)
- {
- if (is_null($values) && !is_int($type))
+ public function __toString()
{
- $values = $type;
- $type = self::NAME_TYPE;
+ return sprintf('%s(%s)', self::getTypeAsString($this->type, true), $this->value);
}
- return ($this->type === $type) && (
- is_null($values) ||
- (is_array($values) && in_array($this->value, $values)) ||
- $this->value == $values
- );
- }
+ /**
+ * Test the current token for a type. The first argument is the type
+ * of the token (if not given Twig_Token::NAME_NAME), the second the
+ * value of the token (if not given value is not checked).
+ * the token value can be an array if multiple checks shoudl be
+ * performed.
+ */
+ public function test($type, $values = null)
+ {
+ if (is_null($values) && !is_int($type)) {
+ $values = $type;
+ $type = self::NAME_TYPE;
+ }
- public function getLine()
- {
- return $this->lineno;
- }
+ return ($this->type === $type) && (
+ is_null($values) ||
+ (is_array($values) && in_array($this->value, $values)) ||
+ $this->value == $values
+ );
+ }
- public function getType()
- {
- return $this->type;
- }
+ public function getLine()
+ {
+ return $this->lineno;
+ }
- public function getValue()
- {
- return $this->value;
- }
+ public function getType()
+ {
+ return $this->type;
+ }
- public function setValue($value)
- {
- $this->value = $value;
- }
+ public function getValue()
+ {
+ return $this->value;
+ }
- static public function getTypeAsString($type, $short = false)
- {
- switch ($type)
+ public function setValue($value)
{
- case self::EOF_TYPE:
- $name = 'EOF_TYPE';
- break;
- case self::TEXT_TYPE:
- $name = 'TEXT_TYPE';
- break;
- case self::BLOCK_START_TYPE:
- $name = 'BLOCK_START_TYPE';
- break;
- case self::VAR_START_TYPE:
- $name = 'VAR_START_TYPE';
- break;
- case self::BLOCK_END_TYPE:
- $name = 'BLOCK_END_TYPE';
- break;
- case self::VAR_END_TYPE:
- $name = 'VAR_END_TYPE';
- break;
- case self::NAME_TYPE:
- $name = 'NAME_TYPE';
- break;
- case self::NUMBER_TYPE:
- $name = 'NUMBER_TYPE';
- break;
- case self::STRING_TYPE:
- $name = 'STRING_TYPE';
- break;
- case self::OPERATOR_TYPE:
- $name = 'OPERATOR_TYPE';
- break;
- default:
- throw new InvalidArgumentException(sprintf('Token of type %s does not exist.', $type));
+ $this->value = $value;
}
- return $short ? $name : 'Twig_Token::'.$name;
- }
+ static public function getTypeAsString($type, $short = false)
+ {
+ switch ($type) {
+ case self::EOF_TYPE:
+ $name = 'EOF_TYPE';
+ break;
+ case self::TEXT_TYPE:
+ $name = 'TEXT_TYPE';
+ break;
+ case self::BLOCK_START_TYPE:
+ $name = 'BLOCK_START_TYPE';
+ break;
+ case self::VAR_START_TYPE:
+ $name = 'VAR_START_TYPE';
+ break;
+ case self::BLOCK_END_TYPE:
+ $name = 'BLOCK_END_TYPE';
+ break;
+ case self::VAR_END_TYPE:
+ $name = 'VAR_END_TYPE';
+ break;
+ case self::NAME_TYPE:
+ $name = 'NAME_TYPE';
+ break;
+ case self::NUMBER_TYPE:
+ $name = 'NUMBER_TYPE';
+ break;
+ case self::STRING_TYPE:
+ $name = 'STRING_TYPE';
+ break;
+ case self::OPERATOR_TYPE:
+ $name = 'OPERATOR_TYPE';
+ break;
+ default:
+ throw new InvalidArgumentException(sprintf('Token of type %s does not exist.', $type));
+ }
+
+ return $short ? $name : 'Twig_Token::'.$name;
+ }
}
*/
abstract class Twig_TokenParser
{
- protected $parser;
+ protected $parser;
- public function setParser(Twig_Parser $parser)
- {
- $this->parser = $parser;
- }
+ public function setParser(Twig_Parser $parser)
+ {
+ $this->parser = $parser;
+ }
- abstract public function parse(Twig_Token $token);
+ abstract public function parse(Twig_Token $token);
- abstract public function getTag();
+ abstract public function getTag();
}
*/
class Twig_TokenParser_AutoEscape extends Twig_TokenParser
{
- public function parse(Twig_Token $token)
- {
- $lineno = $token->getLine();
- $value = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE)->getValue();
- if (!in_array($value, array('on', 'off')))
+ public function parse(Twig_Token $token)
{
- throw new Twig_SyntaxError("Autoescape value must be 'on' or 'off'", $lineno);
- }
- $value = 'on' === $value ? true : false;
+ $lineno = $token->getLine();
+ $value = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE)->getValue();
+ if (!in_array($value, array('on', 'off'))) {
+ throw new Twig_SyntaxError("Autoescape value must be 'on' or 'off'", $lineno);
+ }
+ $value = 'on' === $value ? true : false;
- if ($this->parser->getStream()->test(Twig_Token::NAME_TYPE))
- {
- if (false === $value)
- {
- throw new Twig_SyntaxError(sprintf('Unexpected escaping strategy as you set autoescaping to off.', $lineno), -1);
- }
+ if ($this->parser->getStream()->test(Twig_Token::NAME_TYPE)) {
+ if (false === $value) {
+ throw new Twig_SyntaxError(sprintf('Unexpected escaping strategy as you set autoescaping to off.', $lineno), -1);
+ }
- $value = $this->parser->getStream()->next()->getValue();
- }
+ $value = $this->parser->getStream()->next()->getValue();
+ }
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
- $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true);
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+ $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+ $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true);
+ $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
- return new Twig_Node_AutoEscape($value, $body, $lineno, $this->getTag());
- }
+ return new Twig_Node_AutoEscape($value, $body, $lineno, $this->getTag());
+ }
- public function decideBlockEnd($token)
- {
- return $token->test('endautoescape');
- }
+ public function decideBlockEnd($token)
+ {
+ return $token->test('endautoescape');
+ }
- public function getTag()
- {
- return 'autoescape';
- }
+ public function getTag()
+ {
+ return 'autoescape';
+ }
}
*/
class Twig_TokenParser_Block extends Twig_TokenParser
{
- public function parse(Twig_Token $token)
- {
- $lineno = $token->getLine();
- $stream = $this->parser->getStream();
- $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
- if ($this->parser->hasBlock($name))
+ public function parse(Twig_Token $token)
{
- throw new Twig_SyntaxError("The block '$name' has already been defined", $lineno);
- }
- $this->parser->pushBlockStack($name);
-
- if ($stream->test(Twig_Token::BLOCK_END_TYPE))
- {
- $stream->next();
+ $lineno = $token->getLine();
+ $stream = $this->parser->getStream();
+ $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
+ if ($this->parser->hasBlock($name)) {
+ throw new Twig_SyntaxError("The block '$name' has already been defined", $lineno);
+ }
+ $this->parser->pushBlockStack($name);
+
+ if ($stream->test(Twig_Token::BLOCK_END_TYPE)) {
+ $stream->next();
+
+ $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true);
+ if ($stream->test(Twig_Token::NAME_TYPE)) {
+ $value = $stream->next()->getValue();
+
+ if ($value != $name) {
+ throw new Twig_SyntaxError(sprintf("Expected endblock for block '$name' (but %s given)", $value), $lineno);
+ }
+ }
+ } else {
+ $body = new Twig_NodeList(array(
+ new Twig_Node_Print($this->parser->getExpressionParser()->parseExpression(), $lineno),
+ ));
+ }
+ $stream->expect(Twig_Token::BLOCK_END_TYPE);
- $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true);
- if ($stream->test(Twig_Token::NAME_TYPE))
- {
- $value = $stream->next()->getValue();
+ $block = new Twig_Node_Block($name, $body, $lineno);
+ $this->parser->setBlock($name, $block);
+ $this->parser->popBlockStack();
- if ($value != $name)
- {
- throw new Twig_SyntaxError(sprintf("Expected endblock for block '$name' (but %s given)", $value), $lineno);
- }
- }
+ return new Twig_Node_BlockReference($name, $lineno, $this->getTag());
}
- else
+
+ public function decideBlockEnd($token)
{
- $body = new Twig_NodeList(array(
- new Twig_Node_Print($this->parser->getExpressionParser()->parseExpression(), $lineno),
- ));
+ return $token->test('endblock');
}
- $stream->expect(Twig_Token::BLOCK_END_TYPE);
-
- $block = new Twig_Node_Block($name, $body, $lineno);
- $this->parser->setBlock($name, $block);
- $this->parser->popBlockStack();
-
- return new Twig_Node_BlockReference($name, $lineno, $this->getTag());
- }
- public function decideBlockEnd($token)
- {
- return $token->test('endblock');
- }
-
- public function getTag()
- {
- return 'block';
- }
+ public function getTag()
+ {
+ return 'block';
+ }
}
class Twig_TokenParser_Debug extends Twig_TokenParser
{
- public function parse(Twig_Token $token)
- {
- $lineno = $token->getLine();
-
- $expr = null;
- if (!$this->parser->getStream()->test(Twig_Token::BLOCK_END_TYPE))
+ public function parse(Twig_Token $token)
{
- $expr = $this->parser->getExpressionParser()->parseExpression();
- }
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+ $lineno = $token->getLine();
+
+ $expr = null;
+ if (!$this->parser->getStream()->test(Twig_Token::BLOCK_END_TYPE)) {
+ $expr = $this->parser->getExpressionParser()->parseExpression();
+ }
+ $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
- return new Twig_Node_Debug($expr, $lineno, $this->getTag());
- }
+ return new Twig_Node_Debug($expr, $lineno, $this->getTag());
+ }
- public function getTag()
- {
- return 'debug';
- }
+ public function getTag()
+ {
+ return 'debug';
+ }
}
*/
class Twig_TokenParser_Display extends Twig_TokenParser
{
- public function parse(Twig_Token $token)
- {
- $lineno = $token->getLine();
- $name = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE)->getValue();
- if (!$this->parser->hasBlock($name))
+ public function parse(Twig_Token $token)
{
- throw new Twig_SyntaxError("The block '$name' cannot be displayed as it has not yet been defined", $lineno);
- }
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+ $lineno = $token->getLine();
+ $name = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE)->getValue();
+ if (!$this->parser->hasBlock($name)) {
+ throw new Twig_SyntaxError("The block '$name' cannot be displayed as it has not yet been defined", $lineno);
+ }
+ $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
- return new Twig_Node_BlockReference($name, $lineno, $this->getTag());
- }
+ return new Twig_Node_BlockReference($name, $lineno, $this->getTag());
+ }
- public function getTag()
- {
- return 'display';
- }
+ public function getTag()
+ {
+ return 'display';
+ }
}
*/
class Twig_TokenParser_Extends extends Twig_TokenParser
{
- public function parse(Twig_Token $token)
- {
- if (null !== $this->parser->getParent())
+ public function parse(Twig_Token $token)
{
- throw new Twig_SyntaxError('Multiple extend tags are forbidden', $token->getLine());
- }
- $this->parser->setParent($this->parser->getStream()->expect(Twig_Token::STRING_TYPE)->getValue());
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+ if (null !== $this->parser->getParent()) {
+ throw new Twig_SyntaxError('Multiple extend tags are forbidden', $token->getLine());
+ }
+ $this->parser->setParent($this->parser->getStream()->expect(Twig_Token::STRING_TYPE)->getValue());
+ $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
- return null;
- }
+ return null;
+ }
- public function getTag()
- {
- return 'extends';
- }
+ public function getTag()
+ {
+ return 'extends';
+ }
}
*/
class Twig_TokenParser_Filter extends Twig_TokenParser
{
- public function parse(Twig_Token $token)
- {
- $lineno = $token->getLine();
- $filters = $this->parser->getExpressionParser()->parseFilterExpressionRaw();
+ public function parse(Twig_Token $token)
+ {
+ $lineno = $token->getLine();
+ $filters = $this->parser->getExpressionParser()->parseFilterExpressionRaw();
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
- $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true);
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+ $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+ $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true);
+ $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
- return new Twig_Node_Filter($filters, $body, $lineno, $this->getTag());
- }
+ return new Twig_Node_Filter($filters, $body, $lineno, $this->getTag());
+ }
- public function decideBlockEnd($token)
- {
- return $token->test('endfilter');
- }
+ public function decideBlockEnd($token)
+ {
+ return $token->test('endfilter');
+ }
- public function getTag()
- {
- return 'filter';
- }
+ public function getTag()
+ {
+ return 'filter';
+ }
}
*/
class Twig_TokenParser_For extends Twig_TokenParser
{
- public function parse(Twig_Token $token)
- {
- $lineno = $token->getLine();
- list($isMultitarget, $item) = $this->parser->getExpressionParser()->parseAssignmentExpression();
- $this->parser->getStream()->expect('in');
- $seq = $this->parser->getExpressionParser()->parseExpression();
-
- $withLoop = true;
- if ($this->parser->getStream()->test('without'))
+ public function parse(Twig_Token $token)
{
- $this->parser->getStream()->next();
- $this->parser->getStream()->expect('loop');
- $withLoop = false;
+ $lineno = $token->getLine();
+ list($isMultitarget, $item) = $this->parser->getExpressionParser()->parseAssignmentExpression();
+ $this->parser->getStream()->expect('in');
+ $seq = $this->parser->getExpressionParser()->parseExpression();
+
+ $withLoop = true;
+ if ($this->parser->getStream()->test('without')) {
+ $this->parser->getStream()->next();
+ $this->parser->getStream()->expect('loop');
+ $withLoop = false;
+ }
+
+ $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+ $body = $this->parser->subparse(array($this, 'decideForFork'));
+ if ($this->parser->getStream()->next()->getValue() == 'else') {
+ $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+ $else = $this->parser->subparse(array($this, 'decideForEnd'), true);
+ } else {
+ $else = null;
+ }
+ $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+
+ return new Twig_Node_For($isMultitarget, $item, $seq, $body, $else, $withLoop, $lineno, $this->getTag());
}
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
- $body = $this->parser->subparse(array($this, 'decideForFork'));
- if ($this->parser->getStream()->next()->getValue() == 'else')
+ public function decideForFork($token)
{
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
- $else = $this->parser->subparse(array($this, 'decideForEnd'), true);
+ return $token->test(array('else', 'endfor'));
}
- else
+
+ public function decideForEnd($token)
{
- $else = null;
+ return $token->test('endfor');
}
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
- return new Twig_Node_For($isMultitarget, $item, $seq, $body, $else, $withLoop, $lineno, $this->getTag());
- }
-
- public function decideForFork($token)
- {
- return $token->test(array('else', 'endfor'));
- }
-
- public function decideForEnd($token)
- {
- return $token->test('endfor');
- }
-
- public function getTag()
- {
- return 'for';
- }
+ public function getTag()
+ {
+ return 'for';
+ }
}
*/
class Twig_TokenParser_If extends Twig_TokenParser
{
- public function parse(Twig_Token $token)
- {
- $lineno = $token->getLine();
- $expr = $this->parser->getExpressionParser()->parseExpression();
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
- $body = $this->parser->subparse(array($this, 'decideIfFork'));
- $tests = array(array($expr, $body));
- $else = null;
-
- $end = false;
- while (!$end)
+ public function parse(Twig_Token $token)
{
- try
- {
- switch ($this->parser->getStream()->next()->getValue())
- {
- case 'else':
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
- $else = $this->parser->subparse(array($this, 'decideIfEnd'));
- break;
+ $lineno = $token->getLine();
+ $expr = $this->parser->getExpressionParser()->parseExpression();
+ $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+ $body = $this->parser->subparse(array($this, 'decideIfFork'));
+ $tests = array(array($expr, $body));
+ $else = null;
+
+ $end = false;
+ while (!$end) {
+ try
+ {
+ switch ($this->parser->getStream()->next()->getValue()) {
+ case 'else':
+ $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+ $else = $this->parser->subparse(array($this, 'decideIfEnd'));
+ break;
- case 'elseif':
- $expr = $this->parser->getExpressionParser()->parseExpression();
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
- $body = $this->parser->subparse(array($this, 'decideIfFork'));
- $tests[] = array($expr, $body);
- break;
+ case 'elseif':
+ $expr = $this->parser->getExpressionParser()->parseExpression();
+ $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+ $body = $this->parser->subparse(array($this, 'decideIfFork'));
+ $tests[] = array($expr, $body);
+ break;
- case 'endif':
- $end = true;
- break;
+ case 'endif':
+ $end = true;
+ break;
- default:
- throw new Twig_SyntaxError('', -1);
+ default:
+ throw new Twig_SyntaxError('', -1);
+ }
+ } catch (Twig_SyntaxError $e) {
+ throw new Twig_SyntaxError(sprintf('Unexpected end of template. Twig was looking for the following tags "else", "elseif", or "endif" to close the "if" block started at line %d)', $lineno), -1);
+ }
}
- }
- catch (Twig_SyntaxError $e)
- {
- throw new Twig_SyntaxError(sprintf('Unexpected end of template. Twig was looking for the following tags "else", "elseif", or "endif" to close the "if" block started at line %d)', $lineno), -1);
- }
- }
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+ $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
- return new Twig_Node_If($tests, $else, $lineno, $this->getTag());
- }
+ return new Twig_Node_If($tests, $else, $lineno, $this->getTag());
+ }
- public function decideIfFork($token)
- {
- return $token->test(array('elseif', 'else', 'endif'));
- }
+ public function decideIfFork($token)
+ {
+ return $token->test(array('elseif', 'else', 'endif'));
+ }
- public function decideIfEnd($token)
- {
- return $token->test(array('endif'));
- }
+ public function decideIfEnd($token)
+ {
+ return $token->test(array('endif'));
+ }
- public function getTag()
- {
- return 'if';
- }
+ public function getTag()
+ {
+ return 'if';
+ }
}
*/
class Twig_TokenParser_Import extends Twig_TokenParser
{
- public function parse(Twig_Token $token)
- {
- $macro = $this->parser->getStream()->expect(Twig_Token::STRING_TYPE)->getValue();
- $this->parser->getStream()->expect('as');
- $var = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE)->getValue();
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+ public function parse(Twig_Token $token)
+ {
+ $macro = $this->parser->getStream()->expect(Twig_Token::STRING_TYPE)->getValue();
+ $this->parser->getStream()->expect('as');
+ $var = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE)->getValue();
+ $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
- return new Twig_Node_Import($macro, $var, $token->getLine(), $this->getTag());
- }
+ return new Twig_Node_Import($macro, $var, $token->getLine(), $this->getTag());
+ }
- public function getTag()
- {
- return 'import';
- }
+ public function getTag()
+ {
+ return 'import';
+ }
}
*/
class Twig_TokenParser_Include extends Twig_TokenParser
{
- public function parse(Twig_Token $token)
- {
- $expr = $this->parser->getExpressionParser()->parseExpression();
-
- $sandboxed = false;
- if ($this->parser->getStream()->test(Twig_Token::NAME_TYPE, 'sandboxed'))
+ public function parse(Twig_Token $token)
{
- $this->parser->getStream()->next();
- $sandboxed = true;
- }
+ $expr = $this->parser->getExpressionParser()->parseExpression();
- $variables = null;
- if ($this->parser->getStream()->test(Twig_Token::NAME_TYPE, 'with'))
- {
- $this->parser->getStream()->next();
- $variables = $this->parser->getExpressionParser()->parseExpression();
- }
+ $sandboxed = false;
+ if ($this->parser->getStream()->test(Twig_Token::NAME_TYPE, 'sandboxed')) {
+ $this->parser->getStream()->next();
+ $sandboxed = true;
+ }
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+ $variables = null;
+ if ($this->parser->getStream()->test(Twig_Token::NAME_TYPE, 'with')) {
+ $this->parser->getStream()->next();
+ $variables = $this->parser->getExpressionParser()->parseExpression();
+ }
- return new Twig_Node_Include($expr, $sandboxed, $variables, $token->getLine(), $this->getTag());
- }
+ $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
- public function getTag()
- {
- return 'include';
- }
+ return new Twig_Node_Include($expr, $sandboxed, $variables, $token->getLine(), $this->getTag());
+ }
+
+ public function getTag()
+ {
+ return 'include';
+ }
}
*/
class Twig_TokenParser_Macro extends Twig_TokenParser
{
- public function parse(Twig_Token $token)
- {
- $lineno = $token->getLine();
- $name = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE)->getValue();
+ public function parse(Twig_Token $token)
+ {
+ $lineno = $token->getLine();
+ $name = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE)->getValue();
- $arguments = $this->parser->getExpressionParser()->parseArguments();
+ $arguments = $this->parser->getExpressionParser()->parseArguments();
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
- $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true);
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+ $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+ $body = $this->parser->subparse(array($this, 'decideBlockEnd'), true);
+ $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
- $this->parser->setMacro($name, new Twig_Node_Macro($name, $body, $arguments, $lineno, $this->getTag()));
+ $this->parser->setMacro($name, new Twig_Node_Macro($name, $body, $arguments, $lineno, $this->getTag()));
- return null;
- }
+ return null;
+ }
- public function decideBlockEnd($token)
- {
- return $token->test('endmacro');
- }
+ public function decideBlockEnd($token)
+ {
+ return $token->test('endmacro');
+ }
- public function getTag()
- {
- return 'macro';
- }
+ public function getTag()
+ {
+ return 'macro';
+ }
}
*/
class Twig_TokenParser_Parent extends Twig_TokenParser
{
- public function parse(Twig_Token $token)
- {
- if (!count($this->parser->getBlockStack()))
+ public function parse(Twig_Token $token)
{
- throw new Twig_SyntaxError('Calling "parent" outside a block is forbidden', $token->getLine());
- }
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+ if (!count($this->parser->getBlockStack())) {
+ throw new Twig_SyntaxError('Calling "parent" outside a block is forbidden', $token->getLine());
+ }
+ $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
- return new Twig_Node_Parent($this->parser->peekBlockStack(), $token->getLine(), $this->getTag());
- }
+ return new Twig_Node_Parent($this->parser->peekBlockStack(), $token->getLine(), $this->getTag());
+ }
- public function getTag()
- {
- return 'parent';
- }
+ public function getTag()
+ {
+ return 'parent';
+ }
}
*/
class Twig_TokenParser_Set extends Twig_TokenParser
{
- public function parse(Twig_Token $token)
- {
- $lineno = $token->getLine();
- $stream = $this->parser->getStream();
- list($isMultitarget, $names) = $this->parser->getExpressionParser()->parseAssignmentExpression();
-
- $capture = false;
- if ($stream->test(Twig_Token::NAME_TYPE, 'as'))
+ public function parse(Twig_Token $token)
{
- $stream->expect(Twig_Token::NAME_TYPE, 'as');
- list(, $values) = $this->parser->getExpressionParser()->parseMultitargetExpression();
+ $lineno = $token->getLine();
+ $stream = $this->parser->getStream();
+ list($isMultitarget, $names) = $this->parser->getExpressionParser()->parseAssignmentExpression();
- $stream->expect(Twig_Token::BLOCK_END_TYPE);
- }
- else
- {
- $capture = true;
+ $capture = false;
+ if ($stream->test(Twig_Token::NAME_TYPE, 'as')) {
+ $stream->expect(Twig_Token::NAME_TYPE, 'as');
+ list(, $values) = $this->parser->getExpressionParser()->parseMultitargetExpression();
+
+ $stream->expect(Twig_Token::BLOCK_END_TYPE);
+ } else {
+ $capture = true;
+
+ if ($isMultitarget) {
+ throw new Twig_SyntaxError("When using set with a block, you cannot have a multi-target.", $lineno);
+ }
+
+ $stream->expect(Twig_Token::BLOCK_END_TYPE);
- if ($isMultitarget)
- {
- throw new Twig_SyntaxError("When using set with a block, you cannot have a multi-target.", $lineno);
- }
+ $values = $this->parser->subparse(array($this, 'decideBlockEnd'), true);
+ $stream->expect(Twig_Token::BLOCK_END_TYPE);
+ }
- $stream->expect(Twig_Token::BLOCK_END_TYPE);
+ if (count($names) !== count($values)) {
+ throw new Twig_SyntaxError("When using set, you must have the same number of variables and assignements.", $lineno);
+ }
- $values = $this->parser->subparse(array($this, 'decideBlockEnd'), true);
- $stream->expect(Twig_Token::BLOCK_END_TYPE);
+ return new Twig_Node_Set($isMultitarget, $capture, $names, $values, $lineno, $this->getTag());
}
- if (count($names) !== count($values))
+ public function decideBlockEnd($token)
{
- throw new Twig_SyntaxError("When using set, you must have the same number of variables and assignements.", $lineno);
+ return $token->test('endset');
}
- return new Twig_Node_Set($isMultitarget, $capture, $names, $values, $lineno, $this->getTag());
- }
-
- public function decideBlockEnd($token)
- {
- return $token->test('endset');
- }
-
- public function getTag()
- {
- return 'set';
- }
+ public function getTag()
+ {
+ return 'set';
+ }
}
*/
class Twig_TokenParser_Trans extends Twig_TokenParser
{
- public function parse(Twig_Token $token)
- {
- $lineno = $token->getLine();
- $stream = $this->parser->getStream();
- $count = false;
- if (!$stream->test(Twig_Token::BLOCK_END_TYPE))
+ public function parse(Twig_Token $token)
{
- $count = new Twig_Node_Expression_Name($stream->expect(Twig_Token::NAME_TYPE)->getValue(), $lineno);
- }
+ $lineno = $token->getLine();
+ $stream = $this->parser->getStream();
+ $count = false;
+ if (!$stream->test(Twig_Token::BLOCK_END_TYPE)) {
+ $count = new Twig_Node_Expression_Name($stream->expect(Twig_Token::NAME_TYPE)->getValue(), $lineno);
+ }
- $stream->expect(Twig_Token::BLOCK_END_TYPE);
- $body = $this->parser->subparse(array($this, 'decideForFork'));
- $plural = false;
- if ('plural' === $stream->next()->getValue())
- {
- $stream->expect(Twig_Token::BLOCK_END_TYPE);
- $plural = $this->parser->subparse(array($this, 'decideForEnd'), true);
+ $stream->expect(Twig_Token::BLOCK_END_TYPE);
+ $body = $this->parser->subparse(array($this, 'decideForFork'));
+ $plural = false;
+ if ('plural' === $stream->next()->getValue()) {
+ $stream->expect(Twig_Token::BLOCK_END_TYPE);
+ $plural = $this->parser->subparse(array($this, 'decideForEnd'), true);
- if (false === $count)
- {
- throw new Twig_SyntaxError('When a plural is used, you must pass the count as an argument to the "trans" tag', $lineno);
- }
- }
- $stream->expect(Twig_Token::BLOCK_END_TYPE);
+ if (false === $count) {
+ throw new Twig_SyntaxError('When a plural is used, you must pass the count as an argument to the "trans" tag', $lineno);
+ }
+ }
+ $stream->expect(Twig_Token::BLOCK_END_TYPE);
- return new Twig_Node_Trans($count, $body, $plural, $lineno, $this->getTag());
- }
+ return new Twig_Node_Trans($count, $body, $plural, $lineno, $this->getTag());
+ }
- public function decideForFork($token)
- {
- return $token->test(array('plural', 'endtrans'));
- }
+ public function decideForFork($token)
+ {
+ return $token->test(array('plural', 'endtrans'));
+ }
- public function decideForEnd($token)
- {
- return $token->test('endtrans');
- }
+ public function decideForEnd($token)
+ {
+ return $token->test('endtrans');
+ }
- public function getTag()
- {
- return 'trans';
- }
+ public function getTag()
+ {
+ return 'trans';
+ }
}
*/
class Twig_TokenStream
{
- protected $pushed;
- protected $originalTokens;
- protected $tokens;
- protected $eof;
- protected $current;
- protected $filename;
- protected $trimBlocks;
-
- public function __construct(array $tokens, $filename, $trimBlocks = true)
- {
- $this->pushed = array();
- $this->originalTokens = $tokens;
- $this->tokens = $tokens;
- $this->filename = $filename;
- $this->trimBlocks = $trimBlocks;
- $this->next();
- }
-
- public function __toString()
- {
- $repr = '';
- foreach ($this->originalTokens as $token)
+ protected $pushed;
+ protected $originalTokens;
+ protected $tokens;
+ protected $eof;
+ protected $current;
+ protected $filename;
+ protected $trimBlocks;
+
+ public function __construct(array $tokens, $filename, $trimBlocks = true)
{
- $repr .= $token."\n";
+ $this->pushed = array();
+ $this->originalTokens = $tokens;
+ $this->tokens = $tokens;
+ $this->filename = $filename;
+ $this->trimBlocks = $trimBlocks;
+ $this->next();
}
- return $repr;
- }
-
- public function push($token)
- {
- $this->pushed[] = $token;
- }
-
- /**
- * Sets the pointer to the next token and returns the old one.
- *
- * @param Boolean $fromStack Whether to get a token from the stack or not
- */
- public function next($fromStack = true)
- {
- if ($fromStack && !empty($this->pushed))
+ public function __toString()
{
- $old = array_shift($this->pushed);
- $token = array_shift($this->pushed);
+ $repr = '';
+ foreach ($this->originalTokens as $token) {
+ $repr .= $token."\n";
+ }
+
+ return $repr;
}
- else
+
+ public function push($token)
{
- $old = $this->current;
- $token = array_shift($this->tokens);
+ $this->pushed[] = $token;
}
- if (null === $token)
+ /**
+ * Sets the pointer to the next token and returns the old one.
+ *
+ * @param Boolean $fromStack Whether to get a token from the stack or not
+ */
+ public function next($fromStack = true)
{
- throw new Twig_SyntaxError('Unexpected end of template', -1);
+ if ($fromStack && !empty($this->pushed)) {
+ $old = array_shift($this->pushed);
+ $token = array_shift($this->pushed);
+ } else {
+ $old = $this->current;
+ $token = array_shift($this->tokens);
+ }
+
+ if (null === $token) {
+ throw new Twig_SyntaxError('Unexpected end of template', -1);
+ }
+
+ // trim blocks
+ if ($this->trimBlocks &&
+ $this->current &&
+ Twig_Token::BLOCK_END_TYPE === $this->current->getType() &&
+ Twig_Token::TEXT_TYPE === $token->getType() &&
+ $token->getValue() &&
+ "\n" === substr($token->getValue(), 0, 1)
+ )
+ {
+ $value = substr($token->getValue(), 1);
+
+ if (!$value) {
+ return $this->next();
+ }
+
+ $token->setValue($value);
+ }
+
+ $this->current = $token;
+
+ $this->eof = $token->getType() === Twig_Token::EOF_TYPE;
+
+ return $old;
}
- // trim blocks
- if ($this->trimBlocks &&
- $this->current &&
- Twig_Token::BLOCK_END_TYPE === $this->current->getType() &&
- Twig_Token::TEXT_TYPE === $token->getType() &&
- $token->getValue() &&
- "\n" === substr($token->getValue(), 0, 1)
- )
+ /**
+ * Looks at the next token.
+ */
+ public function look()
{
- $value = substr($token->getValue(), 1);
+ $old = $this->next(false);
+ $new = $this->current;
+ $this->push($old);
+ $this->push($new);
- if (!$value)
- {
- return $this->next();
- }
+ return $new;
+ }
- $token->setValue($value);
+ /**
+ * Rewinds the pushed tokens.
+ */
+ public function rewind()
+ {
+ $tokens = array();
+ while ($this->pushed) {
+ $tokens[] = array_shift($this->pushed);
+ array_shift($this->pushed);
+ }
+
+ $this->tokens = array_merge($tokens, array($this->current), $this->tokens);
+
+ $this->next();
}
- $this->current = $token;
-
- $this->eof = $token->getType() === Twig_Token::EOF_TYPE;
-
- return $old;
- }
-
- /**
- * Looks at the next token.
- */
- public function look()
- {
- $old = $this->next(false);
- $new = $this->current;
- $this->push($old);
- $this->push($new);
-
- return $new;
- }
-
- /**
- * Rewinds the pushed tokens.
- */
- public function rewind()
- {
- $tokens = array();
- while ($this->pushed)
+ /**
+ * Expects a token (like $token->test()) and returns it or throw a syntax error.
+ */
+ public function expect($primary, $secondary = null)
{
- $tokens[] = array_shift($this->pushed);
- array_shift($this->pushed);
+ $token = $this->current;
+ if (!$token->test($primary, $secondary)) {
+ throw new Twig_SyntaxError(sprintf('Unexpected token "%s" of value "%s" ("%s" expected%s)',
+ Twig_Token::getTypeAsString($token->getType()), $token->getValue(),
+ Twig_Token::getTypeAsString($primary), $secondary ? sprintf(' with value "%s"', $secondary) : ''),
+ $this->current->getLine()
+ );
+ }
+ $this->next();
+
+ return $token;
}
- $this->tokens = array_merge($tokens, array($this->current), $this->tokens);
+ /**
+ * Forwards that call to the current token.
+ */
+ public function test($primary, $secondary = null)
+ {
+ return $this->current->test($primary, $secondary);
+ }
+
+ public function isEOF()
+ {
+ return $this->eof;
+ }
- $this->next();
- }
+ public function getCurrent()
+ {
+ return $this->current;
+ }
- /**
- * Expects a token (like $token->test()) and returns it or throw a syntax error.
- */
- public function expect($primary, $secondary = null)
- {
- $token = $this->current;
- if (!$token->test($primary, $secondary))
+ public function getFilename()
{
- throw new Twig_SyntaxError(sprintf('Unexpected token "%s" of value "%s" ("%s" expected%s)',
- Twig_Token::getTypeAsString($token->getType()), $token->getValue(),
- Twig_Token::getTypeAsString($primary), $secondary ? sprintf(' with value "%s"', $secondary) : ''),
- $this->current->getLine()
- );
+ return $this->filename;
}
- $this->next();
-
- return $token;
- }
-
- /**
- * Forwards that call to the current token.
- */
- public function test($primary, $secondary = null)
- {
- return $this->current->test($primary, $secondary);
- }
-
- public function isEOF()
- {
- return $this->eof;
- }
-
- public function getCurrent()
- {
- return $this->current;
- }
-
- public function getFilename()
- {
- return $this->filename;
- }
}
class Twig_Tests_AutoloaderTest extends PHPUnit_Framework_TestCase
{
- public function testAutoload()
- {
- $this->assertFalse(class_exists('FooBarFoo'), '->autoload() does not try to load classes that does not begin with Twig');
+ public function testAutoload()
+ {
+ $this->assertFalse(class_exists('FooBarFoo'), '->autoload() does not try to load classes that does not begin with Twig');
- $autoloader = new Twig_Autoloader();
- $this->assertTrue($autoloader->autoload('Twig_Parser'), '->autoload() returns true if it is able to load a class');
- $this->assertFalse($autoloader->autoload('Foo'), '->autoload() returns false if it is not able to load a class');
- }
+ $autoloader = new Twig_Autoloader();
+ $this->assertTrue($autoloader->autoload('Twig_Parser'), '->autoload() returns true if it is able to load a class');
+ $this->assertFalse($autoloader->autoload('Foo'), '->autoload() returns false if it is not able to load a class');
+ }
}
class Twig_Tests_Extension_SandboxTest extends PHPUnit_Framework_TestCase
{
- static protected $params, $templates;
-
- public function setUp()
- {
- self::$params = array(
- 'name' => 'Fabien',
- 'obj' => new Object(),
- );
-
- self::$templates = array(
- '1_basic1' => '{{ obj.foo }}',
- '1_basic2' => '{{ name|upper }}',
- '1_basic3' => '{% if name %}foo{% endif %}',
- '1_basic4' => '{{ obj.bar }}',
- '1_basic' => '{% if obj.foo %}{{ obj.foo|upper }}{% endif %}',
- );
- }
-
- public function testSandboxGloballySet()
- {
- $twig = $this->getEnvironment(false, self::$templates);
- $this->assertEquals('FOO', $twig->loadTemplate('1_basic')->render(self::$params), 'Sandbox does nothing if it is disabled globally');
-
- $twig = $this->getEnvironment(true, self::$templates);
- try
- {
- $twig->loadTemplate('1_basic1')->render(self::$params);
- $this->fail('Sandbox throws a SecurityError exception if an unallowed method is called');
- }
- catch (Twig_Sandbox_SecurityError $e)
- {
- }
+ static protected $params, $templates;
- $twig = $this->getEnvironment(true, self::$templates);
- try
- {
- $twig->loadTemplate('1_basic2')->render(self::$params);
- $this->fail('Sandbox throws a SecurityError exception if an unallowed filter is called');
- }
- catch (Twig_Sandbox_SecurityError $e)
+ public function setUp()
{
+ self::$params = array(
+ 'name' => 'Fabien',
+ 'obj' => new Object(),
+ );
+
+ self::$templates = array(
+ '1_basic1' => '{{ obj.foo }}',
+ '1_basic2' => '{{ name|upper }}',
+ '1_basic3' => '{% if name %}foo{% endif %}',
+ '1_basic4' => '{{ obj.bar }}',
+ '1_basic' => '{% if obj.foo %}{{ obj.foo|upper }}{% endif %}',
+ );
}
- $twig = $this->getEnvironment(true, self::$templates);
- try
- {
- $twig->loadTemplate('1_basic3')->render(self::$params);
- $this->fail('Sandbox throws a SecurityError exception if an unallowed tag is used in the template');
- }
- catch (Twig_Sandbox_SecurityError $e)
+ public function testSandboxGloballySet()
{
+ $twig = $this->getEnvironment(false, self::$templates);
+ $this->assertEquals('FOO', $twig->loadTemplate('1_basic')->render(self::$params), 'Sandbox does nothing if it is disabled globally');
+
+ $twig = $this->getEnvironment(true, self::$templates);
+ try {
+ $twig->loadTemplate('1_basic1')->render(self::$params);
+ $this->fail('Sandbox throws a SecurityError exception if an unallowed method is called');
+ } catch (Twig_Sandbox_SecurityError $e) {
+ }
+
+ $twig = $this->getEnvironment(true, self::$templates);
+ try {
+ $twig->loadTemplate('1_basic2')->render(self::$params);
+ $this->fail('Sandbox throws a SecurityError exception if an unallowed filter is called');
+ } catch (Twig_Sandbox_SecurityError $e) {
+ }
+
+ $twig = $this->getEnvironment(true, self::$templates);
+ try {
+ $twig->loadTemplate('1_basic3')->render(self::$params);
+ $this->fail('Sandbox throws a SecurityError exception if an unallowed tag is used in the template');
+ } catch (Twig_Sandbox_SecurityError $e) {
+ }
+
+ $twig = $this->getEnvironment(true, self::$templates);
+ try {
+ $twig->loadTemplate('1_basic4')->render(self::$params);
+ $this->fail('Sandbox throws a SecurityError exception if an unallowed property is called in the template');
+ } catch (Twig_Sandbox_SecurityError $e) {
+ }
+
+ $twig = $this->getEnvironment(true, self::$templates, array(), array(), array('Object' => 'foo'));
+ $this->assertEquals('foo', $twig->loadTemplate('1_basic1')->render(self::$params), 'Sandbox allow some methods');
+
+ $twig = $this->getEnvironment(true, self::$templates, array(), array('upper'));
+ $this->assertEquals('FABIEN', $twig->loadTemplate('1_basic2')->render(self::$params), 'Sandbox allow some filters');
+
+ $twig = $this->getEnvironment(true, self::$templates, array('if'));
+ $this->assertEquals('foo', $twig->loadTemplate('1_basic3')->render(self::$params), 'Sandbox allow some tags');
+
+ $twig = $this->getEnvironment(true, self::$templates, array(), array(), array(), array('Object' => 'bar'));
+ $this->assertEquals('bar', $twig->loadTemplate('1_basic4')->render(self::$params), 'Sandbox allow some properties');
}
- $twig = $this->getEnvironment(true, self::$templates);
- try
- {
- $twig->loadTemplate('1_basic4')->render(self::$params);
- $this->fail('Sandbox throws a SecurityError exception if an unallowed property is called in the template');
- }
- catch (Twig_Sandbox_SecurityError $e)
+ public function testSandboxLocallySetForAnInclude()
{
+ self::$templates = array(
+ '2_basic' => '{{ obj.foo }}{% include "2_included" %}{{ obj.foo }}',
+ '2_included' => '{% if obj.foo %}{{ obj.foo|upper }}{% endif %}',
+ );
+
+ $twig = $this->getEnvironment(false, self::$templates);
+ $this->assertEquals('fooFOOfoo', $twig->loadTemplate('2_basic')->render(self::$params), 'Sandbox does nothing if disabled globally and sandboxed not used for the include');
+
+ self::$templates = array(
+ '3_basic' => '{{ obj.foo }}{% include "3_included" sandboxed %}{{ obj.foo }}',
+ '3_included' => '{% if obj.foo %}{{ obj.foo|upper }}{% endif %}',
+ );
+
+ $twig = $this->getEnvironment(false, self::$templates);
+ $twig = $this->getEnvironment(true, self::$templates);
+ try {
+ $twig->loadTemplate('3_basic')->render(self::$params);
+ $this->fail('Sandbox throws a SecurityError exception when the included file is sandboxed');
+ } catch (Twig_Sandbox_SecurityError $e) {
+ }
}
- $twig = $this->getEnvironment(true, self::$templates, array(), array(), array('Object' => 'foo'));
- $this->assertEquals('foo', $twig->loadTemplate('1_basic1')->render(self::$params), 'Sandbox allow some methods');
-
- $twig = $this->getEnvironment(true, self::$templates, array(), array('upper'));
- $this->assertEquals('FABIEN', $twig->loadTemplate('1_basic2')->render(self::$params), 'Sandbox allow some filters');
-
- $twig = $this->getEnvironment(true, self::$templates, array('if'));
- $this->assertEquals('foo', $twig->loadTemplate('1_basic3')->render(self::$params), 'Sandbox allow some tags');
-
- $twig = $this->getEnvironment(true, self::$templates, array(), array(), array(), array('Object' => 'bar'));
- $this->assertEquals('bar', $twig->loadTemplate('1_basic4')->render(self::$params), 'Sandbox allow some properties');
- }
-
- public function testSandboxLocallySetForAnInclude()
- {
- self::$templates = array(
- '2_basic' => '{{ obj.foo }}{% include "2_included" %}{{ obj.foo }}',
- '2_included' => '{% if obj.foo %}{{ obj.foo|upper }}{% endif %}',
- );
-
- $twig = $this->getEnvironment(false, self::$templates);
- $this->assertEquals('fooFOOfoo', $twig->loadTemplate('2_basic')->render(self::$params), 'Sandbox does nothing if disabled globally and sandboxed not used for the include');
-
- self::$templates = array(
- '3_basic' => '{{ obj.foo }}{% include "3_included" sandboxed %}{{ obj.foo }}',
- '3_included' => '{% if obj.foo %}{{ obj.foo|upper }}{% endif %}',
- );
-
- $twig = $this->getEnvironment(false, self::$templates);
- $twig = $this->getEnvironment(true, self::$templates);
- try
- {
- $twig->loadTemplate('3_basic')->render(self::$params);
- $this->fail('Sandbox throws a SecurityError exception when the included file is sandboxed');
- }
- catch (Twig_Sandbox_SecurityError $e)
+ protected function getEnvironment($sandboxed, $templates, $tags = array(), $filters = array(), $methods = array(), $properties = array())
{
- }
- }
-
- protected function getEnvironment($sandboxed, $templates, $tags = array(), $filters = array(), $methods = array(), $properties = array())
- {
- $loader = new Twig_Loader_Array($templates);
- $twig = new Twig_Environment($loader, array('trim_blocks' => true, 'debug' => true));
- $policy = new Twig_Sandbox_SecurityPolicy($tags, $filters, $methods, $properties);
- $twig->addExtension(new Twig_Extension_Sandbox($policy, $sandboxed));
+ $loader = new Twig_Loader_Array($templates);
+ $twig = new Twig_Environment($loader, array('trim_blocks' => true, 'debug' => true));
+ $policy = new Twig_Sandbox_SecurityPolicy($tags, $filters, $methods, $properties);
+ $twig->addExtension(new Twig_Extension_Sandbox($policy, $sandboxed));
- return $twig;
- }
+ return $twig;
+ }
}
class Object
{
- public $bar = 'bar';
+ public $bar = 'bar';
- public function foo()
- {
- return 'foo';
- }
+ public function foo()
+ {
+ return 'foo';
+ }
}
class Twig_Tests_TokenStreamTest extends PHPUnit_Framework_TestCase
{
- static protected $tokens;
+ static protected $tokens;
- public function setUp()
- {
- self::$tokens = array(
- new Twig_Token(Twig_Token::TEXT_TYPE, 1, 0),
- new Twig_Token(Twig_Token::TEXT_TYPE, 2, 0),
- new Twig_Token(Twig_Token::TEXT_TYPE, 3, 0),
- new Twig_Token(Twig_Token::TEXT_TYPE, 4, 0),
- new Twig_Token(Twig_Token::TEXT_TYPE, 5, 0),
- new Twig_Token(Twig_Token::TEXT_TYPE, 6, 0),
- new Twig_Token(Twig_Token::TEXT_TYPE, 7, 0),
- new Twig_Token(Twig_Token::EOF_TYPE, 0, 0),
- );
- }
-
- public function testNext()
- {
- $stream = new Twig_TokenStream(self::$tokens, '', false);
- $repr = array();
- while (!$stream->isEOF())
+ public function setUp()
{
- $token = $stream->next();
-
- $repr[] = $token->getValue();
+ self::$tokens = array(
+ new Twig_Token(Twig_Token::TEXT_TYPE, 1, 0),
+ new Twig_Token(Twig_Token::TEXT_TYPE, 2, 0),
+ new Twig_Token(Twig_Token::TEXT_TYPE, 3, 0),
+ new Twig_Token(Twig_Token::TEXT_TYPE, 4, 0),
+ new Twig_Token(Twig_Token::TEXT_TYPE, 5, 0),
+ new Twig_Token(Twig_Token::TEXT_TYPE, 6, 0),
+ new Twig_Token(Twig_Token::TEXT_TYPE, 7, 0),
+ new Twig_Token(Twig_Token::EOF_TYPE, 0, 0),
+ );
}
- $this->assertEquals('1, 2, 3, 4, 5, 6, 7', implode(', ', $repr), '->next() returns the next token in the stream');
- }
- public function testLook()
- {
- $stream = new Twig_TokenStream(self::$tokens, '', false);
- $this->assertEquals(2, $stream->look()->getValue(), '->look() returns the next token');
- $repr = array();
- while (!$stream->isEOF())
+ public function testNext()
{
- $token = $stream->next();
+ $stream = new Twig_TokenStream(self::$tokens, '', false);
+ $repr = array();
+ while (!$stream->isEOF()) {
+ $token = $stream->next();
- $repr[] = $token->getValue();
+ $repr[] = $token->getValue();
+ }
+ $this->assertEquals('1, 2, 3, 4, 5, 6, 7', implode(', ', $repr), '->next() returns the next token in the stream');
}
- $this->assertEquals('1, 2, 3, 4, 5, 6, 7', implode(', ', $repr), '->look() pushes the token to the stack');
- $stream = new Twig_TokenStream(self::$tokens, '', false);
- $this->assertEquals(2, $stream->look()->getValue(), '->look() returns the next token');
- $this->assertEquals(3, $stream->look()->getValue(), '->look() can be called several times to look more than one upcoming token');
- $this->assertEquals(4, $stream->look()->getValue(), '->look() can be called several times to look more than one upcoming token');
- $this->assertEquals(5, $stream->look()->getValue(), '->look() can be called several times to look more than one upcoming token');
- $repr = array();
- while (!$stream->isEOF())
+ public function testLook()
{
- $token = $stream->next();
+ $stream = new Twig_TokenStream(self::$tokens, '', false);
+ $this->assertEquals(2, $stream->look()->getValue(), '->look() returns the next token');
+ $repr = array();
+ while (!$stream->isEOF()) {
+ $token = $stream->next();
+
+ $repr[] = $token->getValue();
+ }
+ $this->assertEquals('1, 2, 3, 4, 5, 6, 7', implode(', ', $repr), '->look() pushes the token to the stack');
+
+ $stream = new Twig_TokenStream(self::$tokens, '', false);
+ $this->assertEquals(2, $stream->look()->getValue(), '->look() returns the next token');
+ $this->assertEquals(3, $stream->look()->getValue(), '->look() can be called several times to look more than one upcoming token');
+ $this->assertEquals(4, $stream->look()->getValue(), '->look() can be called several times to look more than one upcoming token');
+ $this->assertEquals(5, $stream->look()->getValue(), '->look() can be called several times to look more than one upcoming token');
+ $repr = array();
+ while (!$stream->isEOF()) {
+ $token = $stream->next();
- $repr[] = $token->getValue();
+ $repr[] = $token->getValue();
+ }
+ $this->assertEquals('1, 2, 3, 4, 5, 6, 7', implode(', ', $repr), '->look() pushes the token to the stack');
}
- $this->assertEquals('1, 2, 3, 4, 5, 6, 7', implode(', ', $repr), '->look() pushes the token to the stack');
- }
- public function testRewind()
- {
- $stream = new Twig_TokenStream(self::$tokens, '', false);
- $this->assertEquals(2, $stream->look()->getValue(), '->look() returns the next token');
- $this->assertEquals(3, $stream->look()->getValue(), '->look() can be called several times to look more than one upcoming token');
- $this->assertEquals(4, $stream->look()->getValue(), '->look() can be called several times to look more than one upcoming token');
- $this->assertEquals(5, $stream->look()->getValue(), '->look() can be called several times to look more than one upcoming token');
- $stream->rewind();
- $repr = array();
- while (!$stream->isEOF())
+ public function testRewind()
{
- $token = $stream->next(false);
+ $stream = new Twig_TokenStream(self::$tokens, '', false);
+ $this->assertEquals(2, $stream->look()->getValue(), '->look() returns the next token');
+ $this->assertEquals(3, $stream->look()->getValue(), '->look() can be called several times to look more than one upcoming token');
+ $this->assertEquals(4, $stream->look()->getValue(), '->look() can be called several times to look more than one upcoming token');
+ $this->assertEquals(5, $stream->look()->getValue(), '->look() can be called several times to look more than one upcoming token');
+ $stream->rewind();
+ $repr = array();
+ while (!$stream->isEOF()) {
+ $token = $stream->next(false);
- $repr[] = $token->getValue();
+ $repr[] = $token->getValue();
+ }
+ $this->assertEquals('1, 2, 3, 4, 5, 6, 7', implode(', ', $repr), '->rewind() pushes all pushed tokens to the token array');
}
- $this->assertEquals('1, 2, 3, 4, 5, 6, 7', implode(', ', $repr), '->rewind() pushes all pushed tokens to the token array');
- }
}
class Twig_Tests_IntegrationTest extends PHPUnit_Framework_TestCase
{
- static protected $fixturesDir;
+ static protected $fixturesDir;
- public function setUp()
- {
- self::$fixturesDir = realpath(dirname(__FILE__).'/../../fixtures/');
- }
+ public function setUp()
+ {
+ self::$fixturesDir = realpath(dirname(__FILE__).'/../../fixtures/');
+ }
- public function testIntegration()
- {
- foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator(self::$fixturesDir), RecursiveIteratorIterator::LEAVES_ONLY) as $file)
+ public function testIntegration()
{
- if (!preg_match('/\.test$/', $file))
- {
- continue;
- }
-
- $test = file_get_contents($file->getRealpath());
-
- if (!preg_match('/--TEST--\s*(.*?)\s*((?:--TEMPLATE(?:\(.*?\))?--(?:.*?))+)--DATA--.*?--EXPECT--.*/s', $test, $match))
- {
- throw new InvalidArgumentException(sprintf('Test "%s" is not valid.', str_replace(self::$fixturesDir.'/', '', $file)));
- }
-
- $message = $match[1];
- $templates = array();
- preg_match_all('/--TEMPLATE(?:\((.*?)\))?--(.*?)(?=\-\-TEMPLATE|$)/s', $match[2], $matches, PREG_SET_ORDER);
- foreach ($matches as $match)
- {
- $templates[($match[1] ? $match[1] : 'index.twig')] = $match[2];
- }
-
- $loader = new Twig_Loader_Array($templates);
- $twig = new Twig_Environment($loader, array('trim_blocks' => true, 'cache' => false));
- $twig->addExtension(new Twig_Extension_Escaper());
- $twig->addExtension(new TestExtension());
-
- $template = $twig->loadTemplate('index.twig');
-
- preg_match_all('/--DATA--(.*?)--EXPECT--(.*?)(?=\-\-DATA\-\-|$)/s', $test, $matches, PREG_SET_ORDER);
- foreach ($matches as $match)
- {
- $output = trim($template->render(eval($match[1].';')), "\n ");
- $expected = trim($match[2], "\n ");
-
- $this->assertEquals($expected, $output, $message);
- if ($output != $expected)
- {
- echo 'Compiled template that failed:';
-
- foreach (array_keys($templates) as $name)
- {
- $source = $loader->getSource($name);
- echo $twig->compile($twig->parse($twig->tokenize($source, $name)));
- }
+ foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator(self::$fixturesDir), RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
+ if (!preg_match('/\.test$/', $file)) {
+ continue;
+ }
+
+ $test = file_get_contents($file->getRealpath());
+
+ if (!preg_match('/--TEST--\s*(.*?)\s*((?:--TEMPLATE(?:\(.*?\))?--(?:.*?))+)--DATA--.*?--EXPECT--.*/s', $test, $match)) {
+ throw new InvalidArgumentException(sprintf('Test "%s" is not valid.', str_replace(self::$fixturesDir.'/', '', $file)));
+ }
+
+ $message = $match[1];
+ $templates = array();
+ preg_match_all('/--TEMPLATE(?:\((.*?)\))?--(.*?)(?=\-\-TEMPLATE|$)/s', $match[2], $matches, PREG_SET_ORDER);
+ foreach ($matches as $match) {
+ $templates[($match[1] ? $match[1] : 'index.twig')] = $match[2];
+ }
+
+ $loader = new Twig_Loader_Array($templates);
+ $twig = new Twig_Environment($loader, array('trim_blocks' => true, 'cache' => false));
+ $twig->addExtension(new Twig_Extension_Escaper());
+ $twig->addExtension(new TestExtension());
+
+ $template = $twig->loadTemplate('index.twig');
+
+ preg_match_all('/--DATA--(.*?)--EXPECT--(.*?)(?=\-\-DATA\-\-|$)/s', $test, $matches, PREG_SET_ORDER);
+ foreach ($matches as $match) {
+ $output = trim($template->render(eval($match[1].';')), "\n ");
+ $expected = trim($match[2], "\n ");
+
+ $this->assertEquals($expected, $output, $message);
+ if ($output != $expected) {
+ echo 'Compiled template that failed:';
+
+ foreach (array_keys($templates) as $name) {
+ $source = $loader->getSource($name);
+ echo $twig->compile($twig->parse($twig->tokenize($source, $name)));
+ }
+ }
+ }
}
- }
}
- }
}
class Foo
{
- public function bar($param1 = null, $param2 = null)
- {
- return 'bar'.($param1 ? '_'.$param1 : '').($param2 ? '-'.$param2 : '');
- }
-
- public function getFoo()
- {
- return 'foo';
- }
-
- public function getSelf()
- {
- return $this;
- }
+ public function bar($param1 = null, $param2 = null)
+ {
+ return 'bar'.($param1 ? '_'.$param1 : '').($param2 ? '-'.$param2 : '');
+ }
+
+ public function getFoo()
+ {
+ return 'foo';
+ }
+
+ public function getSelf()
+ {
+ return $this;
+ }
}
class TestExtension extends Twig_Extension
{
- public function getFilters()
- {
- return array('nl2br' => new Twig_Filter_Method($this, 'nl2br'));
- }
-
- public function nl2br($value, $sep = '<br />')
- {
- return str_replace("\n", $sep."\n", $value);
- }
-
- public function getName()
- {
- return 'test';
- }
+ public function getFilters()
+ {
+ return array('nl2br' => new Twig_Filter_Method($this, 'nl2br'));
+ }
+
+ public function nl2br($value, $sep = '<br />')
+ {
+ return str_replace("\n", $sep."\n", $value);
+ }
+
+ public function getName()
+ {
+ return 'test';
+ }
}