1. Simon Richard
  2. dotclear

Commits

dsls  committed 0b114ae Merge

Merge with default (removing twig)

  • Participants
  • Parent commits 1c84658, 8e25b11
  • Branches safemode

Comments (0)

Files changed (125)

File inc/libs/twig/AUTHORS

  • Ignore whitespace
-Twig is written and maintained by the Twig Team:
-
-Lead Developer:
-
-- Fabien Potencier <fabien.potencier@symfony-project.org>
-
-Project Founder:
-
-- Armin Ronacher <armin.ronacher@active-4.com>

File inc/libs/twig/Autoloader.php

  • Ignore whitespace
-<?php
-
-/*
- * This file is part of Twig.
- *
- * (c) 2009 Fabien Potencier
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-/**
- * Autoloads Twig classes.
- *
- * @package twig
- * @author  Fabien Potencier <fabien.potencier@symfony-project.com>
- */
-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')) {
-            return;
-        }
-
-        if (file_exists($file = dirname(__FILE__).'/../'.str_replace('_', '/', $class).'.php')) {
-            require $file;
-        }
-    }
-}

File inc/libs/twig/CHANGELOG

  • Ignore whitespace
-* 1.0.0 (2011-03-27)
-
-Changes:
-
- * fixed output when using mbstring
- * fixed duplicate call of methods when using the sandbox
- * made the charset configurable for the escape filter
-
-* 1.0.0-RC2 (2011-02-21)
-
-Changes:
-
- * changed the way {% set %} works when capturing (the content is now marked as safe)
- * added support for macro name in the endmacro tag
- * make Twig_Error compatible with PHP 5.3.0 >
- * fixed an infinite loop on some Windows configurations
- * fixed the "length" filter for numbers
- * fixed Template::getAttribute() as properties in PHP are case sensitive
- * removed coupling between Twig_Node and Twig_Template
- * fixed the ternary operator precedence rule
-
-* 1.0.0-RC1 (2011-01-09)
-
-Backward incompatibilities:
-
- * the "items" filter, which has been deprecated for quite a long time now, has been removed
- * the "range" filter has been converted to a function: 0|range(10) -> range(0, 10)
- * the "constant" filter has been converted to a function: {{ some_date|date('DATE_W3C'|constant) }} -> {{ some_date|date(constant('DATE_W3C')) }}
- * the "cycle" filter has been converted to a function: {{ ['odd', 'even']|cycle(i) }} -> {{ cycle(['odd', 'even'], i) }}
- * the "for" tag does not support "joined by" anymore
- * the "autoescape" first argument is now "true"/"false" (instead of "on"/"off")
- * the "parent" tag has been replaced by a "parent" function ({{ parent() }} instead of {% parent %})
- * the "display" tag has been replaced by a "block" function ({{ block('title') }} instead of {% display title %})
- * removed the grammar and simple token parser (moved to the Twig Extensions repository)
-
-Changes:
-
- * added "needs_context" option for filters and functions (the context is then passed as a first argument)
- * added global variables support
- * made macros return their value instead of echoing directly (fixes calling a macro in sandbox mode)
- * added the "from" tag to import macros as functions
- * added support for functions (a function is just syntactic sugar for a getAttribute() call)
- * made macros callable when sandbox mode is enabled
- * added an exception when a macro uses a reserved name
- * the "default" filter now uses the "empty" test instead of just checking for null
- * added the "empty" test
-
-* 0.9.10 (2010-12-16)
-
-Backward incompatibilities:
-
- * The Escaper extension is enabled by default, which means that all displayed
-   variables are now automatically escaped. You can revert to the previous
-   behavior by removing the extension via $env->removeExtension('escaper')
-   or just set the 'autoescape' option to 'false'.
- * removed the "without loop" attribute for the "for" tag (not needed anymore
-   as the Optimizer take care of that for most cases)
- * arrays and hashes have now a different syntax
-     * arrays keep the same syntax with square brackets: [1, 2]
-     * hashes now use curly braces (["a": "b"] should now be written as {"a": "b"})
-     * support for "arrays with keys" and "hashes without keys" is not supported anymore ([1, "foo": "bar"] or {"foo": "bar", 1})
- * the i18n extension is now part of the Twig Extensions repository
-
-Changes:
-
- * added the merge filter
- * removed 'is_escaper' option for filters (a left over from the previous version) -- you must use 'is_safe' now instead
- * fixed usage of operators as method names (like is, in, and not)
- * changed the order of execution for node visitors
- * fixed default() filter behavior when used with strict_variables set to on
- * fixed filesystem loader compatibility with PHAR files
- * enhanced error messages when an unexpected token is parsed in an expression
- * fixed filename not being added to syntax error messages
- * added the autoescape option to enable/disable autoescaping
- * removed the newline after a comment (mimicks PHP behavior)
- * added a syntax error exception when parent block is used on a template that does not extend another one
- * made the Escaper extension enabled by default
- * fixed sandbox extension when used with auto output escaping
- * fixed escaper when wrapping a Twig_Node_Print (the original class must be preserved)
- * added an Optimizer extension (enabled by default; optimizes "for" loops and "raw" filters)
- * added priority to node visitors
-
-* 0.9.9 (2010-11-28)
-
-Backward incompatibilities:
- * the self special variable has been renamed to _self
- * the odd and even filters are now tests:
-     {{ foo|odd }} must now be written {{ foo is odd }}
- * the "safe" filter has been renamed to "raw"
- * in Node classes,
-        sub-nodes are now accessed via getNode() (instead of property access)
-        attributes via getAttribute() (instead of array access)
- * the urlencode filter had been renamed to url_encode
- * the include tag now merges the passed variables with the current context by default
-   (the old behavior is still possible by adding the "only" keyword)
- * moved Exceptions to Twig_Error_* (Twig_SyntaxError/Twig_RuntimeError are now Twig_Error_Syntax/Twig_Error_Runtime)
- * removed support for {{ 1 < i < 3 }} (use {{ i > 1 and i < 3 }} instead)
- * the "in" filter has been removed ({{ a|in(b) }} should now be written {{ a in b }})
-
-Changes:
- * added file and line to Twig_Error_Runtime exceptions thrown from Twig_Template
- * changed trans tag to accept any variable for the plural count
- * fixed sandbox mode (__toString() method check was not enforced if called implicitly from complex statements)
- * added the ** (power) operator
- * changed the algorithm used for parsing expressions
- * added the spaceless tag
- * removed trim_blocks option
- * added support for is*() methods for attributes (foo.bar now looks for foo->getBar() or foo->isBar())
- * changed all exceptions to extend Twig_Error
- * fixed unary expressions ({{ not(1 or 0) }})
- * fixed child templates (with an extend tag) that uses one or more imports
- * added support for {{ 1 not in [2, 3] }} (more readable than the current {{ not (1 in [2, 3]) }})
- * escaping has been rewritten
- * the implementation of template inheritance has been rewritten
-   (blocks can now be called individually and still work with inheritance)
- * fixed error handling for if tag when a syntax error occurs within a subparse process
- * added a way to implement custom logic for resolving token parsers given a tag name
- * fixed js escaper to be stricter (now uses a whilelist-based js escaper)
- * added the following filers: "constant", "trans", "replace", "json_encode"
- * added a "constant" test
- * fixed objects with __toString() not being autoescaped
- * fixed subscript expressions when calling __call() (methods now keep the case)
- * added "test" feature (accessible via the "is" operator)
- * removed the debug tag (should be done in an extension)
- * fixed trans tag when no vars are used in plural form
- * fixed race condition when writing template cache
- * added the special _charset variable to reference the current charset
- * added the special _context variable to reference the current context
- * renamed self to _self (to avoid conflict)
- * fixed Twig_Template::getAttribute() for protected properties
-
-* 0.9.8 (2010-06-28)
-
-Backward incompatibilities:
- * the trans tag plural count is now attached to the plural tag:
-    old: `{% trans count %}...{% plural %}...{% endtrans %}`
-    new: `{% trans %}...{% plural count %}...{% endtrans %}`
-
- * added a way to translate strings coming from a variable ({% trans var %})
- * fixed trans tag when used with the Escaper extension
- * fixed default cache umask
- * removed Twig_Template instances from the debug tag output
- * fixed objects with __isset() defined
- * fixed set tag when used with a capture
- * fixed type hinting for Twig_Environment::addFilter() method
-
-* 0.9.7 (2010-06-12)
-
-Backward incompatibilities:
- * changed 'as' to '=' for the set tag ({% set title as "Title" %} must now be {% set title = "Title" %})
- * removed the sandboxed attribute of the include tag (use the new sandbox tag instead)
- * refactored the Node system (if you have custom nodes, you will have to update them to use the new API)
-
- * added self as a special variable that refers to the current template (useful for importing macros from the current template)
- * added Twig_Template instance support to the include tag
- * added support for dynamic and conditional inheritance ({% extends some_var %} and {% extends standalone ? "minimum" : "base" %})
- * added a grammar sub-framework to ease the creation of custom tags
- * fixed the for tag for large arrays (some loop variables are now only available for arrays and objects that implement the Countable interface)
- * removed the Twig_Resource::resolveMissingFilter() method
- * fixed the filter tag which did not apply filtering to included files
- * added a bunch of unit tests
- * added a bunch of phpdoc
- * added a sandbox tag in the sandbox extension
- * changed the date filter to support any date format supported by DateTime
- * added strict_variable setting to throw an exception when an invalid variable is used in a template (disabled by default)
- * added the lexer, parser, and compiler as arguments to the Twig_Environment constructor
- * changed the cache option to only accepts an explicit path to a cache directory or false
- * added a way to add token parsers, filters, and visitors without creating an extension
- * added three interfaces: Twig_NodeInterface, Twig_TokenParserInterface, and Twig_FilterInterface
- * changed the generated code to match the new coding standards
- * fixed sandbox mode (__toString() method check was not enforced if called implicitly from a simple statement like {{ article }})
- * added an exception when a child template has a non-empty body (as it is always ignored when rendering)
-
-* 0.9.6 (2010-05-12)
-
- * fixed variables defined outside a loop and for which the value changes in a for loop
- * fixed the test suite for PHP 5.2 and older versions of PHPUnit
- * added support for __call() in expression resolution
- * fixed node visiting for macros (macros are now visited by visitors as any other node)
- * fixed nested block definitions with a parent call (rarely useful but nonetheless supported now)
- * added the cycle filter
- * fixed the Lexer when mbstring.func_overload is used with an mbstring.internal_encoding different from ASCII
- * added a long-syntax for the set tag ({% set foo %}...{% endset %})
- * unit tests are now powered by PHPUnit
- * added support for gettext via the `i18n` extension
- * fixed twig_capitalize_string_filter() and fixed twig_length_filter() when used with UTF-8 values
- * added a more useful exception if an if tag is not closed properly
- * added support for escaping strategy in the autoescape tag
- * fixed lexer when a template has a big chunk of text between/in a block
-
-* 0.9.5 (2010-01-20)
-
-As for any new release, don't forget to remove all cached templates after
-upgrading.
-
-If you have defined custom filters, you MUST upgrade them for this release. To
-upgrade, replace "array" with "new Twig_Filter_Function", and replace the
-environment constant by the "needs_environment" option:
-
-  // before
-  'even'   => array('twig_is_even_filter', false),
-  'escape' => array('twig_escape_filter', true),
-
-  // after
-  'even'   => new Twig_Filter_Function('twig_is_even_filter'),
-  'escape' => new Twig_Filter_Function('twig_escape_filter', array('needs_environment' => true)),
-
-If you have created NodeTransformer classes, you will need to upgrade them to
-the new interface (please note that the interface is not yet considered
-stable).
-
- * fixed list nodes that did not extend the Twig_NodeListInterface
- * added the "without loop" option to the for tag (it disables the generation of the loop variable)
- * refactored node transformers to node visitors
- * fixed automatic-escaping for blocks
- * added a way to specify variables to pass to an included template
- * changed the automatic-escaping rules to be more sensible and more configurable in custom filters (the documentation lists all the rules)
- * improved the filter system to allow object methods to be used as filters
- * changed the Array and String loaders to actually make use of the cache mechanism
- * included the default filter function definitions in the extension class files directly (Core, Escaper)
- * added the // operator (like the floor() PHP function)
- * added the .. operator (as a syntactic sugar for the range filter when the step is 1)
- * added the in operator (as a syntactic sugar for the in filter)
- * added the following filters in the Core extension: in, range
- * added support for arrays (same behavior as in PHP, a mix between lists and dictionaries, arrays and hashes)
- * enhanced some error messages to provide better feedback in case of parsing errors
-
-* 0.9.4 (2009-12-02)
-
-If you have custom loaders, you MUST upgrade them for this release: The
-Twig_Loader base class has been removed, and the Twig_LoaderInterface has also
-been changed (see the source code for more information or the documentation).
-
- * added support for DateTime instances for the date filter
- * fixed loop.last when the array only has one item
- * made it possible to insert newlines in tag and variable blocks
- * fixed a bug when a literal '\n' were present in a template text
- * fixed bug when the filename of a template contains */
- * refactored loaders
-
-* 0.9.3 (2009-11-11)
-
-This release is NOT backward compatible with the previous releases.
-
-  The loaders do not take the cache and autoReload arguments anymore. Instead,
-  the Twig_Environment class has two new options: cache and auto_reload.
-  Upgrading your code means changing this kind of code:
-
-      $loader = new Twig_Loader_Filesystem('/path/to/templates', '/path/to/compilation_cache', true);
-      $twig = new Twig_Environment($loader);
-
-  to something like this:
-
-      $loader = new Twig_Loader_Filesystem('/path/to/templates');
-      $twig = new Twig_Environment($loader, array(
-        'cache' => '/path/to/compilation_cache',
-        'auto_reload' => true,
-      ));
-
- * deprecated the "items" filter as it is not needed anymore
- * made cache and auto_reload options of Twig_Environment instead of arguments of Twig_Loader
- * optimized template loading speed
- * removed output when an error occurs in a template and render() is used
- * made major speed improvements for loops (up to 300% on even the smallest loops)
- * added properties as part of the sandbox mode
- * added public properties support (obj.item can now be the item property on the obj object)
- * extended set tag to support expression as value ({% set foo as 'foo' ~ 'bar' %} )
- * fixed bug when \ was used in HTML
-
-* 0.9.2 (2009-10-29)
-
- * made some speed optimizations
- * changed the cache extension to .php
- * added a js escaping strategy
- * added support for short block tag
- * changed the filter tag to allow chained filters
- * made lexer more flexible as you can now change the default delimiters
- * added set tag
- * changed default directory permission when cache dir does not exist (more secure)
- * added macro support
- * changed filters first optional argument to be a Twig_Environment instance instead of a Twig_Template instance
- * made Twig_Autoloader::autoload() a static method
- * avoid writing template file if an error occurs
- * added $ escaping when outputting raw strings
- * enhanced some error messages to ease debugging
- * fixed empty cache files when the template contains an error
-
-* 0.9.1 (2009-10-14)
-
-  * fixed a bug in PHP 5.2.6
-  * fixed numbers with one than one decimal
-  * added support for method calls with arguments ({{ foo.bar('a', 43) }})
-  * made small speed optimizations
-  * made minor tweaks to allow better extensibility and flexibility
-
-* 0.9.0 (2009-10-12)
-
- * Initial release

