diff --git a/.gitignore b/.gitignore
index 8c18237..fd7f94d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,5 @@
-pico.sublime-project
-pico.sublime-workspace
\ No newline at end of file
+composer.lock
+composer.phar
+vendor/twig/twig/doc/*
+vendor/twig/twig/ext/*
+vendor/twig/twig/test/*
\ No newline at end of file
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..9ebb075
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,5 @@
+{
+ "require": {
+ "twig/twig": "1.12.*"
+ }
+}
\ No newline at end of file
diff --git a/config.php b/config.php
index 0ec25f9..74b509b 100644
--- a/config.php
+++ b/config.php
@@ -3,7 +3,7 @@
/*
Override any of the default settings below:
-$config['site_title'] = 'Pico'; // Site title
+$config['site_title'] = 'Pico'; // Site title
$config['base_url'] = ''; // Override base URL (e.g. http://example.com)
$config['theme'] = 'default'; // Set the theme (defaults to "default")
$config['enable_cache'] = false; // Enable caching
diff --git a/index.php b/index.php
index 6e9b678..1b278a6 100644
--- a/index.php
+++ b/index.php
@@ -11,8 +11,8 @@ define('THEMES_DIR', ROOT_DIR .'themes/');
define('CACHE_DIR', LIB_DIR .'cache/');
require('config.php');
+require(ROOT_DIR .'vendor/autoload.php');
require(LIB_DIR .'markdown.php');
-require(LIB_DIR .'twig/lib/Twig/Autoloader.php');
require(LIB_DIR .'pico.php');
$pico = new Pico();
diff --git a/lib/twig/bin/create_pear_package.php b/lib/twig/bin/create_pear_package.php
deleted file mode 100755
index 4899927..0000000
--- a/lib/twig/bin/create_pear_package.php
+++ /dev/null
@@ -1,42 +0,0 @@
- 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'] .= ' '."\n";
- }
-}
-
-$template = file_get_contents(dirname(__FILE__).'/../package.xml.tpl');
-$content = preg_replace_callback('/\{\{\s*([a-zA-Z0-9_]+)\s*\}\}/', 'replace_parameters', $template);
-file_put_contents(dirname(__FILE__).'/../package.xml', $content);
-
-function replace_parameters($matches)
-{
- global $context;
-
- return isset($context[$matches[1]]) ? $context[$matches[1]] : null;
-}
diff --git a/lib/twig/doc/advanced.rst b/lib/twig/doc/advanced.rst
deleted file mode 100755
index e82a521..0000000
--- a/lib/twig/doc/advanced.rst
+++ /dev/null
@@ -1,489 +0,0 @@
-Extending Twig
-==============
-
-Twig can be extended in many ways; you can add extra tags, filters, tests,
-operators, global variables, and functions. You can even extend the parser
-itself with node visitors.
-
-.. note::
-
- This chapter describes how to extend Twig easily. If you want to reuse
- your changes in different projects or if you want to share them with
- others, you should then create an extension as described in the next
- chapter.
-
-Before extending Twig, you must understand the differences between all the
-different possible extension points and when to use them.
-
-First, remember that Twig has two main language constructs:
-
-* ``{{ }}``: used to print the result of an expression evaluation;
-
-* ``{% %}``: used to execute statements.
-
-To understand why Twig exposes so many extension points, let's see how to
-implement a *Lorem ipsum* generator (it needs to know the number of words to
-generate).
-
-You can use a ``lipsum`` *tag*:
-
-.. code-block:: jinja
-
- {% lipsum 40 %}
-
-That works, but using a tag for ``lipsum`` is not a good idea for at least
-three main reasons:
-
-* ``lipsum`` is not a language construct;
-* The tag outputs something;
-* The tag is not flexible as you cannot use it in an expression:
-
- .. code-block:: jinja
-
- {{ 'some text' ~ {% lipsum 40 %} ~ 'some more text' }}
-
-In fact, you rarely need to create tags; and that's good news because tags are
-the most complex extension point of Twig.
-
-Now, let's use a ``lipsum`` *filter*:
-
-.. code-block:: jinja
-
- {{ 40|lipsum }}
-
-Again, it works, but it looks weird. A filter transforms the passed value to
-something else but here we use the value to indicate the number of words to
-generate.
-
-Next, let's use a ``lipsum`` *function*:
-
-.. code-block:: jinja
-
- {{ lipsum(40) }}
-
-Here we go. For this specific example, the creation of a function is the
-extension point to use. And you can use it anywhere an expression is accepted:
-
-.. code-block:: jinja
-
- {{ 'some text' ~ ipsum(40) ~ 'some more text' }}
-
- {% set ipsum = ipsum(40) %}
-
-Last but not the least, you can also use a *global* object with a method able
-to generate lorem ipsum text:
-
-.. code-block:: jinja
-
- {{ text.lipsum(40) }}
-
-As a rule of thumb, use functions for frequently used features and global
-objects for everything else.
-
-Keep in mind the following when you want to extend Twig:
-
-========== ========================== ========== =========================
-What? Implementation difficulty? How often? When?
-========== ========================== ========== =========================
-*macro* trivial frequent Content generation
-*global* trivial frequent Helper object
-*function* trivial frequent Content generation
-*filter* trivial frequent Value transformation
-*tag* complex rare DSL language construct
-*test* trivial rare Boolean decision
-*operator* trivial rare Values transformation
-========== ========================== ========== =========================
-
-Globals
--------
-
-A global variable is like any other template variable, except that it's
-available in all templates and macros::
-
- $twig = new Twig_Environment($loader);
- $twig->addGlobal('text', new Text());
-
-You can then use the ``text`` variable anywhere in a template:
-
-.. code-block:: jinja
-
- {{ text.lipsum(40) }}
-
-Filters
--------
-
-A filter is a regular PHP function or an object method that takes the left
-side of the filter (before the pipe ``|``) as first argument and the extra
-arguments passed to the filter (within parentheses ``()``) as extra arguments.
-
-Defining a filter is as easy as associating the filter name with a PHP
-callable. For instance, let's say you have the following code in a template:
-
-.. code-block:: jinja
-
- {{ 'TWIG'|lower }}
-
-When compiling this template to PHP, Twig looks for the PHP callable
-associated with the ``lower`` filter. The ``lower`` filter is a built-in Twig
-filter, and it is simply mapped to the PHP ``strtolower()`` function. After
-compilation, the generated PHP code is roughly equivalent to:
-
-.. code-block:: html+php
-
-
-
-As you can see, the ``'TWIG'`` string is passed as a first argument to the PHP
-function.
-
-A filter can also take extra arguments like in the following example:
-
-.. code-block:: jinja
-
- {{ now|date('d/m/Y') }}
-
-In this case, the extra arguments are passed to the function after the main
-argument, and the compiled code is equivalent to:
-
-.. code-block:: html+php
-
-
-
-Let's see how to create a new filter.
-
-In this section, we will create a ``rot13`` filter, which should return the
-`rot13`_ transformation of a string. Here is an example of its usage and the
-expected output:
-
-.. code-block:: jinja
-
- {{ "Twig"|rot13 }}
-
- {# should displays Gjvt #}
-
-Adding a filter is as simple as calling the ``addFilter()`` method on the
-``Twig_Environment`` instance::
-
- $twig = new Twig_Environment($loader);
- $twig->addFilter('rot13', new Twig_Filter_Function('str_rot13'));
-
-The second argument of ``addFilter()`` is an instance of ``Twig_Filter``.
-Here, we use ``Twig_Filter_Function`` as the filter is a PHP function. The
-first argument passed to the ``Twig_Filter_Function`` constructor is the name
-of the PHP function to call, here ``str_rot13``, a native PHP function.
-
-Let's say I now want to be able to add a prefix before the converted string:
-
-.. code-block:: jinja
-
- {{ "Twig"|rot13('prefix_') }}
-
- {# should displays prefix_Gjvt #}
-
-As the PHP ``str_rot13()`` function does not support this requirement, let's
-create a new PHP function::
-
- function project_compute_rot13($string, $prefix = '')
- {
- return $prefix.str_rot13($string);
- }
-
-As you can see, the ``prefix`` argument of the filter is passed as an extra
-argument to the ``project_compute_rot13()`` function.
-
-Adding this filter is as easy as before::
-
- $twig->addFilter('rot13', new Twig_Filter_Function('project_compute_rot13'));
-
-For better encapsulation, a filter can also be defined as a static method of a
-class. The ``Twig_Filter_Function`` class can also be used to register such
-static methods as filters::
-
- $twig->addFilter('rot13', new Twig_Filter_Function('SomeClass::rot13Filter'));
-
-.. tip::
-
- In an extension, you can also define a filter as a static method of the
- extension class.
-
-Environment aware Filters
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The ``Twig_Filter`` classes take options as their last argument. For instance,
-if you want access to the current environment instance in your filter, set the
-``needs_environment`` option to ``true``::
-
- $filter = new Twig_Filter_Function('str_rot13', array('needs_environment' => true));
-
-Twig will then pass the current environment as the first argument to the
-filter call::
-
- function twig_compute_rot13(Twig_Environment $env, $string)
- {
- // get the current charset for instance
- $charset = $env->getCharset();
-
- return str_rot13($string);
- }
-
-Automatic Escaping
-~~~~~~~~~~~~~~~~~~
-
-If automatic escaping is enabled, the output of the filter may be escaped
-before printing. If your filter acts as an escaper (or explicitly outputs html
-or javascript code), you will want the raw output to be printed. In such a
-case, set the ``is_safe`` option::
-
- $filter = new Twig_Filter_Function('nl2br', array('is_safe' => array('html')));
-
-Some filters may have to work on already escaped or safe values. In such a
-case, set the ``pre_escape`` option::
-
- $filter = new Twig_Filter_Function('somefilter', array('pre_escape' => 'html', 'is_safe' => array('html')));
-
-Dynamic Filters
-~~~~~~~~~~~~~~~
-
-.. versionadded:: 1.5
- Dynamic filters support was added in Twig 1.5.
-
-A filter name containing the special ``*`` character is a dynamic filter as
-the ``*`` can be any string::
-
- $twig->addFilter('*_path', new Twig_Filter_Function('twig_path'));
-
- function twig_path($name, $arguments)
- {
- // ...
- }
-
-The following filters will be matched by the above defined dynamic filter:
-
-* ``product_path``
-* ``category_path``
-
-A dynamic filter can define more than one dynamic parts::
-
- $twig->addFilter('*_path_*', new Twig_Filter_Function('twig_path'));
-
- function twig_path($name, $suffix, $arguments)
- {
- // ...
- }
-
-The filter will receive all dynamic part values before the normal filters
-arguments. For instance, a call to ``'foo'|a_path_b()`` will result in the
-following PHP call: ``twig_path('a', 'b', 'foo')``.
-
-Functions
----------
-
-A function is a regular PHP function or an object method that can be called from
-templates.
-
-.. code-block:: jinja
-
- {{ constant("DATE_W3C") }}
-
-When compiling this template to PHP, Twig looks for the PHP callable
-associated with the ``constant`` function. The ``constant`` function is a built-in Twig
-function, and it is simply mapped to the PHP ``constant()`` function. After
-compilation, the generated PHP code is roughly equivalent to:
-
-.. code-block:: html+php
-
-
-
-Adding a function is similar to adding a filter. This can be done by calling the
-``addFunction()`` method on the ``Twig_Environment`` instance::
-
- $twig = new Twig_Environment($loader);
- $twig->addFunction('functionName', new Twig_Function_Function('someFunction'));
-
-You can also expose extension methods as functions in your templates::
-
- // $this is an object that implements Twig_ExtensionInterface.
- $twig = new Twig_Environment($loader);
- $twig->addFunction('otherFunction', new Twig_Function_Method($this, 'someMethod'));
-
-Functions also support ``needs_environment`` and ``is_safe`` parameters.
-
-Dynamic Functions
-~~~~~~~~~~~~~~~~~
-
-.. versionadded:: 1.5
- Dynamic functions support was added in Twig 1.5.
-
-A function name containing the special ``*`` character is a dynamic function
-as the ``*`` can be any string::
-
- $twig->addFunction('*_path', new Twig_Function_Function('twig_path'));
-
- function twig_path($name, $arguments)
- {
- // ...
- }
-
-The following functions will be matched by the above defined dynamic function:
-
-* ``product_path``
-* ``category_path``
-
-A dynamic function can define more than one dynamic parts::
-
- $twig->addFilter('*_path_*', new Twig_Filter_Function('twig_path'));
-
- function twig_path($name, $suffix, $arguments)
- {
- // ...
- }
-
-The function will receive all dynamic part values before the normal functions
-arguments. For instance, a call to ``a_path_b('foo')`` will result in the
-following PHP call: ``twig_path('a', 'b', 'foo')``.
-
-Tags
-----
-
-One of the most exciting feature of a template engine like Twig is the
-possibility to define new language constructs. This is also the most complex
-feature as you need to understand how Twig's internals work.
-
-Let's create a simple ``set`` tag that allows the definition of simple
-variables from within a template. The tag can be used like follows:
-
-.. code-block:: jinja
-
- {% set name = "value" %}
-
- {{ name }}
-
- {# should output value #}
-
-.. note::
-
- The ``set`` tag is part of the Core extension and as such is always
- available. The built-in version is slightly more powerful and supports
- multiple assignments by default (cf. the template designers chapter for
- more information).
-
-Three steps are needed to define a new tag:
-
-* Defining a Token Parser class (responsible for parsing the template code);
-
-* Defining a Node class (responsible for converting the parsed code to PHP);
-
-* Registering the tag.
-
-Registering a new tag
-~~~~~~~~~~~~~~~~~~~~~
-
-Adding a tag is as simple as calling the ``addTokenParser`` method on the
-``Twig_Environment`` instance::
-
- $twig = new Twig_Environment($loader);
- $twig->addTokenParser(new Project_Set_TokenParser());
-
-Defining a Token Parser
-~~~~~~~~~~~~~~~~~~~~~~~
-
-Now, let's see the actual code of this class::
-
- class Project_Set_TokenParser extends Twig_TokenParser
- {
- public function parse(Twig_Token $token)
- {
- $lineno = $token->getLine();
- $name = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE)->getValue();
- $this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, '=');
- $value = $this->parser->getExpressionParser()->parseExpression();
-
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
-
- return new Project_Set_Node($name, $value, $lineno, $this->getTag());
- }
-
- public function getTag()
- {
- return 'set';
- }
- }
-
-The ``getTag()`` method must return the tag we want to parse, here ``set``.
-
-The ``parse()`` method is invoked whenever the parser encounters a ``set``
-tag. It should return a ``Twig_Node`` instance that represents the node (the
-``Project_Set_Node`` calls creating is explained in the next section).
-
-The parsing process is simplified thanks to a bunch of methods you can call
-from the token stream (``$this->parser->getStream()``):
-
-* ``getCurrent()``: Gets the current token in the stream.
-
-* ``next()``: Moves to the next token in the stream, *but returns the old one*.
-
-* ``test($type)``, ``test($value)`` or ``test($type, $value)``: Determines whether
- the current token is of a particular type or value (or both). The value may be an
- array of several possible values.
-
-* ``expect($type[, $value[, $message]])``: If the current token isn't of the given
- type/value a syntax error is thrown. Otherwise, if the type and value are correct,
- the token is returned and the stream moves to the next token.
-
-* ``look()``: Looks a the next token without consuming it.
-
-Parsing expressions is done by calling the ``parseExpression()`` like we did for
-the ``set`` tag.
-
-.. tip::
-
- Reading the existing ``TokenParser`` classes is the best way to learn all
- the nitty-gritty details of the parsing process.
-
-Defining a Node
-~~~~~~~~~~~~~~~
-
-The ``Project_Set_Node`` class itself is rather simple::
-
- class Project_Set_Node extends Twig_Node
- {
- public function __construct($name, Twig_Node_Expression $value, $lineno, $tag = null)
- {
- parent::__construct(array('value' => $value), array('name' => $name), $lineno, $tag);
- }
-
- public function compile(Twig_Compiler $compiler)
- {
- $compiler
- ->addDebugInfo($this)
- ->write('$context[\''.$this->getAttribute('name').'\'] = ')
- ->subcompile($this->getNode('value'))
- ->raw(";\n")
- ;
- }
- }
-
-The compiler implements a fluid interface and provides methods that helps the
-developer generate beautiful and readable PHP code:
-
-* ``subcompile()``: Compiles a node.
-
-* ``raw()``: Writes the given string as is.
-
-* ``write()``: Writes the given string by adding indentation at the beginning
- of each line.
-
-* ``string()``: Writes a quoted string.
-
-* ``repr()``: Writes a PHP representation of a given value (see
- ``Twig_Node_For`` for a usage example).
-
-* ``addDebugInfo()``: Adds the line of the original template file related to
- the current node as a comment.
-
-* ``indent()``: Indents the generated code (see ``Twig_Node_Block`` for a
- usage example).
-
-* ``outdent()``: Outdents the generated code (see ``Twig_Node_Block`` for a
- usage example).
-
-.. _`rot13`: http://www.php.net/manual/en/function.str-rot13.php
diff --git a/lib/twig/doc/api.rst b/lib/twig/doc/api.rst
deleted file mode 100755
index 864585e..0000000
--- a/lib/twig/doc/api.rst
+++ /dev/null
@@ -1,479 +0,0 @@
-Twig for Developers
-===================
-
-This chapter describes the API to Twig and not the template language. It will
-be most useful as reference to those implementing the template interface to
-the application and not those who are creating Twig templates.
-
-Basics
-------
-
-Twig uses a central object called the **environment** (of class
-``Twig_Environment``). Instances of this class are used to store the
-configuration and extensions, and are used to load templates from the file
-system or other locations.
-
-Most applications will create one ``Twig_Environment`` object on application
-initialization and use that to load templates. In some cases it's however
-useful to have multiple environments side by side, if different configurations
-are in use.
-
-The simplest way to configure Twig to load templates for your application
-looks roughly like this::
-
- require_once '/path/to/lib/Twig/Autoloader.php';
- Twig_Autoloader::register();
-
- $loader = new Twig_Loader_Filesystem('/path/to/templates');
- $twig = new Twig_Environment($loader, array(
- 'cache' => '/path/to/compilation_cache',
- ));
-
-This will create a template environment with the default settings and a loader
-that looks up the templates in the ``/path/to/templates/`` folder. Different
-loaders are available and you can also write your own if you want to load
-templates from a database or other resources.
-
-.. note::
-
- Notice that the second argument of the environment is an array of options.
- The ``cache`` option is a compilation cache directory, where Twig caches
- the compiled templates to avoid the parsing phase for sub-sequent
- requests. It is very different from the cache you might want to add for
- the evaluated templates. For such a need, you can use any available PHP
- cache library.
-
-To load a template from this environment you just have to call the
-``loadTemplate()`` method which then returns a ``Twig_Template`` instance::
-
- $template = $twig->loadTemplate('index.html');
-
-To render the template with some variables, call the ``render()`` method::
-
- echo $template->render(array('the' => 'variables', 'go' => 'here'));
-
-.. note::
-
- The ``display()`` method is a shortcut to output the template directly.
-
-You can also load and render the template in one fell swoop::
-
- echo $twig->render('index.html', array('the' => 'variables', 'go' => 'here'));
-
-Environment Options
--------------------
-
-When creating a new ``Twig_Environment`` instance, you can pass an array of
-options as the constructor second argument::
-
- $twig = new Twig_Environment($loader, array('debug' => true));
-
-The following options are available:
-
-* ``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 caching (which is the default).
-
-* ``auto_reload``: When developing with Twig, it's useful to recompile the
- template whenever the source code changes. If you don't provide a value for
- the ``auto_reload`` option, it will be determined automatically based on the
- ``debug`` value.
-
-* ``strict_variables``: If set to ``false``, Twig will silently ignore invalid
- variables (variables and or attributes/methods that do not exist) and
- replace them with a ``null`` value. When set to ``true``, Twig throws an
- exception instead (default to ``false``).
-
-* ``autoescape``: If set to ``true``, auto-escaping will be enabled by default
- for all templates (default to ``true``).
-
-* ``optimizations``: A flag that indicates which optimizations to apply
- (default to ``-1`` -- all optimizations are enabled; set it to ``0`` to
- disable).
-
-Loaders
--------
-
-Loaders are responsible for loading templates from a resource such as the file
-system.
-
-Compilation Cache
-~~~~~~~~~~~~~~~~~
-
-All template loaders can cache the compiled templates on the filesystem for
-future reuse. It speeds up Twig a lot as templates are only compiled once; and
-the performance boost is even larger if you use a PHP accelerator such as APC.
-See the ``cache`` and ``auto_reload`` options of ``Twig_Environment`` above
-for more information.
-
-Built-in Loaders
-~~~~~~~~~~~~~~~~
-
-Here is a list of the built-in loaders Twig provides:
-
-* ``Twig_Loader_Filesystem``: Loads templates from the file system. This
- loader can find templates in folders on the file system and is the preferred
- way to load them::
-
- $loader = new Twig_Loader_Filesystem($templateDir);
-
- It can also look for templates in an array of directories::
-
- $loader = new Twig_Loader_Filesystem(array($templateDir1, $templateDir2));
-
- With such a configuration, Twig will first look for templates in
- ``$templateDir1`` and if they do not exist, it will fallback to look for
- them in the ``$templateDir2``.
-
-* ``Twig_Loader_String``: Loads templates from a string. It's a dummy loader
- as you pass it the source code directly::
-
- $loader = new Twig_Loader_String();
-
-* ``Twig_Loader_Array``: Loads a template from a PHP array. It's passed an
- array of strings bound to template names. This loader is useful for unit
- testing::
-
- $loader = new Twig_Loader_Array($templates);
-
-.. tip::
-
- When using the ``Array`` or ``String`` loaders with a cache mechanism, you
- should know that a new cache key is generated each time a template content
- "changes" (the cache key being the source code of the template). If you
- don't want to see your cache grows out of control, you need to take care
- of clearing the old cache file by yourself.
-
-Create your own Loader
-~~~~~~~~~~~~~~~~~~~~~~
-
-All loaders implement the ``Twig_LoaderInterface``::
-
- 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
- */
- 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
- */
- 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
- */
- function isFresh($name, $time);
- }
-
-As an example, here is how the built-in ``Twig_Loader_String`` reads::
-
- class Twig_Loader_String implements Twig_LoaderInterface
- {
- public function getSource($name)
- {
- return $name;
- }
-
- public function getCacheKey($name)
- {
- return $name;
- }
-
- public function isFresh($name, $time)
- {
- return false;
- }
- }
-
-The ``isFresh()`` method must return ``true`` if the current cached template
-is still fresh, given the last modification time, or ``false`` otherwise.
-
-Using Extensions
-----------------
-
-Twig extensions are packages that add new features to Twig. Using an
-extension is as simple as using the ``addExtension()`` method::
-
- $twig->addExtension(new Twig_Extension_Sandbox());
-
-Twig comes bundled with the following extensions:
-
-* *Twig_Extension_Core*: Defines all the core features of Twig.
-
-* *Twig_Extension_Escaper*: Adds automatic output-escaping and the possibility
- to escape/unescape blocks of code.
-
-* *Twig_Extension_Sandbox*: Adds a sandbox mode to the default Twig
- environment, making it safe to evaluated untrusted code.
-
-* *Twig_Extension_Optimizer*: Optimizers the node tree before compilation.
-
-The core, escaper, and optimizer extensions do not need to be added to the
-Twig environment, as they are registered by default. You can disable an
-already registered extension::
-
- $twig->removeExtension('escaper');
-
-Built-in Extensions
--------------------
-
-This section describes the features added by the built-in extensions.
-
-.. tip::
-
- Read the chapter about extending Twig to learn how to create your own
- extensions.
-
-Core Extension
-~~~~~~~~~~~~~~
-
-The ``core`` extension defines all the core features of Twig:
-
-* Tags:
-
- * ``for``
- * ``if``
- * ``extends``
- * ``include``
- * ``block``
- * ``filter``
- * ``macro``
- * ``import``
- * ``from``
- * ``set``
- * ``spaceless``
-
-* Filters:
-
- * ``date``
- * ``format``
- * ``replace``
- * ``url_encode``
- * ``json_encode``
- * ``title``
- * ``capitalize``
- * ``upper``
- * ``lower``
- * ``striptags``
- * ``join``
- * ``reverse``
- * ``length``
- * ``sort``
- * ``merge``
- * ``default``
- * ``keys``
- * ``escape``
- * ``e``
-
-* Functions:
-
- * ``range``
- * ``constant``
- * ``cycle``
- * ``parent``
- * ``block``
-
-* Tests:
-
- * ``even``
- * ``odd``
- * ``defined``
- * ``sameas``
- * ``null``
- * ``divisibleby``
- * ``constant``
- * ``empty``
-
-Escaper Extension
-~~~~~~~~~~~~~~~~~
-
-The ``escaper`` extension adds automatic output escaping to Twig. It defines a
-new tag, ``autoescape``, and a new filter, ``raw``.
-
-When creating the escaper extension, you can switch on or off the global
-output escaping strategy::
-
- $escaper = new Twig_Extension_Escaper(true);
- $twig->addExtension($escaper);
-
-If set to ``true``, all variables in templates are escaped, except those using
-the ``raw`` filter:
-
-.. code-block:: jinja
-
- {{ article.to_html|raw }}
-
-You can also change the escaping mode locally by using the ``autoescape`` tag:
-
-.. code-block:: jinja
-
- {% autoescape true %}
- {{ var }}
- {{ var|raw }} {# var won't be escaped #}
- {{ var|escape }} {# var won't be double-escaped #}
- {% endautoescape %}
-
-.. warning::
-
- The ``autoescape`` tag has no effect on included files.
-
-The escaping rules are implemented as follows:
-
-* Literals (integers, booleans, arrays, ...) used in the template directly as
- variables or filter arguments are never automatically escaped:
-
- .. code-block:: jinja
-
- {{ "Twig " }} {# won't be escaped #}
-
- {% set text = "Twig " %}
- {{ text }} {# will be escaped #}
-
-* Expressions which the result is always a literal or a variable marked safe
- are never automatically escaped:
-
- .. code-block:: jinja
-
- {{ foo ? "Twig " : " Twig" }} {# won't be escaped #}
-
- {% set text = "Twig " %}
- {{ foo ? text : " Twig" }} {# will be escaped #}
-
- {% set text = "Twig " %}
- {{ foo ? text|raw : " Twig" }} {# won't be escaped #}
-
- {% set text = "Twig " %}
- {{ foo ? text|escape : " Twig" }} {# the result of the expression won't be escaped #}
-
-* Escaping is applied before printing, after any other filter is applied:
-
- .. code-block:: jinja
-
- {{ var|upper }} {# is equivalent to {{ var|upper|escape }} #}
-
-* The `raw` filter should only be used at the end of the filter chain:
-
- .. code-block:: jinja
-
- {{ var|raw|upper }} {# will be escaped #}
-
- {{ var|upper|raw }} {# won't be escaped #}
-
-* Automatic escaping is not applied if the last filter in the chain is marked
- safe for the current context (e.g. ``html`` or ``js``). ``escaper`` and
- ``escaper('html')`` are marked safe for html, ``escaper('js')`` is marked
- safe for javascript, ``raw`` is marked safe for everything.
-
- .. code-block:: jinja
-
- {% autoescape true js %}
- {{ var|escape('html') }} {# will be escaped for html and javascript #}
- {{ var }} {# will be escaped for javascript #}
- {{ var|escape('js') }} {# won't be double-escaped #}
- {% endautoescape %}
-
-.. note::
-
- Note that autoescaping has some limitations as escaping is applied on
- expressions after evaluation. For instance, when working with
- concatenation, ``{{ foo|raw ~ bar }}`` won't give the expected result as
- escaping is applied on the result of the concatenation, not on the
- individual variables (so, the ``raw`` filter won't have any effect here).
-
-Sandbox Extension
-~~~~~~~~~~~~~~~~~
-
-The ``sandbox`` extension can be used to evaluate untrusted code. Access to
-unsafe attributes and methods is prohibited. The sandbox security is managed
-by a policy instance. By default, Twig comes with one policy class:
-``Twig_Sandbox_SecurityPolicy``. This class allows you to white-list some
-tags, filters, properties, and methods::
-
- $tags = array('if');
- $filters = array('upper');
- $methods = array(
- 'Article' => array('getTitle', 'getBody'),
- );
- $properties = array(
- 'Article' => array('title', 'body'),
- );
- $functions = array('range');
- $policy = new Twig_Sandbox_SecurityPolicy($tags, $filters, $methods, $properties, $functions);
-
-With the previous configuration, the security policy will only allow usage of
-the ``if`` tag, and the ``upper`` filter. Moreover, the templates will only be
-able to call the ``getTitle()`` and ``getBody()`` methods on ``Article``
-objects, and the ``title`` and ``body`` public properties. Everything else
-won't be allowed and will generate a ``Twig_Sandbox_SecurityError`` exception.
-
-The policy object is the first argument of the sandbox constructor::
-
- $sandbox = new Twig_Extension_Sandbox($policy);
- $twig->addExtension($sandbox);
-
-By default, the sandbox mode is disabled and should be enabled when including
-untrusted template code by using the ``sandbox`` tag:
-
-.. code-block:: jinja
-
- {% sandbox %}
- {% include 'user.html' %}
- {% endsandbox %}
-
-You can sandbox all templates by passing ``true`` as the second argument of
-the extension constructor::
-
- $sandbox = new Twig_Extension_Sandbox($policy, true);
-
-Optimizer Extension
-~~~~~~~~~~~~~~~~~~~
-
-The ``optimizer`` extension optimizes the node tree before compilation::
-
- $twig->addExtension(new Twig_Extension_Optimizer());
-
-By default, all optimizations are turned on. You can select the ones you want
-to enable by passing them to the constructor::
-
- $optimizer = new Twig_Extension_Optimizer(Twig_NodeVisitor_Optimizer::OPTIMIZE_FOR);
-
- $twig->addExtension($optimizer);
-
-Exceptions
-----------
-
-Twig can throw exceptions:
-
-* ``Twig_Error``: The base exception for all errors.
-
-* ``Twig_Error_Syntax``: Thrown to tell the user that there is a problem with
- the template syntax.
-
-* ``Twig_Error_Runtime``: Thrown when an error occurs at runtime (when a filter
- does not exist for instance).
-
-* ``Twig_Error_Loader``: Thrown when an error occurs during template loading.
-
-* ``Twig_Sandbox_SecurityError``: Thrown when an unallowed tag, filter, or
- method is called in a sandboxed template.
diff --git a/lib/twig/doc/coding_standards.rst b/lib/twig/doc/coding_standards.rst
deleted file mode 100755
index e0aab35..0000000
--- a/lib/twig/doc/coding_standards.rst
+++ /dev/null
@@ -1,101 +0,0 @@
-Coding Standards
-================
-
-When writing Twig templates, we recommend you to follow these official coding
-standards:
-
-* Put one (and only one) space after the start of a delimiter (``{{``, ``{%``,
- and ``{#``) and before the end of a delimiter (``}}``, ``%}``, and ``#}``):
-
- .. code-block:: jinja
-
- {{ foo }}
- {# comment #}
- {% if foo %}{% endif %}
-
- When using the whitespace control character, do not put any spaces between
- it and the delimiter:
-
- .. code-block:: jinja
-
- {{- foo -}}
- {#- comment -#}
- {%- if foo -%}{%- endif -%}
-
-* Put one (and only one) space before and after the following operators:
- comparison operators (``==``, ``!=``, ``<``, ``>``, ``>=``, ``<=``), math
- operators (``+``, ``-``, ``/``, ``*``, ``%``, ``//``, ``**``), logic
- operators (``not``, ``and``, ``or``), ``~``, ``is``, ``in``, and the ternary
- operator (``?:``):
-
- .. code-block:: jinja
-
- {{ 1 + 2 }}
- {{ foo ~ bar }}
- {{ true ? true : false }}
-
-* Put one (and only one) space after the ``:`` sign in hashes and ``,`` in
- arrays and hashes:
-
- .. code-block:: jinja
-
- {{ [1, 2, 3] }}
- {{ {'foo': 'bar'} }}
-
-* Do not put any spaces after an opening parenthesis and before a closing
- parenthesis in expressions:
-
- .. code-block:: jinja
-
- {{ 1 + (2 * 3) }}
-
-* Do not put any spaces before and after string delimiters:
-
- .. code-block:: jinja
-
- {{ 'foo' }}
- {{ "foo" }}
-
-* Do not put any spaces before and after the following operators: ``|``,
- ``.``, ``..``, ``[]``:
-
- .. code-block:: jinja
-
- {{ foo|upper|lower }}
- {{ user.name }}
- {{ user[name] }}
- {% for i in 1..12 %}{% endfor %}
-
-* Do not put any spaces before and after the parenthesis used for filter and
- function calls:
-
- .. code-block:: jinja
-
- {{ foo|default('foo') }}
- {{ range(1..10) }}
-
-* Do not put any spaces before and after the opening and the closing of arrays
- and hashes:
-
- .. code-block:: jinja
-
- {{ [1, 2, 3] }}
- {{ {'foo': 'bar'} }}
-
-* Use lower cased and underscored variable names:
-
- .. code-block:: jinja
-
- {% set foo = 'foo' %}
- {% set foo_bar = 'foo' %}
-
-* Indent your code inside tags (use the same indentation as the one used for
- the main language of the file):
-
- .. code-block:: jinja
-
- {% block foo %}
- {% if true %}
- true
- {% endif %}
- {% endblock %}
diff --git a/lib/twig/doc/extensions.rst b/lib/twig/doc/extensions.rst
deleted file mode 100755
index f4dd481..0000000
--- a/lib/twig/doc/extensions.rst
+++ /dev/null
@@ -1,328 +0,0 @@
-Creating a Twig Extension
-=========================
-
-The main motivation for writing an extension is to move often used code into a
-reusable class like adding support for internationalization. An extension can
-define tags, filters, tests, operators, global variables, functions, and node
-visitors.
-
-Creating an extension also makes for a better separation of code that is
-executed at compilation time and code needed at runtime. As such, it makes
-your code faster.
-
-Most of the time, it is useful to create a single extension for your project,
-to host all the specific tags and filters you want to add to Twig.
-
-.. note::
-
- Before writing your own extensions, have a look at the Twig official
- extension repository: http://github.com/fabpot/Twig-extensions.
-
-An extension is a class that implements the following interface::
-
- interface Twig_ExtensionInterface
- {
- /**
- * Initializes the runtime environment.
- *
- * This is where you can load some file that contains filter functions for instance.
- *
- * @param Twig_Environment $environment The current Twig_Environment instance
- */
- function initRuntime(Twig_Environment $environment);
-
- /**
- * Returns the token parser instances to add to the existing list.
- *
- * @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances
- */
- function getTokenParsers();
-
- /**
- * Returns the node visitor instances to add to the existing list.
- *
- * @return array An array of Twig_NodeVisitorInterface instances
- */
- function getNodeVisitors();
-
- /**
- * Returns a list of filters to add to the existing list.
- *
- * @return array An array of filters
- */
- function getFilters();
-
- /**
- * Returns a list of tests to add to the existing list.
- *
- * @return array An array of tests
- */
- function getTests();
-
- /**
- * Returns a list of functions to add to the existing list.
- *
- * @return array An array of functions
- */
- function getFunctions();
-
- /**
- * Returns a list of operators to add to the existing list.
- *
- * @return array An array of operators
- */
- function getOperators();
-
- /**
- * Returns a list of global variables to add to the existing list.
- *
- * @return array An array of global variables
- */
- function getGlobals();
-
- /**
- * Returns the name of the extension.
- *
- * @return string The extension name
- */
- function getName();
- }
-
-To keep your extension class clean and lean, it can inherit from the built-in
-``Twig_Extension`` class instead of implementing the whole interface. That
-way, you just need to implement the ``getName()`` method as the
-``Twig_Extension`` provides empty implementations for all other methods.
-
-The ``getName()`` method must return a unique identifier for your extension.
-
-Now, with this information in mind, let's create the most basic extension
-possible::
-
- class Project_Twig_Extension extends Twig_Extension
- {
- public function getName()
- {
- return 'project';
- }
- }
-
-.. note::
-
- Of course, this extension does nothing for now. We will customize it in
- the next sections.
-
-Twig does not care where you save your extension on the filesystem, as all
-extensions must be registered explicitly to be available in your templates.
-
-You can register an extension by using the ``addExtension()`` method on your
-main ``Environment`` object::
-
- $twig = new Twig_Environment($loader);
- $twig->addExtension(new Project_Twig_Extension());
-
-Of course, you need to first load the extension file by either using
-``require_once()`` or by using an autoloader (see `spl_autoload_register()`_).
-
-.. tip::
-
- The bundled extensions are great examples of how extensions work.
-
-Globals
--------
-
-Global variables can be registered in an extension via the ``getGlobals()``
-method::
-
- class Project_Twig_Extension extends Twig_Extension
- {
- public function getGlobals()
- {
- return array(
- 'text' => new Text(),
- );
- }
-
- // ...
- }
-
-Functions
----------
-
-Functions can be registered in an extension via the ``getFunctions()``
-method::
-
- class Project_Twig_Extension extends Twig_Extension
- {
- public function getFunctions()
- {
- return array(
- 'lipsum' => new Twig_Function_Function('generate_lipsum'),
- );
- }
-
- // ...
- }
-
-Filters
--------
-
-To add a filter to an extension, you need to override the ``getFilters()``
-method. This method must return an array of filters to add to the Twig
-environment::
-
- class Project_Twig_Extension extends Twig_Extension
- {
- public function getFilters()
- {
- return array(
- 'rot13' => new Twig_Filter_Function('str_rot13'),
- );
- }
-
- // ...
- }
-
-As you can see in the above code, the ``getFilters()`` method returns an array
-where keys are the name of the filters (``rot13``) and the values the
-definition of the filter (``new Twig_Filter_Function('str_rot13')``).
-
-As seen in the previous chapter, you can also define filters as static methods
-on the extension class::
-
-$twig->addFilter('rot13', new Twig_Filter_Function('Project_Twig_Extension::rot13Filter'));
-
-You can also use ``Twig_Filter_Method`` instead of ``Twig_Filter_Function``
-when defining a filter to use a method::
-
- class Project_Twig_Extension extends Twig_Extension
- {
- public function getFilters()
- {
- return array(
- 'rot13' => new Twig_Filter_Method($this, 'rot13Filter'),
- );
- }
-
- public function rot13Filter($string)
- {
- return str_rot13($string);
- }
-
- // ...
- }
-
-The first argument of the ``Twig_Filter_Method`` constructor is always
-``$this``, the current extension object. The second one is the name of the
-method to call.
-
-Using methods for filters is a great way to package your filter without
-polluting the global namespace. This also gives the developer more flexibility
-at the cost of a small overhead.
-
-Overriding default Filters
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-If some default core filters do not suit your needs, you can easily override
-them by creating your own core extension. Of course, you don't need to copy
-and paste the whole core extension code of Twig. Instead, you can just extends
-it and override the filter(s) you want by overriding the ``getFilters()``
-method::
-
- class MyCoreExtension extends Twig_Extension_Core
- {
- public function getFilters()
- {
- return array_merge(parent::getFilters(), array(
- 'date' => new Twig_Filter_Method($this, 'dateFilter'),
- // ...
- ));
- }
-
- public function dateFilter($timestamp, $format = 'F j, Y H:i')
- {
- return '...'.twig_date_format_filter($timestamp, $format);
- }
-
- // ...
- }
-
-Here, we override the ``date`` filter with a custom one. Using this new core
-extension is as simple as registering the ``MyCoreExtension`` extension by
-calling the ``addExtension()`` method on the environment instance::
-
- $twig = new Twig_Environment($loader);
- $twig->addExtension(new MyCoreExtension());
-
-But I can already hear some people wondering how it can work as the Core
-extension is loaded by default. That's true, but the trick is that both
-extensions share the same unique identifier (``core`` - defined in the
-``getName()`` method). By registering an extension with the same name as an
-existing one, you have actually overridden the default one, even if it is
-already registered::
-
- $twig->addExtension(new Twig_Extension_Core());
- $twig->addExtension(new MyCoreExtension());
-
-Tags
-----
-
-Adding a tag in an extension can be done by overriding the
-``getTokenParsers()`` method. This method must return an array of tags to add
-to the Twig environment::
-
- class Project_Twig_Extension extends Twig_Extension
- {
- public function getTokenParsers()
- {
- return array(new Project_Set_TokenParser());
- }
-
- // ...
- }
-
-In the above code, we have added a single new tag, defined by the
-``Project_Set_TokenParser`` class. The ``Project_Set_TokenParser`` class is
-responsible for parsing the tag and compiling it to PHP.
-
-Operators
----------
-
-The ``getOperators()`` methods allows to add new operators. Here is how to add
-``!``, ``||``, and ``&&`` operators::
-
- class Project_Twig_Extension extends Twig_Extension
- {
- public function getOperators()
- {
- return array(
- array(
- '!' => array('precedence' => 50, 'class' => 'Twig_Node_Expression_Unary_Not'),
- ),
- array(
- '||' => array('precedence' => 10, 'class' => 'Twig_Node_Expression_Binary_Or', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
- '&&' => array('precedence' => 15, 'class' => 'Twig_Node_Expression_Binary_And', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT),
- ),
- );
- }
-
- // ...
- }
-
-Tests
------
-
-The ``getTests()`` methods allows to add new test functions::
-
- class Project_Twig_Extension extends Twig_Extension
- {
- public function getTests()
- {
- return array(
- 'even' => new Twig_Test_Function('twig_test_even'),
- );
- }
-
- // ...
- }
-
-.. _`spl_autoload_register()`: http://www.php.net/spl_autoload_register
diff --git a/lib/twig/doc/filters/capitalize.rst b/lib/twig/doc/filters/capitalize.rst
deleted file mode 100755
index 10546a1..0000000
--- a/lib/twig/doc/filters/capitalize.rst
+++ /dev/null
@@ -1,11 +0,0 @@
-``capitalize``
-==============
-
-The ``capitalize`` filter capitalizes a value. The first character will be
-uppercase, all others lowercase:
-
-.. code-block:: jinja
-
- {{ 'my first car'|capitalize }}
-
- {# outputs 'My first car' #}
diff --git a/lib/twig/doc/filters/convert_encoding.rst b/lib/twig/doc/filters/convert_encoding.rst
deleted file mode 100755
index be40b0d..0000000
--- a/lib/twig/doc/filters/convert_encoding.rst
+++ /dev/null
@@ -1,22 +0,0 @@
-``convert_encoding``
-====================
-
-.. versionadded:: 1.4
- The ``convert_encoding`` filter was added in Twig 1.4.
-
-The ``convert_encoding`` filter converts a string from one encoding to
-another. The first argument is the expected output charset and the second one
-is the input charset:
-
-.. code-block:: jinja
-
- {{ data|convert_encoding('UTF-8', 'iso-2022-jp') }}
-
-.. note::
-
- This filter relies on the `iconv`_ or `mbstring`_ extension, so one of
- them must be installed. In case both are installed, `iconv`_ is used
- by default.
-
-.. _`iconv`: http://php.net/iconv
-.. _`mbstring`: http://php.net/mbstring
diff --git a/lib/twig/doc/filters/date.rst b/lib/twig/doc/filters/date.rst
deleted file mode 100755
index 9833f03..0000000
--- a/lib/twig/doc/filters/date.rst
+++ /dev/null
@@ -1,65 +0,0 @@
-``date``
-========
-
-.. versionadded:: 1.1
- The timezone support has been added in Twig 1.1.
-
-.. versionadded:: 1.5
- The default date format support has been added in Twig 1.5.
-
-.. versionadded:: 1.6.1
- The default timezone support has been added in Twig 1.6.1.
-
-The ``date`` filter formats a date to a given format:
-
-.. code-block:: jinja
-
- {{ post.published_at|date("m/d/Y") }}
-
-The ``date`` filter accepts strings (it must be in a format supported by the
-`date`_ function), `DateTime`_ instances, or `DateInterval`_ instances. For
-instance, to display the current date, filter the word "now":
-
-.. code-block:: jinja
-
- {{ "now"|date("m/d/Y") }}
-
-To escape words and characters in the date format use ``\\`` in front of each character:
-
-.. code-block:: jinja
-
- {{ post.published_at|date("F jS \\a\\t g:ia") }}
-
-You can also specify a timezone:
-
-.. code-block:: jinja
-
- {{ post.published_at|date("m/d/Y", "Europe/Paris") }}
-
-If no format is provided, Twig will use the default one: ``F j, Y H:i``. This
-default can be easily changed by calling the ``setDateFormat()`` method on the
-``core`` extension instance. The first argument is the default format for
-dates and the second one is the default format for date intervals:
-
-.. code-block:: php
-
- $twig = new Twig_Environment($loader);
- $twig->getExtension('core')->setDateFormat('d/m/Y', '%d days');
-
-The default timezone can also be set globally by calling ``setTimezone()``:
-
-.. code-block:: php
-
- $twig = new Twig_Environment($loader);
- $twig->getExtension('core')->setTimezone('Europe/Paris');
-
-.. _`date`: http://www.php.net/date
-.. _`DateTime`: http://www.php.net/DateTime
-.. _`DateInterval`: http://www.php.net/DateInterval
-
-If the value passed to the ``date`` filter is null, it will return the current date by default.
-If an empty string is desired instead of the current date, use a ternary operator:
-
-.. code-block:: jinja
-
- {{ post.published_at is empty ? "" : post.published_at|date("m/d/Y") }}
diff --git a/lib/twig/doc/filters/default.rst b/lib/twig/doc/filters/default.rst
deleted file mode 100755
index 4055ead..0000000
--- a/lib/twig/doc/filters/default.rst
+++ /dev/null
@@ -1,28 +0,0 @@
-``default``
-===========
-
-The ``default`` filter returns the passed default value if the value is
-undefined or empty, otherwise the value of the variable:
-
-.. code-block:: jinja
-
- {{ var|default('var is not defined') }}
-
- {{ var.foo|default('foo item on var is not defined') }}
-
- {{ var['foo']|default('foo item on var is not defined') }}
-
- {{ ''|default('passed var is empty') }}
-
-When using the ``default`` filter on an expression that uses variables in some
-method calls, be sure to use the ``default`` filter whenever a variable can be
-undefined:
-
-.. code-block:: jinja
-
- {{ var.method(foo|default('foo'))|default('foo') }}
-
-.. note::
-
- Read the documentation for the :doc:`defined<../tests/defined>` and
- :doc:`empty<../tests/empty>` tests to learn more about their semantics.
diff --git a/lib/twig/doc/filters/escape.rst b/lib/twig/doc/filters/escape.rst
deleted file mode 100755
index dd927b4..0000000
--- a/lib/twig/doc/filters/escape.rst
+++ /dev/null
@@ -1,30 +0,0 @@
-``escape``
-==========
-
-The ``escape`` filter converts the characters ``&``, ``<``, ``>``, ``'``, and
-``"`` in strings to HTML-safe sequences. Use this if you need to display text
-that might contain such characters in HTML:
-
-.. code-block:: jinja
-
- {{ user.username|escape }}
-
-For convenience, the ``e`` filter is defined as an alias:
-
-.. code-block:: jinja
-
- {{ user.username|e }}
-
-The ``escape`` filter can also be used in another context than HTML; for
-instance, to escape variables included in a JavaScript:
-
-.. code-block:: jinja
-
- {{ user.username|escape('js') }}
- {{ user.username|e('js') }}
-
-.. note::
-
- Internally, ``escape`` uses the PHP native `htmlspecialchars`_ function.
-
-.. _`htmlspecialchars`: http://php.net/htmlspecialchars
diff --git a/lib/twig/doc/filters/format.rst b/lib/twig/doc/filters/format.rst
deleted file mode 100755
index fd5b18d..0000000
--- a/lib/twig/doc/filters/format.rst
+++ /dev/null
@@ -1,16 +0,0 @@
-``format``
-==========
-
-The ``format`` filter formats a given string by replacing the placeholders
-(placeholders follows the `printf`_ notation):
-
-.. code-block:: jinja
-
- {{ "I like %s and %s."|format(foo, "bar") }}
-
- {# returns I like foo and bar
- if the foo parameter equals to the foo string. #}
-
-.. _`printf`: http://www.php.net/printf
-
-.. seealso:: :doc:`replace`
diff --git a/lib/twig/doc/filters/index.rst b/lib/twig/doc/filters/index.rst
deleted file mode 100755
index db2b39f..0000000
--- a/lib/twig/doc/filters/index.rst
+++ /dev/null
@@ -1,29 +0,0 @@
-Filters
-=======
-
-.. toctree::
- :maxdepth: 1
-
- date
- format
- replace
- number_format
- url_encode
- json_encode
- convert_encoding
- title
- capitalize
- nl2br
- upper
- lower
- striptags
- join
- reverse
- length
- sort
- default
- keys
- escape
- raw
- merge
- slice
diff --git a/lib/twig/doc/filters/join.rst b/lib/twig/doc/filters/join.rst
deleted file mode 100755
index eec2045..0000000
--- a/lib/twig/doc/filters/join.rst
+++ /dev/null
@@ -1,18 +0,0 @@
-``join``
-========
-
-The ``join`` filter returns a string which is the concatenation of the items
-of a sequence:
-
-.. code-block:: jinja
-
- {{ [1, 2, 3]|join }}
- {# returns 123 #}
-
-The separator between elements is an empty string per default, but you can
-define it with the optional first parameter:
-
-.. code-block:: jinja
-
- {{ [1, 2, 3]|join('|') }}
- {# returns 1|2|3 #}
diff --git a/lib/twig/doc/filters/json_encode.rst b/lib/twig/doc/filters/json_encode.rst
deleted file mode 100755
index c7d19b3..0000000
--- a/lib/twig/doc/filters/json_encode.rst
+++ /dev/null
@@ -1,14 +0,0 @@
-``json_encode``
-===============
-
-The ``json_encode`` filter returns the JSON representation of a string:
-
-.. code-block:: jinja
-
- {{ data|json_encode() }}
-
-.. note::
-
- Internally, Twig uses the PHP `json_encode`_ function.
-
-.. _`json_encode`: http://php.net/json_encode
diff --git a/lib/twig/doc/filters/keys.rst b/lib/twig/doc/filters/keys.rst
deleted file mode 100755
index e4f090c..0000000
--- a/lib/twig/doc/filters/keys.rst
+++ /dev/null
@@ -1,11 +0,0 @@
-``keys``
-========
-
-The ``keys`` filter returns the keys of an array. It is useful when you want to
-iterate over the keys of an array:
-
-.. code-block:: jinja
-
- {% for key in array|keys %}
- ...
- {% endfor %}
diff --git a/lib/twig/doc/filters/length.rst b/lib/twig/doc/filters/length.rst
deleted file mode 100755
index f79b9bd..0000000
--- a/lib/twig/doc/filters/length.rst
+++ /dev/null
@@ -1,12 +0,0 @@
-``length``
-==========
-
-The ``length`` filters returns the number of items of a sequence or mapping, or
-the length of a string:
-
-.. code-block:: jinja
-
- {% if users|length > 10 %}
- ...
- {% endif %}
-
diff --git a/lib/twig/doc/filters/lower.rst b/lib/twig/doc/filters/lower.rst
deleted file mode 100755
index ef9faa9..0000000
--- a/lib/twig/doc/filters/lower.rst
+++ /dev/null
@@ -1,10 +0,0 @@
-``lower``
-=========
-
-The ``lower`` filter converts a value to lowercase:
-
-.. code-block:: jinja
-
- {{ 'WELCOME'|lower }}
-
- {# outputs 'welcome' #}
diff --git a/lib/twig/doc/filters/merge.rst b/lib/twig/doc/filters/merge.rst
deleted file mode 100755
index 4348e7a..0000000
--- a/lib/twig/doc/filters/merge.rst
+++ /dev/null
@@ -1,41 +0,0 @@
-``merge``
-=========
-
-The ``merge`` filter merges an array with the another array:
-
-.. code-block:: jinja
-
- {% set values = [1, 2] %}
-
- {% set values = values|merge(['apple', 'orange']) %}
-
- {# values now contains [1, 2, 'apple', 'orange'] #}
-
-New values are added at the end of the existing ones.
-
-The ``merge`` filter also works on hashes:
-
-.. code-block:: jinja
-
- {% set items = { 'apple': 'fruit', 'orange': 'fruit', 'peugeot': 'unknown' } %}
-
- {% set items = items|merge({ 'peugeot': 'car', 'renault': 'car' }) %}
-
- {# items now contains { 'apple': 'fruit', 'orange': 'fruit', 'peugeot': 'car', 'renault': 'car' } #}
-
-For hashes, the merging process occurs on the keys: if the key does not
-already exist, it is added but if the key already exists, its value is
-overridden.
-
-.. tip::
-
- If you want to ensure that some values are defined in an array (by given
- default values), reverse the two elements in the call:
-
- .. code-block:: jinja
-
- {% set items = { 'apple': 'fruit', 'orange': 'fruit' } %}
-
- {% set items = { 'apple': 'unknown' }|merge(items) %}
-
- {# items now contains { 'apple': 'fruit', 'orange': 'fruit' } #}
diff --git a/lib/twig/doc/filters/nl2br.rst b/lib/twig/doc/filters/nl2br.rst
deleted file mode 100755
index 694c672..0000000
--- a/lib/twig/doc/filters/nl2br.rst
+++ /dev/null
@@ -1,22 +0,0 @@
-``nl2br``
-=========
-
-.. versionadded:: 1.5
- The nl2br filter was added in Twig 1.5.
-
-The ``nl2br`` filter inserts HTML line breaks before all newlines in a string:
-
-.. code-block:: jinja
-
- {{ "I like Twig.\nYou will like it too."|nl2br }}
- {# outputs
-
- I like Twig.
- You will like it too.
-
- #}
-
-.. note::
-
- The ``nl2br`` filter pre-escapes the input before applying the
- transformation.
diff --git a/lib/twig/doc/filters/number_format.rst b/lib/twig/doc/filters/number_format.rst
deleted file mode 100755
index ccc8f2f..0000000
--- a/lib/twig/doc/filters/number_format.rst
+++ /dev/null
@@ -1,38 +0,0 @@
-``number_format``
-=================
-
-.. versionadded:: 1.5
- The number_format filter was added in Twig 1.5
-
-The ``number_format`` filter formats numbers. It is a wrapper around PHP's
-`number_format`_ function:
-
-.. code-block:: jinja
-
- {{ 200.35|number_format }}
-
-You can control the number of decimal places, decimal point, and thousands
-separator using the additional arguments:
-
-.. code-block:: jinja
-
- {{ 9800.333|number_format(2, ',', '.') }}
-
-If no formatting options are provided then Twig will use the default formatting
-options of:
-
-- 0 decimal places.
-- ``.`` as the decimal point.
-- ``,`` as the thousands separator.
-
-These defaults can be easily changed through the core extension:
-
-.. code-block:: php
-
- $twig = new Twig_Environment($loader);
- $twig->getExtension('core')->setNumberFormat(3, ',', '.');
-
-The defaults set for ``number_format`` can be over-ridden upon each call using the
-additional parameters.
-
-.. _`number_format`: http://php.net/number_format
diff --git a/lib/twig/doc/filters/raw.rst b/lib/twig/doc/filters/raw.rst
deleted file mode 100755
index 434dd24..0000000
--- a/lib/twig/doc/filters/raw.rst
+++ /dev/null
@@ -1,12 +0,0 @@
-``raw``
-=======
-
-The ``raw`` filter marks the value as being "safe", which means that in an
-environment with automatic escaping enabled this variable will not be escaped
-if ``raw`` is the last filter applied to it:
-
-.. code-block:: jinja
-
- {% autoescape true %}
- {{ var|raw }} {# var won't be escaped #}
- {% endautoescape %}
diff --git a/lib/twig/doc/filters/replace.rst b/lib/twig/doc/filters/replace.rst
deleted file mode 100755
index cc603fa..0000000
--- a/lib/twig/doc/filters/replace.rst
+++ /dev/null
@@ -1,14 +0,0 @@
-``replace``
-===========
-
-The ``replace`` filter formats a given string by replacing the placeholders
-(placeholders are free-form):
-
-.. code-block:: jinja
-
- {{ "I like %this% and %that%."|replace({'%this%': foo, '%that%': "bar"}) }}
-
- {# returns I like foo and bar
- if the foo parameter equals to the foo string. #}
-
-.. seealso:: :doc:`format`
diff --git a/lib/twig/doc/filters/reverse.rst b/lib/twig/doc/filters/reverse.rst
deleted file mode 100755
index 54fafb4..0000000
--- a/lib/twig/doc/filters/reverse.rst
+++ /dev/null
@@ -1,23 +0,0 @@
-``reverse``
-===========
-
-.. versionadded:: 1.6
- Support for strings has been added in Twig 1.6.
-
-The ``reverse`` filter reverses a sequence, a mapping, or a string:
-
-.. code-block:: jinja
-
- {% for use in users|reverse %}
- ...
- {% endfor %}
-
- {{ '1234'|reverse }}
-
- {# outputs 4321 #}
-
-.. note::
-
- It also works with objects implementing the `Traversable`_ interface.
-
-.. _`Traversable`: http://php.net/Traversable
diff --git a/lib/twig/doc/filters/slice.rst b/lib/twig/doc/filters/slice.rst
deleted file mode 100755
index 80a4293..0000000
--- a/lib/twig/doc/filters/slice.rst
+++ /dev/null
@@ -1,57 +0,0 @@
-``slice``
-===========
-
-.. versionadded:: 1.6
- The slice filter was added in Twig 1.6.
-
-The ``slice`` filter extracts a slice of a sequence, a mapping, or a string:
-
-.. code-block:: jinja
-
- {% for i in [1, 2, 3, 4]|slice(1, 2) %}
- {# will iterate over 2 and 3 #}
- {% endfor %}
-
- {{ '1234'|slice(1, 2) }}
-
- {# outputs 23 #}
-
-You can use any valid expression for both the start and the length:
-
-.. code-block:: jinja
-
- {% for i in [1, 2, 3, 4]|slice(start, length) %}
- {# ... #}
- {% endfor %}
-
-As syntactic sugar, you can also use the ``[]`` notation:
-
-.. code-block:: jinja
-
- {% for i in [1, 2, 3, 4][start:length] %}
- {# ... #}
- {% endfor %}
-
- {{ '1234'[1:2] }}
-
-The ``slice`` filter works as the `array_slice`_ PHP function for arrays and
-`substr`_ for strings.
-
-If the start is non-negative, the sequence will start at that start in the
-variable. If start is negative, the sequence will start that far from the end
-of the variable.
-
-If length is given and is positive, then the sequence will have up to that
-many elements in it. If the variable is shorter than the length, then only the
-available variable elements will be present. If length is given and is
-negative then the sequence will stop that many elements from the end of the
-variable. If it is omitted, then the sequence will have everything from offset
-up until the end of the variable.
-
-.. note::
-
- It also works with objects implementing the `Traversable`_ interface.
-
-.. _`Traversable`: http://php.net/manual/en/class.traversable.php
-.. _`array_slice`: http://php.net/array_slice
-.. _`substr`: http://php.net/substr
diff --git a/lib/twig/doc/filters/sort.rst b/lib/twig/doc/filters/sort.rst
deleted file mode 100755
index 0e330d2..0000000
--- a/lib/twig/doc/filters/sort.rst
+++ /dev/null
@@ -1,17 +0,0 @@
-``sort``
-========
-
-The ``sort`` filter sorts an array:
-
-.. code-block:: jinja
-
- {% for use in users|sort %}
- ...
- {% endfor %}
-
-.. note::
-
- Internally, Twig uses the PHP `asort`_ function to maintain index
- association.
-
-.. _`asort`: http://php.net/asort
diff --git a/lib/twig/doc/filters/striptags.rst b/lib/twig/doc/filters/striptags.rst
deleted file mode 100755
index 5ccca45..0000000
--- a/lib/twig/doc/filters/striptags.rst
+++ /dev/null
@@ -1,15 +0,0 @@
-``striptags``
-=============
-
-The ``striptags`` filter strips SGML/XML tags and replace adjacent whitespace
-by one space:
-
-.. code-block:: jinja
-
- {% some_html|striptags %}
-
-.. note::
-
- Internally, Twig uses the PHP `strip_tags`_ function.
-
-.. _`strip_tags`: http://php.net/strip_tags
diff --git a/lib/twig/doc/filters/title.rst b/lib/twig/doc/filters/title.rst
deleted file mode 100755
index c5a318e..0000000
--- a/lib/twig/doc/filters/title.rst
+++ /dev/null
@@ -1,11 +0,0 @@
-``title``
-=========
-
-The ``title`` filter returns a titlecased version of the value. Words will
-start with uppercase letters, all remaining characters are lowercase:
-
-.. code-block:: jinja
-
- {{ 'my first car'|title }}
-
- {# outputs 'My First Car' #}
diff --git a/lib/twig/doc/filters/trim.rst b/lib/twig/doc/filters/trim.rst
deleted file mode 100755
index f1215f6..0000000
--- a/lib/twig/doc/filters/trim.rst
+++ /dev/null
@@ -1,24 +0,0 @@
-``trim``
-========
-
-.. versionadded:: 1.6.2
- The trim filter was added in Twig 1.6.2.
-
-The ``trim`` filter strips whitespace (or other characters) from the beginning
-and end of a string:
-
-.. code-block:: jinja
-
- {{ ' I like Twig. '|trim }}
-
- {# outputs 'I like Twig.' #}
-
- {{ ' I like Twig.'|trim('.') }}
-
- {# outputs ' I like Twig' #}
-
-.. note::
-
- Internally, Twig uses the PHP `trim`_ function.
-
-.. _`trim`: http://php.net/trim
diff --git a/lib/twig/doc/filters/upper.rst b/lib/twig/doc/filters/upper.rst
deleted file mode 100755
index 561cebe..0000000
--- a/lib/twig/doc/filters/upper.rst
+++ /dev/null
@@ -1,10 +0,0 @@
-``upper``
-=========
-
-The ``upper`` filter converts a value to uppercase:
-
-.. code-block:: jinja
-
- {{ 'welcome'|upper }}
-
- {# outputs 'WELCOME' #}
diff --git a/lib/twig/doc/filters/url_encode.rst b/lib/twig/doc/filters/url_encode.rst
deleted file mode 100755
index c141f3b..0000000
--- a/lib/twig/doc/filters/url_encode.rst
+++ /dev/null
@@ -1,14 +0,0 @@
-``url_encode``
-==============
-
-The ``url_encode`` filter URL encodes a given string:
-
-.. code-block:: jinja
-
- {{ data|url_encode() }}
-
-.. note::
-
- Internally, Twig uses the PHP `urlencode`_ function.
-
-.. _`urlencode`: http://php.net/urlencode
diff --git a/lib/twig/doc/functions/attribute.rst b/lib/twig/doc/functions/attribute.rst
deleted file mode 100755
index 3051bda..0000000
--- a/lib/twig/doc/functions/attribute.rst
+++ /dev/null
@@ -1,18 +0,0 @@
-``attribute``
-=============
-
-.. versionadded:: 1.2
- The ``attribute`` function was added in Twig 1.2.
-
-``attribute`` can be used to access a "dynamic" attribute of a variable:
-
-.. code-block:: jinja
-
- {{ attribute(object, method) }}
- {{ attribute(object, method, arguments) }}
- {{ attribute(array, item) }}
-
-.. note::
-
- The resolution algorithm is the same as the one used for the ``.``
- notation, except that the item can be any valid expression.
diff --git a/lib/twig/doc/functions/block.rst b/lib/twig/doc/functions/block.rst
deleted file mode 100755
index fd571ef..0000000
--- a/lib/twig/doc/functions/block.rst
+++ /dev/null
@@ -1,15 +0,0 @@
-``block``
-=========
-
-When a template uses inheritance and if you want to print a block multiple
-times, use the ``block`` function:
-
-.. code-block:: jinja
-
- {% block title %}{% endblock %}
-
-
{{ block('title') }}
-
- {% block body %}{% endblock %}
-
-.. seealso:: :doc:`extends<../tags/extends>`, :doc:`parent<../functions/parent>`
diff --git a/lib/twig/doc/functions/constant.rst b/lib/twig/doc/functions/constant.rst
deleted file mode 100755
index 5b247b3..0000000
--- a/lib/twig/doc/functions/constant.rst
+++ /dev/null
@@ -1,9 +0,0 @@
-``constant``
-============
-
-``constant`` returns the constant value for a given string:
-
-.. code-block:: jinja
-
- {{ some_date|date(constant('DATE_W3C')) }}
- {{ constant('Namespace\\Classname::CONSTANT_NAME') }}
diff --git a/lib/twig/doc/functions/cycle.rst b/lib/twig/doc/functions/cycle.rst
deleted file mode 100755
index fe11d68..0000000
--- a/lib/twig/doc/functions/cycle.rst
+++ /dev/null
@@ -1,20 +0,0 @@
-``cycle``
-=========
-
-The ``cycle`` function cycles on an array of values:
-
-.. code-block:: jinja
-
- {% for i in 0..10 %}
- {{ cycle(['odd', 'even'], i) }}
- {% endfor %}
-
-The array can contain any number of values:
-
-.. code-block:: jinja
-
- {% set fruits = ['apple', 'orange', 'citrus'] %}
-
- {% for i in 0..10 %}
- {{ cycle(fruits, i) }}
- {% endfor %}
diff --git a/lib/twig/doc/functions/date.rst b/lib/twig/doc/functions/date.rst
deleted file mode 100755
index c1a011c..0000000
--- a/lib/twig/doc/functions/date.rst
+++ /dev/null
@@ -1,46 +0,0 @@
-``date``
-========
-
-.. versionadded:: 1.6
- The date function has been added in Twig 1.6.
-
-.. versionadded:: 1.6.1
- The default timezone support has been added in Twig 1.6.1.
-
-Converts an argument to a date to allow date comparison:
-
-.. code-block:: jinja
-
- {% if date(user.created_at) < date('+2days') %}
- {# do something #}
- {% endif %}
-
-The argument must be in a format supported by the `date`_ function.
-
-You can pass a timezone as the second argument:
-
-.. code-block:: jinja
-
- {% if date(user.created_at) < date('+2days', 'Europe/Paris') %}
- {# do something #}
- {% endif %}
-
-If no argument is passed, the function returns the current date:
-
-.. code-block:: jinja
-
- {% if date(user.created_at) < date() %}
- {# always! #}
- {% endif %}
-
-.. note::
-
- You can set the default timezone globally by calling ``setTimezone()`` on
- the ``core`` extension instance:
-
- .. code-block:: php
-
- $twig = new Twig_Environment($loader);
- $twig->getExtension('core')->setTimezone('Europe/Paris');
-
-.. _`date`: http://www.php.net/date
diff --git a/lib/twig/doc/functions/dump.rst b/lib/twig/doc/functions/dump.rst
deleted file mode 100755
index 5f27b4b..0000000
--- a/lib/twig/doc/functions/dump.rst
+++ /dev/null
@@ -1,58 +0,0 @@
-``dump``
-========
-
-.. versionadded:: 1.5
- The dump function was added in Twig 1.5.
-
-The ``dump`` function dumps information about a template variable. This is
-mostly useful to debug a template that does not behave as expected by
-introspecting its variables:
-
-.. code-block:: jinja
-
- {{ dump(user) }}
-
-.. note::
-
- The ``debug`` function is not available by default. You must load it explicitly::
-
- $twig = new Twig_Environment($loader, $config);
- $twig->addExtension(new Twig_Extension_Debug());
-
- Even when loaded explicitly, it won't do anything if the ``debug`` option
- is not enabled.
-
-In an HTML context, wrap the output with a ``pre`` tag to make it easier to
-read:
-
-.. code-block:: jinja
-
-
- {{ dump(user) }}
-
-
-.. tip::
-
- Using a ``pre`` tag is not needed when `XDebug`_ is enabled and
- ``html_errors`` is ``on``; as a bonus, the output is also nicer with
- XDebug enabled.
-
-You can debug several variables by passing them as additional arguments:
-
-.. code-block:: jinja
-
- {{ dump(user, categories) }}
-
-If you don't pass any value, all variables from the current context are
-dumped:
-
-.. code-block:: jinja
-
- {{ dump() }}
-
-.. note::
-
- Internally, Twig uses the PHP `var_dump`_ function.
-
-.. _`XDebug`: http://xdebug.org/docs/display
-.. _`var_dump`: http://php.net/var_dump
diff --git a/lib/twig/doc/functions/index.rst b/lib/twig/doc/functions/index.rst
deleted file mode 100755
index 3315528..0000000
--- a/lib/twig/doc/functions/index.rst
+++ /dev/null
@@ -1,15 +0,0 @@
-Functions
-=========
-
-.. toctree::
- :maxdepth: 1
-
- range
- cycle
- constant
- random
- attribute
- block
- parent
- dump
- date
diff --git a/lib/twig/doc/functions/parent.rst b/lib/twig/doc/functions/parent.rst
deleted file mode 100755
index f5bd200..0000000
--- a/lib/twig/doc/functions/parent.rst
+++ /dev/null
@@ -1,20 +0,0 @@
-``parent``
-==========
-
-When a template uses inheritance, it's possible to render the contents of the
-parent block when overriding a block by using the ``parent`` function:
-
-.. code-block:: jinja
-
- {% extends "base.html" %}
-
- {% block sidebar %}
-
Table Of Contents
- ...
- {{ parent() }}
- {% endblock %}
-
-The ``parent()`` call will return the content of the ``sidebar`` block as
-defined in the ``base.html`` template.
-
-.. seealso:: :doc:`extends<../tags/extends>`, :doc:`block<../functions/block>`, :doc:`block<../tags/block>`
diff --git a/lib/twig/doc/functions/random.rst b/lib/twig/doc/functions/random.rst
deleted file mode 100755
index 104493d..0000000
--- a/lib/twig/doc/functions/random.rst
+++ /dev/null
@@ -1,24 +0,0 @@
-``random``
-==========
-
-.. versionadded:: 1.5
- The random function was added in Twig 1.5.
-
-.. versionadded:: 1.6
- String and integer handling was added in Twig 1.6.
-
-The ``random`` function returns a random value depending on the supplied
-parameter type:
-
-* a random item from a sequence;
-* a random character from a string;
-* a random integer between 0 and the integer parameter (inclusive).
-
-.. code-block:: jinja
-
- {{ random(['apple', 'orange', 'citrus']) }} {# example output: orange #}
- {{ random('ABC') }} {# example output: C #}
- {{ random() }} {# example output: 15386094 (works as native PHP `mt_rand`_ function) #}
- {{ random(5) }} {# example output: 3 #}
-
-.. _`mt_rand`: http://php.net/mt_rand
diff --git a/lib/twig/doc/functions/range.rst b/lib/twig/doc/functions/range.rst
deleted file mode 100755
index c9bdd96..0000000
--- a/lib/twig/doc/functions/range.rst
+++ /dev/null
@@ -1,38 +0,0 @@
-``range``
-=========
-
-Returns a list containing an arithmetic progression of integers:
-
-.. code-block:: jinja
-
- {% for i in range(0, 3) %}
- {{ i }},
- {% endfor %}
-
- {# returns 0, 1, 2, 3 #}
-
-When step is given (as the third parameter), it specifies the increment (or
-decrement):
-
-.. code-block:: jinja
-
- {% for i in range(0, 6, 2) %}
- {{ i }},
- {% endfor %}
-
- {# returns 0, 2, 4, 6 #}
-
-The Twig built-in ``..`` operator is just syntactic sugar for the ``range``
-function (with a step of 1):
-
-.. code-block:: jinja
-
- {% for i in 0..3 %}
- {{ i }},
- {% endfor %}
-
-.. tip::
-
- The ``range`` function works as the native PHP `range`_ function.
-
-.. _`range`: http://php.net/range
diff --git a/lib/twig/doc/hacking.rst b/lib/twig/doc/hacking.rst
deleted file mode 100755
index 0a82b6c..0000000
--- a/lib/twig/doc/hacking.rst
+++ /dev/null
@@ -1,184 +0,0 @@
-Hacking Twig
-============
-
-Twig is very extensible and you can easily hack it. Keep in mind that you
-should probably try to create an extension before hacking the core, as most
-features and enhancements can be done with extensions. This chapter is also
-useful for people who want to understand how Twig works under the hood.
-
-How Twig works?
----------------
-
-The rendering of a Twig template can be summarized into four key steps:
-
-* **Load** the template: If the template is already compiled, load it and go
- to the *evaluation* step, otherwise:
-
- * First, the **lexer** tokenizes the template source code into small pieces
- for easier processing;
- * Then, the **parser** converts the token stream into a meaningful tree
- of nodes (the Abstract Syntax Tree);
- * Eventually, the *compiler* transforms the AST into PHP code;
-
-* **Evaluate** the template: It basically means calling the ``display()``
- method of the compiled template and passing it the context.
-
-The Lexer
----------
-
-The Twig lexer goal is to tokenize a source code into a token stream (each
-token is of class ``Token``, and the stream is an instance of
-``Twig_TokenStream``). The default lexer recognizes nine different token types:
-
-* ``Twig_Token::TEXT_TYPE``
-* ``Twig_Token::BLOCK_START_TYPE``
-* ``Twig_Token::VAR_START_TYPE``
-* ``Twig_Token::BLOCK_END_TYPE``
-* ``Twig_Token::VAR_END_TYPE``
-* ``Twig_Token::NAME_TYPE``
-* ``Twig_Token::NUMBER_TYPE``
-* ``Twig_Token::STRING_TYPE``
-* ``Twig_Token::OPERATOR_TYPE``
-* ``Twig_Token::EOF_TYPE``
-
-You can manually convert a source code into a token stream by calling the
-``tokenize()`` of an environment::
-
- $stream = $twig->tokenize($source, $identifier);
-
-As the stream has a ``__toString()`` method, you can have a textual
-representation of it by echoing the object::
-
- echo $stream."\n";
-
-Here is the output for the ``Hello {{ name }}`` template:
-
-.. code-block:: text
-
- TEXT_TYPE(Hello )
- VAR_START_TYPE()
- NAME_TYPE(name)
- VAR_END_TYPE()
- EOF_TYPE()
-
-You can change the default lexer use by Twig (``Twig_Lexer``) by calling the
-``setLexer()`` method::
-
- $twig->setLexer($lexer);
-
-Lexer classes must implement the ``Twig_LexerInterface``::
-
- 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
- */
- function tokenize($code, $filename = 'n/a');
- }
-
-The Parser
-----------
-
-The parser converts the token stream into an AST (Abstract Syntax Tree), or a
-node tree (of class ``Twig_Node_Module``). The core extension defines the
-basic nodes like: ``for``, ``if``, ... and the expression nodes.
-
-You can manually convert a token stream into a node tree by calling the
-``parse()`` method of an environment::
-
- $nodes = $twig->parse($stream);
-
-Echoing the node object gives you a nice representation of the tree::
-
- echo $nodes."\n";
-
-Here is the output for the ``Hello {{ name }}`` template:
-
-.. code-block:: text
-
- Twig_Node_Module(
- Twig_Node_Text(Hello )
- Twig_Node_Print(
- Twig_Node_Expression_Name(name)
- )
- )
-
-The default parser (``Twig_TokenParser``) can be also changed by calling the
-``setParser()`` method::
-
- $twig->setParser($parser);
-
-All Twig parsers must implement the ``Twig_ParserInterface``::
-
- 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
- */
- function parser(Twig_TokenStream $code);
- }
-
-The Compiler
-------------
-
-The last step is done by the compiler. It takes a node tree as an input and
-generates PHP code usable for runtime execution of the templates. The default
-compiler generates PHP classes to ease the implementation of the template
-inheritance feature.
-
-You can call the compiler by hand with the ``compile()`` method of an
-environment::
-
- $php = $twig->compile($nodes);
-
-The ``compile()`` method returns the PHP source code representing the node.
-
-The generated template for a ``Hello {{ name }}`` template reads as follows::
-
- /* Hello {{ name }} */
- class __TwigTemplate_1121b6f109fe93ebe8c6e22e3712bceb extends Twig_Template
- {
- public function display($context)
- {
- $this->env->initRuntime();
-
- // line 1
- echo "Hello ";
- echo (isset($context['name']) ? $context['name'] : null);
- }
- }
-
-As for the lexer and the parser, the default compiler (``Twig_Compiler``) can
-be changed by calling the ``setCompiler()`` method::
-
- $twig->setCompiler($compiler);
-
-All Twig compilers must implement the ``Twig_CompilerInterface``::
-
- interface Twig_CompilerInterface
- {
- /**
- * Compiles a node.
- *
- * @param Twig_Node $node The node to compile
- *
- * @return Twig_Compiler The current compiler instance
- */
- function compile(Twig_Node $node);
-
- /**
- * Gets the current PHP code after compilation.
- *
- * @return string The PHP code
- */
- function getSource();
- }
diff --git a/lib/twig/doc/index.rst b/lib/twig/doc/index.rst
deleted file mode 100755
index 55517ea..0000000
--- a/lib/twig/doc/index.rst
+++ /dev/null
@@ -1,18 +0,0 @@
-Twig
-====
-
-.. toctree::
- :maxdepth: 2
-
- intro
- templates
- api
- advanced
- extensions
- hacking
- recipes
- coding_standards
- tags/index
- filters/index
- functions/index
- tests/index
diff --git a/lib/twig/doc/intro.rst b/lib/twig/doc/intro.rst
deleted file mode 100755
index 06eabd8..0000000
--- a/lib/twig/doc/intro.rst
+++ /dev/null
@@ -1,153 +0,0 @@
-Introduction
-============
-
-This is the documentation for Twig, the flexible, fast, and secure template
-engine for PHP.
-
-If you have any exposure to other text-based template languages, such as
-Smarty, Django, or Jinja, you should feel right at home with Twig. It's both
-designer and developer friendly by sticking to PHP's principles and adding
-functionality useful for templating environments.
-
-The key-features are...
-
-* *Fast*: Twig compiles templates down to plain optimized PHP code. The
- overhead compared to regular PHP code was reduced to the very minimum.
-
-* *Secure*: Twig has a sandbox mode to evaluate untrusted template code. This
- allows Twig to be used as a template language for applications where users
- may modify the template design.
-
-* *Flexible*: Twig is powered by a flexible lexer and parser. This allows the
- developer to define its own custom tags and filters, and create its own DSL.
-
-Prerequisites
--------------
-
-Twig needs at least **PHP 5.2.4** to run.
-
-Installation
-------------
-
-You have multiple ways to install Twig. If you are unsure what to do, go with
-the tarball.
-
-Installing from the tarball release
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-1. Download the most recent tarball from the `download page`_
-2. Unpack the tarball
-3. Move the files somewhere in your project
-
-Installing the development version
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-1. Install Subversion or Git
-2. For Git: ``git clone git://github.com/fabpot/Twig.git``
-3. For Subversion: ``svn co http://svn.twig-project.org/trunk/ twig``
-
-Installing the PEAR package
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-1. Install PEAR
-2. ``pear channel-discover pear.twig-project.org``
-3. ``pear install twig/Twig`` (or ``pear install twig/Twig-beta``)
-
-Installing via Composer
-~~~~~~~~~~~~~~~~~~~~~~~
-
-1. Install composer in your project:
-
-.. code-block:: bash
-
- curl -s http://getcomposer.org/installer | php``
-
-2. Create a ``composer.json`` file in your project root:
-
-.. code-block:: javascript
-
- {
- "require": {
- "twig/twig": "1.6.0"
- }
- }
-
-3. Install via composer
-
-.. code-block:: bash
-
- php composer.phar install
-
-Installing the C extension
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. versionadded:: 1.4
- The C extension was added in Twig 1.4.
-
-Twig comes with a C extension that enhances the performance of the Twig
-runtime engine. You can install it like any other PHP extension:
-
-.. code-block:: bash
-
- $ cd ext/twig
- $ phpize
- $ ./configure
- $ make
- $ make install
-
-Finally, enable the extension in your ``php.ini`` configuration file:
-
-.. code-block:: ini
-
- extension=twig.so
-
-And from now on, Twig will automatically compile your templates to take
-advantage of the C extension.
-
-.. tip::
-
- On Windows, you can also simply download and install a `pre-build DLL`_.
-
-Basic API Usage
----------------
-
-This section gives you a brief introduction to the PHP API for Twig.
-
-The first step to use Twig is to register its autoloader::
-
- require_once '/path/to/lib/Twig/Autoloader.php';
- Twig_Autoloader::register();
-
-Replace the ``/path/to/lib/`` path with the path you used for Twig
-installation.
-
-.. note::
-
- Twig follows the PEAR convention names for its classes, which means you
- can easily integrate Twig classes loading in your own autoloader.
-
-.. code-block:: php
-
- $loader = new Twig_Loader_String();
- $twig = new Twig_Environment($loader);
-
- echo $twig->render('Hello {{ name }}!', array('name' => 'Fabien'));
-
-Twig uses a loader (``Twig_Loader_String``) to locate templates, and an
-environment (``Twig_Environment``) to store the configuration.
-
-The ``render()`` method loads the template passed as a first argument and
-renders it with the variables passed as a second argument.
-
-As templates are generally stored on the filesystem, Twig also comes with a
-filesystem loader::
-
- $loader = new Twig_Loader_Filesystem('/path/to/templates');
- $twig = new Twig_Environment($loader, array(
- 'cache' => '/path/to/compilation_cache',
- ));
-
- echo $twig->render('index.html', array('name' => 'Fabien'));
-
-.. _`download page`: https://github.com/fabpot/Twig/tags
-.. _`pre-build DLL`: https://github.com/stealth35/stealth35.github.com/downloads
diff --git a/lib/twig/doc/recipes.rst b/lib/twig/doc/recipes.rst
deleted file mode 100755
index 0335335..0000000
--- a/lib/twig/doc/recipes.rst
+++ /dev/null
@@ -1,301 +0,0 @@
-Recipes
-=======
-
-Making a Layout conditional
----------------------------
-
-Working with Ajax means that the same content is sometimes displayed as is,
-and sometimes decorated with a layout. As Twig layout template names can be
-any valid expression, you can pass a variable that evaluates to ``true`` when
-the request is made via Ajax and choose the layout accordingly:
-
-.. code-block:: jinja
-
- {% extends request.ajax ? "base_ajax.html" : "base.html" %}
-
- {% block content %}
- This is the content to be displayed.
- {% endblock %}
-
-Making an Include dynamic
--------------------------
-
-When including a template, its name does not need to be a string. For
-instance, the name can depend on the value of a variable:
-
-.. code-block:: jinja
-
- {% include var ~ '_foo.html' %}
-
-If ``var`` evaluates to ``index``, the ``index_foo.html`` template will be
-rendered.
-
-As a matter of fact, the template name can be any valid expression, such as
-the following:
-
-.. code-block:: jinja
-
- {% include var|default('index') ~ '_foo.html' %}
-
-Overriding a Template that also extends itself
-----------------------------------------------
-
-A template can be customized in two different ways:
-
-* *Inheritance*: A template *extends* a parent template and overrides some
- blocks;
-
-* *Replacement*: If you use the filesystem loader, Twig loads the first
- template it finds in a list of configured directories; a template found in a
- directory *replaces* another one from a directory further in the list.
-
-But how do you combine both: *replace* a template that also extends itself
-(aka a template in a directory further in the list)?
-
-Let's say that your templates are loaded from both ``.../templates/mysite``
-and ``.../templates/default`` in this order. The ``page.twig`` template,
-stored in ``.../templates/default`` reads as follows:
-
-.. code-block:: jinja
-
- {# page.twig #}
- {% extends "layout.twig" %}
-
- {% block content %}
- {% endblock %}
-
-You can replace this template by putting a file with the same name in
-``.../templates/mysite``. And if you want to extend the original template, you
-might be tempted to write the following:
-
-.. code-block:: jinja
-
- {# page.twig in .../templates/mysite #}
- {% extends "page.twig" %} {# from .../templates/default #}
-
-Of course, this will not work as Twig will always load the template from
-``.../templates/mysite``.
-
-It turns out it is possible to get this to work, by adding a directory right
-at the end of your template directories, which is the parent of all of the
-other directories: ``.../templates`` in our case. This has the effect of
-making every template file within our system uniquely addressable. Most of the
-time you will use the "normal" paths, but in the special case of wanting to
-extend a template with an overriding version of itself we can reference its
-parent's full, unambiguous template path in the extends tag:
-
-.. code-block:: jinja
-
- {# page.twig in .../templates/mysite #}
- {% extends "default/page.twig" %} {# from .../templates #}
-
-.. note::
-
- This recipe was inspired by the following Django wiki page:
- http://code.djangoproject.com/wiki/ExtendingTemplates
-
-Customizing the Syntax
-----------------------
-
-Twig allows some syntax customization for the block delimiters. It's not
-recommended to use this feature as templates will be tied with your custom
-syntax. But for specific projects, it can make sense to change the defaults.
-
-To change the block delimiters, you need to create your own lexer object::
-
- $twig = new Twig_Environment();
-
- $lexer = new Twig_Lexer($twig, array(
- 'tag_comment' => array('{#', '#}'),
- 'tag_block' => array('{%', '%}'),
- 'tag_variable' => array('{{', '}}'),
- ));
- $twig->setLexer($lexer);
-
-Here are some configuration example that simulates some other template engines
-syntax::
-
- // Ruby erb syntax
- $lexer = new Twig_Lexer($twig, array(
- 'tag_comment' => array('<%#', '%>'),
- 'tag_block' => array('<%', '%>'),
- 'tag_variable' => array('<%=', '%>'),
- ));
-
- // SGML Comment Syntax
- $lexer = new Twig_Lexer($twig, array(
- 'tag_comment' => array(''),
- 'tag_block' => array(''),
- 'tag_variable' => array('${', '}'),
- ));
-
- // Smarty like
- $lexer = new Twig_Lexer($twig, array(
- 'tag_comment' => array('{*', '*}'),
- 'tag_block' => array('{', '}'),
- 'tag_variable' => array('{$', '}'),
- ));
-
-Using dynamic Object Properties
--------------------------------
-
-When Twig encounters a variable like ``article.title``, it tries to find a
-``title`` public property in the ``article`` object.
-
-It also works if the property does not exist but is rather defined dynamically
-thanks to the magic ``__get()`` method; you just need to also implement the
-``__isset()`` magic method like shown in the following snippet of code::
-
- class Article
- {
- public function __get($name)
- {
- if ('title' == $name)
- {
- return 'The title';
- }
-
- // throw some kind of error
- }
-
- public function __isset($name)
- {
- if ('title' == $name)
- {
- return true;
- }
-
- return false;
- }
- }
-
-Accessing the parent Context in Nested Loops
---------------------------------------------
-
-Sometimes, when using nested loops, you need to access the parent context. The
-parent context is always accessible via the ``loop.parent`` variable. For
-instance, if you have the following template data::
-
- $data = array(
- 'topics' => array(
- 'topic1' => array('Message 1 of topic 1', 'Message 2 of topic 1'),
- 'topic2' => array('Message 1 of topic 2', 'Message 2 of topic 2'),
- ),
- );
-
-And the following template to display all messages in all topics:
-
-.. code-block:: jinja
-
- {% for topic, messages in topics %}
- * {{ loop.index }}: {{ topic }}
- {% for message in messages %}
- - {{ loop.parent.loop.index }}.{{ loop.index }}: {{ message }}
- {% endfor %}
- {% endfor %}
-
-The output will be similar to:
-
-.. code-block:: text
-
- * 1: topic1
- - 1.1: The message 1 of topic 1
- - 1.2: The message 2 of topic 1
- * 2: topic2
- - 2.1: The message 1 of topic 2
- - 2.2: The message 2 of topic 2
-
-In the inner loop, the ``loop.parent`` variable is used to access the outer
-context. So, the index of the current ``topic`` defined in the outer for loop
-is accessible via the ``loop.parent.loop.index`` variable.
-
-Defining undefined Functions and Filters on the Fly
----------------------------------------------------
-
-When a function (or a filter) is not defined, Twig defaults to throw a
-``Twig_Error_Syntax`` exception. However, it can also call a `callback`_ (any
-valid PHP callable) which should return a function (or a filter).
-
-For filters, register callbacks with ``registerUndefinedFilterCallback()``.
-For functions, use ``registerUndefinedFunctionCallback()``::
-
- // auto-register all native PHP functions as Twig functions
- // don't try this at home as it's not secure at all!
- $twig->registerUndefinedFunctionCallback(function ($name) {
- if (function_exists($name)) {
- return new Twig_Function_Function($name);
- }
-
- return false;
- });
-
-If the callable is not able to return a valid function (or filter), it must
-return ``false``.
-
-If you register more than one callback, Twig will call them in turn until one
-does not return ``false``.
-
-.. tip::
-
- As the resolution of functions and filters is done during compilation,
- there is no overhead when registering these callbacks.
-
-Validating the Template Syntax
-------------------------------
-
-When template code is providing by a third-party (through a web interface for
-instance), it might be interesting to validate the template syntax before
-saving it. If the template code is stored in a `$template` variable, here is
-how you can do it::
-
- try {
- $twig->parse($twig->tokenize($template));
-
- // the $template is valid
- } catch (Twig_Error_Syntax $e) {
- // $template contains one or more syntax errors
- }
-
-Refreshing modified Templates when APC is enabled and apc.stat = 0
-------------------------------------------------------------------
-
-When using APC with ``apc.stat`` set to ``0`` and Twig cache enabled, clearing
-the template cache won't update the APC cache. To get around this, one can
-extend ``Twig_Environment`` and force the update of the APC cache when Twig
-rewrites the cache::
-
- class Twig_Environment_APC extends Twig_Environment
- {
- protected function writeCacheFile($file, $content)
- {
- parent::writeCacheFile($file, $content);
-
- // Compile cached file into bytecode cache
- apc_compile_file($file);
- }
- }
-
-Reusing a stateful Node Visitor
--------------------------------
-
-When attaching a visitor to a ``Twig_Environment`` instance, Twig uses it to
-visit *all* templates it compiles. If you need to keep some state information
-around, you probably want to reset it when visiting a new template.
-
-This can be easily achieved with the following code::
-
- protected $someTemplateState = array();
-
- public function enterNode(Twig_NodeInterface $node, Twig_Environment $env)
- {
- if ($node instanceof Twig_Node_Module) {
- // reset the state as we are entering a new template
- $this->someTemplateState = array();
- }
-
- // ...
-
- return $node;
- }
-
-.. _callback: http://www.php.net/manual/en/function.is-callable.php
diff --git a/lib/twig/doc/tags/autoescape.rst b/lib/twig/doc/tags/autoescape.rst
deleted file mode 100755
index 89c0420..0000000
--- a/lib/twig/doc/tags/autoescape.rst
+++ /dev/null
@@ -1,43 +0,0 @@
-``autoescape``
-==============
-
-Whether automatic escaping is enabled or not, you can mark a section of a
-template to be escaped or not by using the ``autoescape`` tag:
-
-.. code-block:: jinja
-
- {% autoescape true %}
- Everything will be automatically escaped in this block
- {% endautoescape %}
-
- {% autoescape false %}
- Everything will be outputed as is in this block
- {% endautoescape %}
-
- {% autoescape true js %}
- Everything will be automatically escaped in this block
- using the js escaping strategy
- {% endautoescape %}
-
-When automatic escaping is enabled everything is escaped by default except for
-values explicitly marked as safe. Those can be marked in the template by using
-the :doc:`raw<../filters/raw>` filter:
-
-.. code-block:: jinja
-
- {% autoescape true %}
- {{ safe_value|raw }}
- {% endautoescape %}
-
-Functions returning template data (like :doc:`macros` and
-:doc:`parent<../functions/parent>`) always return safe markup.
-
-.. note::
-
- Twig is smart enough to not escape an already escaped value by the
- :doc:`escape<../filters/escape>` filter.
-
-.. note::
-
- The chapter :doc:`Twig for Developers<../api>` gives more information
- about when and how automatic escaping is applied.
diff --git a/lib/twig/doc/tags/block.rst b/lib/twig/doc/tags/block.rst
deleted file mode 100755
index e380482..0000000
--- a/lib/twig/doc/tags/block.rst
+++ /dev/null
@@ -1,11 +0,0 @@
-``block``
-=========
-
-Blocks are used for inheritance and act as placeholders and replacements at
-the same time. They are documented in detail in the documentation for the
-:doc:`extends<../tags/extends>` tag.
-
-Block names should consist of alphanumeric characters, and underscores. Dashes
-are not permitted.
-
-.. seealso:: :doc:`block<../functions/block>`, :doc:`parent<../functions/parent>`, :doc:`use<../tags/use>`, :doc:`extends<../tags/extends>`
diff --git a/lib/twig/doc/tags/do.rst b/lib/twig/doc/tags/do.rst
deleted file mode 100755
index eca63d0..0000000
--- a/lib/twig/doc/tags/do.rst
+++ /dev/null
@@ -1,12 +0,0 @@
-``do``
-======
-
-.. versionadded:: 1.5
- The do tag was added in Twig 1.5.
-
-The ``do`` tag works exactly like the regular variable expression (``{{ ...
-}}``) just that it doesn't print anything:
-
-.. code-block:: jinja
-
- {% do 1 + 2 %}
diff --git a/lib/twig/doc/tags/extends.rst b/lib/twig/doc/tags/extends.rst
deleted file mode 100755
index 8d64436..0000000
--- a/lib/twig/doc/tags/extends.rst
+++ /dev/null
@@ -1,187 +0,0 @@
-``extends``
-===========
-
-The ``extends`` tag can be used to extend a template from another one.
-
-.. note::
-
- Like PHP, Twig does not support multiple inheritance. So you can only have
- one extends tag called per rendering. However, Twig supports horizontal
- :doc:`reuse
+ *
+ * @param string $value A string
+ * @param string $delimiter The delimiter
+ * @param integer $limit The limit
+ *
+ * @return array The split string as an array
+ */
+function twig_split_filter($value, $delimiter, $limit = null)
+{
+ if (empty($delimiter)) {
+ return str_split($value, null === $limit ? 1 : $limit);
+ }
+
+ return null === $limit ? explode($delimiter, $value) : explode($delimiter, $value, $limit);
+}
+
// The '_default' filter is used internally to avoid using the ternary operator
// which costs a lot for big contexts (before PHP 5.4). So, on average,
// a function call is cheaper.
@@ -709,15 +822,15 @@ function twig_sort_filter($array)
function twig_in_filter($value, $compare)
{
if (is_array($compare)) {
- return in_array($value, $compare);
+ return in_array($value, $compare, is_object($value));
} elseif (is_string($compare)) {
- if (!strlen((string) $value)) {
+ if (!strlen($value)) {
return empty($compare);
}
return false !== strpos($compare, (string) $value);
- } elseif (is_object($compare) && $compare instanceof Traversable) {
- return in_array($value, iterator_to_array($compare, false));
+ } elseif ($compare instanceof Traversable) {
+ return in_array($value, iterator_to_array($compare, false), is_object($value));
}
return false;
@@ -728,11 +841,11 @@ function twig_in_filter($value, $compare)
*
* @param Twig_Environment $env A Twig_Environment instance
* @param string $string The value to be escaped
- * @param string $type The escaping strategy
+ * @param string $strategy The escaping strategy
* @param string $charset The charset
* @param Boolean $autoescape Whether the function is called by the auto-escaping feature (true) or by the developer (false)
*/
-function twig_escape_filter(Twig_Environment $env, $string, $type = 'html', $charset = null, $autoescape = false)
+function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html', $charset = null, $autoescape = false)
{
if ($autoescape && is_object($string) && $string instanceof Twig_Markup) {
return $string;
@@ -748,7 +861,7 @@ function twig_escape_filter(Twig_Environment $env, $string, $type = 'html', $cha
$string = (string) $string;
- switch ($type) {
+ switch ($strategy) {
case 'js':
// escape all non-alphanumeric characters
// into their \xHH or \uHHHH representations
@@ -756,10 +869,46 @@ function twig_escape_filter(Twig_Environment $env, $string, $type = 'html', $cha
$string = twig_convert_encoding($string, 'UTF-8', $charset);
}
- if (null === $string = preg_replace_callback('#[^\p{L}\p{N} ]#u', '_twig_escape_js_callback', $string)) {
+ if (0 == strlen($string) ? false : (1 == preg_match('/^./su', $string) ? false : true)) {
throw new Twig_Error_Runtime('The string to escape is not a valid UTF-8 string.');
}
+ $string = preg_replace_callback('#[^a-zA-Z0-9,\._]#Su', '_twig_escape_js_callback', $string);
+
+ if ('UTF-8' != $charset) {
+ $string = twig_convert_encoding($string, $charset, 'UTF-8');
+ }
+
+ return $string;
+
+ case 'css':
+ if ('UTF-8' != $charset) {
+ $string = twig_convert_encoding($string, 'UTF-8', $charset);
+ }
+
+ if (0 == strlen($string) ? false : (1 == preg_match('/^./su', $string) ? false : true)) {
+ throw new Twig_Error_Runtime('The string to escape is not a valid UTF-8 string.');
+ }
+
+ $string = preg_replace_callback('#[^a-zA-Z0-9]#Su', '_twig_escape_css_callback', $string);
+
+ if ('UTF-8' != $charset) {
+ $string = twig_convert_encoding($string, $charset, 'UTF-8');
+ }
+
+ return $string;
+
+ case 'html_attr':
+ if ('UTF-8' != $charset) {
+ $string = twig_convert_encoding($string, 'UTF-8', $charset);
+ }
+
+ if (0 == strlen($string) ? false : (1 == preg_match('/^./su', $string) ? false : true)) {
+ throw new Twig_Error_Runtime('The string to escape is not a valid UTF-8 string.');
+ }
+
+ $string = preg_replace_callback('#[^a-zA-Z0-9,\.\-_]#Su', '_twig_escape_html_attr_callback', $string);
+
if ('UTF-8' != $charset) {
$string = twig_convert_encoding($string, $charset, 'UTF-8');
}
@@ -771,7 +920,7 @@ function twig_escape_filter(Twig_Environment $env, $string, $type = 'html', $cha
// Using a static variable to avoid initializing the array
// each time the function is called. Moving the declaration on the
- // top of the function slow downs other escaping types.
+ // top of the function slow downs other escaping strategies.
static $htmlspecialcharsCharsets = array(
'iso-8859-1' => true, 'iso8859-1' => true,
'iso-8859-15' => true, 'iso8859-15' => true,
@@ -798,8 +947,15 @@ function twig_escape_filter(Twig_Environment $env, $string, $type = 'html', $cha
return twig_convert_encoding($string, $charset, 'UTF-8');
+ case 'url':
+ if (version_compare(PHP_VERSION, '5.3.0', '<')) {
+ return str_replace('%7E', '~', rawurlencode($string));
+ }
+
+ return rawurlencode($string);
+
default:
- throw new Twig_Error_Runtime(sprintf('Invalid escape type "%s".', $type));
+ throw new Twig_Error_Runtime(sprintf('Invalid escaping strategy "%s" (valid ones: html, js, url, css, and html_attr).', $strategy));
}
}
@@ -817,16 +973,16 @@ function twig_escape_filter_is_safe(Twig_Node $filterArgs)
return array('html');
}
-if (function_exists('iconv')) {
- function twig_convert_encoding($string, $to, $from)
- {
- return iconv($from, $to, $string);
- }
-} elseif (function_exists('mb_convert_encoding')) {
+if (function_exists('mb_convert_encoding')) {
function twig_convert_encoding($string, $to, $from)
{
return mb_convert_encoding($string, $to, $from);
}
+} elseif (function_exists('iconv')) {
+ function twig_convert_encoding($string, $to, $from)
+ {
+ return iconv($from, $to, $string);
+ }
} else {
function twig_convert_encoding($string, $to, $from)
{
@@ -840,13 +996,89 @@ function _twig_escape_js_callback($matches)
// \xHH
if (!isset($char[1])) {
- return '\\x'.substr('00'.bin2hex($char), -2);
+ return '\\x'.strtoupper(substr('00'.bin2hex($char), -2));
}
// \uHHHH
$char = twig_convert_encoding($char, 'UTF-16BE', 'UTF-8');
- return '\\u'.substr('0000'.bin2hex($char), -4);
+ return '\\u'.strtoupper(substr('0000'.bin2hex($char), -4));
+}
+
+function _twig_escape_css_callback($matches)
+{
+ $char = $matches[0];
+
+ // \xHH
+ if (!isset($char[1])) {
+ $hex = ltrim(strtoupper(bin2hex($char)), '0');
+ if (0 === strlen($hex)) {
+ $hex = '0';
+ }
+
+ return '\\'.$hex.' ';
+ }
+
+ // \uHHHH
+ $char = twig_convert_encoding($char, 'UTF-16BE', 'UTF-8');
+
+ return '\\'.ltrim(strtoupper(bin2hex($char)), '0').' ';
+}
+
+/**
+ * This function is adapted from code coming from Zend Framework.
+ *
+ * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
+ * @license http://framework.zend.com/license/new-bsd New BSD License
+ */
+function _twig_escape_html_attr_callback($matches)
+{
+ /*
+ * While HTML supports far more named entities, the lowest common denominator
+ * has become HTML5's XML Serialisation which is restricted to the those named
+ * entities that XML supports. Using HTML entities would result in this error:
+ * XML Parsing Error: undefined entity
+ */
+ static $entityMap = array(
+ 34 => 'quot', /* quotation mark */
+ 38 => 'amp', /* ampersand */
+ 60 => 'lt', /* less-than sign */
+ 62 => 'gt', /* greater-than sign */
+ );
+
+ $chr = $matches[0];
+ $ord = ord($chr);
+
+ /**
+ * The following replaces characters undefined in HTML with the
+ * hex entity for the Unicode replacement character.
+ */
+ if (($ord <= 0x1f && $chr != "\t" && $chr != "\n" && $chr != "\r") || ($ord >= 0x7f && $ord <= 0x9f)) {
+ return '�';
+ }
+
+ /**
+ * Check if the current character to escape has a name entity we should
+ * replace it with while grabbing the hex value of the character.
+ */
+ if (strlen($chr) == 1) {
+ $hex = strtoupper(substr('00'.bin2hex($chr), -2));
+ } else {
+ $chr = twig_convert_encoding($chr, 'UTF-16BE', 'UTF-8');
+ $hex = strtoupper(substr('0000'.bin2hex($chr), -4));
+ }
+
+ $int = hexdec($hex);
+ if (array_key_exists($int, $entityMap)) {
+ return sprintf('&%s;', $entityMap[$int]);
+ }
+
+ /**
+ * Per OWASP recommendations, we'll use hex entities for any other
+ * characters where a named entity does not exist.
+ */
+
+ return sprintf('%s;', $hex);
}
// add multibyte extensions if possible
@@ -934,8 +1166,7 @@ if (function_exists('mb_get_info')) {
}
}
// and byte fallback
-else
-{
+else {
/**
* Returns the length of a variable.
*
@@ -979,11 +1210,11 @@ else
/* used internally */
function twig_ensure_traversable($seq)
{
- if (is_array($seq) || (is_object($seq) && $seq instanceof Traversable)) {
+ if ($seq instanceof Traversable || is_array($seq)) {
return $seq;
- } else {
- return array();
}
+
+ return array();
}
/**
@@ -1006,5 +1237,108 @@ function twig_test_empty($value)
return 0 == count($value);
}
- return false === $value || (empty($value) && '0' != $value);
+ return '' === $value || false === $value || null === $value || array() === $value;
+}
+
+/**
+ * Checks if a variable is traversable.
+ *
+ *
+ * {# evaluates to true if the foo variable is an array or a traversable object #}
+ * {% if foo is traversable %}
+ * {# ... #}
+ * {% endif %}
+ *
+ *
+ * @param mixed $value A variable
+ *
+ * @return Boolean true if the value is traversable
+ */
+function twig_test_iterable($value)
+{
+ return $value instanceof Traversable || is_array($value);
+}
+
+/**
+ * Renders a template.
+ *
+ * @param string template The template to render
+ * @param array variables The variables to pass to the template
+ * @param Boolean with_context Whether to pass the current context variables or not
+ * @param Boolean ignore_missing Whether to ignore missing templates or not
+ * @param Boolean sandboxed Whether to sandbox the template or not
+ *
+ * @return string The rendered template
+ */
+function twig_include(Twig_Environment $env, $context, $template, $variables = array(), $withContext = true, $ignoreMissing = false, $sandboxed = false)
+{
+ if ($withContext) {
+ $variables = array_merge($context, $variables);
+ }
+
+ if ($isSandboxed = $sandboxed && $env->hasExtension('sandbox')) {
+ $sandbox = $env->getExtension('sandbox');
+ if (!$alreadySandboxed = $sandbox->isSandboxed()) {
+ $sandbox->enableSandbox();
+ }
+ }
+
+ try {
+ return $env->resolveTemplate($template)->display($variables);
+ } catch (Twig_Error_Loader $e) {
+ if (!$ignoreMissing) {
+ throw $e;
+ }
+ }
+
+ if ($isSandboxed && !$alreadySandboxed) {
+ $sandbox->disableSandbox();
+ }
+}
+
+/**
+ * Provides the ability to get constants from instances as well as class/global constants.
+ *
+ * @param string $constant The name of the constant
+ * @param null|object $object The object to get the constant from
+ *
+ * @return string
+ */
+function twig_constant($constant, $object = null)
+{
+ if (null !== $object) {
+ $constant = get_class($object).'::'.$constant;
+ }
+
+ return constant($constant);
+}
+
+/**
+ * Batches item.
+ *
+ * @param array $items An array of items
+ * @param integer $size The size of the batch
+ * @param string $fill A string to fill missing items
+ *
+ * @return array
+ */
+function twig_array_batch($items, $size, $fill = null)
+{
+ if ($items instanceof Traversable) {
+ $items = iterator_to_array($items, false);
+ }
+
+ $size = ceil($size);
+
+ $result = array_chunk($items, $size, true);
+
+ if (null !== $fill) {
+ $last = count($result) - 1;
+ $result[$last] = array_merge(
+ $result[$last],
+ array_fill(0, $size - count($result[$last]), $fill)
+ );
+ }
+
+ return $result;
}
diff --git a/lib/twig/lib/Twig/Extension/Debug.php b/vendor/twig/twig/lib/Twig/Extension/Debug.php
old mode 100755
new mode 100644
similarity index 60%
rename from lib/twig/lib/Twig/Extension/Debug.php
rename to vendor/twig/twig/lib/Twig/Extension/Debug.php
index aab7093..97007fb
--- a/lib/twig/lib/Twig/Extension/Debug.php
+++ b/vendor/twig/twig/lib/Twig/Extension/Debug.php
@@ -17,11 +17,17 @@ class Twig_Extension_Debug extends Twig_Extension
*/
public function getFunctions()
{
- // dump is safe if var_dump is overriden by xdebug
- $isDumpOutputHtmlSafe = extension_loaded('xdebug') && (false === get_cfg_var('xdebug.overload_var_dump') || get_cfg_var('xdebug.overload_var_dump')) && get_cfg_var('html_errors');
+ // dump is safe if var_dump is overridden by xdebug
+ $isDumpOutputHtmlSafe = extension_loaded('xdebug')
+ // false means that it was not set (and the default is on) or it explicitly enabled
+ && (false === ini_get('xdebug.overload_var_dump') || ini_get('xdebug.overload_var_dump'))
+ // false means that it was not set (and the default is on) or it explicitly enabled
+ // xdebug.overload_var_dump produces HTML only when html_errors is also enabled
+ && (false === ini_get('html_errors') || ini_get('html_errors'))
+ ;
return array(
- 'dump' => new Twig_Function_Function('twig_var_dump', array('is_safe' => $isDumpOutputHtmlSafe ? array('html') : array(), 'needs_context' => true, 'needs_environment' => true)),
+ new Twig_SimpleFunction('dump', 'twig_var_dump', array('is_safe' => $isDumpOutputHtmlSafe ? array('html') : array(), 'needs_context' => true, 'needs_environment' => true)),
);
}
diff --git a/lib/twig/lib/Twig/Extension/Escaper.php b/vendor/twig/twig/lib/Twig/Extension/Escaper.php
old mode 100755
new mode 100644
similarity index 50%
rename from lib/twig/lib/Twig/Extension/Escaper.php
rename to vendor/twig/twig/lib/Twig/Extension/Escaper.php
index 43ae111..c9a7f68
--- a/lib/twig/lib/Twig/Extension/Escaper.php
+++ b/vendor/twig/twig/lib/Twig/Extension/Escaper.php
@@ -10,11 +10,11 @@
*/
class Twig_Extension_Escaper extends Twig_Extension
{
- protected $autoescape;
+ protected $defaultStrategy;
- public function __construct($autoescape = true)
+ public function __construct($defaultStrategy = 'html')
{
- $this->autoescape = $autoescape;
+ $this->setDefaultStrategy($defaultStrategy);
}
/**
@@ -45,13 +45,44 @@ class Twig_Extension_Escaper extends Twig_Extension
public function getFilters()
{
return array(
- 'raw' => new Twig_Filter_Function('twig_raw_filter', array('is_safe' => array('all'))),
+ new Twig_SimpleFilter('raw', 'twig_raw_filter', array('is_safe' => array('all'))),
);
}
- public function isGlobal()
+ /**
+ * Sets the default strategy to use when not defined by the user.
+ *
+ * The strategy can be a valid PHP callback that takes the template
+ * "filename" as an argument and returns the strategy to use.
+ *
+ * @param mixed $defaultStrategy An escaping strategy
+ */
+ public function setDefaultStrategy($defaultStrategy)
{
- return $this->autoescape;
+ // for BC
+ if (true === $defaultStrategy) {
+ $defaultStrategy = 'html';
+ }
+
+ $this->defaultStrategy = $defaultStrategy;
+ }
+
+ /**
+ * Gets the default strategy to use when not defined by the user.
+ *
+ * @param string $filename The template "filename"
+ *
+ * @return string The default strategy to use for the template
+ */
+ public function getDefaultStrategy($filename)
+ {
+ // disable string callables to avoid calling a function named html or js,
+ // or any other upcoming escaping strategy
+ if (!is_string($this->defaultStrategy) && is_callable($this->defaultStrategy)) {
+ return call_user_func($this->defaultStrategy, $filename);
+ }
+
+ return $this->defaultStrategy;
}
/**
@@ -74,4 +105,3 @@ function twig_raw_filter($string)
{
return $string;
}
-
diff --git a/lib/twig/lib/Twig/Extension/Optimizer.php b/vendor/twig/twig/lib/Twig/Extension/Optimizer.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/Extension/Optimizer.php
rename to vendor/twig/twig/lib/Twig/Extension/Optimizer.php
diff --git a/lib/twig/lib/Twig/Extension/Sandbox.php b/vendor/twig/twig/lib/Twig/Extension/Sandbox.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/Extension/Sandbox.php
rename to vendor/twig/twig/lib/Twig/Extension/Sandbox.php
diff --git a/vendor/twig/twig/lib/Twig/Extension/Staging.php b/vendor/twig/twig/lib/Twig/Extension/Staging.php
new file mode 100644
index 0000000..8ab0f45
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/Extension/Staging.php
@@ -0,0 +1,113 @@
+
+ */
+class Twig_Extension_Staging extends Twig_Extension
+{
+ protected $functions = array();
+ protected $filters = array();
+ protected $visitors = array();
+ protected $tokenParsers = array();
+ protected $globals = array();
+ protected $tests = array();
+
+ public function addFunction($name, $function)
+ {
+ $this->functions[$name] = $function;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFunctions()
+ {
+ return $this->functions;
+ }
+
+ public function addFilter($name, $filter)
+ {
+ $this->filters[$name] = $filter;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFilters()
+ {
+ return $this->filters;
+ }
+
+ public function addNodeVisitor(Twig_NodeVisitorInterface $visitor)
+ {
+ $this->visitors[] = $visitor;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getNodeVisitors()
+ {
+ return $this->visitors;
+ }
+
+ public function addTokenParser(Twig_TokenParserInterface $parser)
+ {
+ $this->tokenParsers[] = $parser;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getTokenParsers()
+ {
+ return $this->tokenParsers;
+ }
+
+ public function addGlobal($name, $value)
+ {
+ $this->globals[$name] = $value;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getGlobals()
+ {
+ return $this->globals;
+ }
+
+ public function addTest($name, $test)
+ {
+ $this->tests[$name] = $test;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getTests()
+ {
+ return $this->tests;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'staging';
+ }
+}
diff --git a/vendor/twig/twig/lib/Twig/Extension/StringLoader.php b/vendor/twig/twig/lib/Twig/Extension/StringLoader.php
new file mode 100644
index 0000000..d5b881b
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/Extension/StringLoader.php
@@ -0,0 +1,64 @@
+ true)),
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getName()
+ {
+ return 'string_loader';
+ }
+}
+
+/**
+ * Loads a template from a string.
+ *
+ *
+ * {% include template_from_string("Hello {{ name }}") }}
+ *
+ *
+ * @param Twig_Environment $env A Twig_Environment instance
+ * @param string $template A template as a string
+ *
+ * @return Twig_Template A Twig_Template instance
+ */
+function twig_template_from_string(Twig_Environment $env, $template)
+{
+ static $loader;
+
+ if (null === $loader) {
+ $loader = new Twig_Loader_String();
+ }
+
+ $current = $env->getLoader();
+ $env->setLoader($loader);
+ try {
+ $template = $env->loadTemplate($template);
+ } catch (Exception $e) {
+ $env->setLoader($current);
+
+ throw $e;
+ }
+ $env->setLoader($current);
+
+ return $template;
+}
diff --git a/lib/twig/lib/Twig/ExtensionInterface.php b/vendor/twig/twig/lib/Twig/ExtensionInterface.php
old mode 100755
new mode 100644
similarity index 80%
rename from lib/twig/lib/Twig/ExtensionInterface.php
rename to vendor/twig/twig/lib/Twig/ExtensionInterface.php
index 0bfed88..f189e9d
--- a/lib/twig/lib/Twig/ExtensionInterface.php
+++ b/vendor/twig/twig/lib/Twig/ExtensionInterface.php
@@ -12,8 +12,7 @@
/**
* Interface implemented by extension classes.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
interface Twig_ExtensionInterface
{
@@ -24,61 +23,61 @@ interface Twig_ExtensionInterface
*
* @param Twig_Environment $environment The current Twig_Environment instance
*/
- function initRuntime(Twig_Environment $environment);
+ public function initRuntime(Twig_Environment $environment);
/**
* Returns the token parser instances to add to the existing list.
*
* @return array An array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances
*/
- function getTokenParsers();
+ public function getTokenParsers();
/**
* Returns the node visitor instances to add to the existing list.
*
* @return array An array of Twig_NodeVisitorInterface instances
*/
- function getNodeVisitors();
+ public function getNodeVisitors();
/**
* Returns a list of filters to add to the existing list.
*
* @return array An array of filters
*/
- function getFilters();
+ public function getFilters();
/**
* Returns a list of tests to add to the existing list.
*
* @return array An array of tests
*/
- function getTests();
+ public function getTests();
/**
* Returns a list of functions to add to the existing list.
*
* @return array An array of functions
*/
- function getFunctions();
+ public function getFunctions();
/**
* Returns a list of operators to add to the existing list.
*
* @return array An array of operators
*/
- function getOperators();
+ public function getOperators();
/**
* Returns a list of global variables to add to the existing list.
*
* @return array An array of global variables
*/
- function getGlobals();
+ public function getGlobals();
/**
* Returns the name of the extension.
*
* @return string The extension name
*/
- function getName();
+ public function getName();
}
diff --git a/lib/twig/lib/Twig/Filter.php b/vendor/twig/twig/lib/Twig/Filter.php
old mode 100755
new mode 100644
similarity index 72%
rename from lib/twig/lib/Twig/Filter.php
rename to vendor/twig/twig/lib/Twig/Filter.php
index f27f08e..1891788
--- a/lib/twig/lib/Twig/Filter.php
+++ b/vendor/twig/twig/lib/Twig/Filter.php
@@ -12,10 +12,12 @@
/**
* Represents a template filter.
*
- * @package twig
- * @author Fabien Potencier
+ * Use Twig_SimpleFilter instead.
+ *
+ * @author Fabien Potencier
+ * @deprecated since 1.12 (to be removed in 2.0)
*/
-abstract class Twig_Filter implements Twig_FilterInterface
+abstract class Twig_Filter implements Twig_FilterInterface, Twig_FilterCallableInterface
{
protected $options;
protected $arguments = array();
@@ -26,6 +28,8 @@ abstract class Twig_Filter implements Twig_FilterInterface
'needs_environment' => false,
'needs_context' => false,
'pre_escape' => null,
+ 'preserves_safety' => null,
+ 'callable' => null,
), $options);
}
@@ -59,11 +63,21 @@ abstract class Twig_Filter implements Twig_FilterInterface
return call_user_func($this->options['is_safe_callback'], $filterArgs);
}
- return array();
+ return null;
+ }
+
+ public function getPreservesSafety()
+ {
+ return $this->options['preserves_safety'];
}
public function getPreEscape()
{
return $this->options['pre_escape'];
}
+
+ public function getCallable()
+ {
+ return $this->options['callable'];
+ }
}
diff --git a/lib/twig/lib/Twig/Filter/Function.php b/vendor/twig/twig/lib/Twig/Filter/Function.php
old mode 100755
new mode 100644
similarity index 76%
rename from lib/twig/lib/Twig/Filter/Function.php
rename to vendor/twig/twig/lib/Twig/Filter/Function.php
index 1de078b..ad374a5
--- a/lib/twig/lib/Twig/Filter/Function.php
+++ b/vendor/twig/twig/lib/Twig/Filter/Function.php
@@ -12,8 +12,10 @@
/**
* Represents a function template filter.
*
- * @package twig
- * @author Fabien Potencier
+ * Use Twig_SimpleFilter instead.
+ *
+ * @author Fabien Potencier
+ * @deprecated since 1.12 (to be removed in 2.0)
*/
class Twig_Filter_Function extends Twig_Filter
{
@@ -21,6 +23,8 @@ class Twig_Filter_Function extends Twig_Filter
public function __construct($function, array $options = array())
{
+ $options['callable'] = $function;
+
parent::__construct($options);
$this->function = $function;
diff --git a/lib/twig/lib/Twig/Filter/Method.php b/vendor/twig/twig/lib/Twig/Filter/Method.php
old mode 100755
new mode 100644
similarity index 73%
rename from lib/twig/lib/Twig/Filter/Method.php
rename to vendor/twig/twig/lib/Twig/Filter/Method.php
index d831e0f..63c8c3b
--- a/lib/twig/lib/Twig/Filter/Method.php
+++ b/vendor/twig/twig/lib/Twig/Filter/Method.php
@@ -12,15 +12,20 @@
/**
* Represents a method template filter.
*
- * @package twig
- * @author Fabien Potencier
+ * Use Twig_SimpleFilter instead.
+ *
+ * @author Fabien Potencier
+ * @deprecated since 1.12 (to be removed in 2.0)
*/
class Twig_Filter_Method extends Twig_Filter
{
- protected $extension, $method;
+ protected $extension;
+ protected $method;
public function __construct(Twig_ExtensionInterface $extension, $method, array $options = array())
{
+ $options['callable'] = array($extension, $method);
+
parent::__construct($options);
$this->extension = $extension;
diff --git a/lib/twig/lib/Twig/Filter/Node.php b/vendor/twig/twig/lib/Twig/Filter/Node.php
old mode 100755
new mode 100644
similarity index 81%
rename from lib/twig/lib/Twig/Filter/Node.php
rename to vendor/twig/twig/lib/Twig/Filter/Node.php
index 7481c05..8744c5e
--- a/lib/twig/lib/Twig/Filter/Node.php
+++ b/vendor/twig/twig/lib/Twig/Filter/Node.php
@@ -12,8 +12,10 @@
/**
* Represents a template filter as a node.
*
- * @package twig
- * @author Fabien Potencier
+ * Use Twig_SimpleFilter instead.
+ *
+ * @author Fabien Potencier
+ * @deprecated since 1.12 (to be removed in 2.0)
*/
class Twig_Filter_Node extends Twig_Filter
{
diff --git a/vendor/twig/twig/lib/Twig/FilterCallableInterface.php b/vendor/twig/twig/lib/Twig/FilterCallableInterface.php
new file mode 100644
index 0000000..145534d
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/FilterCallableInterface.php
@@ -0,0 +1,23 @@
+
+ * @deprecated since 1.12 (to be removed in 2.0)
+ */
+interface Twig_FilterCallableInterface
+{
+ public function getCallable();
+}
diff --git a/vendor/twig/twig/lib/Twig/FilterInterface.php b/vendor/twig/twig/lib/Twig/FilterInterface.php
new file mode 100644
index 0000000..5319ecc
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/FilterInterface.php
@@ -0,0 +1,42 @@
+
+ * @deprecated since 1.12 (to be removed in 2.0)
+ */
+interface Twig_FilterInterface
+{
+ /**
+ * Compiles a filter.
+ *
+ * @return string The PHP code for the filter
+ */
+ public function compile();
+
+ public function needsEnvironment();
+
+ public function needsContext();
+
+ public function getSafe(Twig_Node $filterArgs);
+
+ public function getPreservesSafety();
+
+ public function getPreEscape();
+
+ public function setArguments($arguments);
+
+ public function getArguments();
+}
diff --git a/lib/twig/lib/Twig/Function.php b/vendor/twig/twig/lib/Twig/Function.php
old mode 100755
new mode 100644
similarity index 77%
rename from lib/twig/lib/Twig/Function.php
rename to vendor/twig/twig/lib/Twig/Function.php
index cd7643f..b5ffb2b
--- a/lib/twig/lib/Twig/Function.php
+++ b/vendor/twig/twig/lib/Twig/Function.php
@@ -12,10 +12,12 @@
/**
* Represents a template function.
*
- * @package twig
- * @author Fabien Potencier
+ * Use Twig_SimpleFunction instead.
+ *
+ * @author Fabien Potencier
+ * @deprecated since 1.12 (to be removed in 2.0)
*/
-abstract class Twig_Function implements Twig_FunctionInterface
+abstract class Twig_Function implements Twig_FunctionInterface, Twig_FunctionCallableInterface
{
protected $options;
protected $arguments = array();
@@ -25,6 +27,7 @@ abstract class Twig_Function implements Twig_FunctionInterface
$this->options = array_merge(array(
'needs_environment' => false,
'needs_context' => false,
+ 'callable' => null,
), $options);
}
@@ -60,4 +63,9 @@ abstract class Twig_Function implements Twig_FunctionInterface
return array();
}
+
+ public function getCallable()
+ {
+ return $this->options['callable'];
+ }
}
diff --git a/lib/twig/lib/Twig/Function/Function.php b/vendor/twig/twig/lib/Twig/Function/Function.php
old mode 100755
new mode 100644
similarity index 77%
rename from lib/twig/lib/Twig/Function/Function.php
rename to vendor/twig/twig/lib/Twig/Function/Function.php
index 3237d8c..d1e1b96
--- a/lib/twig/lib/Twig/Function/Function.php
+++ b/vendor/twig/twig/lib/Twig/Function/Function.php
@@ -13,8 +13,10 @@
/**
* Represents a function template function.
*
- * @package twig
- * @author Arnaud Le Blanc
+ * Use Twig_SimpleFunction instead.
+ *
+ * @author Arnaud Le Blanc
+ * @deprecated since 1.12 (to be removed in 2.0)
*/
class Twig_Function_Function extends Twig_Function
{
@@ -22,6 +24,8 @@ class Twig_Function_Function extends Twig_Function
public function __construct($function, array $options = array())
{
+ $options['callable'] = $function;
+
parent::__construct($options);
$this->function = $function;
diff --git a/lib/twig/lib/Twig/Function/Method.php b/vendor/twig/twig/lib/Twig/Function/Method.php
old mode 100755
new mode 100644
similarity index 74%
rename from lib/twig/lib/Twig/Function/Method.php
rename to vendor/twig/twig/lib/Twig/Function/Method.php
index 7328566..67039a9
--- a/lib/twig/lib/Twig/Function/Method.php
+++ b/vendor/twig/twig/lib/Twig/Function/Method.php
@@ -13,15 +13,20 @@
/**
* Represents a method template function.
*
- * @package twig
- * @author Arnaud Le Blanc
+ * Use Twig_SimpleFunction instead.
+ *
+ * @author Arnaud Le Blanc
+ * @deprecated since 1.12 (to be removed in 2.0)
*/
class Twig_Function_Method extends Twig_Function
{
- protected $extension, $method;
+ protected $extension;
+ protected $method;
public function __construct(Twig_ExtensionInterface $extension, $method, array $options = array())
{
+ $options['callable'] = array($extension, $method);
+
parent::__construct($options);
$this->extension = $extension;
diff --git a/lib/twig/lib/Twig/Function/Node.php b/vendor/twig/twig/lib/Twig/Function/Node.php
old mode 100755
new mode 100644
similarity index 75%
rename from lib/twig/lib/Twig/Function/Node.php
rename to vendor/twig/twig/lib/Twig/Function/Node.php
index a687a84..06a0d0d
--- a/lib/twig/lib/Twig/Function/Node.php
+++ b/vendor/twig/twig/lib/Twig/Function/Node.php
@@ -12,10 +12,12 @@
/**
* Represents a template function as a node.
*
- * @package twig
- * @author Fabien Potencier
+ * Use Twig_SimpleFunction instead.
+ *
+ * @author Fabien Potencier
+ * @deprecated since 1.12 (to be removed in 2.0)
*/
-class Twig_Function_Node extends Twig_Filter
+class Twig_Function_Node extends Twig_Function
{
protected $class;
diff --git a/vendor/twig/twig/lib/Twig/FunctionCallableInterface.php b/vendor/twig/twig/lib/Twig/FunctionCallableInterface.php
new file mode 100644
index 0000000..0aab4f5
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/FunctionCallableInterface.php
@@ -0,0 +1,23 @@
+
+ * @deprecated since 1.12 (to be removed in 2.0)
+ */
+interface Twig_FunctionCallableInterface
+{
+ public function getCallable();
+}
diff --git a/lib/twig/lib/Twig/FunctionInterface.php b/vendor/twig/twig/lib/Twig/FunctionInterface.php
old mode 100755
new mode 100644
similarity index 52%
rename from lib/twig/lib/Twig/FunctionInterface.php
rename to vendor/twig/twig/lib/Twig/FunctionInterface.php
index d402d17..67f4f89
--- a/lib/twig/lib/Twig/FunctionInterface.php
+++ b/vendor/twig/twig/lib/Twig/FunctionInterface.php
@@ -13,8 +13,10 @@
/**
* Represents a template function.
*
- * @package twig
- * @author Arnaud Le Blanc
+ * Use Twig_SimpleFunction instead.
+ *
+ * @author Arnaud Le Blanc
+ * @deprecated since 1.12 (to be removed in 2.0)
*/
interface Twig_FunctionInterface
{
@@ -23,15 +25,15 @@ interface Twig_FunctionInterface
*
* @return string The PHP code for the function
*/
- function compile();
+ public function compile();
- function needsEnvironment();
+ public function needsEnvironment();
- function needsContext();
+ public function needsContext();
- function getSafe(Twig_Node $filterArgs);
+ public function getSafe(Twig_Node $filterArgs);
- function setArguments($arguments);
+ public function setArguments($arguments);
- function getArguments();
+ public function getArguments();
}
diff --git a/lib/twig/lib/Twig/Lexer.php b/vendor/twig/twig/lib/Twig/Lexer.php
old mode 100755
new mode 100644
similarity index 92%
rename from lib/twig/lib/Twig/Lexer.php
rename to vendor/twig/twig/lib/Twig/Lexer.php
index 4958cb6..000b038
--- a/lib/twig/lib/Twig/Lexer.php
+++ b/vendor/twig/twig/lib/Twig/Lexer.php
@@ -13,8 +13,7 @@
/**
* Lexes a template string.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Lexer implements Twig_LexerInterface
{
@@ -30,6 +29,9 @@ class Twig_Lexer implements Twig_LexerInterface
protected $filename;
protected $options;
protected $regexes;
+ protected $position;
+ protected $positions;
+ protected $currentVarBlockLine;
const STATE_DATA = 0;
const STATE_BLOCK = 1;
@@ -59,10 +61,10 @@ class Twig_Lexer implements Twig_LexerInterface
$this->regexes = array(
'lex_var' => '/\s*'.preg_quote($this->options['whitespace_trim'].$this->options['tag_variable'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_variable'][1], '/').'/A',
'lex_block' => '/\s*(?:'.preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_block'][1], '/').')\n?/A',
- 'lex_raw_data' => '/('.preg_quote($this->options['tag_block'][0].$this->options['whitespace_trim'], '/').'|'.preg_quote($this->options['tag_block'][0], '/').')\s*endraw\s*(?:'.preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_block'][1], '/').')/s',
+ 'lex_raw_data' => '/('.preg_quote($this->options['tag_block'][0].$this->options['whitespace_trim'], '/').'|'.preg_quote($this->options['tag_block'][0], '/').')\s*(?:end%s)\s*(?:'.preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_block'][1], '/').')/s',
'operator' => $this->getOperatorRegex(),
'lex_comment' => '/(?:'.preg_quote($this->options['whitespace_trim'], '/').preg_quote($this->options['tag_comment'][1], '/').'\s*|'.preg_quote($this->options['tag_comment'][1], '/').')\n?/s',
- 'lex_block_raw' => '/\s*raw\s*(?:'.preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_block'][1], '/').')/As',
+ 'lex_block_raw' => '/\s*(raw|verbatim)\s*(?:'.preg_quote($this->options['whitespace_trim'].$this->options['tag_block'][1], '/').'\s*|\s*'.preg_quote($this->options['tag_block'][1], '/').')/As',
'lex_block_line' => '/\s*line\s+(\d+)\s*'.preg_quote($this->options['tag_block'][1], '/').'/As',
'lex_tokens_start' => '/('.preg_quote($this->options['tag_variable'][0], '/').'|'.preg_quote($this->options['tag_block'][0], '/').'|'.preg_quote($this->options['tag_comment'][0], '/').')('.preg_quote($this->options['whitespace_trim'], '/').')?/s',
'interpolation_start' => '/'.preg_quote($this->options['interpolation'][0], '/').'\s*/A',
@@ -73,8 +75,8 @@ class Twig_Lexer implements Twig_LexerInterface
/**
* Tokenizes a source code.
*
- * @param string $code The source code
- * @param string $filename A unique identifier for the 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
*/
@@ -176,7 +178,7 @@ class Twig_Lexer implements Twig_LexerInterface
// raw data?
if (preg_match($this->regexes['lex_block_raw'], $this->code, $match, null, $this->cursor)) {
$this->moveCursor($match[0]);
- $this->lexRawData();
+ $this->lexRawData($match[1]);
// {% line \d+ %}
} elseif (preg_match($this->regexes['lex_block_line'], $this->code, $match, null, $this->cursor)) {
$this->moveCursor($match[0]);
@@ -184,12 +186,14 @@ class Twig_Lexer implements Twig_LexerInterface
} else {
$this->pushToken(Twig_Token::BLOCK_START_TYPE);
$this->pushState(self::STATE_BLOCK);
+ $this->currentVarBlockLine = $this->lineno;
}
break;
case $this->options['tag_variable'][0]:
$this->pushToken(Twig_Token::VAR_START_TYPE);
$this->pushState(self::STATE_VAR);
+ $this->currentVarBlockLine = $this->lineno;
break;
}
}
@@ -223,7 +227,7 @@ class Twig_Lexer implements Twig_LexerInterface
$this->moveCursor($match[0]);
if ($this->cursor >= $this->end) {
- throw new Twig_Error_Syntax(sprintf('Unexpected end of file: Unclosed "%s"', $this->state === self::STATE_BLOCK ? 'block' : 'variable'));
+ throw new Twig_Error_Syntax(sprintf('Unclosed "%s"', $this->state === self::STATE_BLOCK ? 'block' : 'variable'), $this->currentVarBlockLine, $this->filename);
}
}
@@ -284,10 +288,10 @@ class Twig_Lexer implements Twig_LexerInterface
}
}
- protected function lexRawData()
+ protected function lexRawData($tag)
{
- if (!preg_match($this->regexes['lex_raw_data'], $this->code, $match, PREG_OFFSET_CAPTURE, $this->cursor)) {
- throw new Twig_Error_Syntax(sprintf('Unexpected end of file: Unclosed "block"'));
+ if (!preg_match(str_replace('%s', $tag, $this->regexes['lex_raw_data']), $this->code, $match, PREG_OFFSET_CAPTURE, $this->cursor)) {
+ throw new Twig_Error_Syntax(sprintf('Unexpected end of file: Unclosed "%s" block', $tag), $this->lineno, $this->filename);
}
$text = substr($this->code, $this->cursor, $match[0][1] - $this->cursor);
@@ -330,8 +334,6 @@ class Twig_Lexer implements Twig_LexerInterface
$this->popState();
++$this->cursor;
-
- return;
}
}
diff --git a/lib/twig/lib/Twig/LexerInterface.php b/vendor/twig/twig/lib/Twig/LexerInterface.php
old mode 100755
new mode 100644
similarity index 60%
rename from lib/twig/lib/Twig/LexerInterface.php
rename to vendor/twig/twig/lib/Twig/LexerInterface.php
index 0223384..4b83f81
--- a/lib/twig/lib/Twig/LexerInterface.php
+++ b/vendor/twig/twig/lib/Twig/LexerInterface.php
@@ -12,18 +12,18 @@
/**
* Interface implemented by lexer classes.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
+ * @deprecated since 1.12 (to be removed in 2.0)
*/
interface Twig_LexerInterface
{
/**
* Tokenizes a source code.
*
- * @param string $code The source code
- * @param string $filename A unique identifier for the 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
*/
- function tokenize($code, $filename = null);
+ public function tokenize($code, $filename = null);
}
diff --git a/lib/twig/lib/Twig/Loader/Array.php b/vendor/twig/twig/lib/Twig/Loader/Array.php
old mode 100755
new mode 100644
similarity index 75%
rename from lib/twig/lib/Twig/Loader/Array.php
rename to vendor/twig/twig/lib/Twig/Loader/Array.php
index 32bb7e4..89087ae
--- a/lib/twig/lib/Twig/Loader/Array.php
+++ b/vendor/twig/twig/lib/Twig/Loader/Array.php
@@ -17,10 +17,9 @@
* source code of the template). If you don't want to see your cache grows out of
* control, you need to take care of clearing the old cache file by yourself.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
-class Twig_Loader_Array implements Twig_LoaderInterface
+class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
{
protected $templates;
@@ -51,11 +50,7 @@ class Twig_Loader_Array implements Twig_LoaderInterface
}
/**
- * Gets the source code of a template, given its name.
- *
- * @param string $name The name of the template to load
- *
- * @return string The template source code
+ * {@inheritdoc}
*/
public function getSource($name)
{
@@ -68,11 +63,15 @@ class Twig_Loader_Array implements Twig_LoaderInterface
}
/**
- * Gets the cache key to use for the cache for a given template name.
- *
- * @param string $name The name of the template to load
- *
- * @return string The cache key
+ * {@inheritdoc}
+ */
+ public function exists($name)
+ {
+ return isset($this->templates[(string) $name]);
+ }
+
+ /**
+ * {@inheritdoc}
*/
public function getCacheKey($name)
{
@@ -85,10 +84,7 @@ class Twig_Loader_Array implements Twig_LoaderInterface
}
/**
- * 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
+ * {@inheritdoc}
*/
public function isFresh($name, $time)
{
diff --git a/vendor/twig/twig/lib/Twig/Loader/Chain.php b/vendor/twig/twig/lib/Twig/Loader/Chain.php
new file mode 100644
index 0000000..cd64b05
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/Loader/Chain.php
@@ -0,0 +1,135 @@
+
+ */
+class Twig_Loader_Chain implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
+{
+ private $hasSourceCache = array();
+ protected $loaders;
+
+ /**
+ * Constructor.
+ *
+ * @param Twig_LoaderInterface[] $loaders An array of loader instances
+ */
+ public function __construct(array $loaders = array())
+ {
+ $this->loaders = array();
+ foreach ($loaders as $loader) {
+ $this->addLoader($loader);
+ }
+ }
+
+ /**
+ * Adds a loader instance.
+ *
+ * @param Twig_LoaderInterface $loader A Loader instance
+ */
+ public function addLoader(Twig_LoaderInterface $loader)
+ {
+ $this->loaders[] = $loader;
+ $this->hasSourceCache = array();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getSource($name)
+ {
+ $exceptions = array();
+ foreach ($this->loaders as $loader) {
+ if ($loader instanceof Twig_ExistsLoaderInterface && !$loader->exists($name)) {
+ continue;
+ }
+
+ try {
+ return $loader->getSource($name);
+ } catch (Twig_Error_Loader $e) {
+ $exceptions[] = $e->getMessage();
+ }
+ }
+
+ throw new Twig_Error_Loader(sprintf('Template "%s" is not defined (%s).', $name, implode(', ', $exceptions)));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function exists($name)
+ {
+ $name = (string) $name;
+
+ if (isset($this->hasSourceCache[$name])) {
+ return $this->hasSourceCache[$name];
+ }
+
+ foreach ($this->loaders as $loader) {
+ if ($loader instanceof Twig_ExistsLoaderInterface && $loader->exists($name)) {
+ return $this->hasSourceCache[$name] = true;
+ }
+
+ try {
+ $loader->getSource($name);
+
+ return $this->hasSourceCache[$name] = true;
+ } catch (Twig_Error_Loader $e) {
+ }
+ }
+
+ return $this->hasSourceCache[$name] = false;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getCacheKey($name)
+ {
+ $exceptions = array();
+ foreach ($this->loaders as $loader) {
+ if ($loader instanceof Twig_ExistsLoaderInterface && !$loader->exists($name)) {
+ continue;
+ }
+
+ try {
+ return $loader->getCacheKey($name);
+ } catch (Twig_Error_Loader $e) {
+ $exceptions[] = get_class($loader).': '.$e->getMessage();
+ }
+ }
+
+ throw new Twig_Error_Loader(sprintf('Template "%s" is not defined (%s).', $name, implode(' ', $exceptions)));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isFresh($name, $time)
+ {
+ $exceptions = array();
+ foreach ($this->loaders as $loader) {
+ if ($loader instanceof Twig_ExistsLoaderInterface && !$loader->exists($name)) {
+ continue;
+ }
+
+ try {
+ return $loader->isFresh($name, $time);
+ } catch (Twig_Error_Loader $e) {
+ $exceptions[] = get_class($loader).': '.$e->getMessage();
+ }
+ }
+
+ throw new Twig_Error_Loader(sprintf('Template "%s" is not defined (%s).', $name, implode(' ', $exceptions)));
+ }
+}
diff --git a/vendor/twig/twig/lib/Twig/Loader/Filesystem.php b/vendor/twig/twig/lib/Twig/Loader/Filesystem.php
new file mode 100644
index 0000000..84a5e03
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/Loader/Filesystem.php
@@ -0,0 +1,221 @@
+
+ */
+class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
+{
+ 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.
+ *
+ * @param string $namespace A path namespace
+ *
+ * @return array The array of paths where to look for templates
+ */
+ public function getPaths($namespace = '__main__')
+ {
+ return isset($this->paths[$namespace]) ? $this->paths[$namespace] : array();
+ }
+
+ /**
+ * Returns the path namespaces.
+ *
+ * The "__main__" namespace is always defined.
+ *
+ * @return array The array of defined namespaces
+ */
+ public function getNamespaces()
+ {
+ return array_keys($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
+ * @param string $namespace A path namespace
+ */
+ public function setPaths($paths, $namespace = '__main__')
+ {
+ if (!is_array($paths)) {
+ $paths = array($paths);
+ }
+
+ $this->paths[$namespace] = array();
+ foreach ($paths as $path) {
+ $this->addPath($path, $namespace);
+ }
+ }
+
+ /**
+ * Adds a path where templates are stored.
+ *
+ * @param string $path A path where to look for templates
+ * @param string $namespace A path name
+ *
+ * @throws Twig_Error_Loader
+ */
+ public function addPath($path, $namespace = '__main__')
+ {
+ // invalidate the cache
+ $this->cache = array();
+
+ if (!is_dir($path)) {
+ throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $path));
+ }
+
+ $this->paths[$namespace][] = rtrim($path, '/\\');
+ }
+
+ /**
+ * Prepends a path where templates are stored.
+ *
+ * @param string $path A path where to look for templates
+ * @param string $namespace A path name
+ *
+ * @throws Twig_Error_Loader
+ */
+ public function prependPath($path, $namespace = '__main__')
+ {
+ // invalidate the cache
+ $this->cache = array();
+
+ if (!is_dir($path)) {
+ throw new Twig_Error_Loader(sprintf('The "%s" directory does not exist.', $path));
+ }
+
+ $path = rtrim($path, '/\\');
+
+ if (!isset($this->paths[$namespace])) {
+ $this->paths[$namespace][] = $path;
+ } else {
+ array_unshift($this->paths[$namespace], $path);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getSource($name)
+ {
+ return file_get_contents($this->findTemplate($name));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getCacheKey($name)
+ {
+ return $this->findTemplate($name);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function exists($name)
+ {
+ $name = (string) $name;
+ if (isset($this->cache[$name])) {
+ return true;
+ }
+
+ try {
+ $this->findTemplate($name);
+
+ return true;
+ } catch (Twig_Error_Loader $exception) {
+ return false;
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function isFresh($name, $time)
+ {
+ return filemtime($this->findTemplate($name)) <= $time;
+ }
+
+ protected function findTemplate($name)
+ {
+ $name = (string) $name;
+
+ // normalize name
+ $name = preg_replace('#/{2,}#', '/', strtr($name, '\\', '/'));
+
+ if (isset($this->cache[$name])) {
+ return $this->cache[$name];
+ }
+
+ $this->validateName($name);
+
+ $namespace = '__main__';
+ if (isset($name[0]) && '@' == $name[0]) {
+ if (false === $pos = strpos($name, '/')) {
+ throw new Twig_Error_Loader(sprintf('Malformed namespaced template name "%s" (expecting "@namespace/template_name").', $name));
+ }
+
+ $namespace = substr($name, 1, $pos - 1);
+
+ $name = substr($name, $pos + 1);
+ }
+
+ if (!isset($this->paths[$namespace])) {
+ throw new Twig_Error_Loader(sprintf('There are no registered paths for namespace "%s".', $namespace));
+ }
+
+ foreach ($this->paths[$namespace] as $path) {
+ if (is_file($path.'/'.$name)) {
+ return $this->cache[$name] = $path.'/'.$name;
+ }
+ }
+
+ throw new Twig_Error_Loader(sprintf('Unable to find template "%s" (looked into: %s).', $name, implode(', ', $this->paths[$namespace])));
+ }
+
+ protected function validateName($name)
+ {
+ if (false !== strpos($name, "\0")) {
+ throw new Twig_Error_Loader('A template name cannot contain NUL bytes.');
+ }
+
+ $name = ltrim($name, '/');
+ $parts = explode('/', $name);
+ $level = 0;
+ foreach ($parts as $part) {
+ if ('..' === $part) {
+ --$level;
+ } elseif ('.' !== $part) {
+ ++$level;
+ }
+
+ if ($level < 0) {
+ throw new Twig_Error_Loader(sprintf('Looks like you try to load a template outside configured directories (%s).', $name));
+ }
+ }
+ }
+}
diff --git a/lib/twig/lib/Twig/Loader/String.php b/vendor/twig/twig/lib/Twig/Loader/String.php
old mode 100755
new mode 100644
similarity index 55%
rename from lib/twig/lib/Twig/Loader/String.php
rename to vendor/twig/twig/lib/Twig/Loader/String.php
index 26eb009..8ad9856
--- a/lib/twig/lib/Twig/Loader/String.php
+++ b/vendor/twig/twig/lib/Twig/Loader/String.php
@@ -12,22 +12,21 @@
/**
* Loads a template from a string.
*
+ * This loader should only be used for unit testing as it has many limitations
+ * (for instance, the include or extends tag does not make any sense for a string
+ * loader).
+ *
* When using this loader with a cache mechanism, you should know that a new cache
* key is generated each time a template content "changes" (the cache key being the
* source code of the template). If you don't want to see your cache grows out of
* control, you need to take care of clearing the old cache file by yourself.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
-class Twig_Loader_String implements Twig_LoaderInterface
+class Twig_Loader_String implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
{
/**
- * Gets the source code of a template, given its name.
- *
- * @param string $name The name of the template to load
- *
- * @return string The template source code
+ * {@inheritdoc}
*/
public function getSource($name)
{
@@ -35,11 +34,15 @@ class Twig_Loader_String implements Twig_LoaderInterface
}
/**
- * Gets the cache key to use for the cache for a given template name.
- *
- * @param string $name The name of the template to load
- *
- * @return string The cache key
+ * {@inheritdoc}
+ */
+ public function exists($name)
+ {
+ return true;
+ }
+
+ /**
+ * {@inheritdoc}
*/
public function getCacheKey($name)
{
@@ -47,10 +50,7 @@ class Twig_Loader_String implements Twig_LoaderInterface
}
/**
- * 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
+ * {@inheritdoc}
*/
public function isFresh($name, $time)
{
diff --git a/lib/twig/lib/Twig/LoaderInterface.php b/vendor/twig/twig/lib/Twig/LoaderInterface.php
old mode 100755
new mode 100644
similarity index 77%
rename from lib/twig/lib/Twig/LoaderInterface.php
rename to vendor/twig/twig/lib/Twig/LoaderInterface.php
index d8ae444..927786d
--- a/lib/twig/lib/Twig/LoaderInterface.php
+++ b/vendor/twig/twig/lib/Twig/LoaderInterface.php
@@ -12,32 +12,31 @@
/**
* Interface all loaders must implement.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
interface Twig_LoaderInterface
{
/**
* Gets the source code of a template, given its name.
*
- * @param string $name The name of the template to load
+ * @param string $name The name of the template to load
*
* @return string The template source code
*
* @throws Twig_Error_Loader When $name is not found
*/
- function getSource($name);
+ public function getSource($name);
/**
* Gets the cache key to use for the cache for a given template name.
*
- * @param string $name The name of the template to load
+ * @param string $name The name of the template to load
*
* @return string The cache key
*
* @throws Twig_Error_Loader When $name is not found
*/
- function getCacheKey($name);
+ public function getCacheKey($name);
/**
* Returns true if the template is still fresh.
@@ -49,5 +48,5 @@ interface Twig_LoaderInterface
*
* @throws Twig_Error_Loader When $name is not found
*/
- function isFresh($name, $time);
+ public function isFresh($name, $time);
}
diff --git a/lib/twig/lib/Twig/Markup.php b/vendor/twig/twig/lib/Twig/Markup.php
old mode 100755
new mode 100644
similarity index 90%
rename from lib/twig/lib/Twig/Markup.php
rename to vendor/twig/twig/lib/Twig/Markup.php
index 7099b29..69871fc
--- a/lib/twig/lib/Twig/Markup.php
+++ b/vendor/twig/twig/lib/Twig/Markup.php
@@ -12,8 +12,7 @@
/**
* Marks a content as safe.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Markup implements Countable
{
diff --git a/lib/twig/lib/Twig/Node.php b/vendor/twig/twig/lib/Twig/Node.php
old mode 100755
new mode 100644
similarity index 93%
rename from lib/twig/lib/Twig/Node.php
rename to vendor/twig/twig/lib/Twig/Node.php
index 651ffc4..931b463
--- a/lib/twig/lib/Twig/Node.php
+++ b/vendor/twig/twig/lib/Twig/Node.php
@@ -13,8 +13,7 @@
/**
* Represents a node in the AST.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Node implements Twig_NodeInterface
{
@@ -134,12 +133,12 @@ class Twig_Node implements Twig_NodeInterface
*
* @param string The attribute name
*
- * @return mixed The attribute value
+ * @return mixed The attribute value
*/
public function getAttribute($name)
{
if (!array_key_exists($name, $this->attributes)) {
- throw new Twig_Error_Runtime(sprintf('Attribute "%s" does not exist for Node "%s".', $name, get_class($this)));
+ throw new LogicException(sprintf('Attribute "%s" does not exist for Node "%s".', $name, get_class($this)));
}
return $this->attributes[$name];
@@ -188,7 +187,7 @@ class Twig_Node implements Twig_NodeInterface
public function getNode($name)
{
if (!array_key_exists($name, $this->nodes)) {
- throw new Twig_Error_Runtime(sprintf('Node "%s" does not exist for Node "%s".', $name, get_class($this)));
+ throw new LogicException(sprintf('Node "%s" does not exist for Node "%s".', $name, get_class($this)));
}
return $this->nodes[$name];
diff --git a/lib/twig/lib/Twig/Node/AutoEscape.php b/vendor/twig/twig/lib/Twig/Node/AutoEscape.php
old mode 100755
new mode 100644
similarity index 92%
rename from lib/twig/lib/Twig/Node/AutoEscape.php
rename to vendor/twig/twig/lib/Twig/Node/AutoEscape.php
index a0c2ee6..8f190e0
--- a/lib/twig/lib/Twig/Node/AutoEscape.php
+++ b/vendor/twig/twig/lib/Twig/Node/AutoEscape.php
@@ -18,8 +18,7 @@
*
* If autoescaping is disabled, then the value is false.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Node_AutoEscape extends Twig_Node
{
diff --git a/lib/twig/lib/Twig/Node/Block.php b/vendor/twig/twig/lib/Twig/Node/Block.php
old mode 100755
new mode 100644
similarity index 93%
rename from lib/twig/lib/Twig/Node/Block.php
rename to vendor/twig/twig/lib/Twig/Node/Block.php
index 5548ad0..50eb67e
--- a/lib/twig/lib/Twig/Node/Block.php
+++ b/vendor/twig/twig/lib/Twig/Node/Block.php
@@ -13,8 +13,7 @@
/**
* Represents a block node.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Node_Block extends Twig_Node
{
diff --git a/lib/twig/lib/Twig/Node/BlockReference.php b/vendor/twig/twig/lib/Twig/Node/BlockReference.php
old mode 100755
new mode 100644
similarity index 92%
rename from lib/twig/lib/Twig/Node/BlockReference.php
rename to vendor/twig/twig/lib/Twig/Node/BlockReference.php
index 53f6287..013e369
--- a/lib/twig/lib/Twig/Node/BlockReference.php
+++ b/vendor/twig/twig/lib/Twig/Node/BlockReference.php
@@ -13,8 +13,7 @@
/**
* Represents a block call node.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Node_BlockReference extends Twig_Node implements Twig_NodeOutputInterface
{
diff --git a/lib/twig/lib/Twig/Node/Body.php b/vendor/twig/twig/lib/Twig/Node/Body.php
old mode 100755
new mode 100644
similarity index 79%
rename from lib/twig/lib/Twig/Node/Body.php
rename to vendor/twig/twig/lib/Twig/Node/Body.php
index f72bf50..3ffb134
--- a/lib/twig/lib/Twig/Node/Body.php
+++ b/vendor/twig/twig/lib/Twig/Node/Body.php
@@ -12,8 +12,7 @@
/**
* Represents a body node.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Node_Body extends Twig_Node
{
diff --git a/lib/twig/lib/Twig/Node/Do.php b/vendor/twig/twig/lib/Twig/Node/Do.php
old mode 100755
new mode 100644
similarity index 91%
rename from lib/twig/lib/Twig/Node/Do.php
rename to vendor/twig/twig/lib/Twig/Node/Do.php
index aa419d9..c528066
--- a/lib/twig/lib/Twig/Node/Do.php
+++ b/vendor/twig/twig/lib/Twig/Node/Do.php
@@ -12,8 +12,7 @@
/**
* Represents a do node.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Node_Do extends Twig_Node
{
diff --git a/vendor/twig/twig/lib/Twig/Node/Embed.php b/vendor/twig/twig/lib/Twig/Node/Embed.php
new file mode 100644
index 0000000..4c9456d
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/Node/Embed.php
@@ -0,0 +1,38 @@
+
+ */
+class Twig_Node_Embed extends Twig_Node_Include
+{
+ // we don't inject the module to avoid node visitors to traverse it twice (as it will be already visited in the main module)
+ public function __construct($filename, $index, Twig_Node_Expression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null)
+ {
+ parent::__construct(new Twig_Node_Expression_Constant('not_used', $lineno), $variables, $only, $ignoreMissing, $lineno, $tag);
+
+ $this->setAttribute('filename', $filename);
+ $this->setAttribute('index', $index);
+ }
+
+ protected function addGetTemplate(Twig_Compiler $compiler)
+ {
+ $compiler
+ ->write("\$this->env->loadTemplate(")
+ ->string($this->getAttribute('filename'))
+ ->raw(', ')
+ ->string($this->getAttribute('index'))
+ ->raw(")")
+ ;
+ }
+}
diff --git a/lib/twig/lib/Twig/Node/Expression.php b/vendor/twig/twig/lib/Twig/Node/Expression.php
old mode 100755
new mode 100644
similarity index 83%
rename from lib/twig/lib/Twig/Node/Expression.php
rename to vendor/twig/twig/lib/Twig/Node/Expression.php
index 13b170e..a7382e7
--- a/lib/twig/lib/Twig/Node/Expression.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression.php
@@ -13,8 +13,7 @@
/**
* Abstract class for all nodes that represents an expression.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
abstract class Twig_Node_Expression extends Twig_Node
{
diff --git a/lib/twig/lib/Twig/Node/Expression/Array.php b/vendor/twig/twig/lib/Twig/Node/Expression/Array.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/Node/Expression/Array.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Array.php
diff --git a/lib/twig/lib/Twig/Node/Expression/AssignName.php b/vendor/twig/twig/lib/Twig/Node/Expression/AssignName.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/Node/Expression/AssignName.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/AssignName.php
diff --git a/lib/twig/lib/Twig/Node/Expression/Binary.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/Node/Expression/Binary.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Binary.php
diff --git a/lib/twig/lib/Twig/Node/Expression/Binary/Add.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Add.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/Node/Expression/Binary/Add.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Binary/Add.php
diff --git a/lib/twig/lib/Twig/Node/Expression/Binary/And.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/And.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/Node/Expression/Binary/And.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Binary/And.php
diff --git a/lib/twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseAnd.php
diff --git a/lib/twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseOr.php
diff --git a/lib/twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Binary/BitwiseXor.php
diff --git a/lib/twig/lib/Twig/Node/Expression/Binary/Concat.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Concat.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/Node/Expression/Binary/Concat.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Binary/Concat.php
diff --git a/lib/twig/lib/Twig/Node/Expression/Binary/Div.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Div.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/Node/Expression/Binary/Div.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Binary/Div.php
diff --git a/lib/twig/lib/Twig/Node/Expression/Binary/Equal.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Equal.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/Node/Expression/Binary/Equal.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Binary/Equal.php
diff --git a/lib/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Binary/FloorDiv.php
diff --git a/lib/twig/lib/Twig/Node/Expression/Binary/Greater.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Greater.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/Node/Expression/Binary/Greater.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Binary/Greater.php
diff --git a/lib/twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Binary/GreaterEqual.php
diff --git a/lib/twig/lib/Twig/Node/Expression/Binary/In.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/In.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/Node/Expression/Binary/In.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Binary/In.php
diff --git a/lib/twig/lib/Twig/Node/Expression/Binary/Less.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Less.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/Node/Expression/Binary/Less.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Binary/Less.php
diff --git a/lib/twig/lib/Twig/Node/Expression/Binary/LessEqual.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/LessEqual.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/Node/Expression/Binary/LessEqual.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Binary/LessEqual.php
diff --git a/lib/twig/lib/Twig/Node/Expression/Binary/Mod.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mod.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/Node/Expression/Binary/Mod.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mod.php
diff --git a/lib/twig/lib/Twig/Node/Expression/Binary/Mul.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mul.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/Node/Expression/Binary/Mul.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Binary/Mul.php
diff --git a/lib/twig/lib/Twig/Node/Expression/Binary/NotEqual.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotEqual.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/Node/Expression/Binary/NotEqual.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotEqual.php
diff --git a/lib/twig/lib/Twig/Node/Expression/Binary/NotIn.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotIn.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/Node/Expression/Binary/NotIn.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Binary/NotIn.php
diff --git a/lib/twig/lib/Twig/Node/Expression/Binary/Or.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Or.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/Node/Expression/Binary/Or.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Binary/Or.php
diff --git a/lib/twig/lib/Twig/Node/Expression/Binary/Power.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Power.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/Node/Expression/Binary/Power.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Binary/Power.php
diff --git a/lib/twig/lib/Twig/Node/Expression/Binary/Range.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Range.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/Node/Expression/Binary/Range.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Binary/Range.php
diff --git a/lib/twig/lib/Twig/Node/Expression/Binary/Sub.php b/vendor/twig/twig/lib/Twig/Node/Expression/Binary/Sub.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/Node/Expression/Binary/Sub.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Binary/Sub.php
diff --git a/lib/twig/lib/Twig/Node/Expression/BlockReference.php b/vendor/twig/twig/lib/Twig/Node/Expression/BlockReference.php
old mode 100755
new mode 100644
similarity index 94%
rename from lib/twig/lib/Twig/Node/Expression/BlockReference.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/BlockReference.php
index 174d909..647196e
--- a/lib/twig/lib/Twig/Node/Expression/BlockReference.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/BlockReference.php
@@ -13,8 +13,7 @@
/**
* Represents a block call node.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Node_Expression_BlockReference extends Twig_Node_Expression
{
diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Call.php b/vendor/twig/twig/lib/Twig/Node/Expression/Call.php
new file mode 100644
index 0000000..a97b3b5
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/Call.php
@@ -0,0 +1,171 @@
+getAttribute('callable');
+
+ $closingParenthesis = false;
+ if ($callable) {
+ if (is_string($callable)) {
+ $compiler->raw($callable);
+ } elseif (is_array($callable) && $callable[0] instanceof Twig_ExtensionInterface) {
+ $compiler->raw(sprintf('$this->env->getExtension(\'%s\')->%s', $callable[0]->getName(), $callable[1]));
+ } else {
+ $type = ucfirst($this->getAttribute('type'));
+ $compiler->raw(sprintf('call_user_func_array($this->env->get%s(\'%s\')->getCallable(), array', $type, $this->getAttribute('name')));
+ $closingParenthesis = true;
+ }
+ } else {
+ $compiler->raw($this->getAttribute('thing')->compile());
+ }
+
+ $this->compileArguments($compiler);
+
+ if ($closingParenthesis) {
+ $compiler->raw(')');
+ }
+ }
+
+ protected function compileArguments(Twig_Compiler $compiler)
+ {
+ $compiler->raw('(');
+
+ $first = true;
+
+ if ($this->hasAttribute('needs_environment') && $this->getAttribute('needs_environment')) {
+ $compiler->raw('$this->env');
+ $first = false;
+ }
+
+ if ($this->hasAttribute('needs_context') && $this->getAttribute('needs_context')) {
+ if (!$first) {
+ $compiler->raw(', ');
+ }
+ $compiler->raw('$context');
+ $first = false;
+ }
+
+ if ($this->hasAttribute('arguments')) {
+ foreach ($this->getAttribute('arguments') as $argument) {
+ if (!$first) {
+ $compiler->raw(', ');
+ }
+ $compiler->string($argument);
+ $first = false;
+ }
+ }
+
+ if ($this->hasNode('node')) {
+ if (!$first) {
+ $compiler->raw(', ');
+ }
+ $compiler->subcompile($this->getNode('node'));
+ $first = false;
+ }
+
+ if ($this->hasNode('arguments') && null !== $this->getNode('arguments')) {
+ $callable = $this->hasAttribute('callable') ? $this->getAttribute('callable') : null;
+
+ $arguments = $this->getArguments($callable, $this->getNode('arguments'));
+
+ foreach ($arguments as $node) {
+ if (!$first) {
+ $compiler->raw(', ');
+ }
+ $compiler->subcompile($node);
+ $first = false;
+ }
+ }
+
+ $compiler->raw(')');
+ }
+
+ protected function getArguments($callable, $arguments)
+ {
+ $parameters = array();
+ $named = false;
+ foreach ($arguments as $name => $node) {
+ if (!is_int($name)) {
+ $named = true;
+ $name = $this->normalizeName($name);
+ }
+ $parameters[$name] = $node;
+ }
+
+ if (!$named) {
+ return $parameters;
+ }
+
+ if (!$callable) {
+ throw new LogicException(sprintf('Named arguments are not supported for %s "%s".', $this->getAttribute('type'), $this->getAttribute('name')));
+ }
+
+ // manage named arguments
+ if (is_array($callable)) {
+ $r = new ReflectionMethod($callable[0], $callable[1]);
+ } elseif (is_object($callable) && !$callable instanceof Closure) {
+ $r = new ReflectionObject($callable);
+ $r = $r->getMethod('__invoke');
+ } else {
+ $r = new ReflectionFunction($callable);
+ }
+
+ $definition = $r->getParameters();
+ if ($this->hasNode('node')) {
+ array_shift($definition);
+ }
+ if ($this->hasAttribute('needs_environment') && $this->getAttribute('needs_environment')) {
+ array_shift($definition);
+ }
+ if ($this->hasAttribute('needs_context') && $this->getAttribute('needs_context')) {
+ array_shift($definition);
+ }
+ if ($this->hasAttribute('arguments') && null !== $this->getAttribute('arguments')) {
+ foreach ($this->getAttribute('arguments') as $argument) {
+ array_shift($definition);
+ }
+ }
+
+ $arguments = array();
+ $pos = 0;
+ foreach ($definition as $param) {
+ $name = $this->normalizeName($param->name);
+
+ if (array_key_exists($name, $parameters)) {
+ $arguments[] = $parameters[$name];
+ unset($parameters[$name]);
+ } elseif (array_key_exists($pos, $parameters)) {
+ $arguments[] = $parameters[$pos];
+ unset($parameters[$pos]);
+ ++$pos;
+ } elseif ($param->isDefaultValueAvailable()) {
+ $arguments[] = new Twig_Node_Expression_Constant($param->getDefaultValue(), -1);
+ } elseif ($param->isOptional()) {
+ break;
+ } else {
+ throw new Twig_Error_Syntax(sprintf('Value for argument "%s" is required for %s "%s".', $name, $this->getAttribute('type'), $this->getAttribute('name')));
+ }
+ }
+
+ foreach (array_keys($parameters) as $name) {
+ throw new Twig_Error_Syntax(sprintf('Unknown argument "%s" for %s "%s".', $name, $this->getAttribute('type'), $this->getAttribute('name')));
+ }
+
+ return $arguments;
+ }
+
+ protected function normalizeName($name)
+ {
+ return strtolower(preg_replace(array('/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'), array('\\1_\\2', '\\1_\\2'), $name));
+ }
+}
diff --git a/lib/twig/lib/Twig/Node/Expression/Conditional.php b/vendor/twig/twig/lib/Twig/Node/Expression/Conditional.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/Node/Expression/Conditional.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Conditional.php
diff --git a/lib/twig/lib/Twig/Node/Expression/Constant.php b/vendor/twig/twig/lib/Twig/Node/Expression/Constant.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/Node/Expression/Constant.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Constant.php
diff --git a/lib/twig/lib/Twig/Node/Expression/ExtensionReference.php b/vendor/twig/twig/lib/Twig/Node/Expression/ExtensionReference.php
old mode 100755
new mode 100644
similarity index 91%
rename from lib/twig/lib/Twig/Node/Expression/ExtensionReference.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/ExtensionReference.php
index cb4efad..00ac670
--- a/lib/twig/lib/Twig/Node/Expression/ExtensionReference.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/ExtensionReference.php
@@ -12,8 +12,7 @@
/**
* Represents an extension call node.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Node_Expression_ExtensionReference extends Twig_Node_Expression
{
diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Filter.php b/vendor/twig/twig/lib/Twig/Node/Expression/Filter.php
new file mode 100644
index 0000000..207b062
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/Filter.php
@@ -0,0 +1,36 @@
+ $node, 'filter' => $filterName, 'arguments' => $arguments), array(), $lineno, $tag);
+ }
+
+ public function compile(Twig_Compiler $compiler)
+ {
+ $name = $this->getNode('filter')->getAttribute('value');
+ $filter = $compiler->getEnvironment()->getFilter($name);
+
+ $this->setAttribute('name', $name);
+ $this->setAttribute('type', 'filter');
+ $this->setAttribute('thing', $filter);
+ $this->setAttribute('needs_environment', $filter->needsEnvironment());
+ $this->setAttribute('needs_context', $filter->needsContext());
+ $this->setAttribute('arguments', $filter->getArguments());
+ if ($filter instanceof Twig_FilterCallableInterface || $filter instanceof Twig_SimpleFilter) {
+ $this->setAttribute('callable', $filter->getCallable());
+ }
+
+ $this->compileCallable($compiler);
+ }
+}
diff --git a/lib/twig/lib/Twig/Node/Expression/Filter/Default.php b/vendor/twig/twig/lib/Twig/Node/Expression/Filter/Default.php
old mode 100755
new mode 100644
similarity index 90%
rename from lib/twig/lib/Twig/Node/Expression/Filter/Default.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Filter/Default.php
index 1cb3342..1827c88
--- a/lib/twig/lib/Twig/Node/Expression/Filter/Default.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/Filter/Default.php
@@ -16,14 +16,13 @@
* {{ var.foo|default('foo item on var is not defined') }}
*
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Node_Expression_Filter_Default extends Twig_Node_Expression_Filter
{
public function __construct(Twig_NodeInterface $node, Twig_Node_Expression_Constant $filterName, Twig_NodeInterface $arguments, $lineno, $tag = null)
{
- $default = new Twig_Node_Expression_Filter($node, new Twig_Node_Expression_Constant('_default', $node->getLine()), $arguments, $node->getLine());
+ $default = new Twig_Node_Expression_Filter($node, new Twig_Node_Expression_Constant('default', $node->getLine()), $arguments, $node->getLine());
if ('default' === $filterName->getAttribute('value') && ($node instanceof Twig_Node_Expression_Name || $node instanceof Twig_Node_Expression_GetAttr)) {
$test = new Twig_Node_Expression_Test_Defined(clone $node, 'defined', new Twig_Node(), $node->getLine());
diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Function.php b/vendor/twig/twig/lib/Twig/Node/Expression/Function.php
new file mode 100644
index 0000000..3e1f6b5
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/Function.php
@@ -0,0 +1,35 @@
+ $arguments), array('name' => $name), $lineno);
+ }
+
+ public function compile(Twig_Compiler $compiler)
+ {
+ $name = $this->getAttribute('name');
+ $function = $compiler->getEnvironment()->getFunction($name);
+
+ $this->setAttribute('name', $name);
+ $this->setAttribute('type', 'function');
+ $this->setAttribute('thing', $function);
+ $this->setAttribute('needs_environment', $function->needsEnvironment());
+ $this->setAttribute('needs_context', $function->needsContext());
+ $this->setAttribute('arguments', $function->getArguments());
+ if ($function instanceof Twig_FunctionCallableInterface || $function instanceof Twig_SimpleFunction) {
+ $this->setAttribute('callable', $function->getCallable());
+ }
+
+ $this->compileCallable($compiler);
+ }
+}
diff --git a/lib/twig/lib/Twig/Node/Expression/GetAttr.php b/vendor/twig/twig/lib/Twig/Node/Expression/GetAttr.php
old mode 100755
new mode 100644
similarity index 91%
rename from lib/twig/lib/Twig/Node/Expression/GetAttr.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/GetAttr.php
index 6498444..81a9b13
--- a/lib/twig/lib/Twig/Node/Expression/GetAttr.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/GetAttr.php
@@ -13,12 +13,12 @@ class Twig_Node_Expression_GetAttr extends Twig_Node_Expression
{
public function __construct(Twig_Node_Expression $node, Twig_Node_Expression $attribute, Twig_Node_Expression_Array $arguments, $type, $lineno)
{
- parent::__construct(array('node' => $node, 'attribute' => $attribute, 'arguments' => $arguments), array('type' => $type, 'is_defined_test' => false, 'ignore_strict_check' => false), $lineno);
+ parent::__construct(array('node' => $node, 'attribute' => $attribute, 'arguments' => $arguments), array('type' => $type, 'is_defined_test' => false, 'ignore_strict_check' => false, 'disable_c_ext' => false), $lineno);
}
public function compile(Twig_Compiler $compiler)
{
- if (function_exists('twig_template_get_attributes')) {
+ if (function_exists('twig_template_get_attributes') && !$this->getAttribute('disable_c_ext')) {
$compiler->raw('twig_template_get_attributes($this, ');
} else {
$compiler->raw('$this->getAttribute(');
diff --git a/lib/twig/lib/Twig/Node/Expression/MethodCall.php b/vendor/twig/twig/lib/Twig/Node/Expression/MethodCall.php
old mode 100755
new mode 100644
similarity index 89%
rename from lib/twig/lib/Twig/Node/Expression/MethodCall.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/MethodCall.php
index 5093808..620b02b
--- a/lib/twig/lib/Twig/Node/Expression/MethodCall.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/MethodCall.php
@@ -13,6 +13,10 @@ class Twig_Node_Expression_MethodCall extends Twig_Node_Expression
public function __construct(Twig_Node_Expression $node, $method, Twig_Node_Expression_Array $arguments, $lineno)
{
parent::__construct(array('node' => $node, 'arguments' => $arguments), array('method' => $method, 'safe' => false), $lineno);
+
+ if ($node instanceof Twig_Node_Expression_Name) {
+ $node->setAttribute('always_defined', true);
+ }
}
public function compile(Twig_Compiler $compiler)
diff --git a/lib/twig/lib/Twig/Node/Expression/Name.php b/vendor/twig/twig/lib/Twig/Node/Expression/Name.php
old mode 100755
new mode 100644
similarity index 76%
rename from lib/twig/lib/Twig/Node/Expression/Name.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Name.php
index 8f5a1ea..3b8fae0
--- a/lib/twig/lib/Twig/Node/Expression/Name.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/Name.php
@@ -19,7 +19,7 @@ class Twig_Node_Expression_Name extends Twig_Node_Expression
public function __construct($name, $lineno)
{
- parent::__construct(array(), array('name' => $name, 'is_defined_test' => false, 'ignore_strict_check' => false), $lineno);
+ parent::__construct(array(), array('name' => $name, 'is_defined_test' => false, 'ignore_strict_check' => false, 'always_defined' => false), $lineno);
}
public function compile(Twig_Compiler $compiler)
@@ -34,19 +34,31 @@ class Twig_Node_Expression_Name extends Twig_Node_Expression
}
} elseif ($this->isSpecial()) {
$compiler->raw($this->specialVars[$name]);
+ } elseif ($this->getAttribute('always_defined')) {
+ $compiler
+ ->raw('$context[')
+ ->string($name)
+ ->raw(']')
+ ;
} else {
// remove the non-PHP 5.4 version when PHP 5.3 support is dropped
// as the non-optimized version is just a workaround for slow ternary operator
// when the context has a lot of variables
- if (version_compare(phpversion(), '5.4.0RC1', '>=') && ($this->getAttribute('ignore_strict_check') || !$compiler->getEnvironment()->isStrictVariables())) {
+ if (version_compare(phpversion(), '5.4.0RC1', '>=')) {
// PHP 5.4 ternary operator performance was optimized
$compiler
->raw('(isset($context[')
->string($name)
->raw(']) ? $context[')
->string($name)
- ->raw('] : null)')
+ ->raw('] : ')
;
+
+ if ($this->getAttribute('ignore_strict_check') || !$compiler->getEnvironment()->isStrictVariables()) {
+ $compiler->raw('null)');
+ } else {
+ $compiler->raw('$this->getContext($context, ')->string($name)->raw('))');
+ }
} else {
$compiler
->raw('$this->getContext($context, ')
diff --git a/lib/twig/lib/Twig/Node/Expression/Parent.php b/vendor/twig/twig/lib/Twig/Node/Expression/Parent.php
old mode 100755
new mode 100644
similarity index 94%
rename from lib/twig/lib/Twig/Node/Expression/Parent.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Parent.php
index ea97349..dcf618c
--- a/lib/twig/lib/Twig/Node/Expression/Parent.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/Parent.php
@@ -13,8 +13,7 @@
/**
* Represents a parent node.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Node_Expression_Parent extends Twig_Node_Expression
{
diff --git a/lib/twig/lib/Twig/Node/Expression/TempName.php b/vendor/twig/twig/lib/Twig/Node/Expression/TempName.php
old mode 100755
new mode 100644
similarity index 79%
rename from lib/twig/lib/Twig/Node/Expression/TempName.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/TempName.php
index eea9d47..e6b058e
--- a/lib/twig/lib/Twig/Node/Expression/TempName.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/TempName.php
@@ -17,6 +17,10 @@ class Twig_Node_Expression_TempName extends Twig_Node_Expression
public function compile(Twig_Compiler $compiler)
{
- $compiler->raw('$_')->raw($this->getAttribute('name'))->raw('_');
+ $compiler
+ ->raw('$_')
+ ->raw($this->getAttribute('name'))
+ ->raw('_')
+ ;
}
}
diff --git a/vendor/twig/twig/lib/Twig/Node/Expression/Test.php b/vendor/twig/twig/lib/Twig/Node/Expression/Test.php
new file mode 100644
index 0000000..639f501
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/Test.php
@@ -0,0 +1,32 @@
+ $node, 'arguments' => $arguments), array('name' => $name), $lineno);
+ }
+
+ public function compile(Twig_Compiler $compiler)
+ {
+ $name = $this->getAttribute('name');
+ $test = $compiler->getEnvironment()->getTest($name);
+
+ $this->setAttribute('name', $name);
+ $this->setAttribute('type', 'test');
+ $this->setAttribute('thing', $test);
+ if ($test instanceof Twig_TestCallableInterface || $test instanceof Twig_SimpleTest) {
+ $this->setAttribute('callable', $test->getCallable());
+ }
+
+ $this->compileCallable($compiler);
+ }
+}
diff --git a/lib/twig/lib/Twig/Node/Expression/Test/Constant.php b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Constant.php
old mode 100755
new mode 100644
similarity index 92%
rename from lib/twig/lib/Twig/Node/Expression/Test/Constant.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Test/Constant.php
index 6e6b6fd..45b1e5d
--- a/lib/twig/lib/Twig/Node/Expression/Test/Constant.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Constant.php
@@ -18,8 +18,7 @@
* {% endif %}
*
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Node_Expression_Test_Constant extends Twig_Node_Expression_Test
{
diff --git a/lib/twig/lib/Twig/Node/Expression/Test/Defined.php b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Defined.php
old mode 100755
new mode 100644
similarity index 92%
rename from lib/twig/lib/Twig/Node/Expression/Test/Defined.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Test/Defined.php
index e7c6828..85b07f5
--- a/lib/twig/lib/Twig/Node/Expression/Test/Defined.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Defined.php
@@ -19,8 +19,7 @@
* {% endif %}
*
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Node_Expression_Test_Defined extends Twig_Node_Expression_Test
{
@@ -35,7 +34,7 @@ class Twig_Node_Expression_Test_Defined extends Twig_Node_Expression_Test
$this->changeIgnoreStrictCheck($node);
} else {
- throw new Twig_Error_Syntax('The "defined" test only works with simple variables', $this->getLine());
+ throw new Twig_Error_Syntax('The "defined" test only works with simple variables', $this->getLine(), $compiler->getFilename());
}
}
diff --git a/lib/twig/lib/Twig/Node/Expression/Test/Divisibleby.php b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Divisibleby.php
old mode 100755
new mode 100644
similarity index 91%
rename from lib/twig/lib/Twig/Node/Expression/Test/Divisibleby.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Test/Divisibleby.php
index 05563d5..0aceb53
--- a/lib/twig/lib/Twig/Node/Expression/Test/Divisibleby.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Divisibleby.php
@@ -16,8 +16,7 @@
* {% if loop.index is divisibleby(3) %}
*
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Node_Expression_Test_Divisibleby extends Twig_Node_Expression_Test
{
diff --git a/lib/twig/lib/Twig/Node/Expression/Test/Even.php b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Even.php
old mode 100755
new mode 100644
similarity index 89%
rename from lib/twig/lib/Twig/Node/Expression/Test/Even.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Test/Even.php
index 08e6d82..d7853e8
--- a/lib/twig/lib/Twig/Node/Expression/Test/Even.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Even.php
@@ -16,8 +16,7 @@
* {{ var is even }}
*
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Node_Expression_Test_Even extends Twig_Node_Expression_Test
{
diff --git a/lib/twig/lib/Twig/Node/Expression/Test/Null.php b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Null.php
old mode 100755
new mode 100644
similarity index 89%
rename from lib/twig/lib/Twig/Node/Expression/Test/Null.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Test/Null.php
index 55061db..1c83825
--- a/lib/twig/lib/Twig/Node/Expression/Test/Null.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Null.php
@@ -16,8 +16,7 @@
* {{ var is none }}
*
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Node_Expression_Test_Null extends Twig_Node_Expression_Test
{
diff --git a/lib/twig/lib/Twig/Node/Expression/Test/Odd.php b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Odd.php
old mode 100755
new mode 100644
similarity index 89%
rename from lib/twig/lib/Twig/Node/Expression/Test/Odd.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Test/Odd.php
index 5fecebc..421c19e
--- a/lib/twig/lib/Twig/Node/Expression/Test/Odd.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Odd.php
@@ -16,8 +16,7 @@
* {{ var is odd }}
*
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Node_Expression_Test_Odd extends Twig_Node_Expression_Test
{
diff --git a/lib/twig/lib/Twig/Node/Expression/Test/Sameas.php b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Sameas.php
old mode 100755
new mode 100644
similarity index 90%
rename from lib/twig/lib/Twig/Node/Expression/Test/Sameas.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Test/Sameas.php
index 8639b96..b48905e
--- a/lib/twig/lib/Twig/Node/Expression/Test/Sameas.php
+++ b/vendor/twig/twig/lib/Twig/Node/Expression/Test/Sameas.php
@@ -12,8 +12,7 @@
/**
* Checks if a variable is the same as another one (=== in PHP).
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Node_Expression_Test_Sameas extends Twig_Node_Expression_Test
{
diff --git a/lib/twig/lib/Twig/Node/Expression/Unary.php b/vendor/twig/twig/lib/Twig/Node/Expression/Unary.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/Node/Expression/Unary.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Unary.php
diff --git a/lib/twig/lib/Twig/Node/Expression/Unary/Neg.php b/vendor/twig/twig/lib/Twig/Node/Expression/Unary/Neg.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/Node/Expression/Unary/Neg.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Unary/Neg.php
diff --git a/lib/twig/lib/Twig/Node/Expression/Unary/Not.php b/vendor/twig/twig/lib/Twig/Node/Expression/Unary/Not.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/Node/Expression/Unary/Not.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Unary/Not.php
diff --git a/lib/twig/lib/Twig/Node/Expression/Unary/Pos.php b/vendor/twig/twig/lib/Twig/Node/Expression/Unary/Pos.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/Node/Expression/Unary/Pos.php
rename to vendor/twig/twig/lib/Twig/Node/Expression/Unary/Pos.php
diff --git a/lib/twig/lib/Twig/Node/Flush.php b/vendor/twig/twig/lib/Twig/Node/Flush.php
old mode 100755
new mode 100644
similarity index 90%
rename from lib/twig/lib/Twig/Node/Flush.php
rename to vendor/twig/twig/lib/Twig/Node/Flush.php
index 8f2ab9d..0467ddc
--- a/lib/twig/lib/Twig/Node/Flush.php
+++ b/vendor/twig/twig/lib/Twig/Node/Flush.php
@@ -12,8 +12,7 @@
/**
* Represents a flush node.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Node_Flush extends Twig_Node
{
diff --git a/lib/twig/lib/Twig/Node/For.php b/vendor/twig/twig/lib/Twig/Node/For.php
old mode 100755
new mode 100644
similarity index 98%
rename from lib/twig/lib/Twig/Node/For.php
rename to vendor/twig/twig/lib/Twig/Node/For.php
index d9d25b3..20e543c
--- a/lib/twig/lib/Twig/Node/For.php
+++ b/vendor/twig/twig/lib/Twig/Node/For.php
@@ -13,8 +13,7 @@
/**
* Represents a for node.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Node_For extends Twig_Node
{
diff --git a/lib/twig/lib/Twig/Node/ForLoop.php b/vendor/twig/twig/lib/Twig/Node/ForLoop.php
old mode 100755
new mode 100644
similarity index 95%
rename from lib/twig/lib/Twig/Node/ForLoop.php
rename to vendor/twig/twig/lib/Twig/Node/ForLoop.php
index 38f2e85..b884158
--- a/lib/twig/lib/Twig/Node/ForLoop.php
+++ b/vendor/twig/twig/lib/Twig/Node/ForLoop.php
@@ -12,8 +12,7 @@
/**
* Internal node used by the for node.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Node_ForLoop extends Twig_Node
{
diff --git a/lib/twig/lib/Twig/Node/If.php b/vendor/twig/twig/lib/Twig/Node/If.php
old mode 100755
new mode 100644
similarity index 95%
rename from lib/twig/lib/Twig/Node/If.php
rename to vendor/twig/twig/lib/Twig/Node/If.php
index aa12efb..4296a8d
--- a/lib/twig/lib/Twig/Node/If.php
+++ b/vendor/twig/twig/lib/Twig/Node/If.php
@@ -13,8 +13,7 @@
/**
* Represents an if node.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Node_If extends Twig_Node
{
diff --git a/lib/twig/lib/Twig/Node/Import.php b/vendor/twig/twig/lib/Twig/Node/Import.php
old mode 100755
new mode 100644
similarity index 94%
rename from lib/twig/lib/Twig/Node/Import.php
rename to vendor/twig/twig/lib/Twig/Node/Import.php
index a327411..99efc09
--- a/lib/twig/lib/Twig/Node/Import.php
+++ b/vendor/twig/twig/lib/Twig/Node/Import.php
@@ -12,8 +12,7 @@
/**
* Represents an import node.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Node_Import extends Twig_Node
{
diff --git a/lib/twig/lib/Twig/Node/Include.php b/vendor/twig/twig/lib/Twig/Node/Include.php
old mode 100755
new mode 100644
similarity index 86%
rename from lib/twig/lib/Twig/Node/Include.php
rename to vendor/twig/twig/lib/Twig/Node/Include.php
index 467749b..ed4a375
--- a/lib/twig/lib/Twig/Node/Include.php
+++ b/vendor/twig/twig/lib/Twig/Node/Include.php
@@ -13,8 +13,7 @@
/**
* Represents an include node.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Node_Include extends Twig_Node implements Twig_NodeOutputInterface
{
@@ -39,21 +38,46 @@ class Twig_Node_Include extends Twig_Node implements Twig_NodeOutputInterface
;
}
+ $this->addGetTemplate($compiler);
+
+ $compiler->raw('->display(');
+
+ $this->addTemplateArguments($compiler);
+
+ $compiler->raw(");\n");
+
+ if ($this->getAttribute('ignore_missing')) {
+ $compiler
+ ->outdent()
+ ->write("} catch (Twig_Error_Loader \$e) {\n")
+ ->indent()
+ ->write("// ignore missing template\n")
+ ->outdent()
+ ->write("}\n\n")
+ ;
+ }
+ }
+
+ protected function addGetTemplate(Twig_Compiler $compiler)
+ {
if ($this->getNode('expr') instanceof Twig_Node_Expression_Constant) {
$compiler
->write("\$this->env->loadTemplate(")
->subcompile($this->getNode('expr'))
- ->raw(")->display(")
+ ->raw(")")
;
} else {
$compiler
->write("\$template = \$this->env->resolveTemplate(")
->subcompile($this->getNode('expr'))
->raw(");\n")
- ->write('$template->display(')
+ ->write('$template')
;
}
+ }
+ protected function addTemplateArguments(Twig_Compiler $compiler)
+ {
if (false === $this->getAttribute('only')) {
if (null === $this->getNode('variables')) {
$compiler->raw('$context');
@@ -71,18 +95,5 @@ class Twig_Node_Include extends Twig_Node implements Twig_NodeOutputInterface
$compiler->subcompile($this->getNode('variables'));
}
}
-
- $compiler->raw(");\n");
-
- if ($this->getAttribute('ignore_missing')) {
- $compiler
- ->outdent()
- ->write("} catch (Twig_Error_Loader \$e) {\n")
- ->indent()
- ->write("// ignore missing template\n")
- ->outdent()
- ->write("}\n\n")
- ;
- }
}
}
diff --git a/lib/twig/lib/Twig/Node/Macro.php b/vendor/twig/twig/lib/Twig/Node/Macro.php
old mode 100755
new mode 100644
similarity index 64%
rename from lib/twig/lib/Twig/Node/Macro.php
rename to vendor/twig/twig/lib/Twig/Node/Macro.php
index 5db1bf1..8991061
--- a/lib/twig/lib/Twig/Node/Macro.php
+++ b/vendor/twig/twig/lib/Twig/Node/Macro.php
@@ -12,8 +12,7 @@
/**
* Represents a macro node.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Node_Macro extends Twig_Node
{
@@ -29,14 +28,27 @@ class Twig_Node_Macro extends Twig_Node
*/
public function compile(Twig_Compiler $compiler)
{
- $arguments = array();
- foreach ($this->getNode('arguments') as $argument) {
- $arguments[] = '$'.$argument->getAttribute('name').' = null';
+ $compiler
+ ->addDebugInfo($this)
+ ->write(sprintf("public function get%s(", $this->getAttribute('name')))
+ ;
+
+ $count = count($this->getNode('arguments'));
+ $pos = 0;
+ foreach ($this->getNode('arguments') as $name => $default) {
+ $compiler
+ ->raw('$_'.$name.' = ')
+ ->subcompile($default)
+ ;
+
+ if (++$pos < $count) {
+ $compiler->raw(', ');
+ }
}
$compiler
- ->addDebugInfo($this)
- ->write(sprintf("public function get%s(%s)\n", $this->getAttribute('name'), implode(', ', $arguments)), "{\n")
+ ->raw(")\n")
+ ->write("{\n")
->indent()
;
@@ -44,15 +56,15 @@ class Twig_Node_Macro extends Twig_Node
$compiler->write("\$context = \$this->env->getGlobals();\n\n");
} else {
$compiler
- ->write("\$context = array_merge(\$this->env->getGlobals(), array(\n")
+ ->write("\$context = \$this->env->mergeGlobals(array(\n")
->indent()
;
- foreach ($this->getNode('arguments') as $argument) {
+ foreach ($this->getNode('arguments') as $name => $default) {
$compiler
->write('')
- ->string($argument->getAttribute('name'))
- ->raw(' => $'.$argument->getAttribute('name'))
+ ->string($name)
+ ->raw(' => $_'.$name)
->raw(",\n")
;
}
@@ -70,13 +82,13 @@ class Twig_Node_Macro extends Twig_Node
->indent()
->subcompile($this->getNode('body'))
->outdent()
- ->write("} catch(Exception \$e) {\n")
+ ->write("} catch (Exception \$e) {\n")
->indent()
->write("ob_end_clean();\n\n")
->write("throw \$e;\n")
->outdent()
->write("}\n\n")
- ->write("return ob_get_clean();\n")
+ ->write("return ('' === \$tmp = ob_get_clean()) ? '' : new Twig_Markup(\$tmp, \$this->env->getCharset());\n")
->outdent()
->write("}\n\n")
;
diff --git a/lib/twig/lib/Twig/Node/Module.php b/vendor/twig/twig/lib/Twig/Node/Module.php
old mode 100755
new mode 100644
similarity index 92%
rename from lib/twig/lib/Twig/Node/Module.php
rename to vendor/twig/twig/lib/Twig/Node/Module.php
index c67bc9a..585048b
--- a/lib/twig/lib/Twig/Node/Module.php
+++ b/vendor/twig/twig/lib/Twig/Node/Module.php
@@ -13,14 +13,19 @@
/**
* Represents a module node.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Node_Module extends Twig_Node
{
- public function __construct(Twig_NodeInterface $body, Twig_Node_Expression $parent = null, Twig_NodeInterface $blocks, Twig_NodeInterface $macros, Twig_NodeInterface $traits, $filename)
+ public function __construct(Twig_NodeInterface $body, Twig_Node_Expression $parent = null, Twig_NodeInterface $blocks, Twig_NodeInterface $macros, Twig_NodeInterface $traits, $embeddedTemplates, $filename)
{
- parent::__construct(array('parent' => $parent, 'body' => $body, 'blocks' => $blocks, 'macros' => $macros, 'traits' => $traits), array('filename' => $filename), 1);
+ // embedded templates are set as attributes so that they are only visited once by the visitors
+ parent::__construct(array('parent' => $parent, 'body' => $body, 'blocks' => $blocks, 'macros' => $macros, 'traits' => $traits), array('filename' => $filename, 'index' => null, 'embedded_templates' => $embeddedTemplates), 1);
+ }
+
+ public function setIndex($index)
+ {
+ $this->setAttribute('index', $index);
}
/**
@@ -31,13 +36,21 @@ class Twig_Node_Module extends Twig_Node
public function compile(Twig_Compiler $compiler)
{
$this->compileTemplate($compiler);
+
+ foreach ($this->getAttribute('embedded_templates') as $template) {
+ $compiler->subcompile($template);
+ }
}
protected function compileTemplate(Twig_Compiler $compiler)
{
+ if (!$this->getAttribute('index')) {
+ $compiler->write('compileClassHeader($compiler);
- if (count($this->getNode('blocks')) || count($this->getNode('traits'))) {
+ if (count($this->getNode('blocks')) || count($this->getNode('traits')) || null === $this->getNode('parent') || $this->getNode('parent') instanceof Twig_Node_Expression_Constant) {
$this->compileConstructor($compiler);
}
@@ -108,10 +121,10 @@ class Twig_Node_Module extends Twig_Node
protected function compileClassHeader(Twig_Compiler $compiler)
{
$compiler
- ->write("write("\n\n")
// if the filename contains */, add a blank to avoid a PHP parse error
->write("/* ".str_replace('*/', '* /', $this->getAttribute('filename'))." */\n")
- ->write('class '.$compiler->getEnvironment()->getTemplateClass($this->getAttribute('filename')))
+ ->write('class '.$compiler->getEnvironment()->getTemplateClass($this->getAttribute('filename'), $this->getAttribute('index')))
->raw(sprintf(" extends %s\n", $compiler->getEnvironment()->getBaseTemplateClass()))
->write("{\n")
->indent()
diff --git a/lib/twig/lib/Twig/Node/Print.php b/vendor/twig/twig/lib/Twig/Node/Print.php
old mode 100755
new mode 100644
similarity index 92%
rename from lib/twig/lib/Twig/Node/Print.php
rename to vendor/twig/twig/lib/Twig/Node/Print.php
index 766725f..b0c41d1
--- a/lib/twig/lib/Twig/Node/Print.php
+++ b/vendor/twig/twig/lib/Twig/Node/Print.php
@@ -13,8 +13,7 @@
/**
* Represents a node that outputs an expression.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Node_Print extends Twig_Node implements Twig_NodeOutputInterface
{
diff --git a/lib/twig/lib/Twig/Node/Sandbox.php b/vendor/twig/twig/lib/Twig/Node/Sandbox.php
old mode 100755
new mode 100644
similarity index 94%
rename from lib/twig/lib/Twig/Node/Sandbox.php
rename to vendor/twig/twig/lib/Twig/Node/Sandbox.php
index cbfcb41..8cf3ed4
--- a/lib/twig/lib/Twig/Node/Sandbox.php
+++ b/vendor/twig/twig/lib/Twig/Node/Sandbox.php
@@ -12,8 +12,7 @@
/**
* Represents a sandbox node.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Node_Sandbox extends Twig_Node
{
diff --git a/lib/twig/lib/Twig/Node/SandboxedModule.php b/vendor/twig/twig/lib/Twig/Node/SandboxedModule.php
old mode 100755
new mode 100644
similarity index 83%
rename from lib/twig/lib/Twig/Node/SandboxedModule.php
rename to vendor/twig/twig/lib/Twig/Node/SandboxedModule.php
index 655efa3..be1f5da
--- a/lib/twig/lib/Twig/Node/SandboxedModule.php
+++ b/vendor/twig/twig/lib/Twig/Node/SandboxedModule.php
@@ -13,8 +13,7 @@
/**
* Represents a module node.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Node_SandboxedModule extends Twig_Node_Module
{
@@ -24,7 +23,9 @@ class Twig_Node_SandboxedModule extends Twig_Node_Module
public function __construct(Twig_Node_Module $node, array $usedFilters, array $usedTags, array $usedFunctions)
{
- parent::__construct($node->getNode('body'), $node->getNode('parent'), $node->getNode('blocks'), $node->getNode('macros'), $node->getNode('traits'), $node->getAttribute('filename'), $node->getLine(), $node->getNodeTag());
+ parent::__construct($node->getNode('body'), $node->getNode('parent'), $node->getNode('blocks'), $node->getNode('macros'), $node->getNode('traits'), $node->getAttribute('embedded_templates'), $node->getAttribute('filename'), $node->getLine(), $node->getNodeTag());
+
+ $this->setAttribute('index', $node->getAttribute('index'));
$this->usedFilters = $usedFilters;
$this->usedTags = $usedTags;
@@ -43,7 +44,7 @@ class Twig_Node_SandboxedModule extends Twig_Node_Module
parent::compileDisplayFooter($compiler);
$compiler
- ->write("protected function checkSecurity() {\n")
+ ->write("protected function checkSecurity()\n", "{\n")
->indent()
->write("\$this->env->getExtension('sandbox')->checkSecurity(\n")
->indent()
diff --git a/lib/twig/lib/Twig/Node/SandboxedPrint.php b/vendor/twig/twig/lib/Twig/Node/SandboxedPrint.php
old mode 100755
new mode 100644
similarity index 95%
rename from lib/twig/lib/Twig/Node/SandboxedPrint.php
rename to vendor/twig/twig/lib/Twig/Node/SandboxedPrint.php
index 77730d8..73dfaa9
--- a/lib/twig/lib/Twig/Node/SandboxedPrint.php
+++ b/vendor/twig/twig/lib/Twig/Node/SandboxedPrint.php
@@ -17,8 +17,7 @@
* and if the sandbox is enabled, we need to check that the __toString()
* method is allowed if 'article' is an object.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Node_SandboxedPrint extends Twig_Node_Print
{
diff --git a/lib/twig/lib/Twig/Node/Set.php b/vendor/twig/twig/lib/Twig/Node/Set.php
old mode 100755
new mode 100644
similarity index 97%
rename from lib/twig/lib/Twig/Node/Set.php
rename to vendor/twig/twig/lib/Twig/Node/Set.php
index 70bb519..4c9c16c
--- a/lib/twig/lib/Twig/Node/Set.php
+++ b/vendor/twig/twig/lib/Twig/Node/Set.php
@@ -12,8 +12,7 @@
/**
* Represents a set node.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Node_Set extends Twig_Node
{
diff --git a/lib/twig/lib/Twig/Node/SetTemp.php b/vendor/twig/twig/lib/Twig/Node/SetTemp.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/Node/SetTemp.php
rename to vendor/twig/twig/lib/Twig/Node/SetTemp.php
diff --git a/lib/twig/lib/Twig/Node/Spaceless.php b/vendor/twig/twig/lib/Twig/Node/Spaceless.php
old mode 100755
new mode 100644
similarity index 92%
rename from lib/twig/lib/Twig/Node/Spaceless.php
rename to vendor/twig/twig/lib/Twig/Node/Spaceless.php
index 4601346..7555fa0
--- a/lib/twig/lib/Twig/Node/Spaceless.php
+++ b/vendor/twig/twig/lib/Twig/Node/Spaceless.php
@@ -14,8 +14,7 @@
*
* It removes spaces between HTML tags.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Node_Spaceless extends Twig_Node
{
diff --git a/lib/twig/lib/Twig/Node/Text.php b/vendor/twig/twig/lib/Twig/Node/Text.php
old mode 100755
new mode 100644
similarity index 91%
rename from lib/twig/lib/Twig/Node/Text.php
rename to vendor/twig/twig/lib/Twig/Node/Text.php
index 0c1c092..21bdcea
--- a/lib/twig/lib/Twig/Node/Text.php
+++ b/vendor/twig/twig/lib/Twig/Node/Text.php
@@ -13,8 +13,7 @@
/**
* Represents a text node.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Node_Text extends Twig_Node implements Twig_NodeOutputInterface
{
diff --git a/lib/twig/lib/Twig/NodeInterface.php b/vendor/twig/twig/lib/Twig/NodeInterface.php
old mode 100755
new mode 100644
similarity index 66%
rename from lib/twig/lib/Twig/NodeInterface.php
rename to vendor/twig/twig/lib/Twig/NodeInterface.php
index 29a84b0..f0ef725
--- a/lib/twig/lib/Twig/NodeInterface.php
+++ b/vendor/twig/twig/lib/Twig/NodeInterface.php
@@ -12,8 +12,8 @@
/**
* Represents a node in the AST.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
+ * @deprecated since 1.12 (to be removed in 2.0)
*/
interface Twig_NodeInterface extends Countable, IteratorAggregate
{
@@ -22,9 +22,9 @@ interface Twig_NodeInterface extends Countable, IteratorAggregate
*
* @param Twig_Compiler A Twig_Compiler instance
*/
- function compile(Twig_Compiler $compiler);
+ public function compile(Twig_Compiler $compiler);
- function getLine();
+ public function getLine();
- function getNodeTag();
+ public function getNodeTag();
}
diff --git a/lib/twig/lib/Twig/NodeOutputInterface.php b/vendor/twig/twig/lib/Twig/NodeOutputInterface.php
old mode 100755
new mode 100644
similarity index 80%
rename from lib/twig/lib/Twig/NodeOutputInterface.php
rename to vendor/twig/twig/lib/Twig/NodeOutputInterface.php
index 7183956..22172c0
--- a/lib/twig/lib/Twig/NodeOutputInterface.php
+++ b/vendor/twig/twig/lib/Twig/NodeOutputInterface.php
@@ -12,8 +12,7 @@
/**
* Represents a displayable node in the AST.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
interface Twig_NodeOutputInterface
{
diff --git a/lib/twig/lib/Twig/NodeTraverser.php b/vendor/twig/twig/lib/Twig/NodeTraverser.php
old mode 100755
new mode 100644
similarity index 96%
rename from lib/twig/lib/Twig/NodeTraverser.php
rename to vendor/twig/twig/lib/Twig/NodeTraverser.php
index 1e82b03..28cba1a
--- a/lib/twig/lib/Twig/NodeTraverser.php
+++ b/vendor/twig/twig/lib/Twig/NodeTraverser.php
@@ -14,8 +14,7 @@
*
* It visits all nodes and their children and call the given visitor for each.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_NodeTraverser
{
diff --git a/lib/twig/lib/Twig/NodeVisitor/Escaper.php b/vendor/twig/twig/lib/Twig/NodeVisitor/Escaper.php
old mode 100755
new mode 100644
similarity index 76%
rename from lib/twig/lib/Twig/NodeVisitor/Escaper.php
rename to vendor/twig/twig/lib/Twig/NodeVisitor/Escaper.php
index f682beb..cc4b3d7
--- a/lib/twig/lib/Twig/NodeVisitor/Escaper.php
+++ b/vendor/twig/twig/lib/Twig/NodeVisitor/Escaper.php
@@ -12,18 +12,18 @@
/**
* Twig_NodeVisitor_Escaper implements output escaping.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface
{
protected $statusStack = array();
protected $blocks = array();
-
protected $safeAnalysis;
protected $traverser;
+ protected $defaultStrategy = false;
+ protected $safeVars = array();
- function __construct()
+ public function __construct()
{
$this->safeAnalysis = new Twig_NodeVisitor_SafeAnalysis();
}
@@ -38,10 +38,17 @@ class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface
*/
public function enterNode(Twig_NodeInterface $node, Twig_Environment $env)
{
- if ($node instanceof Twig_Node_AutoEscape) {
+ if ($node instanceof Twig_Node_Module) {
+ if ($env->hasExtension('escaper') && $defaultStrategy = $env->getExtension('escaper')->getDefaultStrategy($node->getAttribute('filename'))) {
+ $this->defaultStrategy = $defaultStrategy;
+ }
+ $this->safeVars = array();
+ } elseif ($node instanceof Twig_Node_AutoEscape) {
$this->statusStack[] = $node->getAttribute('value');
} elseif ($node instanceof Twig_Node_Block) {
$this->statusStack[] = isset($this->blocks[$node->getAttribute('name')]) ? $this->blocks[$node->getAttribute('name')] : $this->needEscaping($env);
+ } elseif ($node instanceof Twig_Node_Import) {
+ $this->safeVars[] = $node->getNode('var')->getAttribute('name');
}
return $node;
@@ -57,7 +64,10 @@ class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface
*/
public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env)
{
- if ($node instanceof Twig_Node_Expression_Filter) {
+ if ($node instanceof Twig_Node_Module) {
+ $this->defaultStrategy = false;
+ $this->safeVars = array();
+ } elseif ($node instanceof Twig_Node_Expression_Filter) {
return $this->preEscapeFilterNode($node, $env);
} elseif ($node instanceof Twig_Node_Print) {
return $this->escapePrintNode($node, $env, $this->needEscaping($env));
@@ -96,22 +106,18 @@ class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface
{
$name = $filter->getNode('filter')->getAttribute('value');
- if (false !== $f = $env->getFilter($name)) {
- $type = $f->getPreEscape();
- if (null === $type) {
- return $filter;
- }
-
- $node = $filter->getNode('node');
- if ($this->isSafeFor($type, $node, $env)) {
- return $filter;
- }
-
- $filter->setNode('node', $this->getEscaperFilter($type, $node));
-
+ $type = $env->getFilter($name)->getPreEscape();
+ if (null === $type) {
return $filter;
}
+ $node = $filter->getNode('node');
+ if ($this->isSafeFor($type, $node, $env)) {
+ return $filter;
+ }
+
+ $filter->setNode('node', $this->getEscaperFilter($type, $node));
+
return $filter;
}
@@ -123,6 +129,9 @@ class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface
if (null === $this->traverser) {
$this->traverser = new Twig_NodeTraverser($env, array($this->safeAnalysis));
}
+
+ $this->safeAnalysis->setSafeVars($this->safeVars);
+
$this->traverser->traverse($expression);
$safe = $this->safeAnalysis->getSafe($expression);
}
@@ -136,11 +145,7 @@ class Twig_NodeVisitor_Escaper implements Twig_NodeVisitorInterface
return $this->statusStack[count($this->statusStack) - 1];
}
- if ($env->hasExtension('escaper') && $env->getExtension('escaper')->isGlobal()) {
- return 'html';
- }
-
- return false;
+ return $this->defaultStrategy ? $this->defaultStrategy : false;
}
protected function getEscaperFilter($type, Twig_NodeInterface $node)
diff --git a/lib/twig/lib/Twig/NodeVisitor/Optimizer.php b/vendor/twig/twig/lib/Twig/NodeVisitor/Optimizer.php
old mode 100755
new mode 100644
similarity index 96%
rename from lib/twig/lib/Twig/NodeVisitor/Optimizer.php
rename to vendor/twig/twig/lib/Twig/NodeVisitor/Optimizer.php
index cbc61fc..a254def
--- a/lib/twig/lib/Twig/NodeVisitor/Optimizer.php
+++ b/vendor/twig/twig/lib/Twig/NodeVisitor/Optimizer.php
@@ -17,8 +17,7 @@
* You can configure which optimizations you want to activate via the
* optimizer mode.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface
{
@@ -56,7 +55,7 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface
$this->enterOptimizeFor($node, $env);
}
- if (!version_compare(phpversion(), '5.4.0RC1', '>=') && self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('sandbox')) {
+ if (!version_compare(phpversion(), '5.4.0RC1', '>=') && self::OPTIMIZE_VAR_ACCESS === (self::OPTIMIZE_VAR_ACCESS & $this->optimizers) && !$env->isStrictVariables() && !$env->hasExtension('sandbox')) {
if ($this->inABody) {
if (!$node instanceof Twig_Node_Expression) {
if (get_class($node) !== 'Twig_Node') {
diff --git a/lib/twig/lib/Twig/NodeVisitor/SafeAnalysis.php b/vendor/twig/twig/lib/Twig/NodeVisitor/SafeAnalysis.php
old mode 100755
new mode 100644
similarity index 78%
rename from lib/twig/lib/Twig/NodeVisitor/SafeAnalysis.php
rename to vendor/twig/twig/lib/Twig/NodeVisitor/SafeAnalysis.php
index 89d8794..7dc65c0
--- a/lib/twig/lib/Twig/NodeVisitor/SafeAnalysis.php
+++ b/vendor/twig/twig/lib/Twig/NodeVisitor/SafeAnalysis.php
@@ -3,12 +3,18 @@
class Twig_NodeVisitor_SafeAnalysis implements Twig_NodeVisitorInterface
{
protected $data = array();
+ protected $safeVars = array();
+
+ public function setSafeVars($safeVars)
+ {
+ $this->safeVars = $safeVars;
+ }
public function getSafe(Twig_NodeInterface $node)
{
$hash = spl_object_hash($node);
if (isset($this->data[$hash])) {
- foreach($this->data[$hash] as $bucket) {
+ foreach ($this->data[$hash] as $bucket) {
if ($bucket['key'] === $node) {
return $bucket['value'];
}
@@ -22,7 +28,7 @@ class Twig_NodeVisitor_SafeAnalysis implements Twig_NodeVisitorInterface
{
$hash = spl_object_hash($node);
if (isset($this->data[$hash])) {
- foreach($this->data[$hash] as &$bucket) {
+ foreach ($this->data[$hash] as &$bucket) {
if ($bucket['key'] === $node) {
$bucket['value'] = $safe;
@@ -61,7 +67,11 @@ class Twig_NodeVisitor_SafeAnalysis implements Twig_NodeVisitorInterface
$name = $node->getNode('filter')->getAttribute('value');
$args = $node->getNode('arguments');
if (false !== $filter = $env->getFilter($name)) {
- $this->setSafe($node, $filter->getSafe($args));
+ $safe = $filter->getSafe($args);
+ if (null === $safe) {
+ $safe = $this->intersectSafe($this->getSafe($node->getNode('node')), $filter->getPreservesSafety());
+ }
+ $this->setSafe($node, $safe);
} else {
$this->setSafe($node, array());
}
@@ -81,6 +91,14 @@ class Twig_NodeVisitor_SafeAnalysis implements Twig_NodeVisitorInterface
} else {
$this->setSafe($node, array());
}
+ } elseif ($node instanceof Twig_Node_Expression_GetAttr && $node->getNode('node') instanceof Twig_Node_Expression_Name) {
+ $name = $node->getNode('node')->getAttribute('name');
+ // attributes on template instances are safe
+ if ('_self' == $name || in_array($name, $this->safeVars)) {
+ $this->setSafe($node, array('all'));
+ } else {
+ $this->setSafe($node, array());
+ }
} else {
$this->setSafe($node, array());
}
diff --git a/lib/twig/lib/Twig/NodeVisitor/Sandbox.php b/vendor/twig/twig/lib/Twig/NodeVisitor/Sandbox.php
old mode 100755
new mode 100644
similarity index 97%
rename from lib/twig/lib/Twig/NodeVisitor/Sandbox.php
rename to vendor/twig/twig/lib/Twig/NodeVisitor/Sandbox.php
index 1957f8a..fb27045
--- a/lib/twig/lib/Twig/NodeVisitor/Sandbox.php
+++ b/vendor/twig/twig/lib/Twig/NodeVisitor/Sandbox.php
@@ -12,8 +12,7 @@
/**
* Twig_NodeVisitor_Sandbox implements sandboxing.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_NodeVisitor_Sandbox implements Twig_NodeVisitorInterface
{
diff --git a/lib/twig/lib/Twig/NodeVisitorInterface.php b/vendor/twig/twig/lib/Twig/NodeVisitorInterface.php
old mode 100755
new mode 100644
similarity index 74%
rename from lib/twig/lib/Twig/NodeVisitorInterface.php
rename to vendor/twig/twig/lib/Twig/NodeVisitorInterface.php
index e0123b5..f33c13f
--- a/lib/twig/lib/Twig/NodeVisitorInterface.php
+++ b/vendor/twig/twig/lib/Twig/NodeVisitorInterface.php
@@ -12,8 +12,7 @@
/**
* Twig_NodeVisitorInterface is the interface the all node visitor classes must implement.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
interface Twig_NodeVisitorInterface
{
@@ -25,7 +24,7 @@ interface Twig_NodeVisitorInterface
*
* @return Twig_NodeInterface The modified node
*/
- function enterNode(Twig_NodeInterface $node, Twig_Environment $env);
+ public function enterNode(Twig_NodeInterface $node, Twig_Environment $env);
/**
* Called after child nodes are visited.
@@ -33,9 +32,9 @@ interface Twig_NodeVisitorInterface
* @param Twig_NodeInterface $node The node to visit
* @param Twig_Environment $env The Twig environment instance
*
- * @return Twig_NodeInterface The modified node
+ * @return Twig_NodeInterface|false The modified node or false if the node must be removed
*/
- function leaveNode(Twig_NodeInterface $node, Twig_Environment $env);
+ public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env);
/**
* Returns the priority for this visitor.
@@ -44,5 +43,5 @@ interface Twig_NodeVisitorInterface
*
* @return integer The priority level
*/
- function getPriority();
+ public function getPriority();
}
diff --git a/lib/twig/lib/Twig/Parser.php b/vendor/twig/twig/lib/Twig/Parser.php
old mode 100755
new mode 100644
similarity index 77%
rename from lib/twig/lib/Twig/Parser.php
rename to vendor/twig/twig/lib/Twig/Parser.php
index 72d3637..958e46b
--- a/lib/twig/lib/Twig/Parser.php
+++ b/vendor/twig/twig/lib/Twig/Parser.php
@@ -13,8 +13,7 @@
/**
* Default parser implementation.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Parser implements Twig_ParserInterface
{
@@ -29,9 +28,9 @@ class Twig_Parser implements Twig_ParserInterface
protected $macros;
protected $env;
protected $reservedMacroNames;
- protected $importedFunctions;
- protected $tmpVarCount;
+ protected $importedSymbols;
protected $traits;
+ protected $embeddedTemplates = array();
/**
* Constructor.
@@ -50,25 +49,28 @@ class Twig_Parser implements Twig_ParserInterface
public function getVarName()
{
- return sprintf('__internal_%s_%d', substr($this->env->getTemplateClass($this->stream->getFilename()), strlen($this->env->getTemplateClassPrefix())), ++$this->tmpVarCount);
+ return sprintf('__internal_%s', hash('sha1', uniqid(mt_rand(), true), false));
+ }
+
+ public function getFilename()
+ {
+ return $this->stream->getFilename();
}
/**
* Converts a token stream to a node tree.
*
- * @param Twig_TokenStream $stream A token stream instance
+ * @param Twig_TokenStream $stream A token stream instance
*
* @return Twig_Node_Module A node tree
*/
- public function parse(Twig_TokenStream $stream)
+ public function parse(Twig_TokenStream $stream, $test = null, $dropNeedle = false)
{
// push all variables into the stack to keep the current state of the parser
$vars = get_object_vars($this);
unset($vars['stack'], $vars['env'], $vars['handlers'], $vars['visitors'], $vars['expressionParser']);
$this->stack[] = $vars;
- $this->tmpVarCount = 0;
-
// tag handlers
if (null === $this->handlers) {
$this->handlers = $this->env->getTokenParsers();
@@ -90,10 +92,11 @@ class Twig_Parser implements Twig_ParserInterface
$this->macros = array();
$this->traits = array();
$this->blockStack = array();
- $this->importedFunctions = array(array());
+ $this->importedSymbols = array(array());
+ $this->embeddedTemplates = array();
try {
- $body = $this->subparse(null);
+ $body = $this->subparse($test, $dropNeedle);
if (null !== $this->parent) {
if (null === $body = $this->filterBodyNodes($body)) {
@@ -101,14 +104,18 @@ class Twig_Parser implements Twig_ParserInterface
}
}
} catch (Twig_Error_Syntax $e) {
- if (null === $e->getTemplateFile()) {
- $e->setTemplateFile($this->stream->getFilename());
+ if (!$e->getTemplateFile()) {
+ $e->setTemplateFile($this->getFilename());
+ }
+
+ if (!$e->getTemplateLine()) {
+ $e->setTemplateLine($this->stream->getCurrent()->getLine());
}
throw $e;
}
- $node = new Twig_Node_Module(new Twig_Node_Body(array($body)), $this->parent, new Twig_Node($this->blocks), new Twig_Node($this->macros), new Twig_Node($this->traits), $this->stream->getFilename());
+ $node = new Twig_Node_Module(new Twig_Node_Body(array($body)), $this->parent, new Twig_Node($this->blocks), new Twig_Node($this->macros), new Twig_Node($this->traits), $this->embeddedTemplates, $this->getFilename());
$traverser = new Twig_NodeTraverser($this->env, $this->visitors);
@@ -145,7 +152,7 @@ class Twig_Parser implements Twig_ParserInterface
$token = $this->getCurrentToken();
if ($token->getType() !== Twig_Token::NAME_TYPE) {
- throw new Twig_Error_Syntax('A block must start with a tag name', $token->getLine(), $this->stream->getFilename());
+ throw new Twig_Error_Syntax('A block must start with a tag name', $token->getLine(), $this->getFilename());
}
if (null !== $test && call_user_func($test, $token)) {
@@ -163,7 +170,12 @@ class Twig_Parser implements Twig_ParserInterface
$subparser = $this->handlers->getTokenParser($token->getValue());
if (null === $subparser) {
if (null !== $test) {
- throw new Twig_Error_Syntax(sprintf('Unexpected tag name "%s" (expecting closing tag for the "%s" tag defined near line %s)', $token->getValue(), $test[0]->getTag(), $lineno), $token->getLine(), $this->stream->getFilename());
+ $error = sprintf('Unexpected tag name "%s"', $token->getValue());
+ if (is_array($test) && isset($test[0]) && $test[0] instanceof Twig_TokenParserInterface) {
+ $error .= sprintf(' (expecting closing tag for the "%s" tag defined near line %s)', $test[0]->getTag(), $lineno);
+ }
+
+ throw new Twig_Error_Syntax($error, $token->getLine(), $this->getFilename());
}
$message = sprintf('Unknown tag name "%s"', $token->getValue());
@@ -171,7 +183,7 @@ class Twig_Parser implements Twig_ParserInterface
$message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives));
}
- throw new Twig_Error_Syntax($message, $token->getLine(), $this->stream->getFilename());
+ throw new Twig_Error_Syntax($message, $token->getLine(), $this->getFilename());
}
$this->stream->next();
@@ -183,7 +195,7 @@ class Twig_Parser implements Twig_ParserInterface
break;
default:
- throw new Twig_Error_Syntax('Lexer or parser ended up in unsupported state.', -1, $this->stream->getFilename());
+ throw new Twig_Error_Syntax('Lexer or parser ended up in unsupported state.', 0, $this->getFilename());
}
}
@@ -229,9 +241,14 @@ class Twig_Parser implements Twig_ParserInterface
return isset($this->blocks[$name]);
}
+ public function getBlock($name)
+ {
+ return $this->blocks[$name];
+ }
+
public function setBlock($name, $value)
{
- $this->blocks[$name] = new Twig_Node_Body(array($value));
+ $this->blocks[$name] = new Twig_Node_Body(array($value), array(), $value->getLine());
}
public function hasMacro($name)
@@ -250,7 +267,7 @@ class Twig_Parser implements Twig_ParserInterface
}
if (in_array($name, $this->reservedMacroNames)) {
- throw new Twig_Error_Syntax(sprintf('"%s" cannot be used as a macro name as it is a reserved keyword', $name), $node->getLine());
+ throw new Twig_Error_Syntax(sprintf('"%s" cannot be used as a macro name as it is a reserved keyword', $name), $node->getLine(), $this->getFilename());
}
$this->macros[$name] = $node;
@@ -266,33 +283,40 @@ class Twig_Parser implements Twig_ParserInterface
return count($this->traits) > 0;
}
- public function addImportedFunction($alias, $name, Twig_Node_Expression $node)
+ public function embedTemplate(Twig_Node_Module $template)
{
- $this->importedFunctions[0][$alias] = array('name' => $name, 'node' => $node);
+ $template->setIndex(mt_rand());
+
+ $this->embeddedTemplates[] = $template;
}
- public function getImportedFunction($alias)
+ public function addImportedSymbol($type, $alias, $name = null, Twig_Node_Expression $node = null)
{
- foreach ($this->importedFunctions as $functions) {
- if (isset($functions[$alias])) {
- return $functions[$alias];
+ $this->importedSymbols[0][$type][$alias] = array('name' => $name, 'node' => $node);
+ }
+
+ public function getImportedSymbol($type, $alias)
+ {
+ foreach ($this->importedSymbols as $functions) {
+ if (isset($functions[$type][$alias])) {
+ return $functions[$type][$alias];
}
}
}
public function isMainScope()
{
- return 1 === count($this->importedFunctions);
+ return 1 === count($this->importedSymbols);
}
public function pushLocalScope()
{
- array_unshift($this->importedFunctions, array());
+ array_unshift($this->importedSymbols, array());
}
public function popLocalScope()
{
- array_shift($this->importedFunctions);
+ array_shift($this->importedSymbols);
}
/**
@@ -344,10 +368,10 @@ class Twig_Parser implements Twig_ParserInterface
(!$node instanceof Twig_Node_Text && !$node instanceof Twig_Node_BlockReference && $node instanceof Twig_NodeOutputInterface)
) {
if (false !== strpos((string) $node, chr(0xEF).chr(0xBB).chr(0xBF))) {
- throw new Twig_Error_Syntax('A template that extends another one cannot have a body but a byte order mark (BOM) has been detected; it must be removed.', $node->getLine(), $this->stream->getFilename());
- } else {
- throw new Twig_Error_Syntax('A template that extends another one cannot have a body.', $node->getLine(), $this->stream->getFilename());
+ throw new Twig_Error_Syntax('A template that extends another one cannot have a body but a byte order mark (BOM) has been detected; it must be removed.', $node->getLine(), $this->getFilename());
}
+
+ throw new Twig_Error_Syntax('A template that extends another one cannot have a body.', $node->getLine(), $this->getFilename());
}
// bypass "set" nodes as they "capture" the output
diff --git a/lib/twig/lib/Twig/ParserInterface.php b/vendor/twig/twig/lib/Twig/ParserInterface.php
old mode 100755
new mode 100644
similarity index 66%
rename from lib/twig/lib/Twig/ParserInterface.php
rename to vendor/twig/twig/lib/Twig/ParserInterface.php
index 4cb6d28..f0d7900
--- a/lib/twig/lib/Twig/ParserInterface.php
+++ b/vendor/twig/twig/lib/Twig/ParserInterface.php
@@ -12,17 +12,17 @@
/**
* Interface implemented by parser classes.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
+ * @deprecated since 1.12 (to be removed in 2.0)
*/
interface Twig_ParserInterface
{
/**
* Converts a token stream to a node tree.
*
- * @param Twig_TokenStream $stream A token stream instance
+ * @param Twig_TokenStream $stream A token stream instance
*
* @return Twig_Node_Module A node tree
*/
- function parse(Twig_TokenStream $stream);
+ public function parse(Twig_TokenStream $stream);
}
diff --git a/lib/twig/lib/Twig/Sandbox/SecurityError.php b/vendor/twig/twig/lib/Twig/Sandbox/SecurityError.php
old mode 100755
new mode 100644
similarity index 82%
rename from lib/twig/lib/Twig/Sandbox/SecurityError.php
rename to vendor/twig/twig/lib/Twig/Sandbox/SecurityError.php
index debabb7..015bfae
--- a/lib/twig/lib/Twig/Sandbox/SecurityError.php
+++ b/vendor/twig/twig/lib/Twig/Sandbox/SecurityError.php
@@ -12,8 +12,7 @@
/**
* Exception thrown when a security error occurs at runtime.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Sandbox_SecurityError extends Twig_Error
{
diff --git a/lib/twig/lib/Twig/Sandbox/SecurityPolicy.php b/vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicy.php
old mode 100755
new mode 100644
similarity index 98%
rename from lib/twig/lib/Twig/Sandbox/SecurityPolicy.php
rename to vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicy.php
index ba912ef..66ee233
--- a/lib/twig/lib/Twig/Sandbox/SecurityPolicy.php
+++ b/vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicy.php
@@ -12,8 +12,7 @@
/**
* Represents a security policy which need to be enforced when sandbox mode is enabled.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Sandbox_SecurityPolicy implements Twig_Sandbox_SecurityPolicyInterface
{
diff --git a/lib/twig/lib/Twig/Sandbox/SecurityPolicyInterface.php b/vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicyInterface.php
old mode 100755
new mode 100644
similarity index 59%
rename from lib/twig/lib/Twig/Sandbox/SecurityPolicyInterface.php
rename to vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicyInterface.php
index d5015af..6ab48e3
--- a/lib/twig/lib/Twig/Sandbox/SecurityPolicyInterface.php
+++ b/vendor/twig/twig/lib/Twig/Sandbox/SecurityPolicyInterface.php
@@ -12,14 +12,13 @@
/**
* Interfaces that all security policy classes must implements.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
interface Twig_Sandbox_SecurityPolicyInterface
{
- function checkSecurity($tags, $filters, $functions);
+ public function checkSecurity($tags, $filters, $functions);
- function checkMethodAllowed($obj, $method);
+ public function checkMethodAllowed($obj, $method);
- function checkPropertyAllowed($obj, $method);
+ public function checkPropertyAllowed($obj, $method);
}
diff --git a/vendor/twig/twig/lib/Twig/SimpleFilter.php b/vendor/twig/twig/lib/Twig/SimpleFilter.php
new file mode 100644
index 0000000..a6bf60f
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/SimpleFilter.php
@@ -0,0 +1,96 @@
+
+ */
+class Twig_SimpleFilter
+{
+ protected $name;
+ protected $callable;
+ protected $options;
+ protected $arguments = array();
+
+ public function __construct($name, $callable, array $options = array())
+ {
+ $this->name = $name;
+ $this->callable = $callable;
+ $this->options = array_merge(array(
+ 'needs_environment' => false,
+ 'needs_context' => false,
+ 'is_safe' => null,
+ 'is_safe_callback' => null,
+ 'pre_escape' => null,
+ 'preserves_safety' => null,
+ 'node_class' => 'Twig_Node_Expression_Filter',
+ ), $options);
+ }
+
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ public function getCallable()
+ {
+ return $this->callable;
+ }
+
+ public function getNodeClass()
+ {
+ return $this->options['node_class'];
+ }
+
+ public function setArguments($arguments)
+ {
+ $this->arguments = $arguments;
+ }
+
+ public function getArguments()
+ {
+ return $this->arguments;
+ }
+
+ public function needsEnvironment()
+ {
+ return $this->options['needs_environment'];
+ }
+
+ public function needsContext()
+ {
+ return $this->options['needs_context'];
+ }
+
+ public function getSafe(Twig_Node $filterArgs)
+ {
+ if (null !== $this->options['is_safe']) {
+ return $this->options['is_safe'];
+ }
+
+ if (null !== $this->options['is_safe_callback']) {
+ return call_user_func($this->options['is_safe_callback'], $filterArgs);
+ }
+
+ return null;
+ }
+
+ public function getPreservesSafety()
+ {
+ return $this->options['preserves_safety'];
+ }
+
+ public function getPreEscape()
+ {
+ return $this->options['pre_escape'];
+ }
+}
diff --git a/vendor/twig/twig/lib/Twig/SimpleFunction.php b/vendor/twig/twig/lib/Twig/SimpleFunction.php
new file mode 100644
index 0000000..8ef6aca
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/SimpleFunction.php
@@ -0,0 +1,84 @@
+
+ */
+class Twig_SimpleFunction
+{
+ protected $name;
+ protected $callable;
+ protected $options;
+ protected $arguments = array();
+
+ public function __construct($name, $callable, array $options = array())
+ {
+ $this->name = $name;
+ $this->callable = $callable;
+ $this->options = array_merge(array(
+ 'needs_environment' => false,
+ 'needs_context' => false,
+ 'is_safe' => null,
+ 'is_safe_callback' => null,
+ 'node_class' => 'Twig_Node_Expression_Function',
+ ), $options);
+ }
+
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ public function getCallable()
+ {
+ return $this->callable;
+ }
+
+ public function getNodeClass()
+ {
+ return $this->options['node_class'];
+ }
+
+ public function setArguments($arguments)
+ {
+ $this->arguments = $arguments;
+ }
+
+ public function getArguments()
+ {
+ return $this->arguments;
+ }
+
+ public function needsEnvironment()
+ {
+ return $this->options['needs_environment'];
+ }
+
+ public function needsContext()
+ {
+ return $this->options['needs_context'];
+ }
+
+ public function getSafe(Twig_Node $functionArgs)
+ {
+ if (null !== $this->options['is_safe']) {
+ return $this->options['is_safe'];
+ }
+
+ if (null !== $this->options['is_safe_callback']) {
+ return call_user_func($this->options['is_safe_callback'], $functionArgs);
+ }
+
+ return array();
+ }
+}
diff --git a/vendor/twig/twig/lib/Twig/SimpleTest.php b/vendor/twig/twig/lib/Twig/SimpleTest.php
new file mode 100644
index 0000000..225459c
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/SimpleTest.php
@@ -0,0 +1,46 @@
+
+ */
+class Twig_SimpleTest
+{
+ protected $name;
+ protected $callable;
+ protected $options;
+
+ public function __construct($name, $callable, array $options = array())
+ {
+ $this->name = $name;
+ $this->callable = $callable;
+ $this->options = array_merge(array(
+ 'node_class' => 'Twig_Node_Expression_Test',
+ ), $options);
+ }
+
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ public function getCallable()
+ {
+ return $this->callable;
+ }
+
+ public function getNodeClass()
+ {
+ return $this->options['node_class'];
+ }
+}
diff --git a/lib/twig/lib/Twig/Template.php b/vendor/twig/twig/lib/Twig/Template.php
old mode 100755
new mode 100644
similarity index 90%
rename from lib/twig/lib/Twig/Template.php
rename to vendor/twig/twig/lib/Twig/Template.php
index 1862064..abc3400
--- a/lib/twig/lib/Twig/Template.php
+++ b/vendor/twig/twig/lib/Twig/Template.php
@@ -13,12 +13,11 @@
/**
* Default base class for compiled templates.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
abstract class Twig_Template implements Twig_TemplateInterface
{
- static protected $cache = array();
+ protected static $cache = array();
protected $parent;
protected $parents;
@@ -236,7 +235,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
*/
public function display(array $context, array $blocks = array())
{
- $this->displayWithErrorHandling($this->mergeContextWithGlobals($context), $blocks);
+ $this->displayWithErrorHandling($this->env->mergeGlobals($context), $blocks);
}
/**
@@ -259,24 +258,22 @@ abstract class Twig_Template implements Twig_TemplateInterface
return ob_get_clean();
}
- protected function mergeContextWithGlobals(array $context)
- {
- // we don't use array_merge as the context being generally
- // bigger than globals, this code is faster.
- foreach ($this->env->getGlobals() as $key => $value) {
- if (!array_key_exists($key, $context)) {
- $context[$key] = $value;
- }
- }
-
- return $context;
- }
-
protected function displayWithErrorHandling(array $context, array $blocks = array())
{
try {
$this->doDisplay($context, $blocks);
} catch (Twig_Error $e) {
+ if (!$e->getTemplateFile()) {
+ $e->setTemplateFile($this->getTemplateName());
+ }
+
+ // this is mostly useful for Twig_Error_Loader exceptions
+ // see Twig_Error_Loader
+ if (false === $e->getTemplateLine()) {
+ $e->setTemplateLine(-1);
+ $e->guess();
+ }
+
throw $e;
} catch (Exception $e) {
throw new Twig_Error_Runtime(sprintf('An exception has been thrown during the rendering of a template ("%s").', $e->getMessage()), -1, null, $e);
@@ -297,7 +294,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
* This method is for internal use only and should never be called
* directly.
*
- * This method should not be overriden in a sub-class as this is an
+ * This method should not be overridden in a sub-class as this is an
* implementation detail that has been introduced to optimize variable
* access for versions of PHP before 5.4. This is not a way to override
* the way to get a variable value.
@@ -317,7 +314,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
return null;
}
- throw new Twig_Error_Runtime(sprintf('Variable "%s" does not exist', $item));
+ throw new Twig_Error_Runtime(sprintf('Variable "%s" does not exist', $item), -1, $this->getTemplateName());
}
return $context[$item];
@@ -339,7 +336,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
*/
protected function getAttribute($object, $item, array $arguments = array(), $type = Twig_TemplateInterface::ANY_CALL, $isDefinedTest = false, $ignoreStrictCheck = false)
{
- $item = (string) $item;
+ $item = ctype_digit((string) $item) ? (int) $item : (string) $item;
// array
if (Twig_TemplateInterface::METHOD_CALL !== $type) {
@@ -363,10 +360,11 @@ abstract class Twig_Template implements Twig_TemplateInterface
}
if (is_object($object)) {
- throw new Twig_Error_Runtime(sprintf('Key "%s" in object (with ArrayAccess) of type "%s" does not exist', $item, get_class($object)));
- // array
+ throw new Twig_Error_Runtime(sprintf('Key "%s" in object (with ArrayAccess) of type "%s" does not exist', $item, get_class($object)), -1, $this->getTemplateName());
+ } elseif (is_array($object)) {
+ throw new Twig_Error_Runtime(sprintf('Key "%s" for array with keys "%s" does not exist', $item, implode(', ', array_keys($object))), -1, $this->getTemplateName());
} else {
- throw new Twig_Error_Runtime(sprintf('Key "%s" for array with keys "%s" does not exist', $item, implode(', ', array_keys($object))));
+ throw new Twig_Error_Runtime(sprintf('Impossible to access a key ("%s") on a "%s" variable', $item, gettype($object)), -1, $this->getTemplateName());
}
}
}
@@ -380,21 +378,13 @@ abstract class Twig_Template implements Twig_TemplateInterface
return null;
}
- throw new Twig_Error_Runtime(sprintf('Item "%s" for "%s" does not exist', $item, is_array($object) ? 'Array' : $object));
+ throw new Twig_Error_Runtime(sprintf('Item "%s" for "%s" does not exist', $item, is_array($object) ? 'Array' : $object), -1, $this->getTemplateName());
}
$class = get_class($object);
// object property
if (Twig_TemplateInterface::METHOD_CALL !== $type) {
- /* apparently, this is not needed as this is already covered by the array_key_exists() call below
- if (!isset(self::$cache[$class]['properties'])) {
- foreach (get_object_vars($object) as $k => $v) {
- self::$cache[$class]['properties'][$k] = true;
- }
- }
- */
-
if (isset($object->$item) || array_key_exists($item, $object)) {
if ($isDefinedTest) {
return true;
@@ -431,7 +421,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
return null;
}
- throw new Twig_Error_Runtime(sprintf('Method "%s" for object "%s" does not exist', $item, get_class($object)));
+ throw new Twig_Error_Runtime(sprintf('Method "%s" for object "%s" does not exist', $item, get_class($object)), -1, $this->getTemplateName());
}
if ($isDefinedTest) {
@@ -444,7 +434,8 @@ abstract class Twig_Template implements Twig_TemplateInterface
$ret = call_user_func_array(array($object, $method), $arguments);
- // hack to be removed when macro calls are refactored
+ // useful when calling a template method from a template
+ // this is not supported but unfortunately heavily used in the Symfony profiler
if ($object instanceof Twig_TemplateInterface) {
return $ret === '' ? '' : new Twig_Markup($ret, $this->env->getCharset());
}
@@ -455,7 +446,7 @@ abstract class Twig_Template implements Twig_TemplateInterface
/**
* This method is only useful when testing Twig. Do not use it.
*/
- static public function clearCache()
+ public static function clearCache()
{
self::$cache = array();
}
diff --git a/lib/twig/lib/Twig/TemplateInterface.php b/vendor/twig/twig/lib/Twig/TemplateInterface.php
old mode 100755
new mode 100644
similarity index 79%
rename from lib/twig/lib/Twig/TemplateInterface.php
rename to vendor/twig/twig/lib/Twig/TemplateInterface.php
index 08da116..879f503
--- a/lib/twig/lib/Twig/TemplateInterface.php
+++ b/vendor/twig/twig/lib/Twig/TemplateInterface.php
@@ -12,8 +12,8 @@
/**
* Interface implemented by all compiled templates.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
+ * @deprecated since 1.12 (to be removed in 2.0)
*/
interface Twig_TemplateInterface
{
@@ -28,7 +28,7 @@ interface Twig_TemplateInterface
*
* @return string The rendered template
*/
- function render(array $context);
+ public function render(array $context);
/**
* Displays the template with the given context.
@@ -36,12 +36,12 @@ interface Twig_TemplateInterface
* @param array $context An array of parameters to pass to the template
* @param array $blocks An array of blocks to pass to the template
*/
- function display(array $context, array $blocks = array());
+ public function display(array $context, array $blocks = array());
/**
* Returns the bound environment for this template.
*
* @return Twig_Environment The current environment
*/
- function getEnvironment();
+ public function getEnvironment();
}
diff --git a/vendor/twig/twig/lib/Twig/Test.php b/vendor/twig/twig/lib/Twig/Test.php
new file mode 100644
index 0000000..3baff88
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/Test.php
@@ -0,0 +1,34 @@
+
+ * @deprecated since 1.12 (to be removed in 2.0)
+ */
+abstract class Twig_Test implements Twig_TestInterface, Twig_TestCallableInterface
+{
+ protected $options;
+ protected $arguments = array();
+
+ public function __construct(array $options = array())
+ {
+ $this->options = array_merge(array(
+ 'callable' => null,
+ ), $options);
+ }
+
+ public function getCallable()
+ {
+ return $this->options['callable'];
+ }
+}
diff --git a/lib/twig/lib/Twig/Test/Function.php b/vendor/twig/twig/lib/Twig/Test/Function.php
old mode 100755
new mode 100644
similarity index 58%
rename from lib/twig/lib/Twig/Test/Function.php
rename to vendor/twig/twig/lib/Twig/Test/Function.php
index 1240a0f..4be6b9b
--- a/lib/twig/lib/Twig/Test/Function.php
+++ b/vendor/twig/twig/lib/Twig/Test/Function.php
@@ -12,15 +12,19 @@
/**
* Represents a function template test.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
+ * @deprecated since 1.12 (to be removed in 2.0)
*/
-class Twig_Test_Function implements Twig_TestInterface
+class Twig_Test_Function extends Twig_Test
{
protected $function;
- public function __construct($function)
+ public function __construct($function, array $options = array())
{
+ $options['callable'] = $function;
+
+ parent::__construct($options);
+
$this->function = $function;
}
diff --git a/vendor/twig/twig/lib/Twig/Test/IntegrationTestCase.php b/vendor/twig/twig/lib/Twig/Test/IntegrationTestCase.php
new file mode 100644
index 0000000..724f094
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/Test/IntegrationTestCase.php
@@ -0,0 +1,154 @@
+
+ * @author Karma Dordrak
+ */
+abstract class Twig_Test_IntegrationTestCase extends PHPUnit_Framework_TestCase
+{
+ abstract protected function getExtensions();
+ abstract protected function getFixturesDir();
+
+ /**
+ * @dataProvider getTests
+ */
+ public function testIntegration($file, $message, $condition, $templates, $exception, $outputs)
+ {
+ $this->doIntegrationTest($file, $message, $condition, $templates, $exception, $outputs);
+ }
+
+ public function getTests()
+ {
+ $fixturesDir = realpath($this->getFixturesDir());
+ $tests = array();
+
+ foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($fixturesDir), RecursiveIteratorIterator::LEAVES_ONLY) as $file) {
+ if (!preg_match('/\.test$/', $file)) {
+ continue;
+ }
+
+ $test = file_get_contents($file->getRealpath());
+
+ if (preg_match('/
+ --TEST--\s*(.*?)\s*(?:--CONDITION--\s*(.*))?\s*((?:--TEMPLATE(?:\(.*?\))?--(?:.*?))+)\s*(?:--DATA--\s*(.*))?\s*--EXCEPTION--\s*(.*)/sx', $test, $match)) {
+ $message = $match[1];
+ $condition = $match[2];
+ $templates = $this->parseTemplates($match[3]);
+ $exception = $match[5];
+ $outputs = array(array(null, $match[4], null, ''));
+ } elseif (preg_match('/--TEST--\s*(.*?)\s*(?:--CONDITION--\s*(.*))?\s*((?:--TEMPLATE(?:\(.*?\))?--(?:.*?))+)--DATA--.*?--EXPECT--.*/s', $test, $match)) {
+ $message = $match[1];
+ $condition = $match[2];
+ $templates = $this->parseTemplates($match[3]);
+ $exception = false;
+ preg_match_all('/--DATA--(.*?)(?:--CONFIG--(.*?))?--EXPECT--(.*?)(?=\-\-DATA\-\-|$)/s', $test, $outputs, PREG_SET_ORDER);
+ } else {
+ throw new InvalidArgumentException(sprintf('Test "%s" is not valid.', str_replace($fixturesDir.'/', '', $file)));
+ }
+
+ $tests[] = array(str_replace($fixturesDir.'/', '', $file), $message, $condition, $templates, $exception, $outputs);
+ }
+
+ return $tests;
+ }
+
+ protected function doIntegrationTest($file, $message, $condition, $templates, $exception, $outputs)
+ {
+ if ($condition) {
+ eval('$ret = '.$condition.';');
+ if (!$ret) {
+ $this->markTestSkipped($condition);
+ }
+ }
+
+ $loader = new Twig_Loader_Array($templates);
+
+ foreach ($outputs as $match) {
+ $config = array_merge(array(
+ 'cache' => false,
+ 'strict_variables' => true,
+ ), $match[2] ? eval($match[2].';') : array());
+ $twig = new Twig_Environment($loader, $config);
+ $twig->addGlobal('global', 'global');
+ foreach ($this->getExtensions() as $extension) {
+ $twig->addExtension($extension);
+ }
+
+ try {
+ $template = $twig->loadTemplate('index.twig');
+ } catch (Exception $e) {
+ if (false !== $exception) {
+ $this->assertEquals(trim($exception), trim(sprintf('%s: %s', get_class($e), $e->getMessage())));
+
+ return;
+ }
+
+ if ($e instanceof Twig_Error_Syntax) {
+ $e->setTemplateFile($file);
+
+ throw $e;
+ }
+
+ throw new Twig_Error(sprintf('%s: %s', get_class($e), $e->getMessage()), -1, $file, $e);
+ }
+
+ try {
+ $output = trim($template->render(eval($match[1].';')), "\n ");
+ } catch (Exception $e) {
+ if (false !== $exception) {
+ $this->assertEquals(trim($exception), trim(sprintf('%s: %s', get_class($e), $e->getMessage())));
+
+ return;
+ }
+
+ if ($e instanceof Twig_Error_Syntax) {
+ $e->setTemplateFile($file);
+ } else {
+ $e = new Twig_Error(sprintf('%s: %s', get_class($e), $e->getMessage()), -1, $file, $e);
+ }
+
+ $output = trim(sprintf('%s: %s', get_class($e), $e->getMessage()));
+ }
+
+ if (false !== $exception) {
+ list($class, ) = explode(':', $exception);
+ $this->assertThat(NULL, new PHPUnit_Framework_Constraint_Exception($class));
+ }
+
+ $expected = trim($match[3], "\n ");
+
+ if ($expected != $output) {
+ echo 'Compiled template that failed:';
+
+ foreach (array_keys($templates) as $name) {
+ echo "Template: $name\n";
+ $source = $loader->getSource($name);
+ echo $twig->compile($twig->parse($twig->tokenize($source, $name)));
+ }
+ }
+ $this->assertEquals($expected, $output, $message.' (in '.$file.')');
+ }
+ }
+
+ protected static function parseTemplates($test)
+ {
+ $templates = array();
+ preg_match_all('/--TEMPLATE(?:\((.*?)\))?--(.*?)(?=\-\-TEMPLATE|$)/s', $test, $matches, PREG_SET_ORDER);
+ foreach ($matches as $match) {
+ $templates[($match[1] ? $match[1] : 'index.twig')] = $match[2];
+ }
+
+ return $templates;
+ }
+}
diff --git a/lib/twig/lib/Twig/Test/Method.php b/vendor/twig/twig/lib/Twig/Test/Method.php
old mode 100755
new mode 100644
similarity index 63%
rename from lib/twig/lib/Twig/Test/Method.php
rename to vendor/twig/twig/lib/Twig/Test/Method.php
index a3b3948..17c6c04
--- a/lib/twig/lib/Twig/Test/Method.php
+++ b/vendor/twig/twig/lib/Twig/Test/Method.php
@@ -12,15 +12,20 @@
/**
* Represents a method template test.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
+ * @deprecated since 1.12 (to be removed in 2.0)
*/
-class Twig_Test_Method implements Twig_TestInterface
+class Twig_Test_Method extends Twig_Test
{
- protected $extension, $method;
+ protected $extension;
+ protected $method;
- public function __construct(Twig_ExtensionInterface $extension, $method)
+ public function __construct(Twig_ExtensionInterface $extension, $method, array $options = array())
{
+ $options['callable'] = array($extension, $method);
+
+ parent::__construct($options);
+
$this->extension = $extension;
$this->method = $method;
}
diff --git a/lib/twig/lib/Twig/Test/Node.php b/vendor/twig/twig/lib/Twig/Test/Node.php
old mode 100755
new mode 100644
similarity index 64%
rename from lib/twig/lib/Twig/Test/Node.php
rename to vendor/twig/twig/lib/Twig/Test/Node.php
index 47a978e..c832a57
--- a/lib/twig/lib/Twig/Test/Node.php
+++ b/vendor/twig/twig/lib/Twig/Test/Node.php
@@ -12,15 +12,17 @@
/**
* Represents a template test as a Node.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
+ * @deprecated since 1.12 (to be removed in 2.0)
*/
-class Twig_Test_Node implements Twig_TestInterface
+class Twig_Test_Node extends Twig_Test
{
protected $class;
- public function __construct($class)
+ public function __construct($class, array $options = array())
{
+ parent::__construct($options);
+
$this->class = $class;
}
diff --git a/lib/twig/test/Twig/Tests/Node/TestCase.php b/vendor/twig/twig/lib/Twig/Test/NodeTestCase.php
old mode 100755
new mode 100644
similarity index 95%
rename from lib/twig/test/Twig/Tests/Node/TestCase.php
rename to vendor/twig/twig/lib/Twig/Test/NodeTestCase.php
index f142529..b15c85f
--- a/lib/twig/test/Twig/Tests/Node/TestCase.php
+++ b/vendor/twig/twig/lib/Twig/Test/NodeTestCase.php
@@ -8,7 +8,7 @@
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
-abstract class Twig_Tests_Node_TestCase extends PHPUnit_Framework_TestCase
+abstract class Twig_Test_NodeTestCase extends PHPUnit_Framework_TestCase
{
abstract public function getTests();
diff --git a/vendor/twig/twig/lib/Twig/TestCallableInterface.php b/vendor/twig/twig/lib/Twig/TestCallableInterface.php
new file mode 100644
index 0000000..0db4368
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/TestCallableInterface.php
@@ -0,0 +1,21 @@
+
+ * @deprecated since 1.12 (to be removed in 2.0)
+ */
+interface Twig_TestCallableInterface
+{
+ public function getCallable();
+}
diff --git a/lib/twig/lib/Twig/TestInterface.php b/vendor/twig/twig/lib/Twig/TestInterface.php
old mode 100755
new mode 100644
similarity index 74%
rename from lib/twig/lib/Twig/TestInterface.php
rename to vendor/twig/twig/lib/Twig/TestInterface.php
index c2ff725..30d8a2c
--- a/lib/twig/lib/Twig/TestInterface.php
+++ b/vendor/twig/twig/lib/Twig/TestInterface.php
@@ -12,8 +12,8 @@
/**
* Represents a template test.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
+ * @deprecated since 1.12 (to be removed in 2.0)
*/
interface Twig_TestInterface
{
@@ -22,5 +22,5 @@ interface Twig_TestInterface
*
* @return string The PHP code for the test
*/
- function compile();
+ public function compile();
}
diff --git a/lib/twig/lib/Twig/Token.php b/vendor/twig/twig/lib/Twig/Token.php
old mode 100755
new mode 100644
similarity index 93%
rename from lib/twig/lib/Twig/Token.php
rename to vendor/twig/twig/lib/Twig/Token.php
index 918bb91..bbca90d
--- a/lib/twig/lib/Twig/Token.php
+++ b/vendor/twig/twig/lib/Twig/Token.php
@@ -13,8 +13,7 @@
/**
* Represents a Token.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_Token
{
@@ -126,7 +125,7 @@ class Twig_Token
*
* @return string The string representation
*/
- static public function typeToString($type, $short = false, $line = -1)
+ public static function typeToString($type, $short = false, $line = -1)
{
switch ($type) {
case self::EOF_TYPE:
@@ -169,7 +168,7 @@ class Twig_Token
$name = 'INTERPOLATION_END_TYPE';
break;
default:
- throw new Twig_Error_Syntax(sprintf('Token of type "%s" does not exist.', $type), $line);
+ throw new LogicException(sprintf('Token of type "%s" does not exist.', $type));
}
return $short ? $name : 'Twig_Token::'.$name;
@@ -183,7 +182,7 @@ class Twig_Token
*
* @return string The string representation
*/
- static public function typeToEnglish($type, $line = -1)
+ public static function typeToEnglish($type, $line = -1)
{
switch ($type) {
case self::EOF_TYPE:
@@ -213,7 +212,7 @@ class Twig_Token
case self::INTERPOLATION_END_TYPE:
return 'end of string interpolation';
default:
- throw new Twig_Error_Syntax(sprintf('Token of type "%s" does not exist.', $type), $line);
+ throw new LogicException(sprintf('Token of type "%s" does not exist.', $type));
}
}
}
diff --git a/lib/twig/lib/Twig/TokenParser.php b/vendor/twig/twig/lib/Twig/TokenParser.php
old mode 100755
new mode 100644
similarity index 90%
rename from lib/twig/lib/Twig/TokenParser.php
rename to vendor/twig/twig/lib/Twig/TokenParser.php
index ab18bfa..decebd5
--- a/lib/twig/lib/Twig/TokenParser.php
+++ b/vendor/twig/twig/lib/Twig/TokenParser.php
@@ -12,8 +12,7 @@
/**
* Base class for all token parsers.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
abstract class Twig_TokenParser implements Twig_TokenParserInterface
{
diff --git a/lib/twig/lib/Twig/TokenParser/AutoEscape.php b/vendor/twig/twig/lib/Twig/TokenParser/AutoEscape.php
old mode 100755
new mode 100644
similarity index 57%
rename from lib/twig/lib/Twig/TokenParser/AutoEscape.php
rename to vendor/twig/twig/lib/Twig/TokenParser/AutoEscape.php
index 880e664..2756028
--- a/lib/twig/lib/Twig/TokenParser/AutoEscape.php
+++ b/vendor/twig/twig/lib/Twig/TokenParser/AutoEscape.php
@@ -39,23 +39,35 @@ 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('true', 'false'))) {
- throw new Twig_Error_Syntax("Autoescape value must be 'true' or 'false'", $lineno);
- }
- $value = 'true' === $value ? 'html' : false;
+ $stream = $this->parser->getStream();
- if ($this->parser->getStream()->test(Twig_Token::NAME_TYPE)) {
- if (false === $value) {
- throw new Twig_Error_Syntax('Unexpected escaping strategy as you set autoescaping to false.', $lineno);
+ if ($stream->test(Twig_Token::BLOCK_END_TYPE)) {
+ $value = 'html';
+ } else {
+ $expr = $this->parser->getExpressionParser()->parseExpression();
+ if (!$expr instanceof Twig_Node_Expression_Constant) {
+ throw new Twig_Error_Syntax('An escaping strategy must be a string or a Boolean.', $stream->getCurrent()->getLine(), $stream->getFilename());
+ }
+ $value = $expr->getAttribute('value');
+
+ $compat = true === $value || false === $value;
+
+ if (true === $value) {
+ $value = 'html';
}
- $value = $this->parser->getStream()->next()->getValue();
+ if ($compat && $stream->test(Twig_Token::NAME_TYPE)) {
+ if (false === $value) {
+ throw new Twig_Error_Syntax('Unexpected escaping strategy as you set autoescaping to false.', $stream->getCurrent()->getLine(), $stream->getFilename());
+ }
+
+ $value = $stream->next()->getValue();
+ }
}
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+ $stream->expect(Twig_Token::BLOCK_END_TYPE);
$body = $this->parser->subparse(array($this, 'decideBlockEnd'), true);
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+ $stream->expect(Twig_Token::BLOCK_END_TYPE);
return new Twig_Node_AutoEscape($value, $body, $lineno, $this->getTag());
}
diff --git a/lib/twig/lib/Twig/TokenParser/Block.php b/vendor/twig/twig/lib/Twig/TokenParser/Block.php
old mode 100755
new mode 100644
similarity index 82%
rename from lib/twig/lib/Twig/TokenParser/Block.php
rename to vendor/twig/twig/lib/Twig/TokenParser/Block.php
index 36643f7..a2e017f
--- a/lib/twig/lib/Twig/TokenParser/Block.php
+++ b/vendor/twig/twig/lib/Twig/TokenParser/Block.php
@@ -35,8 +35,9 @@ class Twig_TokenParser_Block extends Twig_TokenParser
$stream = $this->parser->getStream();
$name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
if ($this->parser->hasBlock($name)) {
- throw new Twig_Error_Syntax("The block '$name' has already been defined", $lineno);
+ throw new Twig_Error_Syntax(sprintf("The block '$name' has already been defined line %d", $this->parser->getBlock($name)->getLine()), $stream->getCurrent()->getLine(), $stream->getFilename());
}
+ $this->parser->setBlock($name, $block = new Twig_Node_Block($name, new Twig_Node(array()), $lineno));
$this->parser->pushLocalScope();
$this->parser->pushBlockStack($name);
@@ -48,7 +49,7 @@ class Twig_TokenParser_Block extends Twig_TokenParser
$value = $stream->next()->getValue();
if ($value != $name) {
- throw new Twig_Error_Syntax(sprintf("Expected endblock for block '$name' (but %s given)", $value), $lineno);
+ throw new Twig_Error_Syntax(sprintf("Expected endblock for block '$name' (but %s given)", $value), $stream->getCurrent()->getLine(), $stream->getFilename());
}
}
} else {
@@ -58,8 +59,7 @@ class Twig_TokenParser_Block extends Twig_TokenParser
}
$stream->expect(Twig_Token::BLOCK_END_TYPE);
- $block = new Twig_Node_Block($name, $body, $lineno);
- $this->parser->setBlock($name, $block);
+ $block->setNode('body', $body);
$this->parser->popBlockStack();
$this->parser->popLocalScope();
diff --git a/lib/twig/lib/Twig/TokenParser/Do.php b/vendor/twig/twig/lib/Twig/TokenParser/Do.php
old mode 100755
new mode 100644
similarity index 93%
rename from lib/twig/lib/Twig/TokenParser/Do.php
rename to vendor/twig/twig/lib/Twig/TokenParser/Do.php
index 593d1c6..f50939d
--- a/lib/twig/lib/Twig/TokenParser/Do.php
+++ b/vendor/twig/twig/lib/Twig/TokenParser/Do.php
@@ -10,7 +10,7 @@
*/
/**
- * Evaluates an expression, disgarding the returned value.
+ * Evaluates an expression, discarding the returned value.
*/
class Twig_TokenParser_Do extends Twig_TokenParser
{
diff --git a/vendor/twig/twig/lib/Twig/TokenParser/Embed.php b/vendor/twig/twig/lib/Twig/TokenParser/Embed.php
new file mode 100644
index 0000000..69cb5f3
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/TokenParser/Embed.php
@@ -0,0 +1,66 @@
+parser->getStream();
+
+ $parent = $this->parser->getExpressionParser()->parseExpression();
+
+ list($variables, $only, $ignoreMissing) = $this->parseArguments();
+
+ // inject a fake parent to make the parent() function work
+ $stream->injectTokens(array(
+ new Twig_Token(Twig_Token::BLOCK_START_TYPE, '', $token->getLine()),
+ new Twig_Token(Twig_Token::NAME_TYPE, 'extends', $token->getLine()),
+ new Twig_Token(Twig_Token::STRING_TYPE, '__parent__', $token->getLine()),
+ new Twig_Token(Twig_Token::BLOCK_END_TYPE, '', $token->getLine()),
+ ));
+
+ $module = $this->parser->parse($stream, array($this, 'decideBlockEnd'), true);
+
+ // override the parent with the correct one
+ $module->setNode('parent', $parent);
+
+ $this->parser->embedTemplate($module);
+
+ $stream->expect(Twig_Token::BLOCK_END_TYPE);
+
+ return new Twig_Node_Embed($module->getAttribute('filename'), $module->getAttribute('index'), $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag());
+ }
+
+ public function decideBlockEnd(Twig_Token $token)
+ {
+ return $token->test('endembed');
+ }
+
+ /**
+ * Gets the tag name associated with this token parser.
+ *
+ * @return string The tag name
+ */
+ public function getTag()
+ {
+ return 'embed';
+ }
+}
diff --git a/lib/twig/lib/Twig/TokenParser/Extends.php b/vendor/twig/twig/lib/Twig/TokenParser/Extends.php
old mode 100755
new mode 100644
similarity index 91%
rename from lib/twig/lib/Twig/TokenParser/Extends.php
rename to vendor/twig/twig/lib/Twig/TokenParser/Extends.php
index 54f49ad..110bc8b
--- a/lib/twig/lib/Twig/TokenParser/Extends.php
+++ b/vendor/twig/twig/lib/Twig/TokenParser/Extends.php
@@ -29,11 +29,11 @@ class Twig_TokenParser_Extends extends Twig_TokenParser
public function parse(Twig_Token $token)
{
if (!$this->parser->isMainScope()) {
- throw new Twig_Error_Syntax('Cannot extend from a block', $token->getLine());
+ throw new Twig_Error_Syntax('Cannot extend from a block', $token->getLine(), $this->parser->getFilename());
}
if (null !== $this->parser->getParent()) {
- throw new Twig_Error_Syntax('Multiple extends tags are forbidden', $token->getLine());
+ throw new Twig_Error_Syntax('Multiple extends tags are forbidden', $token->getLine(), $this->parser->getFilename());
}
$this->parser->setParent($this->parser->getExpressionParser()->parseExpression());
diff --git a/lib/twig/lib/Twig/TokenParser/Filter.php b/vendor/twig/twig/lib/Twig/TokenParser/Filter.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/TokenParser/Filter.php
rename to vendor/twig/twig/lib/Twig/TokenParser/Filter.php
diff --git a/lib/twig/lib/Twig/TokenParser/Flush.php b/vendor/twig/twig/lib/Twig/TokenParser/Flush.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/TokenParser/Flush.php
rename to vendor/twig/twig/lib/Twig/TokenParser/Flush.php
diff --git a/vendor/twig/twig/lib/Twig/TokenParser/For.php b/vendor/twig/twig/lib/Twig/TokenParser/For.php
new file mode 100644
index 0000000..98a6d07
--- /dev/null
+++ b/vendor/twig/twig/lib/Twig/TokenParser/For.php
@@ -0,0 +1,136 @@
+
+ *
+ * {% for user in users %}
+ *
{{ user.username|e }}
+ * {% endfor %}
+ *
+ *
+ */
+class Twig_TokenParser_For extends Twig_TokenParser
+{
+ /**
+ * Parses a token and returns a node.
+ *
+ * @param Twig_Token $token A Twig_Token instance
+ *
+ * @return Twig_NodeInterface A Twig_NodeInterface instance
+ */
+ public function parse(Twig_Token $token)
+ {
+ $lineno = $token->getLine();
+ $stream = $this->parser->getStream();
+ $targets = $this->parser->getExpressionParser()->parseAssignmentExpression();
+ $stream->expect(Twig_Token::OPERATOR_TYPE, 'in');
+ $seq = $this->parser->getExpressionParser()->parseExpression();
+
+ $ifexpr = null;
+ if ($stream->test(Twig_Token::NAME_TYPE, 'if')) {
+ $stream->next();
+ $ifexpr = $this->parser->getExpressionParser()->parseExpression();
+ }
+
+ $stream->expect(Twig_Token::BLOCK_END_TYPE);
+ $body = $this->parser->subparse(array($this, 'decideForFork'));
+ if ($stream->next()->getValue() == 'else') {
+ $stream->expect(Twig_Token::BLOCK_END_TYPE);
+ $else = $this->parser->subparse(array($this, 'decideForEnd'), true);
+ } else {
+ $else = null;
+ }
+ $stream->expect(Twig_Token::BLOCK_END_TYPE);
+
+ if (count($targets) > 1) {
+ $keyTarget = $targets->getNode(0);
+ $keyTarget = new Twig_Node_Expression_AssignName($keyTarget->getAttribute('name'), $keyTarget->getLine());
+ $valueTarget = $targets->getNode(1);
+ $valueTarget = new Twig_Node_Expression_AssignName($valueTarget->getAttribute('name'), $valueTarget->getLine());
+ } else {
+ $keyTarget = new Twig_Node_Expression_AssignName('_key', $lineno);
+ $valueTarget = $targets->getNode(0);
+ $valueTarget = new Twig_Node_Expression_AssignName($valueTarget->getAttribute('name'), $valueTarget->getLine());
+ }
+
+ if ($ifexpr) {
+ $this->checkLoopUsageCondition($stream, $ifexpr);
+ $this->checkLoopUsageBody($stream, $body);
+ }
+
+ return new Twig_Node_For($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, $lineno, $this->getTag());
+ }
+
+ public function decideForFork(Twig_Token $token)
+ {
+ return $token->test(array('else', 'endfor'));
+ }
+
+ public function decideForEnd(Twig_Token $token)
+ {
+ return $token->test('endfor');
+ }
+
+ // the loop variable cannot be used in the condition
+ protected function checkLoopUsageCondition(Twig_TokenStream $stream, Twig_NodeInterface $node)
+ {
+ if ($node instanceof Twig_Node_Expression_GetAttr && $node->getNode('node') instanceof Twig_Node_Expression_Name && 'loop' == $node->getNode('node')->getAttribute('name')) {
+ throw new Twig_Error_Syntax('The "loop" variable cannot be used in a looping condition', $node->getLine(), $stream->getFilename());
+ }
+
+ foreach ($node as $n) {
+ if (!$n) {
+ continue;
+ }
+
+ $this->checkLoopUsageCondition($stream, $n);
+ }
+ }
+
+ // check usage of non-defined loop-items
+ // it does not catch all problems (for instance when a for is included into another or when the variable is used in an include)
+ protected function checkLoopUsageBody(Twig_TokenStream $stream, Twig_NodeInterface $node)
+ {
+ if ($node instanceof Twig_Node_Expression_GetAttr && $node->getNode('node') instanceof Twig_Node_Expression_Name && 'loop' == $node->getNode('node')->getAttribute('name')) {
+ $attribute = $node->getNode('attribute');
+ if ($attribute instanceof Twig_Node_Expression_Constant && in_array($attribute->getAttribute('value'), array('length', 'revindex0', 'revindex', 'last'))) {
+ throw new Twig_Error_Syntax(sprintf('The "loop.%s" variable is not defined when looping with a condition', $attribute->getAttribute('value')), $node->getLine(), $stream->getFilename());
+ }
+ }
+
+ // should check for parent.loop.XXX usage
+ if ($node instanceof Twig_Node_For) {
+ return;
+ }
+
+ foreach ($node as $n) {
+ if (!$n) {
+ continue;
+ }
+
+ $this->checkLoopUsageBody($stream, $n);
+ }
+ }
+
+ /**
+ * Gets the tag name associated with this token parser.
+ *
+ * @return string The tag name
+ */
+ public function getTag()
+ {
+ return 'for';
+ }
+}
diff --git a/lib/twig/lib/Twig/TokenParser/From.php b/vendor/twig/twig/lib/Twig/TokenParser/From.php
old mode 100755
new mode 100644
similarity index 91%
rename from lib/twig/lib/Twig/TokenParser/From.php
rename to vendor/twig/twig/lib/Twig/TokenParser/From.php
index 4e20f5c..a54054d
--- a/lib/twig/lib/Twig/TokenParser/From.php
+++ b/vendor/twig/twig/lib/Twig/TokenParser/From.php
@@ -55,8 +55,8 @@ class Twig_TokenParser_From extends Twig_TokenParser
$node = new Twig_Node_Import($macro, new Twig_Node_Expression_AssignName($this->parser->getVarName(), $token->getLine()), $token->getLine(), $this->getTag());
- foreach($targets as $name => $alias) {
- $this->parser->addImportedFunction($alias, 'get'.$name, $node->getNode('var'));
+ foreach ($targets as $name => $alias) {
+ $this->parser->addImportedSymbol('function', $alias, 'get'.$name, $node->getNode('var'));
}
return $node;
diff --git a/lib/twig/lib/Twig/TokenParser/If.php b/vendor/twig/twig/lib/Twig/TokenParser/If.php
old mode 100755
new mode 100644
similarity index 84%
rename from lib/twig/lib/Twig/TokenParser/If.php
rename to vendor/twig/twig/lib/Twig/TokenParser/If.php
index 1a694af..3d7d1f5
--- a/lib/twig/lib/Twig/TokenParser/If.php
+++ b/vendor/twig/twig/lib/Twig/TokenParser/If.php
@@ -36,22 +36,23 @@ class Twig_TokenParser_If extends Twig_TokenParser
{
$lineno = $token->getLine();
$expr = $this->parser->getExpressionParser()->parseExpression();
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+ $stream = $this->parser->getStream();
+ $stream->expect(Twig_Token::BLOCK_END_TYPE);
$body = $this->parser->subparse(array($this, 'decideIfFork'));
$tests = array($expr, $body);
$else = null;
$end = false;
while (!$end) {
- switch ($this->parser->getStream()->next()->getValue()) {
+ switch ($stream->next()->getValue()) {
case 'else':
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+ $stream->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);
+ $stream->expect(Twig_Token::BLOCK_END_TYPE);
$body = $this->parser->subparse(array($this, 'decideIfFork'));
$tests[] = $expr;
$tests[] = $body;
@@ -62,11 +63,11 @@ class Twig_TokenParser_If extends Twig_TokenParser
break;
default:
- throw new Twig_Error_Syntax(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);
+ throw new Twig_Error_Syntax(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), $stream->getCurrent()->getLine(), $stream->getFilename());
}
}
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+ $stream->expect(Twig_Token::BLOCK_END_TYPE);
return new Twig_Node_If(new Twig_Node($tests), $else, $lineno, $this->getTag());
}
diff --git a/lib/twig/lib/Twig/TokenParser/Import.php b/vendor/twig/twig/lib/Twig/TokenParser/Import.php
old mode 100755
new mode 100644
similarity index 93%
rename from lib/twig/lib/Twig/TokenParser/Import.php
rename to vendor/twig/twig/lib/Twig/TokenParser/Import.php
index 5219289..e7050c7
--- a/lib/twig/lib/Twig/TokenParser/Import.php
+++ b/vendor/twig/twig/lib/Twig/TokenParser/Import.php
@@ -32,6 +32,8 @@ class Twig_TokenParser_Import extends Twig_TokenParser
$var = new Twig_Node_Expression_AssignName($this->parser->getStream()->expect(Twig_Token::NAME_TYPE)->getValue(), $token->getLine());
$this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+ $this->parser->addImportedSymbol('template', $var->getAttribute('name'));
+
return new Twig_Node_Import($macro, $var, $token->getLine(), $this->getTag());
}
diff --git a/lib/twig/lib/Twig/TokenParser/Include.php b/vendor/twig/twig/lib/Twig/TokenParser/Include.php
old mode 100755
new mode 100644
similarity index 67%
rename from lib/twig/lib/Twig/TokenParser/Include.php
rename to vendor/twig/twig/lib/Twig/TokenParser/Include.php
index 6725b8f..4a31786
--- a/lib/twig/lib/Twig/TokenParser/Include.php
+++ b/vendor/twig/twig/lib/Twig/TokenParser/Include.php
@@ -32,31 +32,40 @@ class Twig_TokenParser_Include extends Twig_TokenParser
{
$expr = $this->parser->getExpressionParser()->parseExpression();
+ list($variables, $only, $ignoreMissing) = $this->parseArguments();
+
+ return new Twig_Node_Include($expr, $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag());
+ }
+
+ protected function parseArguments()
+ {
+ $stream = $this->parser->getStream();
+
$ignoreMissing = false;
- if ($this->parser->getStream()->test(Twig_Token::NAME_TYPE, 'ignore')) {
- $this->parser->getStream()->next();
- $this->parser->getStream()->expect(Twig_Token::NAME_TYPE, 'missing');
+ if ($stream->test(Twig_Token::NAME_TYPE, 'ignore')) {
+ $stream->next();
+ $stream->expect(Twig_Token::NAME_TYPE, 'missing');
$ignoreMissing = true;
}
$variables = null;
- if ($this->parser->getStream()->test(Twig_Token::NAME_TYPE, 'with')) {
- $this->parser->getStream()->next();
+ if ($stream->test(Twig_Token::NAME_TYPE, 'with')) {
+ $stream->next();
$variables = $this->parser->getExpressionParser()->parseExpression();
}
$only = false;
- if ($this->parser->getStream()->test(Twig_Token::NAME_TYPE, 'only')) {
- $this->parser->getStream()->next();
+ if ($stream->test(Twig_Token::NAME_TYPE, 'only')) {
+ $stream->next();
$only = true;
}
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+ $stream->expect(Twig_Token::BLOCK_END_TYPE);
- return new Twig_Node_Include($expr, $variables, $only, $ignoreMissing, $token->getLine(), $this->getTag());
+ return array($variables, $only, $ignoreMissing);
}
/**
diff --git a/lib/twig/lib/Twig/TokenParser/Macro.php b/vendor/twig/twig/lib/Twig/TokenParser/Macro.php
old mode 100755
new mode 100644
similarity index 77%
rename from lib/twig/lib/Twig/TokenParser/Macro.php
rename to vendor/twig/twig/lib/Twig/TokenParser/Macro.php
index ffd5848..c2a0336
--- a/lib/twig/lib/Twig/TokenParser/Macro.php
+++ b/vendor/twig/twig/lib/Twig/TokenParser/Macro.php
@@ -30,22 +30,23 @@ 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();
+ $stream = $this->parser->getStream();
+ $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
- $arguments = $this->parser->getExpressionParser()->parseArguments();
+ $arguments = $this->parser->getExpressionParser()->parseArguments(true, true);
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+ $stream->expect(Twig_Token::BLOCK_END_TYPE);
$this->parser->pushLocalScope();
$body = $this->parser->subparse(array($this, 'decideBlockEnd'), true);
- if ($this->parser->getStream()->test(Twig_Token::NAME_TYPE)) {
- $value = $this->parser->getStream()->next()->getValue();
+ if ($stream->test(Twig_Token::NAME_TYPE)) {
+ $value = $stream->next()->getValue();
if ($value != $name) {
- throw new Twig_Error_Syntax(sprintf("Expected endmacro for macro '$name' (but %s given)", $value), $lineno);
+ throw new Twig_Error_Syntax(sprintf("Expected endmacro for macro '$name' (but %s given)", $value), $stream->getCurrent()->getLine(), $stream->getFilename());
}
}
$this->parser->popLocalScope();
- $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+ $stream->expect(Twig_Token::BLOCK_END_TYPE);
$this->parser->setMacro($name, new Twig_Node_Macro($name, new Twig_Node_Body(array($body)), $arguments, $lineno, $this->getTag()));
diff --git a/lib/twig/lib/Twig/TokenParser/Sandbox.php b/vendor/twig/twig/lib/Twig/TokenParser/Sandbox.php
old mode 100755
new mode 100644
similarity index 71%
rename from lib/twig/lib/Twig/TokenParser/Sandbox.php
rename to vendor/twig/twig/lib/Twig/TokenParser/Sandbox.php
index 0277c70..9457325
--- a/lib/twig/lib/Twig/TokenParser/Sandbox.php
+++ b/vendor/twig/twig/lib/Twig/TokenParser/Sandbox.php
@@ -35,6 +35,19 @@ class Twig_TokenParser_Sandbox extends Twig_TokenParser
$body = $this->parser->subparse(array($this, 'decideBlockEnd'), true);
$this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);
+ // in a sandbox tag, only include tags are allowed
+ if (!$body instanceof Twig_Node_Include) {
+ foreach ($body as $node) {
+ if ($node instanceof Twig_Node_Text && ctype_space($node->getAttribute('data'))) {
+ continue;
+ }
+
+ if (!$node instanceof Twig_Node_Include) {
+ throw new Twig_Error_Syntax('Only "include" tags are allowed within a "sandbox" section', $node->getLine(), $this->parser->getFilename());
+ }
+ }
+ }
+
return new Twig_Node_Sandbox($body, $token->getLine(), $this->getTag());
}
diff --git a/lib/twig/lib/Twig/TokenParser/Set.php b/vendor/twig/twig/lib/Twig/TokenParser/Set.php
old mode 100755
new mode 100644
similarity index 90%
rename from lib/twig/lib/Twig/TokenParser/Set.php
rename to vendor/twig/twig/lib/Twig/TokenParser/Set.php
index 3b4479c..70e0b41
--- a/lib/twig/lib/Twig/TokenParser/Set.php
+++ b/vendor/twig/twig/lib/Twig/TokenParser/Set.php
@@ -49,13 +49,13 @@ class Twig_TokenParser_Set extends Twig_TokenParser
$stream->expect(Twig_Token::BLOCK_END_TYPE);
if (count($names) !== count($values)) {
- throw new Twig_Error_Syntax("When using set, you must have the same number of variables and assignements.", $lineno);
+ throw new Twig_Error_Syntax("When using set, you must have the same number of variables and assignments.", $stream->getCurrent()->getLine(), $stream->getFilename());
}
} else {
$capture = true;
if (count($names) > 1) {
- throw new Twig_Error_Syntax("When using set with a block, you cannot have a multi-target.", $lineno);
+ throw new Twig_Error_Syntax("When using set with a block, you cannot have a multi-target.", $stream->getCurrent()->getLine(), $stream->getFilename());
}
$stream->expect(Twig_Token::BLOCK_END_TYPE);
diff --git a/lib/twig/lib/Twig/TokenParser/Spaceless.php b/vendor/twig/twig/lib/Twig/TokenParser/Spaceless.php
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/lib/Twig/TokenParser/Spaceless.php
rename to vendor/twig/twig/lib/Twig/TokenParser/Spaceless.php
diff --git a/lib/twig/lib/Twig/TokenParser/Use.php b/vendor/twig/twig/lib/Twig/TokenParser/Use.php
old mode 100755
new mode 100644
similarity index 95%
rename from lib/twig/lib/Twig/TokenParser/Use.php
rename to vendor/twig/twig/lib/Twig/TokenParser/Use.php
index beafc80..85f084a
--- a/lib/twig/lib/Twig/TokenParser/Use.php
+++ b/vendor/twig/twig/lib/Twig/TokenParser/Use.php
@@ -35,13 +35,12 @@ class Twig_TokenParser_Use extends Twig_TokenParser
public function parse(Twig_Token $token)
{
$template = $this->parser->getExpressionParser()->parseExpression();
+ $stream = $this->parser->getStream();
if (!$template instanceof Twig_Node_Expression_Constant) {
- throw new Twig_Error_Syntax('The template references in a "use" statement must be a string.', $token->getLine());
+ throw new Twig_Error_Syntax('The template references in a "use" statement must be a string.', $stream->getCurrent()->getLine(), $stream->getFilename());
}
- $stream = $this->parser->getStream();
-
$targets = array();
if ($stream->test('with')) {
$stream->next();
diff --git a/lib/twig/lib/Twig/TokenParserBroker.php b/vendor/twig/twig/lib/Twig/TokenParserBroker.php
old mode 100755
new mode 100644
similarity index 73%
rename from lib/twig/lib/Twig/TokenParserBroker.php
rename to vendor/twig/twig/lib/Twig/TokenParserBroker.php
index b214e99..9518c7c
--- a/lib/twig/lib/Twig/TokenParserBroker.php
+++ b/vendor/twig/twig/lib/Twig/TokenParserBroker.php
@@ -13,8 +13,8 @@
/**
* Default implementation of a token parser broker.
*
- * @package twig
- * @author Arnaud Le Blanc
+ * @author Arnaud Le Blanc
+ * @deprecated since 1.12 (to be removed in 2.0)
*/
class Twig_TokenParserBroker implements Twig_TokenParserBrokerInterface
{
@@ -32,13 +32,13 @@ class Twig_TokenParserBroker implements Twig_TokenParserBrokerInterface
{
foreach ($parsers as $parser) {
if (!$parser instanceof Twig_TokenParserInterface) {
- throw new Twig_Error('$parsers must a an array of Twig_TokenParserInterface');
+ throw new LogicException('$parsers must a an array of Twig_TokenParserInterface');
}
$this->parsers[$parser->getTag()] = $parser;
}
foreach ($brokers as $broker) {
if (!$broker instanceof Twig_TokenParserBrokerInterface) {
- throw new Twig_Error('$brokers must a an array of Twig_TokenParserBrokerInterface');
+ throw new LogicException('$brokers must a an array of Twig_TokenParserBrokerInterface');
}
$this->brokers[] = $broker;
}
@@ -54,6 +54,19 @@ class Twig_TokenParserBroker implements Twig_TokenParserBrokerInterface
$this->parsers[$parser->getTag()] = $parser;
}
+ /**
+ * Removes a TokenParser.
+ *
+ * @param Twig_TokenParserInterface $parser A Twig_TokenParserInterface instance
+ */
+ public function removeTokenParser(Twig_TokenParserInterface $parser)
+ {
+ $name = $parser->getTag();
+ if (isset($this->parsers[$name]) && $parser === $this->parsers[$name]) {
+ unset($this->parsers[$name]);
+ }
+ }
+
/**
* Adds a TokenParserBroker.
*
@@ -64,6 +77,18 @@ class Twig_TokenParserBroker implements Twig_TokenParserBrokerInterface
$this->brokers[] = $broker;
}
+ /**
+ * Removes a TokenParserBroker.
+ *
+ * @param Twig_TokenParserBroker $broker A Twig_TokenParserBroker instance
+ */
+ public function removeTokenParserBroker(Twig_TokenParserBroker $broker)
+ {
+ if (false !== $pos = array_search($broker, $this->brokers)) {
+ unset($this->brokers[$pos]);
+ }
+ }
+
/**
* Gets a suitable TokenParser for a tag.
*
diff --git a/lib/twig/lib/Twig/TokenParserBrokerInterface.php b/vendor/twig/twig/lib/Twig/TokenParserBrokerInterface.php
old mode 100755
new mode 100644
similarity index 77%
rename from lib/twig/lib/Twig/TokenParserBrokerInterface.php
rename to vendor/twig/twig/lib/Twig/TokenParserBrokerInterface.php
index 3ce8ca2..3f006e3
--- a/lib/twig/lib/Twig/TokenParserBrokerInterface.php
+++ b/vendor/twig/twig/lib/Twig/TokenParserBrokerInterface.php
@@ -15,31 +15,31 @@
*
* Token parser brokers allows to implement custom logic in the process of resolving a token parser for a given tag name.
*
- * @package twig
- * @author Arnaud Le Blanc
+ * @author Arnaud Le Blanc
+ * @deprecated since 1.12 (to be removed in 2.0)
*/
interface Twig_TokenParserBrokerInterface
{
/**
* Gets a TokenParser suitable for a tag.
*
- * @param string $tag A tag name
+ * @param string $tag A tag name
*
* @return null|Twig_TokenParserInterface A Twig_TokenParserInterface or null if no suitable TokenParser was found
*/
- function getTokenParser($tag);
+ public function getTokenParser($tag);
/**
* Calls Twig_TokenParserInterface::setParser on all parsers the implementation knows of.
*
* @param Twig_ParserInterface $parser A Twig_ParserInterface interface
*/
- function setParser(Twig_ParserInterface $parser);
+ public function setParser(Twig_ParserInterface $parser);
/**
* Gets the Twig_ParserInterface.
*
- * @return null|Twig_ParserInterface A Twig_ParserInterface instance of null
+ * @return null|Twig_ParserInterface A Twig_ParserInterface instance or null
*/
- function getParser();
+ public function getParser();
}
diff --git a/lib/twig/lib/Twig/TokenParserInterface.php b/vendor/twig/twig/lib/Twig/TokenParserInterface.php
old mode 100755
new mode 100644
similarity index 80%
rename from lib/twig/lib/Twig/TokenParserInterface.php
rename to vendor/twig/twig/lib/Twig/TokenParserInterface.php
index 192c018..bbde771
--- a/lib/twig/lib/Twig/TokenParserInterface.php
+++ b/vendor/twig/twig/lib/Twig/TokenParserInterface.php
@@ -12,8 +12,7 @@
/**
* Interface implemented by token parsers.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
interface Twig_TokenParserInterface
{
@@ -22,7 +21,7 @@ interface Twig_TokenParserInterface
*
* @param $parser A Twig_Parser instance
*/
- function setParser(Twig_Parser $parser);
+ public function setParser(Twig_Parser $parser);
/**
* Parses a token and returns a node.
@@ -31,12 +30,12 @@ interface Twig_TokenParserInterface
*
* @return Twig_NodeInterface A Twig_NodeInterface instance
*/
- function parse(Twig_Token $token);
+ public function parse(Twig_Token $token);
/**
* Gets the tag name associated with this token parser.
*
* @return string The tag name
*/
- function getTag();
+ public function getTag();
}
diff --git a/lib/twig/lib/Twig/TokenStream.php b/vendor/twig/twig/lib/Twig/TokenStream.php
old mode 100755
new mode 100644
similarity index 88%
rename from lib/twig/lib/Twig/TokenStream.php
rename to vendor/twig/twig/lib/Twig/TokenStream.php
index a2002b4..a78189f
--- a/lib/twig/lib/Twig/TokenStream.php
+++ b/vendor/twig/twig/lib/Twig/TokenStream.php
@@ -13,8 +13,7 @@
/**
* Represents a token stream.
*
- * @package twig
- * @author Fabien Potencier
+ * @author Fabien Potencier
*/
class Twig_TokenStream
{
@@ -45,6 +44,11 @@ class Twig_TokenStream
return implode("\n", $this->tokens);
}
+ public function injectTokens(array $tokens)
+ {
+ $this->tokens = array_merge(array_slice($this->tokens, 0, $this->current), $tokens, array_slice($this->tokens, $this->current));
+ }
+
/**
* Sets the pointer to the next token and returns the old one.
*
@@ -53,7 +57,7 @@ class Twig_TokenStream
public function next()
{
if (!isset($this->tokens[++$this->current])) {
- throw new Twig_Error_Syntax('Unexpected end of template', -1, $this->filename);
+ throw new Twig_Error_Syntax('Unexpected end of template', $this->tokens[$this->current - 1]->getLine(), $this->filename);
}
return $this->tokens[$this->current - 1];
@@ -92,7 +96,7 @@ class Twig_TokenStream
public function look($number = 1)
{
if (!isset($this->tokens[$this->current + $number])) {
- throw new Twig_Error_Syntax('Unexpected end of template', -1, $this->filename);
+ throw new Twig_Error_Syntax('Unexpected end of template', $this->tokens[$this->current + $number - 1]->getLine(), $this->filename);
}
return $this->tokens[$this->current + $number];
diff --git a/lib/twig/phpunit.xml.dist b/vendor/twig/twig/phpunit.xml.dist
old mode 100755
new mode 100644
similarity index 100%
rename from lib/twig/phpunit.xml.dist
rename to vendor/twig/twig/phpunit.xml.dist