File inc/libs/twig/Compiler.php

  • Ignore whitespace
-<?php
-
-/*
- * This file is part of Twig.
- *
- * (c) 2009 Fabien Potencier
- * (c) 2009 Armin Ronacher
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-/**
- * Compiles a node to PHP code.
- *
- * @package    twig
- * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
- */
-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)
-    {
-        $this->env = $env;
-    }
-
-    /**
-     * Returns the environment instance related to this compiler.
-     *
-     * @return Twig_Environment The environment instance
-     */
-    public function getEnvironment()
-    {
-        return $this->env;
-    }
-
-    /**
-     * Gets the current PHP code after compilation.
-     *
-     * @return string The PHP code
-     */
-    public function getSource()
-    {
-        return $this->source;
-    }
-
-    /**
-     * Compiles a node.
-     *
-     * @param Twig_NodeInterface $node   The node to compile
-     * @param integer            $indent The current indentation
-     *
-     * @return Twig_Compiler The current compiler instance
-     */
-    public function compile(Twig_NodeInterface $node, $indentation = 0)
-    {
-        $this->lastLine = null;
-        $this->source = '';
-        $this->indentation = $indentation;
-
-        $node->compile($this);
-
-        return $this;
-    }
-
-    public function subcompile(Twig_NodeInterface $node, $raw = true)
-    {
-        if (false === $raw)
-        {
-            $this->addIndentation();
-        }
-
-        $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->addIndentation();
-            $this->source .= $string;
-        }
-
-        return $this;
-    }
-
-    public function addIndentation()
-    {
-        $this->source .= str_repeat(' ', $this->indentation * 4);
-
-        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 (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;
-    }
-
-    /**
-     * Adds debugging information.
-     *
-     * @param Twig_NodeInterface $node The related twig node
-     *
-     * @return Twig_Compiler The current compiler instance
-     */
-    public function addDebugInfo(Twig_NodeInterface $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;
-
-        if ($this->indentation < 0) {
-            throw new Twig_Error('Unable to call outdent() as the indentation would become negative');
-        }
-
-        return $this;
-    }
-}

File inc/libs/twig/CompilerInterface.php

  • Ignore whitespace
-<?php
-
-/*
- * This file is part of Twig.
- *
- * (c) 2009 Fabien Potencier
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-/**
- * Interface implemented by compiler classes.
- *
- * @package    twig
- * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
- */
-interface Twig_CompilerInterface
-{
-    /**
-     * Compiles a node.
-     *
-     * @param  Twig_NodeInterface $node The node to compile
-     *
-     * @return Twig_CompilerInterface The current compiler instance
-     */
-    function compile(Twig_NodeInterface $node);
-
-    /**
-     * Gets the current PHP code after compilation.
-     *
-     * @return string The PHP code
-     */
-    function getSource();
-}

File inc/libs/twig/Environment.php

  • Ignore whitespace
-<?php
-
-/*
- * This file is part of Twig.
- *
- * (c) 2009 Fabien Potencier
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-/**
- * Stores the Twig configuration.
- *
- * @package twig
- * @author  Fabien Potencier <fabien.potencier@symfony-project.com>
- */
-class Twig_Environment
-{
-    const VERSION = '1.0.0-RC2';
-
-    protected $charset;
-    protected $loader;
-    protected $debug;
-    protected $autoReload;
-    protected $cache;
-    protected $lexer;
-    protected $parser;
-    protected $compiler;
-    protected $baseTemplateClass;
-    protected $extensions;
-    protected $parsers;
-    protected $visitors;
-    protected $filters;
-    protected $tests;
-    protected $functions;
-    protected $globals;
-    protected $runtimeInitialized;
-    protected $loadedTemplates;
-    protected $strictVariables;
-    protected $unaryOperators;
-    protected $binaryOperators;
-    protected $templateClassPrefix = '__TwigTemplate_';
-    protected $functionCallbacks;
-    protected $filterCallbacks;
-
-    /**
-     * 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).
-     *
-     *  * 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: An absolute path where to store the compiled templates, or
-     *           false to disable compilation cache (default)
-     *
-     *  * 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.
-     *
-     *  * strict_variables: Whether to ignore invalid variables in templates
-     *                      (default to false).
-     *
-     *  * autoescape: Whether to enable auto-escaping (default to true);
-     *
-     *  * optimizations: A flag that indicates which optimizations to apply
-     *                   (default to -1 which means that all optimizations are enabled;
-     *                   set it to 0 to disable)
-     *
-     * @param Twig_LoaderInterface   $loader  A Twig_LoaderInterface instance
-     * @param array                  $options An array of options
-     */
-    public function __construct(Twig_LoaderInterface $loader = null, $options = array())
-    {
-        if (null !== $loader) {
-            $this->setLoader($loader);
-        }
-
-        $options = array_merge(array(
-            'debug'               => false,
-            'charset'             => 'UTF-8',
-            'base_template_class' => 'Twig_Template',
-            'strict_variables'    => false,
-            'autoescape'          => true,
-            'cache'               => false,
-            'auto_reload'         => null,
-            'optimizations'       => -1,
-        ), $options);
-
-        $this->debug              = (bool) $options['debug'];
-        $this->charset            = $options['charset'];
-        $this->baseTemplateClass  = $options['base_template_class'];
-        $this->autoReload         = null === $options['auto_reload'] ? $this->debug : (bool) $options['auto_reload'];
-        $this->extensions         = array(
-            'core'      => new Twig_Extension_Core(),
-            'escaper'   => new Twig_Extension_Escaper((bool) $options['autoescape']),
-            'optimizer' => new Twig_Extension_Optimizer($options['optimizations']),
-        );
-        $this->strictVariables    = (bool) $options['strict_variables'];
-        $this->runtimeInitialized = false;
-        $this->setCache($options['cache']);
-        $this->functionCallbacks = array();
-        $this->filterCallbacks = array();
-    }
-
-    /**
-     * Gets the base template class for compiled templates.
-     *
-     * @return string The base template class name
-     */
-    public function getBaseTemplateClass()
-    {
-        return $this->baseTemplateClass;
-    }
-
-    /**
-     * Sets the base template class for compiled templates.
-     *
-     * @param string $class The base template class name
-     */
-    public function setBaseTemplateClass($class)
-    {
-        $this->baseTemplateClass = $class;
-    }
-
-    /**
-     * Enables debugging mode.
-     */
-    public function enableDebug()
-    {
-        $this->debug = true;
-    }
-
-    /**
-     * Disables debugging mode.
-     */
-    public function disableDebug()
-    {
-        $this->debug = false;
-    }
-
-    /**
-     * Checks if debug mode is enabled.
-     *
-     * @return Boolean true if debug mode is enabled, false otherwise
-     */
-    public function isDebug()
-    {
-        return $this->debug;
-    }
-
-    /**
-     * Enables the auto_reload option.
-     */
-    public function enableAutoReload()
-    {
-        $this->autoReload = true;
-    }
-
-    /**
-     * Disables the auto_reload option.
-     */
-    public function disableAutoReload()
-    {
-        $this->autoReload = false;
-    }
-
-    /**
-     * Checks if the auto_reload option is enabled.
-     *
-     * @return Boolean true if auto_reload is enabled, false otherwise
-     */
-    public function isAutoReload()
-    {
-        return $this->autoReload;
-    }
-
-    /**
-     * Enables the strict_variables option.
-     */
-    public function enableStrictVariables()
-    {
-        $this->strictVariables = true;
-    }
-
-    /**
-     * Disables the strict_variables option.
-     */
-    public function disableStrictVariables()
-    {
-        $this->strictVariables = false;
-    }
-
-    /**
-     * Checks if the strict_variables option is enabled.
-     *
-     * @return Boolean true if strict_variables is enabled, false otherwise
-     */
-    public function isStrictVariables()
-    {
-        return $this->strictVariables;
-    }
-
-    /**
-     * Gets the cache directory or false if cache is disabled.
-     *
-     * @return string|false
-     */
-    public function getCache()
-    {
-        return $this->cache;
-    }
-
-     /**
-      * Sets the cache directory or false if cache is disabled.
-      *
-      * @param string|false $cache The absolute path to the compiled templates,
-      *                            or false to disable cache
-      */
-    public function setCache($cache)
-    {
-        $this->cache = $cache ? $cache : false;
-    }
-
-    /**
-     * Gets the cache filename for a given template.
-     *
-     * @param string $name The template name
-     *
-     * @return string The cache file name
-     */
-    public function getCacheFilename($name)
-    {
-        if (false === $this->cache) {
-            return false;
-        }
-
-        $class = substr($this->getTemplateClass($name), strlen($this->templateClassPrefix));
-
-        return $this->getCache().'/'.substr($class, 0, 2).'/'.substr($class, 2, 2).'/'.substr($class, 4).'.php';
-    }
-
-    /**
-     * 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 $this->templateClassPrefix.md5($this->loader->getCacheKey($name));
-    }
-
-    /**
-     * Gets the template class prefix.
-     *
-     * @return string The template class prefix
-     */
-    public function getTemplateClassPrefix()
-    {
-        return $this->templateClassPrefix;
-    }
-
-    /**
-     * Renders a template.
-     *
-     * @param string $name    The template name
-     * @param array  $context An array of parameters to pass to the template
-     *
-     * @return string The rendered template
-     */
-    public function render($name, array $context = array())
-    {
-        return $this->loadTemplate($name)->render($context);
-    }
-
-    /**
-     * 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)))) {
-                    $this->writeCacheFile($cache, $this->compileSource($this->loader->getSource($name), $name));
-                }
-
-                require_once $cache;
-            }
-        }
-
-        if (!$this->runtimeInitialized) {
-            $this->initRuntime();
-        }
-
-        return $this->loadedTemplates[$cls] = new $cls($this);
-    }
-
-    /**
-     * Clears the internal template cache.
-     */
-    public function clearTemplateCache()
-    {
-        $this->loadedTemplates = array();
-    }
-
-    /**
-     * Clears the template cache files on the filesystem.
-     */
-    public function clearCacheFiles()
-    {
-        if (false === $this->cache) {
-            return;
-        }
-
-        foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->cache), RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
-            if ($file->isFile()) {
-                @unlink($file->getPathname());
-            }
-        }
-    }
-
-    /**
-     * Gets the Lexer instance.
-     *
-     * @return Twig_LexerInterface A Twig_LexerInterface instance
-     */
-    public function getLexer()
-    {
-        if (null === $this->lexer) {
-            $this->lexer = new Twig_Lexer($this);
-        }
-
-        return $this->lexer;
-    }
-
-    /**
-     * Sets the Lexer instance.
-     *
-     * @param Twig_LexerInterface A Twig_LexerInterface instance
-     */
-    public function setLexer(Twig_LexerInterface $lexer)
-    {
-        $this->lexer = $lexer;
-    }
-
-    /**
-     * Tokenizes a source code.
-     *
-     * @param string $source The template source code
-     * @param string $name   The template name
-     *
-     * @return Twig_TokenStream A Twig_TokenStream instance
-     */
-    public function tokenize($source, $name = null)
-    {
-        return $this->getLexer()->tokenize($source, $name);
-    }
-
-    /**
-     * Gets the Parser instance.
-     *
-     * @return Twig_ParserInterface A Twig_ParserInterface instance
-     */
-    public function getParser()
-    {
-        if (null === $this->parser) {
-            $this->parser = new Twig_Parser($this);
-        }
-
-        return $this->parser;
-    }
-
-    /**
-     * Sets the Parser instance.
-     *
-     * @param Twig_ParserInterface A Twig_ParserInterface instance
-     */
-    public function setParser(Twig_ParserInterface $parser)
-    {
-        $this->parser = $parser;
-    }
-
-    /**
-     * Parses a token stream.
-     *
-     * @param Twig_TokenStream $tokens A Twig_TokenStream instance
-     *
-     * @return Twig_Node_Module A Node tree
-     */
-    public function parse(Twig_TokenStream $tokens)
-    {
-        return $this->getParser()->parse($tokens);
-    }
-
-    /**
-     * Gets the Compiler instance.
-     *
-     * @return Twig_CompilerInterface A Twig_CompilerInterface instance
-     */
-    public function getCompiler()
-    {
-        if (null === $this->compiler) {
-            $this->compiler = new Twig_Compiler($this);
-        }
-
-        return $this->compiler;
-    }
-
-    /**
-     * Sets the Compiler instance.
-     *
-     * @param Twig_CompilerInterface $compiler A Twig_CompilerInterface instance
-     */
-    public function setCompiler(Twig_CompilerInterface $compiler)
-    {
-        $this->compiler = $compiler;
-    }
-
-    /**
-     * Compiles a Node.
-     *
-     * @param Twig_NodeInterface $node A Twig_NodeInterface instance
-     *
-     * @return string The compiled PHP source code
-     */
-    public function compile(Twig_NodeInterface $node)
-    {
-        return $this->getCompiler()->compile($node)->getSource();
-    }
-
-    /**
-     * Compiles a template source code.
-     *
-     * @param string $source The template source code
-     * @param string $name   The template name
-     *
-     * @return string The compiled PHP source code
-     */
-    public function compileSource($source, $name = null)
-    {
-        return $this->compile($this->parse($this->tokenize($source, $name)));
-    }
-
-    /**
-     * Sets the Loader instance.
-     *
-     * @param Twig_LoaderInterface $loader A Twig_LoaderInterface instance
-     */
-    public function setLoader(Twig_LoaderInterface $loader)
-    {
-        $this->loader = $loader;
-    }
-
-    /**
-     * Gets the Loader instance.
-     *
-     * @return Twig_LoaderInterface A Twig_LoaderInterface instance
-     */
-    public function getLoader()
-    {
-        return $this->loader;
-    }
-
-    /**
-     * Sets the default template charset.
-     *
-     * @param string $charset The default charset
-     */
-    public function setCharset($charset)
-    {
-        $this->charset = $charset;
-    }
-
-    /**
-     * Gets the default template charset.
-     *
-     * @return string The default charset
-     */
-    public function getCharset()
-    {
-        return $this->charset;
-    }
-
-    /**
-     * Initializes the runtime environment.
-     */
-    public function initRuntime()
-    {
-        $this->runtimeInitialized = true;
-
-        foreach ($this->getExtensions() as $extension) {
-            $extension->initRuntime($this);
-        }
-    }
-
-    /**
-     * Returns true if the given extension is registered.
-     *
-     * @param string $name The extension name
-     *
-     * @return Boolean Whether the extension is registered or not
-     */
-    public function hasExtension($name)
-    {
-        return isset($this->extensions[$name]);
-    }
-
-    /**
-     * Gets an extension by name.
-     *
-     * @param string $name The extension name
-     *
-     * @return Twig_ExtensionInterface A Twig_ExtensionInterface instance
-     */
-    public function getExtension($name)
-    {
-        if (!isset($this->extensions[$name])) {
-            throw new Twig_Error_Runtime(sprintf('The "%s" extension is not enabled.', $name));
-        }
-
-        return $this->extensions[$name];
-    }
-
-    /**
-     * Registers an extension.
-     *
-     * @param Twig_ExtensionInterface $extension A Twig_ExtensionInterface instance
-     */
-    public function addExtension(Twig_ExtensionInterface $extension)
-    {
-        $this->extensions[$extension->getName()] = $extension;
-    }
-
-    /**
-     * Removes an extension by name.
-     *
-     * @param string $name The extension name
-     */
-    public function removeExtension($name)
-    {
-        unset($this->extensions[$name]);
-    }
-
-    /**
-     * Registers an array of extensions.
-     *
-     * @param array $extensions An array of extensions
-     */
-    public function setExtensions(array $extensions)
-    {
-        foreach ($extensions as $extension) {
-            $this->addExtension($extension);
-        }
-    }
-
-    /**
-     * Returns all registered extensions.
-     *
-     * @return array An array of extensions
-     */
-    public function getExtensions()
-    {
-        return $this->extensions;
-    }
-
-    /**
-     * Registers a Token Parser.
-     *
-     * @param Twig_TokenParserInterface $parser A Twig_TokenParserInterface instance
-     */
-    public function addTokenParser(Twig_TokenParserInterface $parser)
-    {
-        if (null === $this->parsers) {
-            $this->getTokenParsers();
-        }
-
-        $this->parsers->addTokenParser($parser);
-    }
-
-    /**
-     * Gets the registered Token Parsers.
-     *
-     * @return Twig_TokenParserInterface[] An array of Twig_TokenParserInterface instances
-     */
-    public function getTokenParsers()
-    {
-        if (null === $this->parsers) {
-            $this->parsers = new Twig_TokenParserBroker;
-            foreach ($this->getExtensions() as $extension) {
-                $parsers = $extension->getTokenParsers();
-                foreach($parsers as $parser) {
-                    if ($parser instanceof Twig_TokenParserInterface) {
-                        $this->parsers->addTokenParser($parser);
-                    } else if ($parser instanceof Twig_TokenParserBrokerInterface) {
-                        $this->parsers->addTokenParserBroker($parser);
-                    } else {
-                        throw new Twig_Error_Runtime('getTokenParsers() must return an array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances');
-                    }
-                }
-            }
-        }
-
-        return $this->parsers;
-    }
-
-    /**
-     * Registers a Node Visitor.
-     *
-     * @param Twig_NodeVisitorInterface $visitor A Twig_NodeVisitorInterface instance
-     */
-    public function addNodeVisitor(Twig_NodeVisitorInterface $visitor)
-    {
-        if (null === $this->visitors) {
-            $this->getNodeVisitors();
-        }
-
-        $this->visitors[] = $visitor;
-    }
-
-    /**
-     * Gets the registered Node Visitors.
-     *
-     * @return Twig_NodeVisitorInterface[] An array of Twig_NodeVisitorInterface instances
-     */
-    public function getNodeVisitors()
-    {
-        if (null === $this->visitors) {
-            $this->visitors = array();
-            foreach ($this->getExtensions() as $extension) {
-                $this->visitors = array_merge($this->visitors, $extension->getNodeVisitors());
-            }
-        }
-
-        return $this->visitors;
-    }
-
-    /**
-     * Registers a Filter.
-     *
-     * @param string               $name    The filter name
-     * @param Twig_FilterInterface $visitor A Twig_FilterInterface instance
-     */
-    public function addFilter($name, Twig_FilterInterface $filter)
-    {
-        if (null === $this->filters) {
-            $this->loadFilters();
-        }
-
-        $this->filters[$name] = $filter;
-    }
-
-    /**
-     * Get a filter by name.
-     *
-     * Subclasses may override this method and load filters differently;
-     * so no list of filters is available.
-     *
-     * @param string $name The filter name
-     *
-     * @return Twig_Filter|false A Twig_Filter instance or false if the filter does not exists
-     */
-    public function getFilter($name)
-    {
-        if (null === $this->filters) {
-            $this->loadFilters();
-        }
-
-        if (isset($this->filters[$name])) {
-            return $this->filters[$name];
-        }
-
-        foreach ($this->filterCallbacks as $callback) {
-            if (false !== $filter = call_user_func($callback, $name)) {
-                return $filter;
-            }
-        }
-
-        return false;
-    }
-
-    public function registerUndefinedFilterCallback($callable)
-    {
-        $this->filterCallbacks[] = $callable;
-    }
-
-    /**
-     * Gets the registered Filters.
-     *
-     * @return Twig_FilterInterface[] An array of Twig_FilterInterface instances
-     */
-    protected function loadFilters()
-    {
-        $this->filters = array();
-        foreach ($this->getExtensions() as $extension) {
-            $this->filters = array_merge($this->filters, $extension->getFilters());
-        }
-    }
-
-    /**
-     * Registers a Test.
-     *
-     * @param string             $name    The test name
-     * @param Twig_TestInterface $visitor A Twig_TestInterface instance
-     */
-    public function addTest($name, Twig_TestInterface $test)
-    {
-        if (null === $this->tests) {
-            $this->getTests();
-        }
-
-        $this->tests[$name] = $test;
-    }
-
-    /**
-     * Gets the registered Tests.
-     *
-     * @return Twig_TestInterface[] An array of Twig_TestInterface instances
-     */
-    public function getTests()
-    {
-        if (null === $this->tests) {
-            $this->tests = array();
-            foreach ($this->getExtensions() as $extension) {
-                $this->tests = array_merge($this->tests, $extension->getTests());
-            }
-        }
-
-        return $this->tests;
-    }
-
-    /**
-     * Registers a Function.
-     *
-     * @param string                 $name     The function name
-     * @param Twig_FunctionInterface $function A Twig_FunctionInterface instance
-     */
-    public function addFunction($name, Twig_FunctionInterface $function)
-    {
-        if (null === $this->functions) {
-            $this->loadFunctions();
-        }
-
-        $this->functions[$name] = $function;
-    }
-
-    /**
-     * Get a function by name.
-     *
-     * Subclasses may override this method and load functions differently;
-     * so no list of functions is available.
-     *
-     * @param string $name function name
-     *
-     * @return Twig_Function|false A Twig_Function instance or false if the function does not exists
-     */
-    public function getFunction($name)
-    {
-        if (null === $this->functions) {
-            $this->loadFunctions();
-        }
-
-        if (isset($this->functions[$name])) {
-            return $this->functions[$name];
-        }
-
-        foreach ($this->functionCallbacks as $callback) {
-            if (false !== $function = call_user_func($callback, $name)) {
-                return $function;
-            }
-        }
-
-        return false;
-    }
-
-    public function registerUndefinedFunctionCallback($callable)
-    {
-        $this->functionCallbacks[] = $callable;
-    }
-
-    protected function loadFunctions() {
-        $this->functions = array();
-        foreach ($this->getExtensions() as $extension) {
-            $this->functions = array_merge($this->functions, $extension->getFunctions());
-        }
-    }
-
-    /**
-     * Registers a Global.
-     *
-     * @param string $name  The global name
-     * @param mixed  $value The global value
-     */
-    public function addGlobal($name, $value)
-    {
-        if (null === $this->globals) {
-            $this->getGlobals();
-        }
-
-        $this->globals[$name] = $value;
-    }
-
-    /**
-     * Gets the registered Globals.
-     *
-     * @return array An array of globals
-     */
-    public function getGlobals()
-    {
-        if (null === $this->globals) {
-            $this->globals = array();
-            foreach ($this->getExtensions() as $extension) {
-                $this->globals = array_merge($this->globals, $extension->getGlobals());
-            }
-        }
-
-        return $this->globals;
-    }
-
-    /**
-     * Gets the registered unary Operators.
-     *
-     * @return array An array of unary operators
-     */
-    public function getUnaryOperators()
-    {
-        if (null === $this->unaryOperators) {
-            $this->initOperators();
-        }
-
-        return $this->unaryOperators;
-    }
-
-    /**
-     * Gets the registered binary Operators.
-     *
-     * @return array An array of binary operators
-     */
-    public function getBinaryOperators()
-    {
-        if (null === $this->binaryOperators) {
-            $this->initOperators();
-        }
-
-        return $this->binaryOperators;
-    }
-
-    protected function initOperators()
-    {
-        $this->unaryOperators = array();
-        $this->binaryOperators = array();
-        foreach ($this->getExtensions() as $extension) {
-            $operators = $extension->getOperators();
-
-            if (!$operators) {
-                continue;
-            }
-
-            if (2 !== count($operators)) {
-                throw new InvalidArgumentException(sprintf('"%s::getOperators()" does not return a valid operators array.', get_class($extension)));
-            }
-
-            $this->unaryOperators = array_merge($this->unaryOperators, $operators[0]);
-            $this->binaryOperators = array_merge($this->binaryOperators, $operators[1]);
-        }
-    }
-
-    protected function writeCacheFile($file, $content)
-    {
-        if (!is_dir(dirname($file))) {
-            mkdir(dirname($file), 0777, true);
-        }
-
-        $tmpFile = tempnam(dirname($file), basename($file));
-        if (false !== @file_put_contents($tmpFile, $content)) {
-            // rename does not work on Win32 before 5.2.6
-            if (@rename($tmpFile, $file) || (@copy($tmpFile, $file) && unlink($tmpFile))) {
-                chmod($file, 0644);
-
-                return;
-            }
-        }
-
-        throw new Twig_Error_Runtime(sprintf('Failed to write cache file "%s".', $file));
-    }
-}

File inc/libs/twig/Error.php

  • Ignore whitespace
-<?php
-
-/*
- * This file is part of Twig.
- *
- * (c) 2009 Fabien Potencier
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-/**
- * Twig base exception.
- *
- * @package    twig
- * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
- */
-class Twig_Error extends Exception
-{
-    protected $lineno;
-    protected $filename;
-    protected $rawMessage;
-    protected $previous;
-
-    /**
-     * Constructor.
-     *
-     * @param string    $message  The error message
-     * @param integer   $lineno   The template line where the error occurred
-     * @param string    $filename The template file name where the error occurred
-     * @param Exception $previous The previous exception
-     */
-    public function __construct($message, $lineno = -1, $filename = null, Exception $previous = null)
-    {
-        $this->lineno = $lineno;
-        $this->filename = $filename;
-        $this->rawMessage = $message;
-
-        $this->updateRepr();
-
-        if (version_compare(PHP_VERSION, '5.3.0', '<')) {
-            $this->previous = $previous;
-            parent::__construct($this->message);
-        } else {
-            parent::__construct($this->message, 0, $previous);
-        }
-    }
-
-    /**
-     * Gets the filename where the error occurred.
-     *
-     * @return string The filename
-     */
-    public function getTemplateFile()
-    {
-        return $this->filename;
-    }
-
-    /**
-     * Sets the filename where the error occurred.
-     *
-     * @param string $filename The filename
-     */
-    public function setTemplateFile($filename)
-    {
-        $this->filename = $filename;
-
-        $this->updateRepr();
-    }
-
-    /**
-     * Gets the template line where the error occurred.
-     *
-     * @return integer The template line
-     */
-    public function getTemplateLine()
-    {
-        return $this->lineno;
-    }
-
-    /**
-     * Sets the template line where the error occurred.
-     *
-     * @param integer $lineno The template line
-     */
-    public function setTemplateLine($lineno)
-    {
-        $this->lineno = $lineno;
-
-        $this->updateRepr();
-    }
-
-    /**
-     * For PHP < 5.3.0, provides access to the getPrevious() method.
-     *
-     * @param  string $method    The method name
-     * @param  array  $arguments The parameters to be passed to the method
-     *
-     * @return Exception The previous exception or null
-     */
-    public function __call($method, $arguments)
-    {
-        if ('getprevious' == strtolower($method)) {
-            return $this->previous;
-        }
-
-        throw new BadMethodCallException(sprintf('Method "Twig_Error::%s()" does not exist.', $method));
-    }
-
-    protected function updateRepr()
-    {
-        $this->message = $this->rawMessage;
-
-        if (null !== $this->filename) {
-            $this->message .= sprintf(' in %s', json_encode($this->filename));
-        }
-
-        if ($this->lineno >= 0) {
-            $this->message .= sprintf(' at line %d', $this->lineno);
-        }
-    }
-}

File inc/libs/twig/Error/Loader.php

  • Ignore whitespace
-<?php
-
-/*
- * This file is part of Twig.
- *
- * (c) 2010 Fabien Potencier
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-/**
- * Exception thrown when an error occurs during template loading.
- *
- * @package    twig
- * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
- */
-class Twig_Error_Loader extends Twig_Error
-{
-}

File inc/libs/twig/Error/Runtime.php

  • Ignore whitespace
-<?php
-
-/*
- * This file is part of Twig.
- *
- * (c) 2009 Fabien Potencier
- * (c) 2009 Armin Ronacher
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-/**
- * Exception thrown when an error occurs at runtime.
- *
- * @package    twig
- * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
- */
-class Twig_Error_Runtime extends Twig_Error
-{
-}

File inc/libs/twig/Error/Syntax.php

  • Ignore whitespace
-<?php
-
-/*
- * This file is part of Twig.
- *
- * (c) 2009 Fabien Potencier
- * (c) 2009 Armin Ronacher
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-/**
- * Exception thrown when a syntax error occurs during lexing or parsing of a template.
- *
- * @package    twig
- * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
- */
-class Twig_Error_Syntax extends Twig_Error
-{
-}

File inc/libs/twig/ExpressionParser.php

  • Ignore whitespace
-<?php
-
-/*
- * This file is part of Twig.
- *
- * (c) 2009 Fabien Potencier
- * (c) 2009 Armin Ronacher
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-/**
- * Parses expressions.
- *
- * This parser implements a "Precedence climbing" algorithm.
- *
- * @see http://www.engr.mun.ca/~theo/Misc/exp_parsing.htm
- * @see http://en.wikipedia.org/wiki/Operator-precedence_parser
- *
- * @package    twig
- * @author     Fabien Potencier <fabien.potencier@symfony-project.com>
- */
-class Twig_ExpressionParser
-{
-    const OPERATOR_LEFT = 1;
-    const OPERATOR_RIGHT = 2;
-
-    protected $parser;
-    protected $unaryOperators;
-    protected $binaryOperators;
-
-    public function __construct(Twig_Parser $parser, array $unaryOperators, array $binaryOperators)
-    {
-        $this->parser = $parser;
-        $this->unaryOperators = $unaryOperators;
-        $this->binaryOperators = $binaryOperators;
-    }
-
-    public function parseExpression($precedence = 0)
-    {
-        $expr = $this->getPrimary();
-        $token = $this->parser->getCurrentToken();
-        while ($this->isBinary($token) && $this->binaryOperators[$token->getValue()]['precedence'] >= $precedence) {
-            $op = $this->binaryOperators[$token->getValue()];
-            $this->parser->getStream()->next();
-
-            if (isset($op['callable'])) {
-                $expr = call_user_func($op['callable'], $this->parser, $expr);
-            } else {
-                $expr1 = $this->parseExpression(self::OPERATOR_LEFT === $op['associativity'] ? $op['precedence'] + 1 : $op['precedence']);
-                $class = $op['class'];
-                $expr = new $class($expr, $expr1, $token->getLine());
-            }
-
-            $token = $this->parser->getCurrentToken();
-        }
-
-        if (0 === $precedence) {
-            return $this->parseConditionalExpression($expr);
-        }
-
-        return $expr;
-    }
-
-    protected function getPrimary()
-    {
-        $token = $this->parser->getCurrentToken();
-
-        if ($this->isUnary($token)) {
-            $operator = $this->unaryOperators[$token->getValue()];
-            $this->parser->getStream()->next();
-            $expr = $this->parseExpression($operator['precedence']);
-            $class = $operator['class'];
-
-            return $this->parsePostfixExpression(new $class($expr, $token->getLine()));
-        } elseif ($token->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
-            $this->parser->getStream()->next();
-            $expr = $this->parseExpression();
-            $this->parser->getStream()->expect(Twig_Token::PUNCTUATION_TYPE, ')', 'An opened parenthesis is not properly closed');
-
-            return $this->parsePostfixExpression($expr);
-        }
-
-        return $this->parsePrimaryExpression();
-    }
-
-    protected function parseConditionalExpression($expr)
-    {
-        while ($this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, '?')) {
-            $this->parser->getStream()->next();
-            $expr2 = $this->parseExpression();
-            $this->parser->getStream()->expect(Twig_Token::PUNCTUATION_TYPE, ':', 'The ternary operator must have a default value');
-            $expr3 = $this->parseExpression();
-
-            $expr = new Twig_Node_Expression_Conditional($expr, $expr2, $expr3, $this->parser->getCurrentToken()->getLine());
-        }
-
-        return $expr;
-    }
-
-    protected function isUnary(Twig_Token $token)
-    {
-        return $token->test(Twig_Token::OPERATOR_TYPE) && isset($this->unaryOperators[$token->getValue()]);
-    }
-
-    protected function isBinary(Twig_Token $token)
-    {
-        return $token->test(Twig_Token::OPERATOR_TYPE) && isset($this->binaryOperators[$token->getValue()]);
-    }
-
-    public function parsePrimaryExpression()
-    {
-        $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:
-                        $node = new Twig_Node_Expression_Name($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::PUNCTUATION_TYPE, '[')) {
-                    $node = $this->parseArrayExpression();
-                } elseif ($token->test(Twig_Token::PUNCTUATION_TYPE, '{')) {
-                    $node = $this->parseHashExpression();
-                } else {
-                    throw new Twig_Error_Syntax(sprintf('Unexpected token "%s" of value "%s"', Twig_Token::typeToEnglish($token->getType(), $token->getLine()), $token->getValue()), $token->getLine());
-                }
-        }
-
-        return $this->parsePostfixExpression($node);
-    }
-
-    public function parseArrayExpression()
-    {
-        $stream = $this->parser->getStream();
-        $stream->expect(Twig_Token::PUNCTUATION_TYPE, '[', 'An array element was expected');
-        $elements = array();
-        while (!$stream->test(Twig_Token::PUNCTUATION_TYPE, ']')) {
-            if (!empty($elements)) {
-                $stream->expect(Twig_Token::PUNCTUATION_TYPE, ',', 'An array element must be followed by a comma');
-
-                // trailing ,?
-                if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ']')) {
-                    break;
-                }
-            }
-
-            $elements[] = $this->parseExpression();
-        }
-        $stream->expect(Twig_Token::PUNCTUATION_TYPE, ']', 'An opened array is not properly closed');
-
-        return new Twig_Node_Expression_Array($elements, $stream->getCurrent()->getLine());
-    }
-
-    public function parseHashExpression()
-    {
-        $stream = $this->parser->getStream();
-        $stream->expect(Twig_Token::PUNCTUATION_TYPE, '{', 'A hash element was expected');
-        $elements = array();
-        while (!$stream->test(Twig_Token::PUNCTUATION_TYPE, '}')) {
-            if (!empty($elements)) {
-                $stream->expect(Twig_Token::PUNCTUATION_TYPE, ',', 'A hash value must be followed by a comma');
-
-                // trailing ,?
-                if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '}')) {
-                    break;
-                }
-            }
-
-            if (!$stream->test(Twig_Token::STRING_TYPE) && !$stream->test(Twig_Token::NUMBER_TYPE)) {
-                $current = $stream->getCurrent();
-                throw new Twig_Error_Syntax(sprintf('A hash key must be a quoted string or a number (unexpected token "%s" of value "%s"', Twig_Token::typeToEnglish($current->getType(), $current->getLine()), $current->getValue()), $current->getLine());
-            }
-
-            $key = $stream->next()->getValue();
-            $stream->expect(Twig_Token::PUNCTUATION_TYPE, ':', 'A hash key must be followed by a colon (:)');