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`. - -Let's define a base template, ``base.html``, which defines a simple HTML -skeleton document: - -.. code-block:: html+jinja - - - - - {% block head %} - - {% block title %}{% endblock %} - My Webpage - {% endblock %} - - -
{% block content %}{% endblock %}
- - - - -In this example, the :doc:`block` tags define four blocks that child -templates can fill in. All the ``block`` tag does is to tell the template -engine that a child template may override those portions of the template. - -Child Template --------------- - -A child template might look like this: - -.. code-block:: jinja - - {% extends "base.html" %} - - {% block title %}Index{% endblock %} - {% block head %} - {{ parent() }} - - {% endblock %} - {% block content %} -

Index

-

- Welcome on my awesome homepage. -

- {% endblock %} - -The ``extends`` tag is the key here. It tells the template engine that this -template "extends" another template. When the template system evaluates this -template, first it locates the parent. The extends tag should be the first tag -in the template. - -Note that since the child template doesn't define the ``footer`` block, the -value from the parent template is used instead. - -You can't define multiple ``block`` tags with the same name in the same -template. This limitation exists because a block tag works in "both" -directions. That is, a block tag doesn't just provide a hole to fill - it also -defines the content that fills the hole in the *parent*. If there were two -similarly-named ``block`` tags in a template, that template's parent wouldn't -know which one of the blocks' content to use. - -If you want to print a block multiple times you can however use the -``block`` function: - -.. code-block:: jinja - - {% block title %}{% endblock %} -

{{ block('title') }}

- {% block body %}{% endblock %} - -Parent Blocks -------------- - -It's possible to render the contents of the parent block by using the -:doc:`parent<../functions/parent>` function. This gives back the results of -the parent block: - -.. code-block:: jinja - - {% block sidebar %} -

Table Of Contents

- ... - {{ parent() }} - {% endblock %} - -Named Block End-Tags --------------------- - -Twig allows you to put the name of the block after the end tag for better -readability: - -.. code-block:: jinja - - {% block sidebar %} - {% block inner_sidebar %} - ... - {% endblock inner_sidebar %} - {% endblock sidebar %} - -Of course, the name after the ``endblock`` word must match the block name. - -Block Nesting and Scope ------------------------ - -Blocks can be nested for more complex layouts. Per default, blocks have access -to variables from outer scopes: - -.. code-block:: jinja - - {% for item in seq %} -
  • {% block loop_item %}{{ item }}{% endblock %}
  • - {% endfor %} - -Block Shortcuts ---------------- - -For blocks with few content, it's possible to use a shortcut syntax. The -following constructs do the same: - -.. code-block:: jinja - - {% block title %} - {{ page_title|title }} - {% endblock %} - -.. code-block:: jinja - - {% block title page_title|title %} - -Dynamic Inheritance -------------------- - -Twig supports dynamic inheritance by using a variable as the base template: - -.. code-block:: jinja - - {% extends some_var %} - -If the variable evaluates to a ``Twig_Template`` object, Twig will use it as -the parent template:: - - // {% extends layout %} - - $layout = $twig->loadTemplate('some_layout_template.twig'); - - $twig->display('template.twig', array('layout' => $layout)); - -.. versionadded:: 1.2 - The possibility to pass an array of templates has been added in Twig 1.2. - -You can also provide a list of templates that are checked for existence. The -first template that exists will be used as a parent: - -.. code-block:: jinja - - {% extends ['layout.html', 'base_layout.html'] %} - -Conditional Inheritance ------------------------ - -As the template name for the parent can be any valid Twig expression, it's -possible to make the inheritance mechanism conditional: - -.. code-block:: jinja - - {% extends standalone ? "minimum.html" : "base.html" %} - -In this example, the template will extend the "minimum.html" layout template -if the ``standalone`` variable evaluates to ``true``, and "base.html" -otherwise. - -.. seealso:: :doc:`block<../functions/block>`, :doc:`block<../tags/block>`, :doc:`parent<../functions/parent>`, :doc:`use<../tags/use>` diff --git a/lib/twig/doc/tags/filter.rst b/lib/twig/doc/tags/filter.rst deleted file mode 100755 index 82ca5c6..0000000 --- a/lib/twig/doc/tags/filter.rst +++ /dev/null @@ -1,21 +0,0 @@ -``filter`` -========== - -Filter sections allow you to apply regular Twig filters on a block of template -data. Just wrap the code in the special ``filter`` section: - -.. code-block:: jinja - - {% filter upper %} - This text becomes uppercase - {% endfilter %} - -You can also chain filters: - -.. code-block:: jinja - - {% filter lower|escape %} - SOME TEXT - {% endfilter %} - - {# outputs "<strong>some text</strong>" #} diff --git a/lib/twig/doc/tags/flush.rst b/lib/twig/doc/tags/flush.rst deleted file mode 100755 index 55ef593..0000000 --- a/lib/twig/doc/tags/flush.rst +++ /dev/null @@ -1,17 +0,0 @@ -``flush`` -========= - -.. versionadded:: 1.5 - The flush tag was added in Twig 1.5. - -The ``flush`` tag tells Twig to flush the output buffer: - -.. code-block:: jinja - - {% flush %} - -.. note:: - - Internally, Twig uses the PHP `flush`_ function. - -.. _`flush`: http://php.net/flush diff --git a/lib/twig/doc/tags/for.rst b/lib/twig/doc/tags/for.rst deleted file mode 100755 index 57cbddb..0000000 --- a/lib/twig/doc/tags/for.rst +++ /dev/null @@ -1,149 +0,0 @@ -``for`` -======= - -Loop over each item in a sequence. For example, to display a list of users -provided in a variable called ``users``: - -.. code-block:: jinja - -

    Members

    -
      - {% for user in users %} -
    • {{ user.username|e }}
    • - {% endfor %} -
    - -.. note:: - - A sequence can be either an array or an object implementing the - ``Traversable`` interface. - -If you do need to iterate over a sequence of numbers, you can use the ``..`` -operator: - -.. code-block:: jinja - - {% for i in 0..10 %} - * {{ i }} - {% endfor %} - -The above snippet of code would print all numbers from 0 to 10. - -It can be also useful with letters: - -.. code-block:: jinja - - {% for letter in 'a'..'z' %} - * {{ letter }} - {% endfor %} - -The ``..`` operator can take any expression at both sides: - -.. code-block:: jinja - - {% for letter in 'a'|upper..'z'|upper %} - * {{ letter }} - {% endfor %} - -.. tip: - - If you need a step different from 1, you can use the ``range`` function - instead. - -The `loop` variable -------------------- - -Inside of a ``for`` loop block you can access some special variables: - -===================== ============================================================= -Variable Description -===================== ============================================================= -``loop.index`` The current iteration of the loop. (1 indexed) -``loop.index0`` The current iteration of the loop. (0 indexed) -``loop.revindex`` The number of iterations from the end of the loop (1 indexed) -``loop.revindex0`` The number of iterations from the end of the loop (0 indexed) -``loop.first`` True if first iteration -``loop.last`` True if last iteration -``loop.length`` The number of items in the sequence -``loop.parent`` The parent context -===================== ============================================================= - -.. note:: - - The ``loop.length``, ``loop.revindex``, ``loop.revindex0``, and - ``loop.last`` variables are only available for PHP arrays, or objects that - implement the ``Countable`` interface. - -.. versionadded:: 1.2 - The ``if`` modifier support has been added in Twig 1.2. - -Adding a condition ------------------- - -Unlike in PHP, it's not possible to ``break`` or ``continue`` in a loop. You -can however filter the sequence during iteration which allows you to skip -items. The following example skips all the users which are not active: - -.. code-block:: jinja - -
      - {% for user in users if user.active %} -
    • {{ user.username|e }}
    • - {% endfor %} -
    - -The advantage is that the special loop variable will count correctly thus not -counting the users not iterated over. - -.. note:: - - Using the ``loop`` variable within the condition is not recommended as it - will probably not be doing what you expect it to. For instance, adding a - condition like ``loop.index > 4`` won't work as the index is only - incremented when the condition is true (so the condition will never - match). - -The `else` Clause ------------------ - -If no iteration took place because the sequence was empty, you can render a -replacement block by using ``else``: - -.. code-block:: jinja - -
      - {% for user in users %} -
    • {{ user.username|e }}
    • - {% else %} -
    • no user found
    • - {% endfor %} -
    - -Iterating over Keys -------------------- - -By default, a loop iterates over the values of the sequence. You can iterate -on keys by using the ``keys`` filter: - -.. code-block:: jinja - -

    Members

    -
      - {% for key in users|keys %} -
    • {{ key }}
    • - {% endfor %} -
    - -Iterating over Keys and Values ------------------------------- - -You can also access both keys and values: - -.. code-block:: jinja - -

    Members

    -
      - {% for key, user in users %} -
    • {{ key }}: {{ user.username|e }}
    • - {% endfor %} -
    diff --git a/lib/twig/doc/tags/from.rst b/lib/twig/doc/tags/from.rst deleted file mode 100755 index 5337a23..0000000 --- a/lib/twig/doc/tags/from.rst +++ /dev/null @@ -1,8 +0,0 @@ -``from`` -======== - -The ``from`` tags import :doc:`macro<../tags/macro>` names into the current -namespace. The tag is documented in detail in the documentation for the -:doc:`import<../tags/import>` tag. - -.. seealso:: :doc:`macro<../tags/macro>`, :doc:`import<../tags/import>` diff --git a/lib/twig/doc/tags/if.rst b/lib/twig/doc/tags/if.rst deleted file mode 100755 index 14e12b1..0000000 --- a/lib/twig/doc/tags/if.rst +++ /dev/null @@ -1,43 +0,0 @@ -``if`` -====== - -The ``if`` statement in Twig is comparable with the if statements of PHP. - -In the simplest form you can use it to test if an expression evaluates to -``true``: - -.. code-block:: jinja - - {% if online == false %} -

    Our website is in maintenance mode. Please, come back later.

    - {% endif %} - -You can also test if an array is not empty: - -.. code-block:: jinja - - {% if users %} -
      - {% for user in users %} -
    • {{ user.username|e }}
    • - {% endfor %} -
    - {% endif %} - -.. note:: - - If you want to test if the variable is defined, use ``if users is - defined`` instead. - -For multiple branches ``elseif`` and ``else`` can be used like in PHP. You can use -more complex ``expressions`` there too: - -.. code-block:: jinja - - {% if kenny.sick %} - Kenny is sick. - {% elseif kenny.dead %} - You killed Kenny! You bastard!!! - {% else %} - Kenny looks okay --- so far - {% endif %} diff --git a/lib/twig/doc/tags/import.rst b/lib/twig/doc/tags/import.rst deleted file mode 100755 index 8d47b36..0000000 --- a/lib/twig/doc/tags/import.rst +++ /dev/null @@ -1,79 +0,0 @@ -``import`` -========== - -Twig supports putting often used code into :doc:`macros<../tags/macro>`. These -macros can go into different templates and get imported from there. - -There are two ways to import templates. You can import the complete template -into a variable or request specific macros from it. - -Imagine we have a helper module that renders forms (called ``forms.html``): - -.. code-block:: jinja - - {% macro input(name, value, type, size) %} - - {% endmacro %} - - {% macro textarea(name, value, rows) %} - - {% endmacro %} - -The easiest and most flexible is importing the whole module into a variable. -That way you can access the attributes: - -.. code-block:: jinja - - {% import 'forms.html' as forms %} - -
    -
    Username
    -
    {{ forms.input('username') }}
    -
    Password
    -
    {{ forms.input('password', null, 'password') }}
    -
    -

    {{ forms.textarea('comment') }}

    - -Alternatively you can import names from the template into the current -namespace: - -.. code-block:: jinja - - {% from 'forms.html' import input as input_field, textarea %} - -
    -
    Username
    -
    {{ input_field('username') }}
    -
    Password
    -
    {{ input_field('password', '', 'password') }}
    -
    -

    {{ textarea('comment') }}

    - -Importing is not needed if the macros and the template are defined in the same -file; use the special ``_self`` variable instead: - -.. code-block:: jinja - - {# index.html template #} - - {% macro textarea(name, value, rows) %} - - {% endmacro %} - -

    {{ _self.textarea('comment') }}

    - -But you can still create an alias by importing from the ``_self`` variable: - -.. code-block:: jinja - - {# index.html template #} - - {% macro textarea(name, value, rows) %} - - {% endmacro %} - - {% import _self as forms %} - -

    {{ forms.textarea('comment') }}

    - -.. seealso:: :doc:`macro<../tags/macro>`, :doc:`from<../tags/from>` diff --git a/lib/twig/doc/tags/include.rst b/lib/twig/doc/tags/include.rst deleted file mode 100755 index 7bba404..0000000 --- a/lib/twig/doc/tags/include.rst +++ /dev/null @@ -1,86 +0,0 @@ -``include`` -=========== - -The ``include`` statement includes a template and return the rendered content -of that file into the current namespace: - -.. code-block:: jinja - - {% include 'header.html' %} - Body - {% include 'footer.html' %} - -Included templates have access to the variables of the active context. - -If you are using the filesystem loader, the templates are looked for in the -paths defined by it. - -You can add additional variables by passing them after the ``with`` keyword: - -.. code-block:: jinja - - {# the foo template will have access to the variables from the current context and the foo one #} - {% include 'foo' with {'foo': 'bar'} %} - - {% set vars = {'foo': 'bar'} %} - {% include 'foo' with vars %} - -You can disable access to the context by appending the ``only`` keyword: - -.. code-block:: jinja - - {# only the foo variable will be accessible #} - {% include 'foo' with {'foo': 'bar'} only %} - -.. code-block:: jinja - - {# no variable will be accessible #} - {% include 'foo' only %} - -.. tip:: - - When including a template created by an end user, you should consider - sandboxing it. More information in the :doc:`Twig for Developers<../api>` - chapter. - -The template name can be any valid Twig expression: - -.. code-block:: jinja - - {% include some_var %} - {% include ajax ? 'ajax.html' : 'not_ajax.html' %} - -And if the expression evaluates to a ``Twig_Template`` object, Twig will use it -directly:: - - // {% include template %} - - $template = $twig->loadTemplate('some_template.twig'); - - $twig->loadTemplate('template.twig')->display(array('template' => $template)); - -.. versionadded:: 1.2 - The ``ignore missing`` feature has been added in Twig 1.2. - -You can mark an include with ``ignore missing`` in which case Twig will ignore -the statement if the template to be ignored does not exist. It has to be -placed just after the template name. Here some valid examples: - -.. code-block:: jinja - - {% include "sidebar.html" ignore missing %} - {% include "sidebar.html" ignore missing with {'foo': 'bar} %} - {% include "sidebar.html" ignore missing only %} - -.. versionadded:: 1.2 - The possibility to pass an array of templates has been added in Twig 1.2. - -You can also provide a list of templates that are checked for existence before -inclusion. The first template that exists will be included: - -.. code-block:: jinja - - {% include ['page_detailed.html', 'page.html'] %} - -If ``ignore missing`` is given, it will fall back to rendering nothing if none -of the templates exist, otherwise it will throw an exception. diff --git a/lib/twig/doc/tags/index.rst b/lib/twig/doc/tags/index.rst deleted file mode 100755 index e44e93d..0000000 --- a/lib/twig/doc/tags/index.rst +++ /dev/null @@ -1,22 +0,0 @@ -Tags -==== - -.. toctree:: - :maxdepth: 1 - - for - if - macro - filter - set - extends - block - include - import - from - use - spaceless - autoescape - raw - flush - do diff --git a/lib/twig/doc/tags/macro.rst b/lib/twig/doc/tags/macro.rst deleted file mode 100755 index 3d920e3..0000000 --- a/lib/twig/doc/tags/macro.rst +++ /dev/null @@ -1,91 +0,0 @@ -``macro`` -========= - -Macros are comparable with functions in regular programming languages. They -are useful to put often used HTML idioms into reusable elements to not repeat -yourself. - -Here is a small example of a macro that renders a form element: - -.. code-block:: jinja - - {% macro input(name, value, type, size) %} - - {% endmacro %} - -Macros differs from native PHP functions in a few ways: - -* Default argument values are defined by using the ``default`` filter in the - macro body; - -* Arguments of a macro are always optional. - -But as PHP functions, macros don't have access to the current template -variables. - -.. tip:: - - You can pass the whole context as an argument by using the special - ``_context`` variable. - -Macros can be defined in any template, and need to be "imported" before being -used (see the documentation for the :doc:`import<../tags/import>` tag for more -information): - -.. code-block:: jinja - - {% import "forms.html" as forms %} - -The above ``import`` call imports the "forms.html" file (which can contain only -macros, or a template and some macros), and import the functions as items of -the ``forms`` variable. - -The macro can then be called at will: - -.. code-block:: jinja - -

    {{ forms.input('username') }}

    -

    {{ forms.input('password', null, 'password') }}

    - -If macros are defined and used in the same template, you can use the -special ``_self`` variable, without importing them: - -.. code-block:: jinja - -

    {{ _self.input('username') }}

    - -When you want to use a macro in another one from the same file, use the ``_self`` -variable: - -.. code-block:: jinja - - {% macro input(name, value, type, size) %} - - {% endmacro %} - - {% macro wrapped_input(name, value, type, size) %} -
    - {{ _self.input(name, value, type, size) }} -
    - {% endmacro %} - -When the macro is defined in another file, you need to import it: - -.. code-block:: jinja - - {# forms.html #} - - {% macro input(name, value, type, size) %} - - {% endmacro %} - - {# shortcuts.html #} - - {% macro wrapped_input(name, value, type, size) %} - {% import "forms.html" as forms %} -
    - {{ forms.input(name, value, type, size) }} -
    - {% endmacro %} - -.. seealso:: :doc:`from<../tags/from>`, :doc:`import<../tags/import>` diff --git a/lib/twig/doc/tags/raw.rst b/lib/twig/doc/tags/raw.rst deleted file mode 100755 index 4136c70..0000000 --- a/lib/twig/doc/tags/raw.rst +++ /dev/null @@ -1,16 +0,0 @@ -``raw`` -======= - -The ``raw`` tag marks sections as being raw text that should not be parsed. -For example to put Twig syntax as example into a template you can use this -snippet: - -.. code-block:: jinja - - {% raw %} -
      - {% for item in seq %} -
    • {{ item }}
    • - {% endfor %} -
    - {% endraw %} diff --git a/lib/twig/doc/tags/set.rst b/lib/twig/doc/tags/set.rst deleted file mode 100755 index 15090e7..0000000 --- a/lib/twig/doc/tags/set.rst +++ /dev/null @@ -1,32 +0,0 @@ -``set`` -======= - -Inside code blocks you can also assign values to variables. Assignments use -the ``set`` tag and can have multiple targets: - -.. code-block:: jinja - - {% set foo = 'foo' %} - - {% set foo = [1, 2] %} - - {% set foo = {'foo': 'bar'} %} - - {% set foo = 'foo' ~ 'bar' %} - - {% set foo, bar = 'foo', 'bar' %} - -The ``set`` tag can also be used to 'capture' chunks of text: - -.. code-block:: jinja - - {% set foo %} - - {% endset %} - -.. caution:: - - If you enable automatic output escaping, Twig will only consider the - content to be safe when capturing chunks of text. diff --git a/lib/twig/doc/tags/spaceless.rst b/lib/twig/doc/tags/spaceless.rst deleted file mode 100755 index 12e77b2..0000000 --- a/lib/twig/doc/tags/spaceless.rst +++ /dev/null @@ -1,37 +0,0 @@ -``spaceless`` -============= - -Use the ``spaceless`` tag to remove whitespace *between HTML tags*, not -whitespace within HTML tags or whitespace in plain text: - -.. code-block:: jinja - - {% spaceless %} -
    - foo -
    - {% endspaceless %} - - {# output will be
    foo
    #} - -This tag is not meant to "optimize" the size of the generated HTML content but -merely to avoid extra whitespace between HTML tags to avoid browser rendering -quirks under some circumstances. - -.. tip:: - - If you want to optimize the size of the generated HTML content, gzip - compress the output instead. - -.. tip:: - - If you want to create a tag that actually removes all extra whitespace in - an HTML string, be warned that this is not as easy as it seems to be - (think of ``textarea`` or ``pre`` tags for instance). Using a third-party - library like Tidy is probably a better idea. - -.. tip:: - - For more information on whitespace control, read the - :doc:`dedicated<../templates>` section of the documentation and learn how - you can also use the whitespace control modifier on your tags. diff --git a/lib/twig/doc/tags/use.rst b/lib/twig/doc/tags/use.rst deleted file mode 100755 index 085f916..0000000 --- a/lib/twig/doc/tags/use.rst +++ /dev/null @@ -1,123 +0,0 @@ -``use`` -======= - -.. versionadded:: 1.1 - Horizontal reuse was added in Twig 1.1. - -.. note:: - - Horizontal reuse is an advanced Twig feature that is hardly ever needed in - regular templates. It is mainly used by projects that need to make - template blocks reusable without using inheritance. - -Template inheritance is one of the most powerful Twig's feature but it is -limited to single inheritance; a template can only extend one other template. -This limitation makes template inheritance simple to understand and easy to -debug: - -.. code-block:: jinja - - {% extends "base.html" %} - - {% block title %}{% endblock %} - {% block content %}{% endblock %} - -Horizontal reuse is a way to achieve the same goal as multiple inheritance, -but without the associated complexity: - -.. code-block:: jinja - - {% extends "base.html" %} - - {% use "blocks.html" %} - - {% block title %}{% endblock %} - {% block content %}{% endblock %} - -The ``use`` statement tells Twig to import the blocks defined in -```blocks.html`` into the current template (it's like macros, but for blocks): - -.. code-block:: jinja - - # blocks.html - {% block sidebar %}{% endblock %} - -In this example, the ``use`` statement imports the ``sidebar`` block into the -main template. The code is mostly equivalent to the following one (the -imported blocks are not outputted automatically): - -.. code-block:: jinja - - {% extends "base.html" %} - - {% block sidebar %}{% endblock %} - {% block title %}{% endblock %} - {% block content %}{% endblock %} - -.. note:: - - The ``use`` tag only imports a template if it does not extend another - template, if it does not define macros, and if the body is empty. But it - can *use* other templates. - -.. note:: - - Because ``use`` statements are resolved independently of the context - passed to the template, the template reference cannot be an expression. - -The main template can also override any imported block. If the template -already defines the ``sidebar`` block, then the one defined in ``blocks.html`` -is ignored. To avoid name conflicts, you can rename imported blocks: - -.. code-block:: jinja - - {% extends "base.html" %} - - {% use "blocks.html" with sidebar as base_sidebar %} - - {% block sidebar %}{% endblock %} - {% block title %}{% endblock %} - {% block content %}{% endblock %} - -.. versionadded:: 1.3 - The ``parent()`` support was added in Twig 1.3. - -The ``parent()`` function automatically determines the correct inheritance -tree, so it can be used when overriding a block defined in an imported -template: - -.. code-block:: jinja - - {% extends "base.html" %} - - {% use "blocks.html" %} - - {% block sidebar %} - {{ parent() }} - {% endblock %} - - {% block title %}{% endblock %} - {% block content %}{% endblock %} - -In this example, ``parent()`` will correctly call the ``sidebar`` block from -the ``blocks.html`` template. - -.. tip:: - - In Twig 1.2, renaming allows you to simulate inheritance by calling the - "parent" block: - - .. code-block:: jinja - - {% extends "base.html" %} - - {% use "blocks.html" with sidebar as parent_sidebar %} - - {% block sidebar %} - {{ block('parent_sidebar') }} - {% endblock %} - -.. note:: - - You can use as many ``use`` statements as you want in any given template. - If two imported templates define the same block, the latest one wins. diff --git a/lib/twig/doc/templates.rst b/lib/twig/doc/templates.rst deleted file mode 100755 index bcd0ead..0000000 --- a/lib/twig/doc/templates.rst +++ /dev/null @@ -1,719 +0,0 @@ -Twig for Template Designers -=========================== - -This document describes the syntax and semantics of the template engine and -will be most useful as reference to those creating Twig templates. - -Synopsis --------- - -A template is simply a text file. It can generate any text-based format (HTML, -XML, CSV, LaTeX, etc.). It doesn't have a specific extension, ``.html`` or -``.xml`` are just fine. - -A template contains **variables** or **expressions**, which get replaced with -values when the template is evaluated, and **tags**, which control the logic -of the template. - -Below is a minimal template that illustrates a few basics. We will cover the -details later on: - -.. code-block:: html+jinja - - - - - My Webpage - - - - -

    My Webpage

    - {{ a_variable }} - - - -There are two kinds of delimiters: ``{% ... %}`` and ``{{ ... }}``. The first -one is used to execute statements such as for-loops, the latter prints the -result of an expression to the template. - -IDEs Integration ----------------- - -Many IDEs support syntax highlighting and auto-completion for Twig: - -* *Textmate* via the `Twig bundle`_ -* *Vim* via the `Jinja syntax plugin`_ -* *Netbeans* via the `Twig syntax plugin`_ -* *PhpStorm* (native as of 2.1) -* *Eclipse* via the `Twig plugin`_ -* *Sublime Text* via the `Twig bundle`_ -* *GtkSourceView* via the `Twig language definition`_ (used by gedit and other projects) -* *Coda* and *SubEthaEdit* via the `Twig syntax mode`_ - -Variables ---------- - -The application passes variables to the templates you can mess around in the -template. Variables may have attributes or elements on them you can access -too. How a variable looks like heavily depends on the application providing -those. - -You can use a dot (``.``) to access attributes of a variable (methods or -properties of a PHP object, or items of a PHP array), or the so-called -"subscript" syntax (``[]``): - -.. code-block:: jinja - - {{ foo.bar }} - {{ foo['bar'] }} - -.. note:: - - It's important to know that the curly braces are *not* part of the - variable but the print statement. If you access variables inside tags - don't put the braces around. - -If a variable or attribute does not exist you will get back a ``null`` value. - -.. sidebar:: Implementation - - For convenience sake ``foo.bar`` does the following things on the PHP - layer: - - * check if ``foo`` is an array and ``bar`` a valid element; - * if not, and if ``foo`` is an object, check that ``bar`` is a valid property; - * if not, and if ``foo`` is an object, check that ``bar`` is a valid method - (even if ``bar`` is the constructor - use ``__construct()`` instead); - * if not, and if ``foo`` is an object, check that ``getBar`` is a valid method; - * if not, and if ``foo`` is an object, check that ``isBar`` is a valid method; - * if not, return a ``null`` value. - - ``foo['bar']`` on the other hand only works with PHP arrays: - - * check if ``foo`` is an array and ``bar`` a valid element; - * if not, return a ``null`` value. - -.. note:: - - If you want to get a dynamic attribute on a variable, use the - :doc:`attribute` function instead. - -Global Variables -~~~~~~~~~~~~~~~~ - -The following variables are always available in templates: - -* ``_self``: references the current template; -* ``_context``: references the current context; -* ``_charset``: references the current charset. - -Setting Variables -~~~~~~~~~~~~~~~~~ - -You can assign values to variables inside code blocks. Assignments use the -:doc:`set` tag: - -.. code-block:: jinja - - {% set foo = 'foo' %} - {% set foo = [1, 2] %} - {% set foo = {'foo': 'bar'} %} - -Filters -------- - -Variables can be modified by **filters**. Filters are separated from the -variable by a pipe symbol (``|``) and may have optional arguments in -parentheses. Multiple filters can be chained. The output of one filter is -applied to the next. - -The following example removes all HTML tags from the ``name`` and title-cases -it: - -.. code-block:: jinja - - {{ name|striptags|title }} - -Filters that accept arguments have parentheses around the arguments. This -example will join a list by commas: - -.. code-block:: jinja - - {{ list|join(', ') }} - -To apply a filter on a section of code, wrap it with the -:doc:`filter` tag: - -.. code-block:: jinja - - {% filter upper %} - This text becomes uppercase - {% endfilter %} - -Go to the :doc:`filters` page to learn more about the built-in -filters. - -Functions ---------- - -Functions can be called to generate content. Functions are called by their -name followed by parentheses (``()``) and may have arguments. - -For instance, the ``range`` function returns a list containing an arithmetic -progression of integers: - -.. code-block:: jinja - - {% for i in range(0, 3) %} - {{ i }}, - {% endfor %} - -Go to the :doc:`functions` page to learn more about the -built-in functions. - -Control Structure ------------------ - -A control structure refers to all those things that control the flow of a -program - conditionals (i.e. ``if``/``elseif``/``else``), ``for``-loops, as -well as things like blocks. Control structures appear inside ``{% ... %}`` -blocks. - -For example, to display a list of users provided in a variable called -``users``, use the :doc:`for` tag: - -.. code-block:: jinja - -

    Members

    -
      - {% for user in users %} -
    • {{ user.username|e }}
    • - {% endfor %} -
    - -The :doc:`if` tag can be used to test an expression: - -.. code-block:: jinja - - {% if users|length > 0 %} -
      - {% for user in users %} -
    • {{ user.username|e }}
    • - {% endfor %} -
    - {% endif %} - -Go to the :doc:`tags` page to learn more about the built-in tags. - -Comments --------- - -To comment-out part of a line in a template, use the comment syntax ``{# ... -#}``. This is useful for debugging or to add information for other template -designers or yourself: - -.. code-block:: jinja - - {# note: disabled template because we no longer use this - {% for user in users %} - ... - {% endfor %} - #} - -Including other Templates -------------------------- - -The :doc:`include` tag is useful to include a template and -return the rendered content of that template into the current one: - -.. code-block:: jinja - - {% include 'sidebar.html' %} - -Per default included templates are passed the current context. - -The context that is passed to the included template includes variables defined -in the template: - -.. code-block:: jinja - - {% for box in boxes %} - {% include "render_box.html" %} - {% endfor %} - -The included template ``render_box.html`` is able to access ``box``. - -The filename of the template depends on the template loader. For instance, the -``Twig_Loader_Filesystem`` allows you to access other templates by giving the -filename. You can access templates in subdirectories with a slash: - -.. code-block:: jinja - - {% include "sections/articles/sidebar.html" %} - -This behavior depends on the application embedding Twig. - -Template Inheritance --------------------- - -The most powerful part of Twig is template inheritance. Template inheritance -allows you to build a base "skeleton" template that contains all the common -elements of your site and defines **blocks** that child templates can -override. - -Sounds complicated but is very basic. It's easiest to understand it by -starting with an example. - -Let's define a base template, ``base.html``, which defines a simple HTML -skeleton document that you might use for a simple two-column page: - -.. code-block:: html+jinja - - - - - {% block head %} - - {% block title %}{% endblock %} - My Webpage - {% endblock %} - - -
    {% block content %}{% endblock %}
    - - - - -In this example, the :doc:`block` tags define four blocks that -child templates can fill in. All the ``block`` tag does is to tell the -template engine that a child template may override those portions of the -template. - -A child template might look like this: - -.. code-block:: jinja - - {% extends "base.html" %} - - {% block title %}Index{% endblock %} - {% block head %} - {{ parent() }} - - {% endblock %} - {% block content %} -

    Index

    -

    - Welcome on my awesome homepage. -

    - {% endblock %} - -The :doc:`extends` tag is the key here. It tells the template -engine that this template "extends" another template. When the template system -evaluates this template, first it locates the parent. The extends tag should -be the first tag in the template. - -Note that since the child template doesn't define the ``footer`` block, the -value from the parent template is used instead. - -It's possible to render the contents of the parent block by using the -:doc:`parent` function. This gives back the results of the -parent block: - -.. code-block:: jinja - - {% block sidebar %} -

    Table Of Contents

    - ... - {{ parent() }} - {% endblock %} - -.. tip:: - - The documentation page for the :doc:`extends` tag describes - more advanced features like block nesting, scope, dynamic inheritance, and - conditional inheritance. - -.. note:: - - Twig also supports multiple inheritance with the so called horizontal reuse - with the help of the :doc:`use` tag. This is an advanced feature - hardly ever needed in regular templates. - -HTML Escaping -------------- - -When generating HTML from templates, there's always a risk that a variable -will include characters that affect the resulting HTML. There are two -approaches: manually escaping each variable or automatically escaping -everything by default. - -Twig supports both, automatic escaping is enabled by default. - -.. note:: - - Automatic escaping is only supported if the *escaper* extension has been - enabled (which is the default). - -Working with Manual Escaping -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -If manual escaping is enabled it's **your** responsibility to escape variables -if needed. What to escape? If you have a variable that *may* include any of -the following chars (``>``, ``<``, ``&``, or ``"``) you **have to** escape it -unless the variable contains well-formed and trusted HTML. Escaping works by -piping the variable through the :doc:`escape` or ``e`` filter: - -.. code-block:: jinja - - {{ user.username|e }} - {{ user.username|e('js') }} - -Working with Automatic Escaping -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Whether automatic escaping is enabled or not, you can mark a section of a -template to be escaped or not by using the :doc:`autoescape` -tag: - -.. code-block:: jinja - - {% autoescape true %} - Everything will be automatically escaped in this block - {% endautoescape %} - -Escaping --------- - -It is sometimes desirable or even necessary to have Twig ignore parts it would -otherwise handle as variables or blocks. For example if the default syntax is -used and you want to use ``{{`` as raw string in the template and not start a -variable you have to use a trick. - -The easiest way is to output the variable delimiter (``{{``) by using a variable -expression: - -.. code-block:: jinja - - {{ '{{' }} - -For bigger sections it makes sense to mark a block :doc:`raw`. - -Macros ------- - -Macros are comparable with functions in regular programming languages. They -are useful to put often used HTML idioms into reusable elements to not repeat -yourself. - -A macro is defined via the :doc:`macro` tag. Here is a small -example of a macro that renders a form element: - -.. code-block:: jinja - - {% macro input(name, value, type, size) %} - - {% endmacro %} - -Macros can be defined in any template, and need to be "imported" before being -used via the :doc:`import` tag: - -.. code-block:: jinja - - {% import "forms.html" as forms %} - -

    {{ forms.input('username') }}

    - -Alternatively you can import names from the template into the current -namespace via the :doc:`from` tag: - -.. code-block:: jinja - - {% from 'forms.html' import input as input_field, textarea %} - -
    -
    Username
    -
    {{ input_field('username') }}
    -
    Password
    -
    {{ input_field('password', type='password') }}
    -
    -

    {{ textarea('comment') }}

    - -Expressions ------------ - -Twig allows expressions everywhere. These work very similar to regular PHP and -even if you're not working with PHP you should feel comfortable with it. - -.. note:: - - The operator precedence is as follows, with the lowest-precedence - operators listed first: ``&``, ``^``, ``|``, ``or``, ``and``, ``==``, - ``!=``, ``<``, ``>``, ``>=``, ``<=``, ``in``, ``..``, ``+``, ``-``, ``~``, - ``*``, ``/``, ``//``, ``%``, ``is``, and ``**``. - -Literals -~~~~~~~~ - -.. versionadded:: 1.5 - Support for hash keys as names and expressions was added in Twig 1.5. - -The simplest form of expressions are literals. Literals are representations -for PHP types such as strings, numbers, and arrays. The following literals -exist: - -* ``"Hello World"``: Everything between two double or single quotes is a - string. They are useful whenever you need a string in the template (for - example as arguments to function calls, filters or just to extend or - include a template). - -* ``42`` / ``42.23``: Integers and floating point numbers are created by just - writing the number down. If a dot is present the number is a float, - otherwise an integer. - -* ``["foo", "bar"]``: Arrays are defined by a sequence of expressions - separated by a comma (``,``) and wrapped with squared brackets (``[]``). - -* ``{"foo": "bar"}``: Hashes are defined by a list of keys and values - separated by a comma (``,``) and wrapped with curly braces (``{}``): - - .. code-block:: jinja - - {# keys as string #} - { 'foo': 'foo', 'bar': 'bar' } - - {# keys as names (equivalent to the previous hash) -- as of Twig 1.5 #} - { foo: 'foo', bar: 'bar' } - - {# keys as integer #} - { 2: 'foo', 4: 'bar' } - - {# keys as expressions (the expression must be enclosed into parentheses) -- as of Twig 1.5 #} - { (1 + 1): 'foo', (a ~ 'b'): 'bar' } - -* ``true`` / ``false``: ``true`` represents the true value, ``false`` - represents the false value. - -* ``null``: ``null`` represents no specific value. This is the value returned - when a variable does not exist. ``none`` is an alias for ``null``. - -Arrays and hashes can be nested: - -.. code-block:: jinja - - {% set foo = [1, {"foo": "bar"}] %} - -Math -~~~~ - -Twig allows you to calculate with values. This is rarely useful in templates -but exists for completeness' sake. The following operators are supported: - -* ``+``: Adds two objects together (the operands are casted to numbers). ``{{ - 1 + 1 }}`` is ``2``. - -* ``-``: Substracts the second number from the first one. ``{{ 3 - 2 }}`` is - ``1``. - -* ``/``: Divides two numbers. The return value will be a floating point - number. ``{{ 1 / 2 }}`` is ``{{ 0.5 }}``. - -* ``%``: Calculates the remainder of an integer division. ``{{ 11 % 7 }}`` is - ``4``. - -* ``//``: Divides two numbers and returns the truncated integer result. ``{{ - 20 // 7 }}`` is ``2``. - -* ``*``: Multiplies the left operand with the right one. ``{{ 2 * 2 }}`` would - return ``4``. - -* ``**``: Raises the left operand to the power of the right operand. ``{{ 2 ** - 3 }}`` would return ``8``. - -Logic -~~~~~ - -You can combine multiple expressions with the following operators: - -* ``and``: Returns true if the left and the right operands are both true. - -* ``or``: Returns true if the left or the right operand is true. - -* ``not``: Negates a statement. - -* ``(expr)``: Groups an expression. - -Comparisons -~~~~~~~~~~~ - -The following comparison operators are supported in any expression: ``==``, -``!=``, ``<``, ``>``, ``>=``, and ``<=``. - -Containment Operator -~~~~~~~~~~~~~~~~~~~~ - -The ``in`` operator performs containment test. - -It returns ``true`` if the left operand is contained in the right: - -.. code-block:: jinja - - {# returns true #} - - {{ 1 in [1, 2, 3] }} - - {{ 'cd' in 'abcde' }} - -.. tip:: - - You can use this filter to perform a containment test on strings, arrays, - or objects implementing the ``Traversable`` interface. - -To perform a negative test, use the ``not in`` operator: - -.. code-block:: jinja - - {% if 1 not in [1, 2, 3] %} - - {# is equivalent to #} - {% if not (1 in [1, 2, 3]) %} - -Test Operator -~~~~~~~~~~~~~ - -The ``is`` operator performs tests. Tests can be used to test a variable against -a common expression. The right operand is name of the test: - -.. code-block:: jinja - - {# find out if a variable is odd #} - - {{ name is odd }} - -Tests can accept arguments too: - -.. code-block:: jinja - - {% if loop.index is divisibleby(3) %} - -Tests can be negated by using the ``is not`` operator: - -.. code-block:: jinja - - {% if loop.index is not divisibleby(3) %} - - {# is equivalent to #} - {% if not (loop.index is divisibleby(3)) %} - -Go to the :doc:`tests` page to learn more about the built-in -tests. - -Other Operators -~~~~~~~~~~~~~~~ - -The following operators are very useful but don't fit into any of the other -categories: - -* ``..``: Creates a sequence based on the operand before and after the - operator (this is just syntactic sugar for the :doc:`range` - function). - -* ``|``: Applies a filter. - -* ``~``: Converts all operands into strings and concatenates them. ``{{ "Hello - " ~ name ~ "!" }}`` would return (assuming ``name`` is ``'John'``) ``Hello - John!``. - -* ``.``, ``[]``: Gets an attribute of an object. - -* ``?:``: The PHP ternary operator: ``{{ foo ? 'yes' : 'no' }}`` - -String Interpolation -~~~~~~~~~~~~~~~~~~~~ - -.. versionadded:: 1.5 - String interpolation was added in Twig 1.5. - -String interpolation (`#{expression}`) allows any valid expression to appear -within a string. The result of evaluating that expression is inserted into the -string: - -.. code-block:: jinja - - {{ "foo #{bar} baz" }} - {{ "foo #{1 + 2} baz" }} - -Whitespace Control ------------------- - -.. versionadded:: 1.1 - Tag level whitespace control was added in Twig 1.1. - -The first newline after a template tag is removed automatically (like in PHP.) -Whitespace is not further modified by the template engine, so each whitespace -(spaces, tabs, newlines etc.) is returned unchanged. - -Use the ``spaceless`` tag to remove whitespace *between HTML tags*: - -.. code-block:: jinja - - {% spaceless %} -
    - foo -
    - {% endspaceless %} - - {# output will be
    foo
    #} - -In addition to the spaceless tag you can also control whitespace on a per tag -level. By using the whitespace control modifier on your tags, you can trim -leading and or trailing whitespace: - -.. code-block:: jinja - - {% set value = 'no spaces' %} - {#- No leading/trailing whitespace -#} - {%- if true -%} - {{- value -}} - {%- endif -%} - - {# output 'no spaces' #} - -The above sample shows the default whitespace control modifier, and how you can -use it to remove whitespace around tags. Trimming space will consume all whitespace -for that side of the tag. It is possible to use whitespace trimming on one side -of a tag: - -.. code-block:: jinja - - {% set value = 'no spaces' %} -
  • {{- value }}
  • - - {# outputs '
  • no spaces
  • ' #} - -Extensions ----------- - -Twig can be easily extended. - -If you are looking for new tags, filters, or functions, have a look at the Twig official -`extension repository`_. - -If you want to create your own, read :doc:`extensions`. - -.. _`Twig bundle`: https://github.com/Anomareh/PHP-Twig.tmbundle -.. _`Jinja syntax plugin`: http://jinja.pocoo.org/2/documentation/integration -.. _`Twig syntax plugin`: http://plugins.netbeans.org/plugin/37069/php-twig -.. _`Twig plugin`: https://github.com/pulse00/Twig-Eclipse-Plugin -.. _`Twig language definition`: https://github.com/gabrielcorpse/gedit-twig-template-language -.. _`extension repository`: http://github.com/fabpot/Twig-extensions -.. _`Twig syntax mode`: https://github.com/bobthecow/Twig-HTML.mode diff --git a/lib/twig/doc/tests/constant.rst b/lib/twig/doc/tests/constant.rst deleted file mode 100755 index 7970933..0000000 --- a/lib/twig/doc/tests/constant.rst +++ /dev/null @@ -1,11 +0,0 @@ -``constant`` -============ - -``constant`` checks if a variable has the exact same value as a constant. You -can use either global constants or class constants: - -.. code-block:: jinja - - {% if post.status is constant('Post::PUBLISHED') %} - the status attribute is exactly the same as Post::PUBLISHED - {% endif %} diff --git a/lib/twig/doc/tests/defined.rst b/lib/twig/doc/tests/defined.rst deleted file mode 100755 index 702ce72..0000000 --- a/lib/twig/doc/tests/defined.rst +++ /dev/null @@ -1,30 +0,0 @@ -``defined`` -=========== - -``defined`` checks if a variable is defined in the current context. This is very -useful if you use the ``strict_variables`` option: - -.. code-block:: jinja - - {# defined works with variable names #} - {% if foo is defined %} - ... - {% endif %} - - {# and attributes on variables names #} - {% if foo.bar is defined %} - ... - {% endif %} - - {% if foo['bar'] is defined %} - ... - {% endif %} - -When using the ``defined`` test on an expression that uses variables in some -method calls, be sure that they are all defined first: - -.. code-block:: jinja - - {% if var is defined and foo.method(var) is defined %} - ... - {% endif %} diff --git a/lib/twig/doc/tests/divisibleby.rst b/lib/twig/doc/tests/divisibleby.rst deleted file mode 100755 index 9b0b964..0000000 --- a/lib/twig/doc/tests/divisibleby.rst +++ /dev/null @@ -1,10 +0,0 @@ -``divisibleby`` -=============== - -``divisibleby`` checks if a variable is divisible by a number: - -.. code-block:: jinja - - {% if loop.index is divisibleby(3) %} - ... - {% endif %} diff --git a/lib/twig/doc/tests/empty.rst b/lib/twig/doc/tests/empty.rst deleted file mode 100755 index 0d1eb32..0000000 --- a/lib/twig/doc/tests/empty.rst +++ /dev/null @@ -1,11 +0,0 @@ -``empty`` -========= - -``empty`` checks if a variable is empty: - -.. code-block:: jinja - - {# evaluates to true if the foo variable is null, false, or the empty string #} - {% if foo is empty %} - ... - {% endif %} diff --git a/lib/twig/doc/tests/even.rst b/lib/twig/doc/tests/even.rst deleted file mode 100755 index 6ab5cc3..0000000 --- a/lib/twig/doc/tests/even.rst +++ /dev/null @@ -1,10 +0,0 @@ -``even`` -======== - -``even`` returns ``true`` if the given number is even: - -.. code-block:: jinja - - {{ var is even }} - -.. seealso:: :doc:`odd<../tests/odd>` diff --git a/lib/twig/doc/tests/index.rst b/lib/twig/doc/tests/index.rst deleted file mode 100755 index b16edc5..0000000 --- a/lib/twig/doc/tests/index.rst +++ /dev/null @@ -1,14 +0,0 @@ -Tests -===== - -.. toctree:: - :maxdepth: 1 - - divisibleby - null - even - odd - sameas - constant - defined - empty diff --git a/lib/twig/doc/tests/null.rst b/lib/twig/doc/tests/null.rst deleted file mode 100755 index 44eec62..0000000 --- a/lib/twig/doc/tests/null.rst +++ /dev/null @@ -1,12 +0,0 @@ -``null`` -======== - -``null`` returns ``true`` if the variable is ``null``: - -.. code-block:: jinja - - {{ var is null }} - -.. note:: - - ``none`` is an alias for ``null``. diff --git a/lib/twig/doc/tests/odd.rst b/lib/twig/doc/tests/odd.rst deleted file mode 100755 index 9eece77..0000000 --- a/lib/twig/doc/tests/odd.rst +++ /dev/null @@ -1,10 +0,0 @@ -``odd`` -======= - -``odd`` returns ``true`` if the given number is odd: - -.. code-block:: jinja - - {{ var is odd }} - -.. seealso:: :doc:`even<../tests/even>` diff --git a/lib/twig/doc/tests/sameas.rst b/lib/twig/doc/tests/sameas.rst deleted file mode 100755 index efb15c3..0000000 --- a/lib/twig/doc/tests/sameas.rst +++ /dev/null @@ -1,11 +0,0 @@ -``sameas`` -========== - -``sameas`` checks if a variable points to the same memory address than another -variable: - -.. code-block:: jinja - - {% if foo.attribute is sameas(false) %} - the foo attribute really is the ``false`` PHP value - {% endif %} diff --git a/lib/twig/ext/twig/.gitignore b/lib/twig/ext/twig/.gitignore deleted file mode 100755 index 56ea76c..0000000 --- a/lib/twig/ext/twig/.gitignore +++ /dev/null @@ -1,30 +0,0 @@ -*.sw* -.deps -Makefile -Makefile.fragments -Makefile.global -Makefile.objects -acinclude.m4 -aclocal.m4 -build/ -config.cache -config.guess -config.h -config.h.in -config.log -config.nice -config.status -config.sub -configure -configure.in -install-sh -libtool -ltmain.sh -missing -mkinstalldirs -run-tests.php -twig.loT -.libs/ -modules/ -twig.la -twig.lo diff --git a/lib/twig/ext/twig/LICENSE b/lib/twig/ext/twig/LICENSE deleted file mode 100755 index 66b8bb4..0000000 --- a/lib/twig/ext/twig/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -Copyright (c) 2011, Derick Rethans -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/lib/twig/ext/twig/config.m4 b/lib/twig/ext/twig/config.m4 deleted file mode 100755 index 83486be..0000000 --- a/lib/twig/ext/twig/config.m4 +++ /dev/null @@ -1,8 +0,0 @@ -dnl config.m4 for extension twig - -PHP_ARG_ENABLE(twig, whether to enable twig support, -[ --enable-twig Enable twig support]) - -if test "$PHP_TWIG" != "no"; then - PHP_NEW_EXTENSION(twig, twig.c, $ext_shared) -fi diff --git a/lib/twig/ext/twig/config.w32 b/lib/twig/ext/twig/config.w32 deleted file mode 100755 index cb287b9..0000000 --- a/lib/twig/ext/twig/config.w32 +++ /dev/null @@ -1,8 +0,0 @@ -// vim:ft=javascript - -ARG_ENABLE("twig", "Twig support", "no"); - -if (PHP_TWIG != "no") { - AC_DEFINE('HAVE_TWIG', 1); - EXTENSION('twig', 'twig.c'); -} diff --git a/lib/twig/ext/twig/php_twig.h b/lib/twig/ext/twig/php_twig.h deleted file mode 100755 index 752dd82..0000000 --- a/lib/twig/ext/twig/php_twig.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Twig Extension | - +----------------------------------------------------------------------+ - | Copyright (c) 2011 Derick Rethans | - +----------------------------------------------------------------------+ - | Redistribution and use in source and binary forms, with or without | - | modification, are permitted provided that the conditions mentioned | - | in the accompanying LICENSE file are met (BSD, revised). | - +----------------------------------------------------------------------+ - | Author: Derick Rethans | - +----------------------------------------------------------------------+ - */ - -#ifndef PHP_TWIG_H -#define PHP_TWIG_H - -#define PHP_TWIG_VERSION "1.6.4" - -#include "php.h" - -extern zend_module_entry twig_module_entry; -#define phpext_twig_ptr &twig_module_entry - -#ifdef PHP_WIN32 -#define PHP_TWIG_API __declspec(dllexport) -#else -#define PHP_TWIG_API -#endif - -#ifdef ZTS -#include "TSRM.h" -#endif - -PHP_FUNCTION(twig_template_get_attributes); - -PHP_MINIT_FUNCTION(twig); -PHP_MSHUTDOWN_FUNCTION(twig); -PHP_RINIT_FUNCTION(twig); -PHP_RSHUTDOWN_FUNCTION(twig); -PHP_MINFO_FUNCTION(twig); - -#ifdef ZTS -#define TWIG_G(v) TSRMG(twig_globals_id, zend_twig_globals *, v) -#else -#define TWIG_G(v) (twig_globals.v) -#endif - -#endif diff --git a/lib/twig/ext/twig/twig.c b/lib/twig/ext/twig/twig.c deleted file mode 100755 index 880b964..0000000 --- a/lib/twig/ext/twig/twig.c +++ /dev/null @@ -1,1025 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | Twig Extension | - +----------------------------------------------------------------------+ - | Copyright (c) 2011 Derick Rethans | - +----------------------------------------------------------------------+ - | Redistribution and use in source and binary forms, with or without | - | modification, are permitted provided that the conditions mentioned | - | in the accompanying LICENSE file are met (BSD, revised). | - +----------------------------------------------------------------------+ - | Author: Derick Rethans | - +----------------------------------------------------------------------+ - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "php.h" -#include "php_ini.h" -#include "ext/standard/info.h" -#include "php_twig.h" -#include "ext/standard/php_string.h" -#include "ext/standard/php_smart_str.h" - -#include "Zend/zend_object_handlers.h" -#include "Zend/zend_interfaces.h" -#include "Zend/zend_exceptions.h" - -#ifndef Z_ADDREF_P -#define Z_ADDREF_P(pz) (pz)->refcount++ -#endif - -ZEND_BEGIN_ARG_INFO_EX(twig_template_get_attribute_args, ZEND_SEND_BY_VAL, ZEND_RETURN_VALUE, 6) - ZEND_ARG_INFO(0, template) - ZEND_ARG_INFO(0, object) - ZEND_ARG_INFO(0, item) - ZEND_ARG_INFO(0, arguments) - ZEND_ARG_INFO(0, type) - ZEND_ARG_INFO(0, isDefinedTest) -ZEND_END_ARG_INFO() - -zend_function_entry twig_functions[] = { - PHP_FE(twig_template_get_attributes, twig_template_get_attribute_args) - {NULL, NULL, NULL} -}; - - -zend_module_entry twig_module_entry = { -#if ZEND_MODULE_API_NO >= 20010901 - STANDARD_MODULE_HEADER, -#endif - "twig", - twig_functions, - PHP_MINIT(twig), - PHP_MSHUTDOWN(twig), - PHP_RINIT(twig), - PHP_RSHUTDOWN(twig), - PHP_MINFO(twig), -#if ZEND_MODULE_API_NO >= 20010901 - PHP_TWIG_VERSION, -#endif - STANDARD_MODULE_PROPERTIES -}; - - -#ifdef COMPILE_DL_TWIG -ZEND_GET_MODULE(twig) -#endif - -PHP_INI_BEGIN() -PHP_INI_END() - -PHP_MINIT_FUNCTION(twig) -{ - REGISTER_INI_ENTRIES(); - - return SUCCESS; -} - - -PHP_MSHUTDOWN_FUNCTION(twig) -{ - UNREGISTER_INI_ENTRIES(); - - return SUCCESS; -} - - - -PHP_RINIT_FUNCTION(twig) -{ - return SUCCESS; -} - - - -PHP_RSHUTDOWN_FUNCTION(twig) -{ - return SUCCESS; -} - - -PHP_MINFO_FUNCTION(twig) -{ - php_info_print_table_start(); - php_info_print_table_header(2, "Twig support", "enabled"); - php_info_print_table_row(2, "Version", PHP_TWIG_VERSION); - php_info_print_table_end(); - - DISPLAY_INI_ENTRIES(); - -} - -int TWIG_ARRAY_KEY_EXISTS(zval *array, char* key, int key_len) -{ - if (Z_TYPE_P(array) != IS_ARRAY) { - return 0; - } - return zend_symtable_exists(Z_ARRVAL_P(array), key, key_len + 1); -} - -int TWIG_INSTANCE_OF(zval *object, zend_class_entry *interface TSRMLS_DC) -{ - if (Z_TYPE_P(object) != IS_OBJECT) { - return 0; - } - return instanceof_function(Z_OBJCE_P(object), interface TSRMLS_CC); -} - -int TWIG_INSTANCE_OF_USERLAND(zval *object, char *interface TSRMLS_DC) -{ - zend_class_entry **pce; - if (Z_TYPE_P(object) != IS_OBJECT) { - return 0; - } - if (zend_lookup_class(interface, strlen(interface), &pce TSRMLS_CC) == FAILURE) { - return 0; - } - return instanceof_function(Z_OBJCE_P(object), *pce TSRMLS_CC); -} - -zval *TWIG_GET_ARRAYOBJECT_ELEMENT(zval *object, zval *offset TSRMLS_DC) -{ - zend_class_entry *ce = Z_OBJCE_P(object); - zval *retval; - - if (Z_TYPE_P(object) == IS_OBJECT) { - SEPARATE_ARG_IF_REF(offset); - zend_call_method_with_1_params(&object, ce, NULL, "offsetget", &retval, offset); - - zval_ptr_dtor(&offset); - - if (!retval) { - if (!EG(exception)) { - zend_error(E_ERROR, "Undefined offset for object of type %s used as array", ce->name); - } - return NULL; - } - - return retval; - } - return NULL; -} - -int TWIG_ISSET_ARRAYOBJECT_ELEMENT(zval *object, zval *offset TSRMLS_DC) -{ - zend_class_entry *ce = Z_OBJCE_P(object); - zval *retval; - - if (Z_TYPE_P(object) == IS_OBJECT) { - SEPARATE_ARG_IF_REF(offset); - zend_call_method_with_1_params(&object, ce, NULL, "offsetexists", &retval, offset); - - zval_ptr_dtor(&offset); - - if (!retval) { - if (!EG(exception)) { - zend_error(E_ERROR, "Undefined offset for object of type %s used as array", ce->name); - } - return 0; - } - - return (retval && Z_TYPE_P(retval) == IS_BOOL && Z_LVAL_P(retval)); - } - return 0; -} - -char *TWIG_STRTOLOWER(const char *str, int str_len) -{ - char *item_dup; - - item_dup = estrndup(str, str_len); - php_strtolower(item_dup, str_len); - return item_dup; -} - -zval *TWIG_CALL_USER_FUNC_ARRAY(zval *object, char *function, zval *arguments TSRMLS_DC) -{ - zend_fcall_info fci; - zval ***args = NULL; - int arg_count = 0; - HashTable *table; - HashPosition pos; - int i = 0; - zval *retval_ptr; - zval *zfunction; - - if (arguments) { - table = HASH_OF(arguments); - args = safe_emalloc(sizeof(zval **), table->nNumOfElements, 0); - - zend_hash_internal_pointer_reset_ex(table, &pos); - - while (zend_hash_get_current_data_ex(table, (void **)&args[i], &pos) == SUCCESS) { - i++; - zend_hash_move_forward_ex(table, &pos); - } - arg_count = table->nNumOfElements; - } - - MAKE_STD_ZVAL(zfunction); - ZVAL_STRING(zfunction, function, 1); - fci.size = sizeof(fci); - fci.function_table = EG(function_table); - fci.function_name = zfunction; - fci.symbol_table = NULL; -#if PHP_VERSION_ID >= 50300 - fci.object_ptr = object; -#else - fci.object_pp = &object; -#endif - fci.retval_ptr_ptr = &retval_ptr; - fci.param_count = arg_count; - fci.params = args; - fci.no_separation = 0; - - if (zend_call_function(&fci, NULL TSRMLS_CC) == FAILURE) { - zval_dtor(zfunction); - efree(zfunction); - zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "Could not execute %s::%s()", zend_get_class_entry(object TSRMLS_CC)->name, function TSRMLS_CC); - } - - if (args) { - efree(fci.params); - } - zval_dtor(zfunction); - efree(zfunction); - return retval_ptr; -} - -int TWIG_CALL_BOOLEAN(zval *object, char *functionName TSRMLS_DC) -{ - zval *ret; - int res; - - ret = TWIG_CALL_USER_FUNC_ARRAY(object, functionName, NULL TSRMLS_CC); - res = Z_LVAL_P(ret); - zval_ptr_dtor(&ret); - return res; -} - -zval *TWIG_GET_STATIC_PROPERTY(zval *class, char *prop_name TSRMLS_DC) -{ - zval **tmp_zval; - zend_class_entry *ce; - - if (class == NULL || Z_TYPE_P(class) != IS_OBJECT) { - return NULL; - } - - ce = zend_get_class_entry(class TSRMLS_CC); -#if PHP_VERSION_ID >= 50400 - tmp_zval = zend_std_get_static_property(ce, prop_name, strlen(prop_name), 0, NULL TSRMLS_CC); -#else - tmp_zval = zend_std_get_static_property(ce, prop_name, strlen(prop_name), 0 TSRMLS_CC); -#endif - return *tmp_zval; -} - -zval *TWIG_GET_ARRAY_ELEMENT_ZVAL(zval *class, zval *prop_name TSRMLS_DC) -{ - zval **tmp_zval; - char *tmp_name; - - if (class == NULL || Z_TYPE_P(class) != IS_ARRAY || Z_TYPE_P(prop_name) != IS_STRING) { - if (class != NULL && Z_TYPE_P(class) == IS_OBJECT && TWIG_INSTANCE_OF(class, zend_ce_arrayaccess TSRMLS_CC)) { - // array access object - return TWIG_GET_ARRAYOBJECT_ELEMENT(class, prop_name TSRMLS_CC); - } - return NULL; - } - - convert_to_string(prop_name); - tmp_name = Z_STRVAL_P(prop_name); - if (zend_symtable_find(HASH_OF(class), tmp_name, strlen(tmp_name)+1, (void**) &tmp_zval) == SUCCESS) { - return *tmp_zval; - } - return NULL; -} - -zval *TWIG_GET_ARRAY_ELEMENT(zval *class, char *prop_name, int prop_name_length TSRMLS_DC) -{ - zval **tmp_zval; - - if (class == NULL/* || Z_TYPE_P(class) != IS_ARRAY*/) { - return NULL; - } - - if (class != NULL && Z_TYPE_P(class) == IS_OBJECT && TWIG_INSTANCE_OF(class, zend_ce_arrayaccess TSRMLS_CC)) { - // array access object - zval *tmp_name_zval; - zval *tmp_ret_zval; - - ALLOC_INIT_ZVAL(tmp_name_zval); - ZVAL_STRING(tmp_name_zval, prop_name, 1); - tmp_ret_zval = TWIG_GET_ARRAYOBJECT_ELEMENT(class, tmp_name_zval TSRMLS_CC); - zval_dtor(tmp_name_zval); - efree(tmp_name_zval); - return tmp_ret_zval; - } - - if (zend_symtable_find(HASH_OF(class), prop_name, prop_name_length+1, (void**)&tmp_zval) == SUCCESS) { - return *tmp_zval; - } - return NULL; -} - -zval *TWIG_PROPERTY(zval *object, zval *propname TSRMLS_DC) -{ - char *prot_name; - int prot_name_length; - zval *tmp = NULL; - - tmp = TWIG_GET_ARRAY_ELEMENT(object, Z_STRVAL_P(propname), Z_STRLEN_P(propname) TSRMLS_CC); - if (tmp) { - return tmp; - } - - zend_mangle_property_name(&prot_name, &prot_name_length, "*", 1, Z_STRVAL_P(propname), Z_STRLEN_P(propname), 0); - tmp = TWIG_GET_ARRAY_ELEMENT(object, prot_name, prot_name_length TSRMLS_CC); - efree(prot_name); - if (tmp) { - return tmp; - } - - if (Z_OBJ_HT_P(object)->read_property) { -#if PHP_VERSION_ID >= 50400 - tmp = Z_OBJ_HT_P(object)->read_property(object, propname, BP_VAR_IS, NULL TSRMLS_CC); -#else - tmp = Z_OBJ_HT_P(object)->read_property(object, propname, BP_VAR_IS TSRMLS_CC); -#endif - if (tmp != EG(uninitialized_zval_ptr)) { - return tmp; - } else { - return NULL; - } - } - return tmp; -} - -int TWIG_HAS_PROPERTY(zval *object, zval *propname TSRMLS_DC) -{ - if (Z_OBJ_HT_P(object)->has_property) { -#if PHP_VERSION_ID >= 50400 - return Z_OBJ_HT_P(object)->has_property(object, propname, 0, NULL TSRMLS_CC); -#else - return Z_OBJ_HT_P(object)->has_property(object, propname, 0 TSRMLS_CC); -#endif - } - return 0; -} - -zval *TWIG_PROPERTY_CHAR(zval *object, char *propname TSRMLS_DC) -{ - zval *tmp_name_zval, *tmp; - - ALLOC_INIT_ZVAL(tmp_name_zval); - ZVAL_STRING(tmp_name_zval, propname, 1); - tmp = TWIG_PROPERTY(object, tmp_name_zval TSRMLS_CC); - zval_dtor(tmp_name_zval); - efree(tmp_name_zval); - return tmp; -} - -int TWIG_CALL_B_0(zval *object, char *method) -{ - return 0; -} - -zval *TWIG_CALL_S(zval *object, char *method, char *arg0 TSRMLS_DC) -{ - zend_fcall_info fci; - zval **args[1]; - zval *argument; - zval *zfunction; - zval *retval_ptr; - - MAKE_STD_ZVAL(argument); - ZVAL_STRING(argument, arg0, 1); - args[0] = &argument; - - MAKE_STD_ZVAL(zfunction); - ZVAL_STRING(zfunction, method, 1); - fci.size = sizeof(fci); - fci.function_table = EG(function_table); - fci.function_name = zfunction; - fci.symbol_table = NULL; -#if PHP_VERSION_ID >= 50300 - fci.object_ptr = object; -#else - fci.object_pp = &object; -#endif - fci.retval_ptr_ptr = &retval_ptr; - fci.param_count = 1; - fci.params = args; - fci.no_separation = 0; - - if (zend_call_function(&fci, NULL TSRMLS_CC) == FAILURE) { - zval_dtor(argument); - return 0; - } - zval_dtor(zfunction); - efree(zfunction); - zval_dtor(argument); - efree(argument); - return retval_ptr; -} - -int TWIG_CALL_SB(zval *object, char *method, char *arg0 TSRMLS_DC) -{ - zval *retval_ptr; - int success; - - retval_ptr = TWIG_CALL_S(object, method, arg0 TSRMLS_CC); - success = (retval_ptr && (Z_TYPE_P(retval_ptr) == IS_BOOL) && Z_LVAL_P(retval_ptr)); - - if (retval_ptr) { - zval_ptr_dtor(&retval_ptr); - } - - return success; -} - -int TWIG_CALL_Z(zval *object, char *method, zval *arg1 TSRMLS_DC) -{ - zend_fcall_info fci; - zval **args[1]; - zval *zfunction; - zval *retval_ptr; - int success; - - args[0] = &arg1; - - MAKE_STD_ZVAL(zfunction); - ZVAL_STRING(zfunction, method, 1); - fci.size = sizeof(fci); - fci.function_table = EG(function_table); - fci.function_name = zfunction; - fci.symbol_table = NULL; -#if PHP_VERSION_ID >= 50300 - fci.object_ptr = object; -#else - fci.object_pp = &object; -#endif - fci.retval_ptr_ptr = &retval_ptr; - fci.param_count = 1; - fci.params = args; - fci.no_separation = 0; - - if (zend_call_function(&fci, NULL TSRMLS_CC) == FAILURE) { - zval_dtor(zfunction); - efree(zfunction); - if (retval_ptr) { - zval_ptr_dtor(&retval_ptr); - } - return 0; - } - - zval_dtor(zfunction); - efree(zfunction); - - success = (retval_ptr && (Z_TYPE_P(retval_ptr) == IS_BOOL) && Z_LVAL_P(retval_ptr)); - if (retval_ptr) { - zval_ptr_dtor(&retval_ptr); - } - - return success; -} - -int TWIG_CALL_ZZ(zval *object, char *method, zval *arg1, zval *arg2 TSRMLS_DC) -{ - zend_fcall_info fci; - zval **args[2]; - zval *zfunction; - zval *retval_ptr; - int success; - - args[0] = &arg1; - args[1] = &arg2; - - MAKE_STD_ZVAL(zfunction); - ZVAL_STRING(zfunction, method, 1); - fci.size = sizeof(fci); - fci.function_table = EG(function_table); - fci.function_name = zfunction; - fci.symbol_table = NULL; -#if PHP_VERSION_ID >= 50300 - fci.object_ptr = object; -#else - fci.object_pp = &object; -#endif - fci.retval_ptr_ptr = &retval_ptr; - fci.param_count = 2; - fci.params = args; - fci.no_separation = 0; - - if (zend_call_function(&fci, NULL TSRMLS_CC) == FAILURE) { - zval_dtor(zfunction); - return 0; - } - - zval_dtor(zfunction); - - success = (retval_ptr && (Z_TYPE_P(retval_ptr) == IS_BOOL) && Z_LVAL_P(retval_ptr)); - if (retval_ptr) { - zval_ptr_dtor(&retval_ptr); - } - - return success; -} - -#ifndef Z_SET_REFCOUNT_P -# define Z_SET_REFCOUNT_P(pz, rc) pz->refcount = rc -# define Z_UNSET_ISREF_P(pz) pz->is_ref = 0 -#endif - -void TWIG_NEW(zval *object, char *class, zval *arg0, zval *arg1 TSRMLS_DC) -{ - zend_class_entry **pce; - - if (zend_lookup_class(class, strlen(class), &pce TSRMLS_CC) == FAILURE) { - return; - } - - Z_TYPE_P(object) = IS_OBJECT; - object_init_ex(object, *pce); - Z_SET_REFCOUNT_P(object, 1); - Z_UNSET_ISREF_P(object); - - TWIG_CALL_ZZ(object, "__construct", arg0, arg1 TSRMLS_CC); -} - -static int twig_add_array_key_to_string(void *pDest TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) -{ - smart_str *buf; - char *joiner; - - buf = va_arg(args, smart_str*); - joiner = va_arg(args, char*); - - if (buf->len != 0) { - smart_str_appends(buf, joiner); - } - - if (hash_key->nKeyLength == 0) { - smart_str_append_long(buf, (long) hash_key->h); - } else { - char *key, *tmp_str; - int key_len, tmp_len; - key = php_addcslashes(hash_key->arKey, hash_key->nKeyLength - 1, &key_len, 0, "'\\", 2 TSRMLS_CC); - tmp_str = php_str_to_str_ex(key, key_len, "\0", 1, "' . \"\\0\" . '", 12, &tmp_len, 0, NULL); - - smart_str_appendl(buf, tmp_str, tmp_len); - efree(key); - efree(tmp_str); - } - - return 0; -} - -char *TWIG_IMPLODE_ARRAY_KEYS(char *joiner, zval *array TSRMLS_DC) -{ - smart_str collector = { 0, 0, 0 }; - - smart_str_appendl(&collector, "", 0); - zend_hash_apply_with_arguments(HASH_OF(array) TSRMLS_CC, twig_add_array_key_to_string, 2, &collector, joiner); - smart_str_0(&collector); - - return collector.c; -} - -static void TWIG_THROW_EXCEPTION(char *exception_name TSRMLS_DC, char *message, ...) -{ - char *buffer; - va_list args; - zend_class_entry **pce; - - if (zend_lookup_class(exception_name, strlen(exception_name), &pce TSRMLS_CC) == FAILURE) - { - return; - } - - va_start(args, message); - vspprintf(&buffer, 0, message, args); - va_end(args); - - zend_throw_exception_ex(*pce, 0 TSRMLS_CC, buffer); -} - -char *TWIG_GET_CLASS_NAME(zval *object TSRMLS_DC) -{ - char *class_name; - zend_uint class_name_len; - - if (Z_TYPE_P(object) != IS_OBJECT) { - return ""; - } - zend_get_object_classname(object, &class_name, &class_name_len TSRMLS_CC); - return class_name; -} - -static int twig_add_method_to_class(void *pDest TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) -{ - zval *retval; - char *item; - size_t item_len; - zend_function *mptr = (zend_function *) pDest; - - if (!(mptr->common.fn_flags & ZEND_ACC_PUBLIC)) { - return 0; - } - - retval = va_arg(args, zval*); - - item_len = strlen(mptr->common.function_name); - item = estrndup(mptr->common.function_name, item_len); - php_strtolower(item, item_len); - - add_assoc_stringl_ex(retval, item, item_len+1, item, item_len, 0); - - return 0; -} - -static int twig_add_property_to_class(void *pDest TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) -{ - zend_class_entry *ce; - zval *retval; - char *class_name, *prop_name; - zend_property_info *pptr = (zend_property_info *) pDest; - - if (!(pptr->flags & ZEND_ACC_PUBLIC)) { - return 0; - } - - ce = *va_arg(args, zend_class_entry**); - retval = va_arg(args, zval*); - - zend_unmangle_property_name(pptr->name, pptr->name_length, &class_name, &prop_name); - - add_assoc_string(retval, prop_name, prop_name, 1); - - return 0; -} - -/* {{{ _adddynproperty */ -static int twig_add_dyn_property_to_class(void *pDest TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) -{ - zend_class_entry *ce = *va_arg(args, zend_class_entry**); - zval *retval = va_arg(args, zval*), member; - char *class_name, *prop_name; - - if (hash_key->nKeyLength < 1 || hash_key->arKey[0] == '\0') { - return 0; /* non public cannot be dynamic */ - } - - ZVAL_STRINGL(&member, hash_key->arKey, hash_key->nKeyLength-1, 0); - if (zend_get_property_info(ce, &member, 1 TSRMLS_CC) == &EG(std_property_info)) { - zend_unmangle_property_name((&EG(std_property_info))->name, (&EG(std_property_info))->name_length, &class_name, &prop_name); - add_assoc_string(retval, prop_name, prop_name, 1); - } - return 0; -} - -static void twig_add_class_to_cache(zval *cache, zval *object, char *class_name TSRMLS_DC) -{ - zval *class_info, *class_methods, *class_properties; - zend_class_entry *class_ce; - - class_ce = zend_get_class_entry(object TSRMLS_CC); - - ALLOC_INIT_ZVAL(class_info); - ALLOC_INIT_ZVAL(class_methods); - ALLOC_INIT_ZVAL(class_properties); - array_init(class_info); - array_init(class_methods); - array_init(class_properties); - // add all methods to self::cache[$class]['methods'] - zend_hash_apply_with_arguments(&class_ce->function_table TSRMLS_CC, twig_add_method_to_class, 1, class_methods); - zend_hash_apply_with_arguments(&class_ce->properties_info TSRMLS_CC, twig_add_property_to_class, 2, &class_ce, class_properties); - - if (object && Z_OBJ_HT_P(object)->get_properties) { - HashTable *properties = Z_OBJ_HT_P(object)->get_properties(object TSRMLS_CC); - zend_hash_apply_with_arguments(properties TSRMLS_CC, twig_add_dyn_property_to_class, 2, &class_ce, class_properties); - } - add_assoc_zval(class_info, "methods", class_methods); - add_assoc_zval(class_info, "properties", class_properties); - add_assoc_zval(cache, class_name, class_info); -} - -/* {{{ proto mixed twig_template_get_attributes(TwigTemplate template, mixed object, mixed item, array arguments, string type, boolean isDefinedTest, boolean ignoreStrictCheck) - A C implementation of TwigTemplate::getAttribute() */ -PHP_FUNCTION(twig_template_get_attributes) -{ - zval *template; - zval *object; - char *item; - int item_len; - zval zitem; - zval *arguments = NULL; - zval *ret = NULL; - char *type = NULL; - int type_len = 0; - zend_bool isDefinedTest = 0; - zend_bool ignoreStrictCheck = 0; - int free_ret = 0; - zval *tmp_self_cache; - - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ozs|asbb", &template, &object, &item, &item_len, &arguments, &type, &type_len, &isDefinedTest, &ignoreStrictCheck) == FAILURE) { - return; - } - - INIT_PZVAL(&zitem); - ZVAL_STRINGL(&zitem, item, item_len, 0); - - if (!type) { - type = "any"; - } - -/* - // array - if (Twig_TemplateInterface::METHOD_CALL !== $type) { - if ((is_array($object) && array_key_exists($item, $object)) - || ($object instanceof ArrayAccess && isset($object[$item])) - ) { - if ($isDefinedTest) { - return true; - } - - return $object[$item]; - } -*/ - if (strcmp("method", type) != 0) { -// printf("XXXmethod: %s\n", type); - if ((TWIG_ARRAY_KEY_EXISTS(object, item, item_len)) - || (TWIG_INSTANCE_OF(object, zend_ce_arrayaccess TSRMLS_CC) && TWIG_ISSET_ARRAYOBJECT_ELEMENT(object, &zitem TSRMLS_CC)) - ) { - zval *ret; - - if (isDefinedTest) { - RETURN_TRUE; - } - - ret = TWIG_GET_ARRAY_ELEMENT(object, item, item_len TSRMLS_CC); - RETVAL_ZVAL(ret, 1, 0); - if (free_ret) { - zval_ptr_dtor(&ret); - } - return; - } -/* - if (Twig_TemplateInterface::ARRAY_CALL === $type) { - if ($isDefinedTest) { - return false; - } - if ($ignoreStrictCheck || !$this->env->isStrictVariables()) { - return null; - } -*/ - if (strcmp("array", type) == 0) { - if (isDefinedTest) { - RETURN_FALSE; - } - if (ignoreStrictCheck || !TWIG_CALL_BOOLEAN(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "isStrictVariables" TSRMLS_CC)) { - return; - } -/* - 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 - } else { - throw new Twig_Error_Runtime(sprintf('Key "%s" for array with keys "%s" does not exist', $item, implode(', ', array_keys($object)))); - } - } - } -*/ - if (Z_TYPE_P(object) == IS_OBJECT) { - TWIG_THROW_EXCEPTION("Twig_Error_Runtime" TSRMLS_CC, "Key \"%s\" in object (with ArrayAccess) of type \"%s\" does not exist", item, TWIG_GET_CLASS_NAME(object TSRMLS_CC)); - } else { - TWIG_THROW_EXCEPTION("Twig_Error_Runtime" TSRMLS_CC, "Key \"%s\" for array with keys \"%s\" does not exist", item, TWIG_IMPLODE_ARRAY_KEYS(", ", object TSRMLS_CC)); - } - return; - } - } - -/* - if (!is_object($object)) { - if ($isDefinedTest) { - return false; - } -*/ - - if (Z_TYPE_P(object) != IS_OBJECT) { - if (isDefinedTest) { - RETURN_FALSE; - } -/* - if ($ignoreStrictCheck || !$this->env->isStrictVariables()) { - return null; - } - throw new Twig_Error_Runtime(sprintf('Item "%s" for "%s" does not exist', $item, implode(', ', array_keys($object)))); - } -*/ - if (ignoreStrictCheck || !TWIG_CALL_BOOLEAN(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "isStrictVariables" TSRMLS_CC)) { - RETURN_FALSE; - } - if (Z_TYPE_P(object) == IS_ARRAY) { - TWIG_THROW_EXCEPTION("Twig_Error_Runtime" TSRMLS_CC, "Item \"%s\" for \"Array\" does not exist", item); - } else { - Z_ADDREF_P(object); - convert_to_string_ex(&object); - TWIG_THROW_EXCEPTION("Twig_Error_Runtime" TSRMLS_CC, "Item \"%s\" for \"%s\" does not exist", item, Z_STRVAL_P(object)); - zval_ptr_dtor(&object); - } - return; - } -/* - // get some information about the object - $class = get_class($object); - if (!isset(self::$cache[$class])) { - $r = new ReflectionClass($class); - self::$cache[$class] = array('methods' => array(), 'properties' => array()); - foreach ($r->getMethods(ReflectionMethod::IS_PUBLIC) as $method) { - self::$cache[$class]['methods'][strtolower($method->getName())] = true; - } - - foreach ($r->getProperties(ReflectionProperty::IS_PUBLIC) as $property) { - self::$cache[$class]['properties'][$property->getName()] = true; - } - } -*/ - if (Z_TYPE_P(object) == IS_OBJECT) { - char *class_name = NULL; - - class_name = TWIG_GET_CLASS_NAME(object TSRMLS_CC); - tmp_self_cache = TWIG_GET_STATIC_PROPERTY(template, "cache" TSRMLS_CC); - - if (!TWIG_GET_ARRAY_ELEMENT(tmp_self_cache, class_name, strlen(class_name) TSRMLS_CC)) { - twig_add_class_to_cache(tmp_self_cache, object, class_name TSRMLS_CC); - } - efree(class_name); - } - -/* - // object property - if (Twig_TemplateInterface::METHOD_CALL !== $type) { - if (isset(self::$cache[$class]['properties'][$item]) - || isset($object->$item) || array_key_exists($item, $object) - ) { - if ($isDefinedTest) { - return true; - } - if ($this->env->hasExtension('sandbox')) { - $this->env->getExtension('sandbox')->checkPropertyAllowed($object, $item); - } - - return $object->$item; - } - } -*/ - if (strcmp("method", type) != 0) { - zval *tmp_class, *tmp_properties, *tmp_item; - char *class_name = NULL; - - class_name = TWIG_GET_CLASS_NAME(object TSRMLS_CC); - tmp_class = TWIG_GET_ARRAY_ELEMENT(tmp_self_cache, class_name, strlen(class_name) TSRMLS_CC); - tmp_properties = TWIG_GET_ARRAY_ELEMENT(tmp_class, "properties", strlen("properties") TSRMLS_CC); - tmp_item = TWIG_GET_ARRAY_ELEMENT(tmp_properties, item, item_len TSRMLS_CC); - - efree(class_name); - - if (tmp_item || TWIG_HAS_PROPERTY(object, &zitem TSRMLS_CC) || TWIG_ARRAY_KEY_EXISTS(object, item, item_len) // FIXME: Array key? is that array access here? - ) { - if (isDefinedTest) { - RETURN_TRUE; - } - if (TWIG_CALL_SB(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "hasExtension", "sandbox" TSRMLS_CC)) { - TWIG_CALL_ZZ(TWIG_CALL_S(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "getExtension", "sandbox" TSRMLS_CC), "checkPropertyAllowed", object, &zitem TSRMLS_CC); - } - if (EG(exception)) { - return; - } - - ret = TWIG_PROPERTY(object, &zitem TSRMLS_CC); - RETURN_ZVAL(ret, 1, 0); - } - } -/* - // object method - $lcItem = strtolower($item); - if (isset(self::$cache[$class]['methods'][$lcItem])) { - $method = $item; - } elseif (isset(self::$cache[$class]['methods']['get'.$lcItem])) { - $method = 'get'.$item; - } elseif (isset(self::$cache[$class]['methods']['is'.$lcItem])) { - $method = 'is'.$item; - } elseif (isset(self::$cache[$class]['methods']['__call'])) { - $method = $item; -*/ - { - char *lcItem = TWIG_STRTOLOWER(item, item_len); - int lcItem_length; - char *method = NULL; - char *tmp_method_name_get; - char *tmp_method_name_is; - zval *tmp_class, *tmp_methods; - char *class_name = NULL; - - class_name = TWIG_GET_CLASS_NAME(object TSRMLS_CC); - lcItem_length = strlen(lcItem); - tmp_method_name_get = emalloc(4 + lcItem_length); - tmp_method_name_is = emalloc(3 + lcItem_length); - - sprintf(tmp_method_name_get, "get%s", lcItem); - sprintf(tmp_method_name_is, "is%s", lcItem); - - tmp_class = TWIG_GET_ARRAY_ELEMENT(tmp_self_cache, class_name, strlen(class_name) TSRMLS_CC); - tmp_methods = TWIG_GET_ARRAY_ELEMENT(tmp_class, "methods", strlen("methods") TSRMLS_CC); - efree(class_name); - - if (TWIG_GET_ARRAY_ELEMENT(tmp_methods, lcItem, lcItem_length TSRMLS_CC)) { - method = item; - } else if (TWIG_GET_ARRAY_ELEMENT(tmp_methods, tmp_method_name_get, lcItem_length + 3 TSRMLS_CC)) { - method = tmp_method_name_get; - } else if (TWIG_GET_ARRAY_ELEMENT(tmp_methods, tmp_method_name_is, lcItem_length + 2 TSRMLS_CC)) { - method = tmp_method_name_is; - } else if (TWIG_GET_ARRAY_ELEMENT(tmp_methods, "__call", 6 TSRMLS_CC)) { - method = item; -/* - } else { - if ($isDefinedTest) { - return false; - } - if ($ignoreStrictCheck || !$this->env->isStrictVariables()) { - return null; - } - throw new Twig_Error_Runtime(sprintf('Method "%s" for object "%s" does not exist', $item, get_class($object))); - } - if ($isDefinedTest) { - return true; - } -*/ - } else { - if (isDefinedTest) { - RETURN_FALSE; - } - if (ignoreStrictCheck || !TWIG_CALL_BOOLEAN(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "isStrictVariables" TSRMLS_CC)) { - return; - } - TWIG_THROW_EXCEPTION("Twig_Error_Runtime" TSRMLS_CC, "Method \"%s\" for object \"%s\" does not exist", item, TWIG_GET_CLASS_NAME(object TSRMLS_CC)); - return; - } - if (isDefinedTest) { - efree(tmp_method_name_get); - efree(tmp_method_name_is); - efree(lcItem); - RETURN_TRUE; - } -/* - if ($this->env->hasExtension('sandbox')) { - $this->env->getExtension('sandbox')->checkMethodAllowed($object, $method); - } -*/ - if (TWIG_CALL_SB(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "hasExtension", "sandbox" TSRMLS_CC)) { - TWIG_CALL_ZZ(TWIG_CALL_S(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "getExtension", "sandbox" TSRMLS_CC), "checkMethodAllowed", object, &zitem TSRMLS_CC); - } - if (EG(exception)) { - return; - } -/* - $ret = call_user_func_array(array($object, $method), $arguments); -*/ - if (Z_TYPE_P(object) == IS_OBJECT) { - ret = TWIG_CALL_USER_FUNC_ARRAY(object, method, arguments TSRMLS_CC); - free_ret = 1; - } - efree(tmp_method_name_get); - efree(tmp_method_name_is); - efree(lcItem); - } -/* - if ($object instanceof Twig_TemplateInterface) { - return new Twig_Markup($ret, $this->env->getCharset()); - } -*/ - if (TWIG_INSTANCE_OF_USERLAND(object, "Twig_TemplateInterface" TSRMLS_CC)) { - zval *charset = TWIG_CALL_USER_FUNC_ARRAY(TWIG_PROPERTY_CHAR(template, "env" TSRMLS_CC), "getCharset", NULL TSRMLS_CC); - TWIG_NEW(return_value, "Twig_Markup", ret, charset TSRMLS_CC); - zval_ptr_dtor(&charset); - if (ret) { - zval_ptr_dtor(&ret); - } - return; - } -/* - return $ret; -*/ - if (ret) { - RETVAL_ZVAL(ret, 1, 0); - if (free_ret) { - zval_ptr_dtor(&ret); - } - } -} diff --git a/lib/twig/lib/Twig/Error.php b/lib/twig/lib/Twig/Error.php deleted file mode 100755 index b945706..0000000 --- a/lib/twig/lib/Twig/Error.php +++ /dev/null @@ -1,176 +0,0 @@ - - */ -class Twig_Error extends Exception -{ - protected $lineno; - protected $filename; - protected $rawMessage; - protected $previous; - - /** - * Constructor. - * - * @param string $message The error message - * @param integer $lineno The template line where the error occurred - * @param string $filename The template file name where the error occurred - * @param Exception $previous The previous exception - */ - public function __construct($message, $lineno = -1, $filename = null, Exception $previous = null) - { - if (-1 === $lineno || null === $filename) { - if ($trace = $this->getTemplateTrace()) { - if (-1 === $lineno) { - $lineno = $this->guessTemplateLine($trace); - } - - if (null === $filename) { - $filename = $trace['object']->getTemplateName(); - } - } - } - - $this->lineno = $lineno; - $this->filename = $filename; - $this->rawMessage = $message; - - $this->updateRepr(); - - if (version_compare(PHP_VERSION, '5.3.0', '<')) { - $this->previous = $previous; - parent::__construct($this->message); - } else { - parent::__construct($this->message, 0, $previous); - } - } - - /** - * Gets the raw message. - * - * @return string The raw message - */ - public function getRawMessage() - { - return $this->rawMessage; - } - - /** - * Gets the filename where the error occurred. - * - * @return string The filename - */ - public function getTemplateFile() - { - return $this->filename; - } - - /** - * Sets the filename where the error occurred. - * - * @param string $filename The filename - */ - public function setTemplateFile($filename) - { - $this->filename = $filename; - - $this->updateRepr(); - } - - /** - * Gets the template line where the error occurred. - * - * @return integer The template line - */ - public function getTemplateLine() - { - return $this->lineno; - } - - /** - * Sets the template line where the error occurred. - * - * @param integer $lineno The template line - */ - public function setTemplateLine($lineno) - { - $this->lineno = $lineno; - - $this->updateRepr(); - } - - /** - * For PHP < 5.3.0, provides access to the getPrevious() method. - * - * @param string $method The method name - * @param array $arguments The parameters to be passed to the method - * - * @return Exception The previous exception or null - */ - public function __call($method, $arguments) - { - if ('getprevious' == strtolower($method)) { - return $this->previous; - } - - throw new BadMethodCallException(sprintf('Method "Twig_Error::%s()" does not exist.', $method)); - } - - protected function updateRepr() - { - $this->message = $this->rawMessage; - - $dot = false; - if ('.' === substr($this->message, -1)) { - $this->message = substr($this->message, 0, -1); - $dot = true; - } - - if (null !== $this->filename) { - $this->message .= sprintf(' in %s', is_string($this->filename) ? '"'.$this->filename.'"' : json_encode($this->filename)); - } - - if ($this->lineno >= 0) { - $this->message .= sprintf(' at line %d', $this->lineno); - } - - if ($dot) { - $this->message .= '.'; - } - } - - protected function getTemplateTrace() - { - foreach (debug_backtrace() as $trace) { - if (isset($trace['object']) && $trace['object'] instanceof Twig_Template) { - return $trace; - } - } - } - - protected function guessTemplateLine($trace) - { - if (isset($trace['line'])) { - foreach ($trace['object']->getDebugInfo() as $codeLine => $templateLine) { - if ($codeLine <= $trace['line']) { - return $templateLine; - } - } - } - - return -1; - } -} diff --git a/lib/twig/lib/Twig/Error/Loader.php b/lib/twig/lib/Twig/Error/Loader.php deleted file mode 100755 index 418a776..0000000 --- a/lib/twig/lib/Twig/Error/Loader.php +++ /dev/null @@ -1,20 +0,0 @@ - - */ -class Twig_Error_Loader extends Twig_Error -{ -} diff --git a/lib/twig/lib/Twig/FilterInterface.php b/lib/twig/lib/Twig/FilterInterface.php deleted file mode 100755 index 866e932..0000000 --- a/lib/twig/lib/Twig/FilterInterface.php +++ /dev/null @@ -1,38 +0,0 @@ - - */ -interface Twig_FilterInterface -{ - /** - * Compiles a filter. - * - * @return string The PHP code for the filter - */ - function compile(); - - function needsEnvironment(); - - function needsContext(); - - function getSafe(Twig_Node $filterArgs); - - function getPreEscape(); - - function setArguments($arguments); - - function getArguments(); -} diff --git a/lib/twig/lib/Twig/Loader/Chain.php b/lib/twig/lib/Twig/Loader/Chain.php deleted file mode 100755 index 48dd8b8..0000000 --- a/lib/twig/lib/Twig/Loader/Chain.php +++ /dev/null @@ -1,100 +0,0 @@ - - */ -class Twig_Loader_Chain implements Twig_LoaderInterface -{ - 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; - } - - /** - * 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 - */ - public function getSource($name) - { - foreach ($this->loaders as $loader) { - try { - return $loader->getSource($name); - } catch (Twig_Error_Loader $e) { - } - } - - throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $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 - * - * @return string The cache key - */ - public function getCacheKey($name) - { - foreach ($this->loaders as $loader) { - try { - return $loader->getCacheKey($name); - } catch (Twig_Error_Loader $e) { - } - } - - throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name)); - } - - /** - * Returns true if the template is still fresh. - * - * @param string $name The template name - * @param timestamp $time The last modification time of the cached template - */ - public function isFresh($name, $time) - { - foreach ($this->loaders as $loader) { - try { - return $loader->isFresh($name, $time); - } catch (Twig_Error_Loader $e) { - } - } - - throw new Twig_Error_Loader(sprintf('Template "%s" is not defined.', $name)); - } -} diff --git a/lib/twig/lib/Twig/Loader/Filesystem.php b/lib/twig/lib/Twig/Loader/Filesystem.php deleted file mode 100755 index be348aa..0000000 --- a/lib/twig/lib/Twig/Loader/Filesystem.php +++ /dev/null @@ -1,152 +0,0 @@ - - */ -class Twig_Loader_Filesystem implements Twig_LoaderInterface -{ - protected $paths; - protected $cache; - - /** - * Constructor. - * - * @param string|array $paths A path or an array of paths where to look for templates - */ - public function __construct($paths) - { - $this->setPaths($paths); - } - - /** - * Returns the paths to the templates. - * - * @return array The array of paths where to look for templates - */ - public function getPaths() - { - return $this->paths; - } - - /** - * Sets the paths where templates are stored. - * - * @param string|array $paths A path or an array of paths where to look for templates - */ - public function setPaths($paths) - { - if (!is_array($paths)) { - $paths = array($paths); - } - - $this->paths = array(); - foreach ($paths as $path) { - $this->addPath($path); - } - } - - /** - * Adds a path where templates are stored. - * - * @param string $path A path where to look for templates - */ - public function addPath($path) - { - // 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[] = $path; - } - - /** - * 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 - */ - public function getSource($name) - { - return file_get_contents($this->findTemplate($name)); - } - - /** - * Gets the cache key to use for the cache for a given template name. - * - * @param string $name The name of the template to load - * - * @return string The cache key - */ - public function getCacheKey($name) - { - return $this->findTemplate($name); - } - - /** - * Returns true if the template is still fresh. - * - * @param string $name The template name - * @param timestamp $time The last modification time of the cached template - */ - public function isFresh($name, $time) - { - return filemtime($this->findTemplate($name)) < $time; - } - - protected function findTemplate($name) - { - // normalize name - $name = preg_replace('#/{2,}#', '/', strtr($name, '\\', '/')); - - if (isset($this->cache[$name])) { - return $this->cache[$name]; - } - - $this->validateName($name); - - foreach ($this->paths 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))); - } - - protected function validateName($name) - { - if (false !== strpos($name, "\0")) { - throw new Twig_Error_Loader('A template name cannot contain NUL bytes.'); - } - - $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/Node/Expression/Filter.php b/lib/twig/lib/Twig/Node/Expression/Filter.php deleted file mode 100755 index 8a0903a..0000000 --- a/lib/twig/lib/Twig/Node/Expression/Filter.php +++ /dev/null @@ -1,61 +0,0 @@ - $node, 'filter' => $filterName, 'arguments' => $arguments), array(), $lineno, $tag); - } - - public function compile(Twig_Compiler $compiler) - { - $name = $this->getNode('filter')->getAttribute('value'); - - if (false === $filter = $compiler->getEnvironment()->getFilter($name)) { - $message = sprintf('The filter "%s" does not exist', $name); - if ($alternatives = $compiler->getEnvironment()->computeAlternatives($name, array_keys($compiler->getEnvironment()->getFilters()))) { - $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives)); - } - - throw new Twig_Error_Syntax($message, $this->getLine()); - } - - $this->compileFilter($compiler, $filter); - } - - protected function compileFilter(Twig_Compiler $compiler, Twig_FilterInterface $filter) - { - $compiler - ->raw($filter->compile().'(') - ->raw($filter->needsEnvironment() ? '$this->env, ' : '') - ->raw($filter->needsContext() ? '$context, ' : '') - ; - - foreach ($filter->getArguments() as $argument) { - $compiler - ->string($argument) - ->raw(', ') - ; - } - - $compiler->subcompile($this->getNode('node')); - - foreach ($this->getNode('arguments') as $node) { - $compiler - ->raw(', ') - ->subcompile($node) - ; - } - - $compiler->raw(')'); - } -} diff --git a/lib/twig/lib/Twig/Node/Expression/Function.php b/lib/twig/lib/Twig/Node/Expression/Function.php deleted file mode 100755 index 9342bb1..0000000 --- a/lib/twig/lib/Twig/Node/Expression/Function.php +++ /dev/null @@ -1,66 +0,0 @@ - $arguments), array('name' => $name), $lineno); - } - - public function compile(Twig_Compiler $compiler) - { - $name = $this->getAttribute('name'); - - if (false === $function = $compiler->getEnvironment()->getFunction($name)) { - $message = sprintf('The function "%s" does not exist', $name); - if ($alternatives = $compiler->getEnvironment()->computeAlternatives($name, array_keys($compiler->getEnvironment()->getFunctions()))) { - $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives)); - } - - throw new Twig_Error_Syntax($message, $this->getLine()); - } - - $compiler->raw($function->compile().'('); - - $first = true; - - if ($function->needsEnvironment()) { - $compiler->raw('$this->env'); - $first = false; - } - - if ($function->needsContext()) { - if (!$first) { - $compiler->raw(', '); - } - $compiler->raw('$context'); - $first = false; - } - - foreach ($function->getArguments() as $argument) { - if (!$first) { - $compiler->raw(', '); - } - $compiler->string($argument); - $first = false; - } - - foreach ($this->getNode('arguments') as $node) { - if (!$first) { - $compiler->raw(', '); - } - $compiler->subcompile($node); - $first = false; - } - - $compiler->raw(')'); - } -} diff --git a/lib/twig/lib/Twig/Node/Expression/Test.php b/lib/twig/lib/Twig/Node/Expression/Test.php deleted file mode 100755 index 4e0b25e..0000000 --- a/lib/twig/lib/Twig/Node/Expression/Test.php +++ /dev/null @@ -1,54 +0,0 @@ - $node, 'arguments' => $arguments), array('name' => $name), $lineno); - } - - public function compile(Twig_Compiler $compiler) - { - $name = $this->getAttribute('name'); - $testMap = $compiler->getEnvironment()->getTests(); - if (!isset($testMap[$name])) { - $message = sprintf('The test "%s" does not exist', $name); - if ($alternatives = $compiler->getEnvironment()->computeAlternatives($name, array_keys($compiler->getEnvironment()->getTests()))) { - $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives)); - } - - throw new Twig_Error_Syntax($message, $this->getLine()); - } - - $name = $this->getAttribute('name'); - $node = $this->getNode('node'); - - $compiler - ->raw($testMap[$name]->compile().'(') - ->subcompile($node) - ; - - if (null !== $this->getNode('arguments')) { - $compiler->raw(', '); - - $max = count($this->getNode('arguments')) - 1; - foreach ($this->getNode('arguments') as $i => $arg) { - $compiler->subcompile($arg); - - if ($i != $max) { - $compiler->raw(', '); - } - } - } - - $compiler->raw(')'); - } -} diff --git a/lib/twig/lib/Twig/TokenParser/For.php b/lib/twig/lib/Twig/TokenParser/For.php deleted file mode 100755 index 2cbb580..0000000 --- a/lib/twig/lib/Twig/TokenParser/For.php +++ /dev/null @@ -1,89 +0,0 @@ - - *
      - * {% 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(); - $targets = $this->parser->getExpressionParser()->parseAssignmentExpression(); - $this->parser->getStream()->expect(Twig_Token::OPERATOR_TYPE, 'in'); - $seq = $this->parser->getExpressionParser()->parseExpression(); - - $ifexpr = null; - if ($this->parser->getStream()->test(Twig_Token::NAME_TYPE, 'if')) { - $this->parser->getStream()->next(); - $ifexpr = $this->parser->getExpressionParser()->parseExpression(); - } - - $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); - $body = $this->parser->subparse(array($this, 'decideForFork')); - if ($this->parser->getStream()->next()->getValue() == 'else') { - $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); - $else = $this->parser->subparse(array($this, 'decideForEnd'), true); - } else { - $else = null; - } - $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); - - 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()); - } - - 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'); - } - - /** - * Gets the tag name associated with this token parser. - * - * @return string The tag name - */ - public function getTag() - { - return 'for'; - } -} diff --git a/lib/twig/package.xml.tpl b/lib/twig/package.xml.tpl deleted file mode 100755 index f9a9b89..0000000 --- a/lib/twig/package.xml.tpl +++ /dev/null @@ -1,64 +0,0 @@ - - - Twig - pear.twig-project.org - Twig is a PHP template engine. - - Twig is a template language for PHP, released under the new BSD license - (code and documentation). - - Twig uses a syntax similar to the Django and Jinja template languages which - inspired the Twig runtime environment. - - - Fabien Potencier - fabpot - fabien.potencier@symfony-project.org - yes - - - Armin Ronacher - armin - armin.ronacher@active-4.com - no - - {{ date }} - - - {{ version }} - {{ api_version }} - - - {{ stability }} - {{ stability }} - - BSD Style - - - - - - - - - - -{{ files }} - - - - - - - - 5.2.4 - - - 1.4.0 - - - - - diff --git a/lib/twig/test/Twig/Tests/AutoloaderTest.php b/lib/twig/test/Twig/Tests/AutoloaderTest.php deleted file mode 100755 index c8b7999..0000000 --- a/lib/twig/test/Twig/Tests/AutoloaderTest.php +++ /dev/null @@ -1,21 +0,0 @@ -assertFalse(class_exists('FooBarFoo'), '->autoload() does not try to load classes that does not begin with Twig'); - - $autoloader = new Twig_Autoloader(); - $this->assertNull($autoloader->autoload('Foo'), '->autoload() returns false if it is not able to load a class'); - } -} diff --git a/lib/twig/test/Twig/Tests/CompilerTest.php b/lib/twig/test/Twig/Tests/CompilerTest.php deleted file mode 100755 index ebe79ae..0000000 --- a/lib/twig/test/Twig/Tests/CompilerTest.php +++ /dev/null @@ -1,33 +0,0 @@ -markTestSkipped('Your platform does not support locales.'); - } - - $required_locales = array('fr_FR.UTF-8', 'fr_FR.UTF8', 'fr_FR.utf-8', 'fr_FR.utf8', 'French_France.1252'); - if (false === setlocale(LC_ALL, $required_locales)) { - $this->markTestSkipped('Could not set any of required locales: ' . implode(", ", $required_locales)); - } - - $this->assertEquals('1.2', $compiler->repr(1.2)->getSource()); - $this->assertContains('fr', strtolower(setlocale(LC_NUMERIC, 0))); - - setlocale(LC_ALL, $locale); - } -} diff --git a/lib/twig/test/Twig/Tests/ErrorTest.php b/lib/twig/test/Twig/Tests/ErrorTest.php deleted file mode 100755 index a63b5fa..0000000 --- a/lib/twig/test/Twig/Tests/ErrorTest.php +++ /dev/null @@ -1,81 +0,0 @@ - "\n\n{{ foo.bar }}")); - $twig = new Twig_Environment($loader, array('strict_variables' => true, 'debug' => true, 'cache' => false)); - - $template = $twig->loadTemplate('index'); - - try { - $template->render(array()); - - $this->fail(); - } catch (Twig_Error_Runtime $e) { - $this->assertEquals('Variable "foo" does not exist in "index" at line 3', $e->getMessage()); - $this->assertEquals(3, $e->getTemplateLine()); - $this->assertEquals('index', $e->getTemplateFile()); - } - } - - public function testRenderWrapsExceptions() - { - $loader = new Twig_Loader_Array(array('index' => "\n\n\n{{ foo.bar }}")); - $twig = new Twig_Environment($loader, array('strict_variables' => true, 'debug' => true, 'cache' => false)); - - $template = $twig->loadTemplate('index'); - - try { - $template->render(array('foo' => new Twig_Tests_ErrorTest_Foo())); - - $this->fail(); - } catch (Twig_Error_Runtime $e) { - $this->assertEquals('An exception has been thrown during the rendering of a template ("Runtime error...") in "index" at line 4.', $e->getMessage()); - $this->assertEquals(4, $e->getTemplateLine()); - $this->assertEquals('index', $e->getTemplateFile()); - } - } - - public function testTwigExceptionAddsFileAndLineWhenMissingWithInheritance() - { - $loader = new Twig_Loader_Array(array( - 'index' => "{% extends 'base' %} - {% block content %} - {{ foo.bar }} - {% endblock %}", - 'base' => '{% block content %}{% endblock %}' - )); - $twig = new Twig_Environment($loader, array('strict_variables' => true, 'debug' => true, 'cache' => false)); - - $template = $twig->loadTemplate('index'); - - try { - $template->render(array()); - - $this->fail(); - } catch (Twig_Error_Runtime $e) { - $this->assertEquals('Variable "foo" does not exist in "index" at line 3', $e->getMessage()); - $this->assertEquals(3, $e->getTemplateLine()); - $this->assertEquals('index', $e->getTemplateFile()); - } - } -} - -class Twig_Tests_ErrorTest_Foo -{ - public function bar() - { - throw new Exception('Runtime error...'); - } -} diff --git a/lib/twig/test/Twig/Tests/ExpressionParserTest.php b/lib/twig/test/Twig/Tests/ExpressionParserTest.php deleted file mode 100755 index b3f300f..0000000 --- a/lib/twig/test/Twig/Tests/ExpressionParserTest.php +++ /dev/null @@ -1,217 +0,0 @@ - false, 'autoescape' => false)); - $parser = new Twig_Parser($env); - - $parser->parse($env->tokenize($template, 'index')); - } - - public function getFailingTestsForAssignment() - { - return array( - array('{% set false = "foo" %}'), - array('{% set true = "foo" %}'), - array('{% set none = "foo" %}'), - array('{% set 3 = "foo" %}'), - array('{% set 1 + 2 = "foo" %}'), - array('{% set "bar" = "foo" %}'), - array('{% set %}{% endset %}') - ); - } - - /** - * @dataProvider getTestsForArray - */ - public function testArrayExpression($template, $expected) - { - $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false)); - $stream = $env->tokenize($template, 'index'); - $parser = new Twig_Parser($env); - - $this->assertEquals($expected, $parser->parse($stream)->getNode('body')->getNode(0)->getNode('expr')); - } - - /** - * @expectedException Twig_Error_Syntax - * @dataProvider getFailingTestsForArray - */ - public function testArraySyntaxError($template) - { - $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false)); - $parser = new Twig_Parser($env); - - $parser->parse($env->tokenize($template, 'index')); - } - - public function getFailingTestsForArray() - { - return array( - array('{{ [1, "a": "b"] }}'), - array('{{ {"a": "b", 2} }}'), - ); - } - - public function getTestsForArray() - { - return array( - // simple array - array('{{ [1, 2] }}', new Twig_Node_Expression_Array(array( - new Twig_Node_Expression_Constant(0, 1), - new Twig_Node_Expression_Constant(1, 1), - - new Twig_Node_Expression_Constant(1, 1), - new Twig_Node_Expression_Constant(2, 1), - ), 1), - ), - - // array with trailing , - array('{{ [1, 2, ] }}', new Twig_Node_Expression_Array(array( - new Twig_Node_Expression_Constant(0, 1), - new Twig_Node_Expression_Constant(1, 1), - - new Twig_Node_Expression_Constant(1, 1), - new Twig_Node_Expression_Constant(2, 1), - ), 1), - ), - - // simple hash - array('{{ {"a": "b", "b": "c"} }}', new Twig_Node_Expression_Array(array( - new Twig_Node_Expression_Constant('a', 1), - new Twig_Node_Expression_Constant('b', 1), - - new Twig_Node_Expression_Constant('b', 1), - new Twig_Node_Expression_Constant('c', 1), - ), 1), - ), - - // hash with trailing , - array('{{ {"a": "b", "b": "c", } }}', new Twig_Node_Expression_Array(array( - new Twig_Node_Expression_Constant('a', 1), - new Twig_Node_Expression_Constant('b', 1), - - new Twig_Node_Expression_Constant('b', 1), - new Twig_Node_Expression_Constant('c', 1), - ), 1), - ), - - // hash in an array - array('{{ [1, {"a": "b", "b": "c"}] }}', new Twig_Node_Expression_Array(array( - new Twig_Node_Expression_Constant(0, 1), - new Twig_Node_Expression_Constant(1, 1), - - new Twig_Node_Expression_Constant(1, 1), - new Twig_Node_Expression_Array(array( - new Twig_Node_Expression_Constant('a', 1), - new Twig_Node_Expression_Constant('b', 1), - - new Twig_Node_Expression_Constant('b', 1), - new Twig_Node_Expression_Constant('c', 1), - ), 1), - ), 1), - ), - - // array in a hash - array('{{ {"a": [1, 2], "b": "c"} }}', new Twig_Node_Expression_Array(array( - new Twig_Node_Expression_Constant('a', 1), - new Twig_Node_Expression_Array(array( - new Twig_Node_Expression_Constant(0, 1), - new Twig_Node_Expression_Constant(1, 1), - - new Twig_Node_Expression_Constant(1, 1), - new Twig_Node_Expression_Constant(2, 1), - ), 1), - new Twig_Node_Expression_Constant('b', 1), - new Twig_Node_Expression_Constant('c', 1), - ), 1), - ), - ); - } - - /** - * @expectedException Twig_Error_Syntax - */ - public function testStringExpressionDoesNotConcatenateTwoConsecutiveStrings() - { - $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false, 'optimizations' => 0)); - $stream = $env->tokenize('{{ "a" "b" }}', 'index'); - $parser = new Twig_Parser($env); - - $parser->parse($stream); - } - - /** - * @dataProvider getTestsForString - */ - public function testStringExpression($template, $expected) - { - $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false, 'optimizations' => 0)); - $stream = $env->tokenize($template, 'index'); - $parser = new Twig_Parser($env); - - $this->assertEquals($expected, $parser->parse($stream)->getNode('body')->getNode(0)->getNode('expr')); - } - - public function getTestsForString() - { - return array( - array( - '{{ "foo" }}', new Twig_Node_Expression_Constant('foo', 1), - ), - array( - '{{ "foo #{bar}" }}', new Twig_Node_Expression_Binary_Concat( - new Twig_Node_Expression_Constant('foo ', 1), - new Twig_Node_Expression_Name('bar', 1), - 1 - ), - ), - array( - '{{ "foo #{bar} baz" }}', new Twig_Node_Expression_Binary_Concat( - new Twig_Node_Expression_Binary_Concat( - new Twig_Node_Expression_Constant('foo ', 1), - new Twig_Node_Expression_Name('bar', 1), - 1 - ), - new Twig_Node_Expression_Constant(' baz', 1), - 1 - ) - ), - - array( - '{{ "foo #{"foo #{bar} baz"} baz" }}', new Twig_Node_Expression_Binary_Concat( - new Twig_Node_Expression_Binary_Concat( - new Twig_Node_Expression_Constant('foo ', 1), - new Twig_Node_Expression_Binary_Concat( - new Twig_Node_Expression_Binary_Concat( - new Twig_Node_Expression_Constant('foo ', 1), - new Twig_Node_Expression_Name('bar', 1), - 1 - ), - new Twig_Node_Expression_Constant(' baz', 1), - 1 - ), - 1 - ), - new Twig_Node_Expression_Constant(' baz', 1), - 1 - ), - ), - ); - } -} diff --git a/lib/twig/test/Twig/Tests/Extension/CoreTest.php b/lib/twig/test/Twig/Tests/Extension/CoreTest.php deleted file mode 100755 index 89a7750..0000000 --- a/lib/twig/test/Twig/Tests/Extension/CoreTest.php +++ /dev/null @@ -1,114 +0,0 @@ -assertTrue(in_array(twig_random(new Twig_Environment(), $value), $expectedInArray, true)); // assertContains() would not consider the type - } - } - - public function getRandomFunctionTestData() - { - return array( - array( // array - array('apple', 'orange', 'citrus'), - array('apple', 'orange', 'citrus'), - ), - array( // Traversable - new ArrayObject(array('apple', 'orange', 'citrus')), - array('apple', 'orange', 'citrus'), - ), - array( // unicode string - 'Ä€é', - array('Ä', '€', 'é'), - ), - array( // numeric but string - '123', - array('1', '2', '3'), - ), - array( // integer - 5, - range(0, 5, 1), - ), - array( // float - 5.9, - range(0, 5, 1), - ), - array( // negative - -2, - array(0, -1, -2), - ), - ); - } - - public function testRandomFunctionWithoutParameter() - { - $max = mt_getrandmax(); - - for ($i = 0; $i < 100; $i++) { - $val = twig_random(new Twig_Environment()); - $this->assertTrue(is_int($val) && $val >= 0 && $val <= $max); - } - } - - public function testRandomFunctionReturnsAsIs() - { - $this->assertSame('', twig_random(new Twig_Environment(), '')); - - $instance = new stdClass(); - $this->assertSame($instance, twig_random(new Twig_Environment(), $instance)); - } - - /** - * @expectedException Twig_Error_Runtime - */ - public function testRandomFunctionOfEmptyArrayThrowsException() - { - twig_random(new Twig_Environment(), array()); - } - - public function testRandomFunctionOnNonUTF8String() - { - if (!function_exists('iconv') && !function_exists('mb_convert_encoding')) { - $this->markTestSkipped('needs iconv or mbstring'); - } - - $twig = new Twig_Environment(); - $twig->setCharset('ISO-8859-1'); - - $text = twig_convert_encoding('Äé', 'ISO-8859-1', 'UTF-8'); - for ($i = 0; $i < 30; $i++) { - $rand = twig_random($twig, $text); - $this->assertTrue(in_array(twig_convert_encoding($rand, 'UTF-8', 'ISO-8859-1'), array('Ä', 'é'), true)); - } - } - - public function testReverseFilterOnNonUTF8String() - { - if (!function_exists('iconv') && !function_exists('mb_convert_encoding')) { - $this->markTestSkipped('needs iconv or mbstring'); - } - - $twig = new Twig_Environment(); - $twig->setCharset('ISO-8859-1'); - - $input = twig_convert_encoding('Äé', 'ISO-8859-1', 'UTF-8'); - $output = twig_convert_encoding(twig_reverse_filter($twig, $input), 'UTF-8', 'ISO-8859-1'); - - $this->assertEquals($output, 'éÄ'); - } -} diff --git a/lib/twig/test/Twig/Tests/Extension/SandboxTest.php b/lib/twig/test/Twig/Tests/Extension/SandboxTest.php deleted file mode 100755 index 0768c65..0000000 --- a/lib/twig/test/Twig/Tests/Extension/SandboxTest.php +++ /dev/null @@ -1,209 +0,0 @@ - 'Fabien', - 'obj' => new FooObject(), - 'arr' => array('obj' => new FooObject()), - ); - - self::$templates = array( - '1_basic1' => '{{ obj.foo }}', - '1_basic2' => '{{ name|upper }}', - '1_basic3' => '{% if name %}foo{% endif %}', - '1_basic4' => '{{ obj.bar }}', - '1_basic5' => '{{ obj }}', - '1_basic6' => '{{ arr.obj }}', - '1_basic7' => '{{ cycle(["foo","bar"], 1) }}', - '1_basic8' => '{{ obj.getfoobar }}{{ obj.getFooBar }}', - '1_basic' => '{% if obj.foo %}{{ obj.foo|upper }}{% endif %}', - '1_layout' => '{% block content %}{% endblock %}', - '1_child' => '{% extends "1_layout" %}{% block content %}{{ "a"|json_encode }}{% endblock %}', - ); - } - - /** - * @expectedException Twig_Sandbox_SecurityError - * @expectedExceptionMessage Filter "json_encode" is not allowed in "1_child". - */ - public function testSandboxWithInheritance() - { - $twig = $this->getEnvironment(true, array(), self::$templates, array('block')); - $twig->loadTemplate('1_child')->render(array()); - } - - public function testSandboxGloballySet() - { - $twig = $this->getEnvironment(false, array(), self::$templates); - $this->assertEquals('FOO', $twig->loadTemplate('1_basic')->render(self::$params), 'Sandbox does nothing if it is disabled globally'); - - $twig = $this->getEnvironment(true, array(), self::$templates); - try { - $twig->loadTemplate('1_basic1')->render(self::$params); - $this->fail('Sandbox throws a SecurityError exception if an unallowed method is called'); - } catch (Twig_Sandbox_SecurityError $e) { - } - - $twig = $this->getEnvironment(true, array(), self::$templates); - try { - $twig->loadTemplate('1_basic2')->render(self::$params); - $this->fail('Sandbox throws a SecurityError exception if an unallowed filter is called'); - } catch (Twig_Sandbox_SecurityError $e) { - } - - $twig = $this->getEnvironment(true, array(), self::$templates); - try { - $twig->loadTemplate('1_basic3')->render(self::$params); - $this->fail('Sandbox throws a SecurityError exception if an unallowed tag is used in the template'); - } catch (Twig_Sandbox_SecurityError $e) { - } - - $twig = $this->getEnvironment(true, array(), self::$templates); - try { - $twig->loadTemplate('1_basic4')->render(self::$params); - $this->fail('Sandbox throws a SecurityError exception if an unallowed property is called in the template'); - } catch (Twig_Sandbox_SecurityError $e) { - } - - $twig = $this->getEnvironment(true, array(), self::$templates); - try { - $twig->loadTemplate('1_basic5')->render(self::$params); - $this->fail('Sandbox throws a SecurityError exception if an unallowed method (__toString()) is called in the template'); - } catch (Twig_Sandbox_SecurityError $e) { - } - - $twig = $this->getEnvironment(true, array(), self::$templates); - try { - $twig->loadTemplate('1_basic6')->render(self::$params); - $this->fail('Sandbox throws a SecurityError exception if an unallowed method (__toString()) is called in the template'); - } catch (Twig_Sandbox_SecurityError $e) { - } - - $twig = $this->getEnvironment(true, array(), self::$templates); - try { - $twig->loadTemplate('1_basic7')->render(self::$params); - $this->fail('Sandbox throws a SecurityError exception if an unallowed function is called in the template'); - } catch (Twig_Sandbox_SecurityError $e) { - } - - $twig = $this->getEnvironment(true, array(), self::$templates, array(), array(), array('FooObject' => 'foo')); - FooObject::reset(); - $this->assertEquals('foo', $twig->loadTemplate('1_basic1')->render(self::$params), 'Sandbox allow some methods'); - $this->assertEquals(1, FooObject::$called['foo'], 'Sandbox only calls method once'); - - $twig = $this->getEnvironment(true, array(), self::$templates, array(), array(), array('FooObject' => '__toString')); - FooObject::reset(); - $this->assertEquals('foo', $twig->loadTemplate('1_basic5')->render(self::$params), 'Sandbox allow some methods'); - $this->assertEquals(1, FooObject::$called['__toString'], 'Sandbox only calls method once'); - - $twig = $this->getEnvironment(true, array(), self::$templates, array(), array('upper')); - $this->assertEquals('FABIEN', $twig->loadTemplate('1_basic2')->render(self::$params), 'Sandbox allow some filters'); - - $twig = $this->getEnvironment(true, array(), self::$templates, array('if')); - $this->assertEquals('foo', $twig->loadTemplate('1_basic3')->render(self::$params), 'Sandbox allow some tags'); - - $twig = $this->getEnvironment(true, array(), self::$templates, array(), array(), array(), array('FooObject' => 'bar')); - $this->assertEquals('bar', $twig->loadTemplate('1_basic4')->render(self::$params), 'Sandbox allow some properties'); - - $twig = $this->getEnvironment(true, array(), self::$templates, array(), array(), array(), array(), array('cycle')); - $this->assertEquals('bar', $twig->loadTemplate('1_basic7')->render(self::$params), 'Sandbox allow some functions'); - - foreach (array('getfoobar', 'getFoobar', 'getFooBar') as $name) { - $twig = $this->getEnvironment(true, array(), self::$templates, array(), array(), array('FooObject' => $name)); - FooObject::reset(); - $this->assertEquals('foobarfoobar', $twig->loadTemplate('1_basic8')->render(self::$params), 'Sandbox allow methods in a case-insensitive way'); - $this->assertEquals(2, FooObject::$called['getFooBar'], 'Sandbox only calls method once'); - } - } - - public function testSandboxLocallySetForAnInclude() - { - self::$templates = array( - '2_basic' => '{{ obj.foo }}{% include "2_included" %}{{ obj.foo }}', - '2_included' => '{% if obj.foo %}{{ obj.foo|upper }}{% endif %}', - ); - - $twig = $this->getEnvironment(false, array(), self::$templates); - $this->assertEquals('fooFOOfoo', $twig->loadTemplate('2_basic')->render(self::$params), 'Sandbox does nothing if disabled globally and sandboxed not used for the include'); - - self::$templates = array( - '3_basic' => '{{ obj.foo }}{% sandbox %}{% include "3_included" %}{% endsandbox %}{{ obj.foo }}', - '3_included' => '{% if obj.foo %}{{ obj.foo|upper }}{% endif %}', - ); - - $twig = $this->getEnvironment(true, array(), self::$templates); - try { - $twig->loadTemplate('3_basic')->render(self::$params); - $this->fail('Sandbox throws a SecurityError exception when the included file is sandboxed'); - } catch (Twig_Sandbox_SecurityError $e) { - } - } - - public function testMacrosInASandbox() - { - $twig = $this->getEnvironment(true, array('autoescape' => true), array('index' => <<{{ text }}

    {% endmacro %} -{{ _self.test('username') }} -EOF - ), array('macro'), array('escape')); - - $this->assertEquals('

    username

    ', $twig->loadTemplate('index')->render(array())); - } - - protected function getEnvironment($sandboxed, $options, $templates, $tags = array(), $filters = array(), $methods = array(), $properties = array(), $functions = array()) - { - $loader = new Twig_Loader_Array($templates); - $twig = new Twig_Environment($loader, array_merge(array('debug' => true, 'cache' => false, 'autoescape' => false), $options)); - $policy = new Twig_Sandbox_SecurityPolicy($tags, $filters, $methods, $properties, $functions); - $twig->addExtension(new Twig_Extension_Sandbox($policy, $sandboxed)); - - return $twig; - } -} - -class FooObject -{ - static public $called = array('__toString' => 0, 'foo' => 0, 'getFooBar' => 0); - - public $bar = 'bar'; - - static public function reset() - { - self::$called = array('__toString' => 0, 'foo' => 0, 'getFooBar' => 0); - } - - public function __toString() - { - ++self::$called['__toString']; - - return 'foo'; - } - - public function foo() - { - ++self::$called['foo']; - - return 'foo'; - } - - public function getFooBar() - { - ++self::$called['getFooBar']; - - return 'foobar'; - } -} diff --git a/lib/twig/test/Twig/Tests/FileCachingTest.php b/lib/twig/test/Twig/Tests/FileCachingTest.php deleted file mode 100755 index 2c77c06..0000000 --- a/lib/twig/test/Twig/Tests/FileCachingTest.php +++ /dev/null @@ -1,70 +0,0 @@ -tmpDir = sys_get_temp_dir().'/TwigTests'; - if (!file_exists($this->tmpDir)) { - @mkdir($this->tmpDir, 0777, true);; - } - - if (!is_writable($this->tmpDir)) { - $this->markTestSkipped(sprintf('Unable to run the tests as "%s" is not writable.', $this->tmpDir)); - } - - $this->env = new Twig_Environment(new Twig_Loader_String(), array('cache' => $this->tmpDir)); - } - - public function tearDown() - { - if ($this->fileName) { - unlink($this->fileName); - } - - $this->removeDir($this->tmpDir); - } - - public function testWritingCacheFiles() - { - $name = 'This is just text.'; - $template = $this->env->loadTemplate($name); - $cacheFileName = $this->env->getCacheFilename($name); - - $this->assertTrue(file_exists($cacheFileName), 'Cache file does not exist.'); - $this->fileName = $cacheFileName; - } - - public function testClearingCacheFiles() - { - $name = 'I will be deleted.'; - $template = $this->env->loadTemplate($name); - $cacheFileName = $this->env->getCacheFilename($name); - - $this->assertTrue(file_exists($cacheFileName), 'Cache file does not exist.'); - $this->env->clearCacheFiles(); - $this->assertFalse(file_exists($cacheFileName), 'Cache file was not cleared.'); - } - - private function removeDir($target) - { - $fp = opendir($target); - while (false !== $file = readdir($fp)) { - if (in_array($file, array('.', '..'))) { - continue; - } - - if (is_dir($target.'/'.$file)) { - self::removeDir($target.'/'.$file); - } else { - unlink($target.'/'.$file); - } - } - closedir($fp); - rmdir($target); - } -} diff --git a/lib/twig/test/Twig/Tests/Fixtures/exceptions/unclosed_tag.test b/lib/twig/test/Twig/Tests/Fixtures/exceptions/unclosed_tag.test deleted file mode 100755 index 02245e9..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/exceptions/unclosed_tag.test +++ /dev/null @@ -1,20 +0,0 @@ ---TEST-- -Exception for an unclosed tag ---TEMPLATE-- -{% block foo %} - {% if foo %} - - - - - {% for i in fo %} - - - - {% endfor %} - - - -{% endblock %} ---EXCEPTION-- -Twig_Error_Syntax: Unexpected tag name "endblock" (expecting closing tag for the "if" tag defined near line 4) in "index.twig" at line 16 diff --git a/lib/twig/test/Twig/Tests/Fixtures/expressions/array.test b/lib/twig/test/Twig/Tests/Fixtures/expressions/array.test deleted file mode 100755 index c69b119..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/expressions/array.test +++ /dev/null @@ -1,61 +0,0 @@ ---TEST-- -Twig supports array notation ---TEMPLATE-- -{# empty array #} -{{ []|join(',') }} - -{{ [1, 2]|join(',') }} -{{ ['foo', "bar"]|join(',') }} -{{ {0: 1, 'foo': 'bar'}|join(',') }} -{{ {0: 1, 'foo': 'bar'}|keys|join(',') }} - -{{ {0: 1, foo: 'bar'}|join(',') }} -{{ {0: 1, foo: 'bar'}|keys|join(',') }} - -{# nested arrays #} -{% set a = [1, 2, [1, 2], {'foo': {'foo': 'bar'}}] %} -{{ a[2]|join(',') }} -{{ a[3]["foo"]|join(',') }} - -{# works even if [] is used inside the array #} -{{ [foo[bar]]|join(',') }} - -{# elements can be any expression #} -{{ ['foo'|upper, bar|upper, bar == foo]|join(',') }} - -{# arrays can have a trailing , like in PHP #} -{{ - [ - 1, - 2, - ]|join(',') -}} - -{# keys can be any expression #} -{% set a = 1 %} -{% set b = "foo" %} -{% set ary = { (a): 'a', (b): 'b', 'c': 'c', (a ~ b): 'd' } %} -{{ ary|keys|join(',') }} -{{ ary|join(',') }} ---DATA-- -return array('bar' => 'bar', 'foo' => array('bar' => 'bar')) ---EXPECT-- -1,2 -foo,bar -1,bar -0,foo - -1,bar -0,foo - -1,2 -bar - -bar - -FOO,BAR, - -1,2 - -1,foo,c,1foo -a,b,c,d diff --git a/lib/twig/test/Twig/Tests/Fixtures/expressions/array_call.test b/lib/twig/test/Twig/Tests/Fixtures/expressions/array_call.test deleted file mode 100755 index f3df328..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/expressions/array_call.test +++ /dev/null @@ -1,14 +0,0 @@ ---TEST-- -Twig supports method calls ---TEMPLATE-- -{{ items.foo }} -{{ items['foo'] }} -{{ items[foo] }} -{{ items[items[foo]] }} ---DATA-- -return array('foo' => 'bar', 'items' => array('foo' => 'bar', 'bar' => 'foo')) ---EXPECT-- -bar -bar -foo -bar diff --git a/lib/twig/test/Twig/Tests/Fixtures/expressions/binary.test b/lib/twig/test/Twig/Tests/Fixtures/expressions/binary.test deleted file mode 100755 index f5e6845..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/expressions/binary.test +++ /dev/null @@ -1,46 +0,0 @@ ---TEST-- -Twig supports binary operations (+, -, *, /, ~, %, and, or) ---TEMPLATE-- -{{ 1 + 1 }} -{{ 2 - 1 }} -{{ 2 * 2 }} -{{ 2 / 2 }} -{{ 3 % 2 }} -{{ 1 and 1 }} -{{ 1 and 0 }} -{{ 0 and 1 }} -{{ 0 and 0 }} -{{ 1 or 1 }} -{{ 1 or 0 }} -{{ 0 or 1 }} -{{ 0 or 0 }} -{{ 0 or 1 and 0 }} -{{ 1 or 0 and 1 }} -{{ "foo" ~ "bar" }} -{{ foo ~ "bar" }} -{{ "foo" ~ bar }} -{{ foo ~ bar }} -{{ 20 // 7 }} ---DATA-- -return array('foo' => 'bar', 'bar' => 'foo') ---EXPECT-- -2 -1 -4 -1 -1 -1 - - - -1 -1 -1 - - -1 -foobar -barbar -foofoo -barfoo -2 diff --git a/lib/twig/test/Twig/Tests/Fixtures/expressions/comparison.test b/lib/twig/test/Twig/Tests/Fixtures/expressions/comparison.test deleted file mode 100755 index 726b850..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/expressions/comparison.test +++ /dev/null @@ -1,14 +0,0 @@ ---TEST-- -Twig supports comparison operators (==, !=, <, >, >=, <=) ---TEMPLATE-- -{{ 1 > 2 }}/{{ 1 > 1 }}/{{ 1 >= 2 }}/{{ 1 >= 1 }} -{{ 1 < 2 }}/{{ 1 < 1 }}/{{ 1 <= 2 }}/{{ 1 <= 1 }} -{{ 1 == 1 }}/{{ 1 == 2 }} -{{ 1 != 1 }}/{{ 1 != 2 }} ---DATA-- -return array() ---EXPECT-- -///1 -1//1/1 -1/ -/1 diff --git a/lib/twig/test/Twig/Tests/Fixtures/expressions/dotdot.test b/lib/twig/test/Twig/Tests/Fixtures/expressions/dotdot.test deleted file mode 100755 index 9cd0676..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/expressions/dotdot.test +++ /dev/null @@ -1,20 +0,0 @@ ---TEST-- -Twig supports the .. operator ---TEMPLATE-- -{% for i in 0..10 %}{{ i }} {% endfor %} - -{% for letter in 'a'..'z' %}{{ letter }} {% endfor %} - -{% for letter in 'a'|upper..'z'|upper %}{{ letter }} {% endfor %} - -{% for i in foo[0]..foo[1] %}{{ i }} {% endfor %} - -{% for i in 0 + 1 .. 10 - 1 %}{{ i }} {% endfor %} ---DATA-- -return array('foo' => array(1, 10)) ---EXPECT-- -0 1 2 3 4 5 6 7 8 9 10 -a b c d e f g h i j k l m n o p q r s t u v w x y z -A B C D E F G H I J K L M N O P Q R S T U V W X Y Z -1 2 3 4 5 6 7 8 9 10 -1 2 3 4 5 6 7 8 9 diff --git a/lib/twig/test/Twig/Tests/Fixtures/expressions/grouping.test b/lib/twig/test/Twig/Tests/Fixtures/expressions/grouping.test deleted file mode 100755 index 79f8e0b..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/expressions/grouping.test +++ /dev/null @@ -1,8 +0,0 @@ ---TEST-- -Twig supports grouping of expressions ---TEMPLATE-- -{{ (2 + 2) / 2 }} ---DATA-- -return array() ---EXPECT-- -2 diff --git a/lib/twig/test/Twig/Tests/Fixtures/expressions/literals.test b/lib/twig/test/Twig/Tests/Fixtures/expressions/literals.test deleted file mode 100755 index 7ae3bae..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/expressions/literals.test +++ /dev/null @@ -1,22 +0,0 @@ ---TEST-- -Twig supports literals ---TEMPLATE-- -1 {{ true }} -2 {{ TRUE }} -3 {{ false }} -4 {{ FALSE }} -5 {{ none }} -6 {{ NONE }} -7 {{ null }} -8 {{ NULL }} ---DATA-- -return array() ---EXPECT-- -1 1 -2 1 -3 -4 -5 -6 -7 -8 diff --git a/lib/twig/test/Twig/Tests/Fixtures/expressions/magic_call.test b/lib/twig/test/Twig/Tests/Fixtures/expressions/magic_call.test deleted file mode 100755 index 159db96..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/expressions/magic_call.test +++ /dev/null @@ -1,27 +0,0 @@ ---TEST-- -Twig supports __call() for attributes ---TEMPLATE-- -{{ foo.foo }} -{{ foo.bar }} ---DATA-- -class TestClassForMagicCallAttributes -{ - public function getBar() - { - return 'bar_from_getbar'; - } - - public function __call($method, $arguments) - { - if ('foo' === $method) - { - return 'foo_from_call'; - } - - return false; - } -} -return array('foo' => new TestClassForMagicCallAttributes()) ---EXPECT-- -foo_from_call -bar_from_getbar diff --git a/lib/twig/test/Twig/Tests/Fixtures/expressions/method_call.test b/lib/twig/test/Twig/Tests/Fixtures/expressions/method_call.test deleted file mode 100755 index 9d84a4c..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/expressions/method_call.test +++ /dev/null @@ -1,28 +0,0 @@ ---TEST-- -Twig supports method calls ---TEMPLATE-- -{{ items.foo.foo }} -{{ items.foo.getFoo() }} -{{ items.foo.bar }} -{{ items.foo['bar'] }} -{{ items.foo.bar('a', 43) }} -{{ items.foo.bar(foo) }} -{{ items.foo.self.foo() }} -{{ items.foo.is }} -{{ items.foo.in }} -{{ items.foo.not }} ---DATA-- -return array('foo' => 'bar', 'items' => array('foo' => new Foo(), 'bar' => 'foo')) ---CONFIG-- -return array('strict_variables' => false) ---EXPECT-- -foo -foo -bar - -bar_a-43 -bar_bar -foo -is -in -not diff --git a/lib/twig/test/Twig/Tests/Fixtures/expressions/postfix.test b/lib/twig/test/Twig/Tests/Fixtures/expressions/postfix.test deleted file mode 100755 index db047c0..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/expressions/postfix.test +++ /dev/null @@ -1,21 +0,0 @@ ---TEST-- -Twig parses postfix expressions ---TEMPLATE-- - -{% macro foo() %}foo{% endmacro %} - -{{ 'a' }} -{{ 'a'|upper }} -{{ ('a')|upper }} -{{ -1|upper }} -{{ _self.foo() }} -{{ (_self).foo() }} ---DATA-- -return array(); ---EXPECT-- -a -A -A --1 -foo -foo diff --git a/lib/twig/test/Twig/Tests/Fixtures/expressions/strings.test b/lib/twig/test/Twig/Tests/Fixtures/expressions/strings.test deleted file mode 100755 index a911661..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/expressions/strings.test +++ /dev/null @@ -1,10 +0,0 @@ ---TEST-- -Twig supports string interpolation ---TEMPLATE-- -{{ "foo #{"foo #{bar} baz"} baz" }} -{{ "foo #{bar}#{bar} baz" }} ---DATA-- -return array('bar' => 'BAR'); ---EXPECT-- -foo foo BAR baz baz -foo BARBAR baz diff --git a/lib/twig/test/Twig/Tests/Fixtures/expressions/ternary_operator.test b/lib/twig/test/Twig/Tests/Fixtures/expressions/ternary_operator.test deleted file mode 100755 index 0e6fa96..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/expressions/ternary_operator.test +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -Twig supports the ternary operator ---TEMPLATE-- -{{ 1 ? 'YES' : 'NO' }} -{{ 0 ? 'YES' : 'NO' }} -{{ 0 ? 'YES' : (1 ? 'YES1' : 'NO1') }} -{{ 0 ? 'YES' : (0 ? 'YES1' : 'NO1') }} -{{ 1 == 1 ? 'foo
    ':'' }} -{{ foo ~ (bar ? ('-' ~ bar) : '') }} ---DATA-- -return array('foo' => 'foo', 'bar' => 'bar') ---EXPECT-- -YES -NO -YES1 -NO1 -foo
    -foo-bar diff --git a/lib/twig/test/Twig/Tests/Fixtures/expressions/unary.test b/lib/twig/test/Twig/Tests/Fixtures/expressions/unary.test deleted file mode 100755 index b79219a..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/expressions/unary.test +++ /dev/null @@ -1,12 +0,0 @@ ---TEST-- -Twig supports unary operators (not, -, +) ---TEMPLATE-- -{{ not 1 }}/{{ not 0 }} -{{ +1 + 1 }}/{{ -1 - 1 }} -{{ not (false or true) }} ---DATA-- -return array() ---EXPECT-- -/1 -2/-2 - diff --git a/lib/twig/test/Twig/Tests/Fixtures/expressions/unary_precedence.test b/lib/twig/test/Twig/Tests/Fixtures/expressions/unary_precedence.test deleted file mode 100755 index cc6eef8..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/expressions/unary_precedence.test +++ /dev/null @@ -1,14 +0,0 @@ ---TEST-- -Twig unary operators precedence ---TEMPLATE-- -{{ -1 - 1 }} -{{ -1 - -1 }} -{{ -1 * -1 }} -{{ 4 / -1 * 5 }} ---DATA-- -return array() ---EXPECT-- --2 -0 -1 --20 diff --git a/lib/twig/test/Twig/Tests/Fixtures/filters/convert_encoding.test b/lib/twig/test/Twig/Tests/Fixtures/filters/convert_encoding.test deleted file mode 100755 index 380b04b..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/filters/convert_encoding.test +++ /dev/null @@ -1,10 +0,0 @@ ---TEST-- -"convert_encoding" filter ---CONDITION-- -function_exists('iconv') || function_exists('mb_convert_encoding') ---TEMPLATE-- -{{ "愛していますか?"|convert_encoding('ISO-2022-JP', 'UTF-8')|convert_encoding('UTF-8', 'ISO-2022-JP') }} ---DATA-- -return array() ---EXPECT-- -愛していますか? diff --git a/lib/twig/test/Twig/Tests/Fixtures/filters/date.test b/lib/twig/test/Twig/Tests/Fixtures/filters/date.test deleted file mode 100755 index edfe596..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/filters/date.test +++ /dev/null @@ -1,37 +0,0 @@ ---TEST-- -"date" filter ---TEMPLATE-- -{{ date1|date }} -{{ date1|date('d/m/Y') }} -{{ date1|date('d/m/Y H:i:s', 'Europe/Paris') }} -{{ date2|date }} -{{ date2|date('d/m/Y') }} -{{ date2|date('d/m/Y H:i:s', 'Europe/Paris') }} -{{ date3|date }} -{{ date3|date('d/m/Y') }} -{{ date4|date }} -{{ date4|date('d/m/Y') }} -{{ date5|date }} -{{ date5|date('d/m/Y') }} ---DATA-- -date_default_timezone_set('UTC'); -return array( - 'date1' => mktime(13, 45, 0, 10, 4, 2010), - 'date2' => new DateTime('2010-10-04 13:45'), - 'date3' => '2010-10-04 13:45', - 'date4' => 1286199900, - 'date5' => -86410, -) ---EXPECT-- -October 4, 2010 13:45 -04/10/2010 -04/10/2010 15:45:00 -October 4, 2010 13:45 -04/10/2010 -04/10/2010 15:45:00 -October 4, 2010 13:45 -04/10/2010 -October 4, 2010 13:45 -04/10/2010 -December 30, 1969 23:59 -30/12/1969 diff --git a/lib/twig/test/Twig/Tests/Fixtures/filters/date_default_format.test b/lib/twig/test/Twig/Tests/Fixtures/filters/date_default_format.test deleted file mode 100755 index 11a1ef4..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/filters/date_default_format.test +++ /dev/null @@ -1,14 +0,0 @@ ---TEST-- -"date" filter ---TEMPLATE-- -{{ date1|date }} -{{ date1|date('d/m/Y') }} ---DATA-- -date_default_timezone_set('UTC'); -$twig->getExtension('core')->setDateFormat('Y-m-d', '%d days %h hours'); -return array( - 'date1' => mktime(13, 45, 0, 10, 4, 2010), -) ---EXPECT-- -2010-10-04 -04/10/2010 diff --git a/lib/twig/test/Twig/Tests/Fixtures/filters/date_default_format_interval.test b/lib/twig/test/Twig/Tests/Fixtures/filters/date_default_format_interval.test deleted file mode 100755 index e6d3707..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/filters/date_default_format_interval.test +++ /dev/null @@ -1,16 +0,0 @@ ---TEST-- -"date" filter (interval support as of PHP 5.3) ---CONDITION-- -version_compare(phpversion(), '5.3.0', '>=') ---TEMPLATE-- -{{ date2|date }} -{{ date2|date('%d days') }} ---DATA-- -date_default_timezone_set('UTC'); -$twig->getExtension('core')->setDateFormat('Y-m-d', '%d days %h hours'); -return array( - 'date2' => new DateInterval('P2D'), -) ---EXPECT-- -2 days 0 hours -2 days diff --git a/lib/twig/test/Twig/Tests/Fixtures/filters/date_interval.test b/lib/twig/test/Twig/Tests/Fixtures/filters/date_interval.test deleted file mode 100755 index 2d5adc1..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/filters/date_interval.test +++ /dev/null @@ -1,16 +0,0 @@ ---TEST-- -"date" filter (interval support as of PHP 5.3) ---CONDITION-- -version_compare(phpversion(), '5.3.0', '>=') ---TEMPLATE-- -{{ date6|date }} -{{ date6|date('%d days %h hours') }} ---DATA-- -date_default_timezone_set('UTC'); -return array( - 'date5' => -86410, - 'date6' => new DateInterval('P2D'), -) ---EXPECT-- -2 days -2 days 0 hours diff --git a/lib/twig/test/Twig/Tests/Fixtures/filters/default.test b/lib/twig/test/Twig/Tests/Fixtures/filters/default.test deleted file mode 100755 index 22e86e4..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/filters/default.test +++ /dev/null @@ -1,150 +0,0 @@ ---TEST-- -"default" filter ---TEMPLATE-- -Variable: -{{ definedVar |default('default') is sameas('default') ? 'ko' : 'ok' }} -{{ zeroVar |default('default') is sameas('default') ? 'ko' : 'ok' }} -{{ emptyVar |default('default') is sameas('default') ? 'ok' : 'ko' }} -{{ nullVar |default('default') is sameas('default') ? 'ok' : 'ko' }} -{{ undefinedVar |default('default') is sameas('default') ? 'ok' : 'ko' }} -Array access: -{{ nested.definedVar |default('default') is sameas('default') ? 'ko' : 'ok' }} -{{ nested['definedVar'] |default('default') is sameas('default') ? 'ko' : 'ok' }} -{{ nested.zeroVar |default('default') is sameas('default') ? 'ko' : 'ok' }} -{{ nested.emptyVar |default('default') is sameas('default') ? 'ok' : 'ko' }} -{{ nested.nullVar |default('default') is sameas('default') ? 'ok' : 'ko' }} -{{ nested.undefinedVar |default('default') is sameas('default') ? 'ok' : 'ko' }} -{{ nested['undefinedVar'] |default('default') is sameas('default') ? 'ok' : 'ko' }} -{{ undefinedVar.foo |default('default') is sameas('default') ? 'ok' : 'ko' }} -Plain values: -{{ 'defined' |default('default') is sameas('default') ? 'ko' : 'ok' }} -{{ 0 |default('default') is sameas('default') ? 'ko' : 'ok' }} -{{ '' |default('default') is sameas('default') ? 'ok' : 'ko' }} -{{ null |default('default') is sameas('default') ? 'ok' : 'ko' }} -Precedence: -{{ 'o' ~ nullVar |default('k') }} -{{ 'o' ~ nested.nullVar |default('k') }} -Object methods: -{{ object.foo |default('default') is sameas('default') ? 'ko' : 'ok' }} -{{ object.undefinedMethod |default('default') is sameas('default') ? 'ok' : 'ko' }} -{{ object.getFoo() |default('default') is sameas('default') ? 'ko' : 'ok' }} -{{ object.getFoo('a') |default('default') is sameas('default') ? 'ko' : 'ok' }} -{{ object.undefinedMethod() |default('default') is sameas('default') ? 'ok' : 'ko' }} -{{ object.undefinedMethod('a') |default('default') is sameas('default') ? 'ok' : 'ko' }} -Deep nested: -{{ nested.undefinedVar.foo.bar |default('default') is sameas('default') ? 'ok' : 'ko' }} -{{ nested.definedArray.0 |default('default') is sameas('default') ? 'ko' : 'ok' }} -{{ nested['definedArray'][0] |default('default') is sameas('default') ? 'ko' : 'ok' }} -{{ object.self.foo |default('default') is sameas('default') ? 'ko' : 'ok' }} -{{ object.self.undefinedMethod |default('default') is sameas('default') ? 'ok' : 'ko' }} -{{ object.undefinedMethod.self |default('default') is sameas('default') ? 'ok' : 'ko' }} ---DATA-- -return array( - 'definedVar' => 'defined', - 'zeroVar' => 0, - 'emptyVar' => '', - 'nullVar' => null, - 'nested' => array( - 'definedVar' => 'defined', - 'zeroVar' => 0, - 'emptyVar' => '', - 'nullVar' => null, - 'definedArray' => array(0), - ), - 'object' => new Foo(), -) ---CONFIG-- -return array('strict_variables' => false) ---EXPECT-- -Variable: -ok -ok -ok -ok -ok -Array access: -ok -ok -ok -ok -ok -ok -ok -ok -Plain values: -ok -ok -ok -ok -Precedence: -ok -ok -Object methods: -ok -ok -ok -ok -ok -ok -Deep nested: -ok -ok -ok -ok -ok -ok ---DATA-- -return array( - 'definedVar' => 'defined', - 'zeroVar' => 0, - 'emptyVar' => '', - 'nullVar' => null, - 'nested' => array( - 'definedVar' => 'defined', - 'zeroVar' => 0, - 'emptyVar' => '', - 'nullVar' => null, - 'definedArray' => array(0), - ), - 'object' => new Foo(), -) ---CONFIG-- -return array('strict_variables' => true) ---EXPECT-- -Variable: -ok -ok -ok -ok -ok -Array access: -ok -ok -ok -ok -ok -ok -ok -ok -Plain values: -ok -ok -ok -ok -Precedence: -ok -ok -Object methods: -ok -ok -ok -ok -ok -ok -Deep nested: -ok -ok -ok -ok -ok -ok diff --git a/lib/twig/test/Twig/Tests/Fixtures/filters/dynamic_filter.test b/lib/twig/test/Twig/Tests/Fixtures/filters/dynamic_filter.test deleted file mode 100755 index 93c5913..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/filters/dynamic_filter.test +++ /dev/null @@ -1,10 +0,0 @@ ---TEST-- -dynamic filter ---TEMPLATE-- -{{ 'bar'|foo_path }} -{{ 'bar'|a_foo_b_bar }} ---DATA-- -return array() ---EXPECT-- -foo/bar -a/b/bar diff --git a/lib/twig/test/Twig/Tests/Fixtures/filters/escape.test b/lib/twig/test/Twig/Tests/Fixtures/filters/escape.test deleted file mode 100755 index a606c10..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/filters/escape.test +++ /dev/null @@ -1,8 +0,0 @@ ---TEST-- -"escape" filter ---TEMPLATE-- -{{ "foo
    "|e }} ---DATA-- -return array() ---EXPECT-- -foo <br /> diff --git a/lib/twig/test/Twig/Tests/Fixtures/filters/escape_non_supported_charset.test b/lib/twig/test/Twig/Tests/Fixtures/filters/escape_non_supported_charset.test deleted file mode 100755 index bba26a0..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/filters/escape_non_supported_charset.test +++ /dev/null @@ -1,8 +0,0 @@ ---TEST-- -"escape" filter ---TEMPLATE-- -{{ "愛していますか?
    "|e }} ---DATA-- -return array() ---EXPECT-- -愛していますか? <br /> diff --git a/lib/twig/test/Twig/Tests/Fixtures/filters/force_escape.test b/lib/twig/test/Twig/Tests/Fixtures/filters/force_escape.test deleted file mode 100755 index 3690e71..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/filters/force_escape.test +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -"escape" filter ---TEMPLATE-- -{% set foo %} - foo
    -{% endset %} - -{{ foo|e('html') -}} -{{ foo|e('js') }} -{% autoescape true %} - {{ foo }} -{% endautoescape %} ---DATA-- -return array() ---EXPECT-- - foo<br /> - foo\x3cbr \x2f\x3e\x0a - foo
    diff --git a/lib/twig/test/Twig/Tests/Fixtures/filters/format.test b/lib/twig/test/Twig/Tests/Fixtures/filters/format.test deleted file mode 100755 index 97221ff..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/filters/format.test +++ /dev/null @@ -1,8 +0,0 @@ ---TEST-- -"format" filter ---TEMPLATE-- -{{ string|format(foo, 3) }} ---DATA-- -return array('string' => '%s/%d', 'foo' => 'bar') ---EXPECT-- -bar/3 diff --git a/lib/twig/test/Twig/Tests/Fixtures/filters/join.test b/lib/twig/test/Twig/Tests/Fixtures/filters/join.test deleted file mode 100755 index 8feef63..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/filters/join.test +++ /dev/null @@ -1,12 +0,0 @@ ---TEST-- -"join" filter ---TEMPLATE-- -{{ ["foo", "bar"]|join(', ') }} -{{ foo|join(', ') }} -{{ bar|join(', ') }} ---DATA-- -return array('foo' => new Foo(), 'bar' => new ArrayObject(array(3, 4))) ---EXPECT-- -foo, bar -1, 2 -3, 4 diff --git a/lib/twig/test/Twig/Tests/Fixtures/filters/json_encode.test b/lib/twig/test/Twig/Tests/Fixtures/filters/json_encode.test deleted file mode 100755 index 1738d40..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/filters/json_encode.test +++ /dev/null @@ -1,12 +0,0 @@ ---TEST-- -"json_encode" filter ---TEMPLATE-- -{{ "foo"|json_encode|raw }} -{{ foo|json_encode|raw }} -{{ [foo, "foo"]|json_encode|raw }} ---DATA-- -return array('foo' => new Twig_Markup('foo', 'UTF-8')) ---EXPECT-- -"foo" -"foo" -["foo","foo"] diff --git a/lib/twig/test/Twig/Tests/Fixtures/filters/length.test b/lib/twig/test/Twig/Tests/Fixtures/filters/length.test deleted file mode 100755 index 3347474..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/filters/length.test +++ /dev/null @@ -1,14 +0,0 @@ ---TEST-- -"length" filter ---TEMPLATE-- -{{ array|length }} -{{ string|length }} -{{ number|length }} -{{ markup|length }} ---DATA-- -return array('array' => array(1, 4), 'string' => 'foo', 'number' => 1000, 'markup' => new Twig_Markup('foo', 'UTF-8')) ---EXPECT-- -2 -3 -4 -3 diff --git a/lib/twig/test/Twig/Tests/Fixtures/filters/length_utf8.test b/lib/twig/test/Twig/Tests/Fixtures/filters/length_utf8.test deleted file mode 100755 index 5d5e243..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/filters/length_utf8.test +++ /dev/null @@ -1,12 +0,0 @@ ---TEST-- -"length" filter ---CONDITION-- -function_exists('mb_get_info') ---TEMPLATE-- -{{ string|length }} -{{ markup|length }} ---DATA-- -return array('string' => 'été', 'markup' => new Twig_Markup('foo', 'UTF-8')) ---EXPECT-- -3 -3 diff --git a/lib/twig/test/Twig/Tests/Fixtures/filters/merge.test b/lib/twig/test/Twig/Tests/Fixtures/filters/merge.test deleted file mode 100755 index 357b352..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/filters/merge.test +++ /dev/null @@ -1,14 +0,0 @@ ---TEST-- -"merge" filter ---TEMPLATE-- -{{ items|merge({'bar': 'foo'})|join }} -{{ items|merge({'bar': 'foo'})|keys|join }} -{{ {'bar': 'foo'}|merge(items)|join }} -{{ {'bar': 'foo'}|merge(items)|keys|join }} ---DATA-- -return array('items' => array('foo' => 'bar')) ---EXPECT-- -barfoo -foobar -foobar -barfoo diff --git a/lib/twig/test/Twig/Tests/Fixtures/filters/nl2br.test b/lib/twig/test/Twig/Tests/Fixtures/filters/nl2br.test deleted file mode 100755 index 6545a9b..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/filters/nl2br.test +++ /dev/null @@ -1,14 +0,0 @@ ---TEST-- -"nl2br" filter ---TEMPLATE-- -{{ "I like Twig.\nYou will like it too.\n\nEverybody like it!"|nl2br }} -{{ text|nl2br }} ---DATA-- -return array('text' => "If you have some HTML\nit will be escaped.") ---EXPECT-- -I like Twig.
    -You will like it too.
    -
    -Everybody like it! -If you have some <strong>HTML</strong>
    -it will be escaped. diff --git a/lib/twig/test/Twig/Tests/Fixtures/filters/number_format.test b/lib/twig/test/Twig/Tests/Fixtures/filters/number_format.test deleted file mode 100755 index 639a865..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/filters/number_format.test +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -"number_format" filter ---TEMPLATE-- -{{ 20|number_format }} -{{ 20.25|number_format }} -{{ 20.25|number_format(2) }} -{{ 20.25|number_format(2, ',') }} -{{ 1020.25|number_format(2, ',') }} -{{ 1020.25|number_format(2, ',', '.') }} ---DATA-- -return array(); ---EXPECT-- -20 -20 -20.25 -20,25 -1,020,25 -1.020,25 diff --git a/lib/twig/test/Twig/Tests/Fixtures/filters/number_format_default.test b/lib/twig/test/Twig/Tests/Fixtures/filters/number_format_default.test deleted file mode 100755 index c6903cc..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/filters/number_format_default.test +++ /dev/null @@ -1,21 +0,0 @@ ---TEST-- -"number_format" filter with defaults. ---TEMPLATE-- -{{ 20|number_format }} -{{ 20.25|number_format }} -{{ 20.25|number_format(1) }} -{{ 20.25|number_format(2, ',') }} -{{ 1020.25|number_format }} -{{ 1020.25|number_format(2, ',') }} -{{ 1020.25|number_format(2, ',', '.') }} ---DATA-- -$twig->getExtension('core')->setNumberFormat(2, '!', '='); -return array(); ---EXPECT-- -20!00 -20!25 -20!3 -20,25 -1=020!25 -1=020,25 -1.020,25 diff --git a/lib/twig/test/Twig/Tests/Fixtures/filters/replace.test b/lib/twig/test/Twig/Tests/Fixtures/filters/replace.test deleted file mode 100755 index 4021660..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/filters/replace.test +++ /dev/null @@ -1,8 +0,0 @@ ---TEST-- -"replace" filter ---TEMPLATE-- -{{ "I like %this% and %that%."|replace({'%this%': "foo", '%that%': "bar"}) }} ---DATA-- -return array() ---EXPECT-- -I like foo and bar. diff --git a/lib/twig/test/Twig/Tests/Fixtures/filters/reverse.test b/lib/twig/test/Twig/Tests/Fixtures/filters/reverse.test deleted file mode 100755 index 3c5f410..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/filters/reverse.test +++ /dev/null @@ -1,12 +0,0 @@ ---TEST-- -"reverse" filter ---TEMPLATE-- -{{ [1, 2, 3, 4]|reverse|join('') }} -{{ '1234évènement'|reverse }} -{{ arr|reverse|join('') }} ---DATA-- -return array('arr' => new ArrayObject(array(1, 2, 3, 4))) ---EXPECT-- -4321 -tnemenèvé4321 -4321 diff --git a/lib/twig/test/Twig/Tests/Fixtures/filters/slice.test b/lib/twig/test/Twig/Tests/Fixtures/filters/slice.test deleted file mode 100755 index bb32dfb..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/filters/slice.test +++ /dev/null @@ -1,40 +0,0 @@ ---TEST-- -"slice" filter ---TEMPLATE-- -{{ [1, 2, 3, 4][1:2]|join('') }} -{{ {a: 1, b: 2, c: 3, d: 4}[1:2]|join('') }} -{{ [1, 2, 3, 4][start:length]|join('') }} -{{ [1, 2, 3, 4]|slice(1, 2)|join('') }} -{{ [1, 2, 3, 4]|slice(1, 2)|keys|join('') }} -{{ [1, 2, 3, 4]|slice(1, 2, true)|keys|join('') }} -{{ {a: 1, b: 2, c: 3, d: 4}|slice(1, 2)|join('') }} -{{ {a: 1, b: 2, c: 3, d: 4}|slice(1, 2)|keys|join('') }} -{{ '1234'|slice(1, 2) }} -{{ '1234'[1:2] }} -{{ arr|slice(1, 2)|join('') }} -{{ arr[1:2]|join('') }} - -{{ [1, 2, 3, 4]|slice(1)|join('') }} -{{ [1, 2, 3, 4][1:]|join('') }} -{{ '1234'|slice(1) }} -{{ '1234'[1:] }} ---DATA-- -return array('start' => 1, 'length' => 2, 'arr' => new ArrayObject(array(1, 2, 3, 4))) ---EXPECT-- -23 -23 -23 -23 -01 -12 -23 -bc -23 -23 -23 -23 - -234 -234 -234 -234 diff --git a/lib/twig/test/Twig/Tests/Fixtures/filters/sort.test b/lib/twig/test/Twig/Tests/Fixtures/filters/sort.test deleted file mode 100755 index 21d575f..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/filters/sort.test +++ /dev/null @@ -1,10 +0,0 @@ ---TEST-- -"sort" filter ---TEMPLATE-- -{{ array1|sort|join }} -{{ array2|sort|join }} ---DATA-- -return array('array1' => array(4, 1), 'array2' => array('foo', 'bar')) ---EXPECT-- -14 -barfoo diff --git a/lib/twig/test/Twig/Tests/Fixtures/filters/special_chars.test b/lib/twig/test/Twig/Tests/Fixtures/filters/special_chars.test deleted file mode 100755 index cc91900..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/filters/special_chars.test +++ /dev/null @@ -1,8 +0,0 @@ ---TEST-- -"☃" custom filter ---TEMPLATE-- -{{ 'foo'|☃ }} ---DATA-- -return array() ---EXPECT-- -☃foo☃ diff --git a/lib/twig/test/Twig/Tests/Fixtures/filters/trim.test b/lib/twig/test/Twig/Tests/Fixtures/filters/trim.test deleted file mode 100755 index 3192062..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/filters/trim.test +++ /dev/null @@ -1,12 +0,0 @@ ---TEST-- -"trim" filter ---TEMPLATE-- -{{ " I like Twig. "|trim }} -{{ text|trim }} -{{ " foo/"|trim("/") }} ---DATA-- -return array('text' => " If you have some HTML it will be escaped. ") ---EXPECT-- -I like Twig. -If you have some <strong>HTML</strong> it will be escaped. - foo diff --git a/lib/twig/test/Twig/Tests/Fixtures/functions/attribute.test b/lib/twig/test/Twig/Tests/Fixtures/functions/attribute.test deleted file mode 100755 index ba7d5e8..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/functions/attribute.test +++ /dev/null @@ -1,12 +0,0 @@ ---TEST-- -"attribute" function ---TEMPLATE-- -{{ attribute(obj, method) }} -{{ attribute(array, item) }} -{{ attribute(obj, "bar", ["a", "b"]) }} ---DATA-- -return array('obj' => new Foo(), 'method' => 'foo', 'array' => array('foo' => 'bar'), 'item' => 'foo') ---EXPECT-- -foo -bar -bar_a-b diff --git a/lib/twig/test/Twig/Tests/Fixtures/functions/constant.test b/lib/twig/test/Twig/Tests/Fixtures/functions/constant.test deleted file mode 100755 index 6d4b374..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/functions/constant.test +++ /dev/null @@ -1,12 +0,0 @@ ---TEST-- -"constant" function ---TEMPLATE-- -{% if constant('DATE_W3C') == expect %} -true -{% else %} -false -{% endif %} ---DATA-- -return array('expect' => DATE_W3C); ---EXPECT-- -true diff --git a/lib/twig/test/Twig/Tests/Fixtures/functions/cycle.test b/lib/twig/test/Twig/Tests/Fixtures/functions/cycle.test deleted file mode 100755 index 522a63b..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/functions/cycle.test +++ /dev/null @@ -1,16 +0,0 @@ ---TEST-- -"cycle" function ---TEMPLATE-- -{% for i in 0..6 %} -{{ cycle(array1, i) }}-{{ cycle(array2, i) }} -{% endfor %} ---DATA-- -return array('array1' => array('odd', 'even'), 'array2' => array('apple', 'orange', 'citrus')) ---EXPECT-- -odd-apple -even-orange -odd-citrus -even-apple -odd-orange -even-citrus -odd-apple diff --git a/lib/twig/test/Twig/Tests/Fixtures/functions/date.test b/lib/twig/test/Twig/Tests/Fixtures/functions/date.test deleted file mode 100755 index caeee7a..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/functions/date.test +++ /dev/null @@ -1,25 +0,0 @@ ---TEST-- -"date" function ---TEMPLATE-- -{{ date() == date('now') ? 'OK' : 'KO' }} -{{ date() > date('-1day') ? 'OK' : 'KO' }} -{{ date(date1) == date('2010-10-04 13:45') ? 'OK' : 'KO' }} -{{ date(date2) == date('2010-10-04 13:45') ? 'OK' : 'KO' }} -{{ date(date3) == date('2010-10-04 13:45') ? 'OK' : 'KO' }} -{{ date(date4) == date('2010-10-04 13:45') ? 'OK' : 'KO' }} ---DATA-- -date_default_timezone_set('UTC'); -return array( - 'date1' => mktime(13, 45, 0, 10, 4, 2010), - 'date2' => new DateTime('2010-10-04 13:45'), - 'date3' => '2010-10-04 13:45', - 'date4' => 1286199900, - 'date5' => -86410, -) ---EXPECT-- -OK -OK -OK -OK -OK -OK diff --git a/lib/twig/test/Twig/Tests/Fixtures/functions/dump.test b/lib/twig/test/Twig/Tests/Fixtures/functions/dump.test deleted file mode 100755 index 1b3c453..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/functions/dump.test +++ /dev/null @@ -1,22 +0,0 @@ ---TEST-- -"dump" function ---TEMPLATE-- -{{ dump() }} -{{ dump('foo') }} -{{ dump('foo', 'bar') }} ---DATA-- -return array('foo' => 'foo', 'bar' => 'bar') ---CONFIG-- -return array('debug' => true, 'autoescape' => false); ---EXPECT-- -array(2) { - ["foo"]=> - string(3) "foo" - ["bar"]=> - string(3) "bar" -} - -string(3) "foo" - -string(3) "foo" -string(3) "bar" diff --git a/lib/twig/test/Twig/Tests/Fixtures/functions/dynamic_function.test b/lib/twig/test/Twig/Tests/Fixtures/functions/dynamic_function.test deleted file mode 100755 index 913fbc9..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/functions/dynamic_function.test +++ /dev/null @@ -1,10 +0,0 @@ ---TEST-- -dynamic function ---TEMPLATE-- -{{ foo_path('bar') }} -{{ a_foo_b_bar('bar') }} ---DATA-- -return array() ---EXPECT-- -foo/bar -a/b/bar diff --git a/lib/twig/test/Twig/Tests/Fixtures/functions/special_chars.test b/lib/twig/test/Twig/Tests/Fixtures/functions/special_chars.test deleted file mode 100755 index f602b0d..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/functions/special_chars.test +++ /dev/null @@ -1,8 +0,0 @@ ---TEST-- -"☃" custom function ---TEMPLATE-- -{{ ☃('foo') }} ---DATA-- -return array() ---EXPECT-- -☃foo☃ diff --git a/lib/twig/test/Twig/Tests/Fixtures/macros/simple.test b/lib/twig/test/Twig/Tests/Fixtures/macros/simple.test deleted file mode 100755 index 6a366cd..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/macros/simple.test +++ /dev/null @@ -1,22 +0,0 @@ ---TEST-- -macro ---TEMPLATE-- -{% import _self as test %} -{% from _self import test %} - -{% macro test(a, b) -%} - {{ a|default('a') }}
    - {{- b|default('b') }}
    -{%- endmacro %} - -{{ test.test() }} -{{ test() }} -{{ test.test(1, "c") }} -{{ test(1, "c") }} ---DATA-- -return array(); ---EXPECT-- -a
    b
    -a
    b
    -1
    c
    -1
    c
    diff --git a/lib/twig/test/Twig/Tests/Fixtures/macros/with_filters.test b/lib/twig/test/Twig/Tests/Fixtures/macros/with_filters.test deleted file mode 100755 index 685626f..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/macros/with_filters.test +++ /dev/null @@ -1,14 +0,0 @@ ---TEST-- -macro with a filter ---TEMPLATE-- -{% import _self as test %} - -{% macro test() %} - {% filter escape %}foo
    {% endfilter %} -{% endmacro %} - -{{ test.test() }} ---DATA-- -return array(); ---EXPECT-- -foo<br /> diff --git a/lib/twig/test/Twig/Tests/Fixtures/regression/empty_token.test b/lib/twig/test/Twig/Tests/Fixtures/regression/empty_token.test deleted file mode 100755 index 65f6cd2..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/regression/empty_token.test +++ /dev/null @@ -1,8 +0,0 @@ ---TEST-- -Twig outputs 0 nodes correctly ---TEMPLATE-- -{{ foo }}0{{ foo }} ---DATA-- -return array('foo' => 'foo') ---EXPECT-- -foo0foo diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/basic.test b/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/basic.test deleted file mode 100755 index 62d8c3c..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/basic.test +++ /dev/null @@ -1,22 +0,0 @@ ---TEST-- -"autoescape" tag applies escaping on its children ---TEMPLATE-- -{% autoescape true %} -{{ var }}
    -{% endautoescape %} -{% autoescape false %} -{{ var }}
    -{% endautoescape %} -{% autoescape true %} -{{ var }}
    -{% endautoescape %} -{% autoescape false %} -{{ var }}
    -{% endautoescape %} ---DATA-- -return array('var' => '
    ') ---EXPECT-- -<br />
    -

    -<br />
    -

    diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/blocks.test b/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/blocks.test deleted file mode 100755 index b48f73e..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/blocks.test +++ /dev/null @@ -1,12 +0,0 @@ ---TEST-- -"autoescape" tag applies escaping on embedded blocks ---TEMPLATE-- -{% autoescape true %} - {% block foo %} - {{ var }} - {% endblock %} -{% endautoescape %} ---DATA-- -return array('var' => '
    ') ---EXPECT-- -<br /> diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/double_escaping.test b/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/double_escaping.test deleted file mode 100755 index fd62a84..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/double_escaping.test +++ /dev/null @@ -1,10 +0,0 @@ ---TEST-- -"autoescape" tag does not double-escape ---TEMPLATE-- -{% autoescape true %} -{{ var|escape }} -{% endautoescape %} ---DATA-- -return array('var' => '
    ') ---EXPECT-- -<br /> diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/functions.test b/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/functions.test deleted file mode 100755 index 9a229d0..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/functions.test +++ /dev/null @@ -1,83 +0,0 @@ ---TEST-- -"autoescape" tag applies escaping after calling functions ---TEMPLATE-- - -autoescape false -{% autoescape false %} - -safe_br -{{ safe_br() }} - -unsafe_br -{{ unsafe_br() }} - -{% endautoescape %} - -autoescape true -{% autoescape true %} - -safe_br -{{ safe_br() }} - -unsafe_br -{{ unsafe_br() }} - -unsafe_br()|raw -{{ (unsafe_br())|raw }} - -safe_br()|escape -{{ (safe_br())|escape }} - -safe_br()|raw -{{ (safe_br())|raw }} - -unsafe_br()|escape -{{ (unsafe_br())|escape }} - -{% endautoescape %} - -autoescape true js -{% autoescape true js %} - -safe_br -{{ safe_br() }} - -{% endautoescape %} ---DATA-- -return array() ---EXPECT-- - -autoescape false - -safe_br -
    - -unsafe_br -
    - - -autoescape true - -safe_br -
    - -unsafe_br -<br /> - -unsafe_br()|raw -
    - -safe_br()|escape -<br /> - -safe_br()|raw -
    - -unsafe_br()|escape -<br /> - - -autoescape true js - -safe_br -\x3cbr \x2f\x3e diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/literal.test b/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/literal.test deleted file mode 100755 index 4c92d08..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/literal.test +++ /dev/null @@ -1,45 +0,0 @@ ---TEST-- -"autoescape" tag does not apply escaping on literals ---TEMPLATE-- -{% autoescape true %} - -1. Simple literal -{{ "
    " }} - -2. Conditional expression with only literals -{{ true ? "
    " : "
    " }} - -3. Conditonal expression with a variable -{{ true ? "
    " : someVar }} - -4. Nested conditionals with only literals -{{ true ? (true ? "
    " : "
    ") : "\n" }} - -5. Nested conditionals with a variable -{{ true ? (true ? "
    " : someVar) : "\n" }} - -6. Nested conditionals with a variable marked safe -{{ true ? (true ? "
    " : someVar|raw) : "\n" }} - -{% endautoescape %} ---DATA-- -return array() ---EXPECT-- - -1. Simple literal -
    - -2. Conditional expression with only literals -
    - -3. Conditonal expression with a variable -<br /> - -4. Nested conditionals with only literals -
    - -5. Nested conditionals with a variable -<br /> - -6. Nested conditionals with a variable marked safe -
    diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/nested.test b/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/nested.test deleted file mode 100755 index c911211..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/nested.test +++ /dev/null @@ -1,26 +0,0 @@ ---TEST-- -"autoescape" tags can be nested at will ---TEMPLATE-- -{{ var }} -{% autoescape true %} - {{ var }} - {% autoescape false %} - {{ var }} - {% autoescape true %} - {{ var }} - {% endautoescape %} - {{ var }} - {% endautoescape %} - {{ var }} -{% endautoescape %} -{{ var }} ---DATA-- -return array('var' => '
    ') ---EXPECT-- -<br /> - <br /> -
    - <br /> -
    - <br /> -<br /> diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/objects.test b/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/objects.test deleted file mode 100755 index f6c03ed..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/objects.test +++ /dev/null @@ -1,26 +0,0 @@ ---TEST-- -"autoescape" tag applies escaping to object method calls ---TEMPLATE-- -{% autoescape true %} -{{ user.name }} -{{ user.name|lower }} -{{ user }} -{% endautoescape %} ---DATA-- -class UserForAutoEscapeTest -{ - public function getName() - { - return 'Fabien
    '; - } - - public function __toString() - { - return 'Fabien
    '; - } -} -return array('user' => new UserForAutoEscapeTest()) ---EXPECT-- -Fabien<br /> -fabien<br /> -Fabien<br /> diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/raw.test b/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/raw.test deleted file mode 100755 index 86e55fd..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/raw.test +++ /dev/null @@ -1,10 +0,0 @@ ---TEST-- -"autoescape" tag does not escape when raw is used as a filter ---TEMPLATE-- -{% autoescape true %} -{{ var|raw }} -{% endautoescape %} ---DATA-- -return array('var' => '
    ') ---EXPECT-- -
    diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/strategy.test b/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/strategy.test deleted file mode 100755 index 9ea4fd4..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/strategy.test +++ /dev/null @@ -1,11 +0,0 @@ ---TEST-- -"autoescape" tag accepts an escaping strategy ---TEMPLATE-- -{% autoescape true js %}{{ var }}{% endautoescape %} - -{% autoescape true html %}{{ var }}{% endautoescape %} ---DATA-- -return array('var' => '
    "') ---EXPECT-- -\x3cbr \x2f\x3e\x22 -<br />" diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/type.test b/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/type.test deleted file mode 100755 index 17cec13..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/type.test +++ /dev/null @@ -1,69 +0,0 @@ ---TEST-- -escape types ---TEMPLATE-- - -1. autoescape true |escape('js') - -{% autoescape true %} - -{% endautoescape %} - -2. autoescape true html |escape('js') - -{% autoescape true html %} - -{% endautoescape %} - -3. autoescape true js |escape('js') - -{% autoescape true js %} - -{% endautoescape %} - -4. no escape - -{% autoescape false %} - -{% endautoescape %} - -5. |escape('js')|escape('html') - -{% autoescape false %} - -{% endautoescape %} - -6. autoescape true html |escape('js')|escape('html') - -{% autoescape true html %} - -{% endautoescape %} - ---DATA-- -return array('msg' => "<>\n'\"") ---EXPECT-- - -1. autoescape true |escape('js') - - - -2. autoescape true html |escape('js') - - - -3. autoescape true js |escape('js') - - - -4. no escape - - - -5. |escape('js')|escape('html') - - - -6. autoescape true html |escape('js')|escape('html') - - - diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/with_filters.test b/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/with_filters.test deleted file mode 100755 index d795b82..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/with_filters.test +++ /dev/null @@ -1,131 +0,0 @@ ---TEST-- -"autoescape" tag applies escaping after calling filters ---TEMPLATE-- -{% autoescape true %} - -(escape_and_nl2br is an escaper filter) - -1. Don't escape escaper filter output -( var is escaped by |escape_and_nl2br, line-breaks are added, - the output is not escaped ) -{{ var|escape_and_nl2br }} - -2. Don't escape escaper filter output -( var is escaped by |escape_and_nl2br, line-breaks are added, - the output is not escaped, |raw is redundant ) -{{ var|escape_and_nl2br|raw }} - -3. Explicit escape -( var is escaped by |escape_and_nl2br, line-breaks are added, - the output is explicitly escaped by |escape ) -{{ var|escape_and_nl2br|escape }} - -4. Escape non-escaper filter output -( var is upper-cased by |upper, - the output is auto-escaped ) -{{ var|upper }} - -5. Escape if last filter is not an escaper -( var is escaped by |escape_and_nl2br, line-breaks are added, - the output is upper-cased by |upper, - the output is auto-escaped as |upper is not an escaper ) -{{ var|escape_and_nl2br|upper }} - -6. Don't escape escaper filter output -( var is upper cased by upper, - the output is escaped by |escape_and_nl2br, line-breaks are added, - the output is not escaped as |escape_and_nl2br is an escaper ) -{{ var|upper|escape_and_nl2br }} - -7. Escape if last filter is not an escaper -( the output of |format is "" ~ var ~ "", - the output is auto-escaped ) -{{ "%s"|format(var) }} - -8. Escape if last filter is not an escaper -( the output of |format is "" ~ var ~ "", - |raw is redundant, - the output is auto-escaped ) -{{ "%s"|raw|format(var) }} - -9. Don't escape escaper filter output -( the output of |format is "" ~ var ~ "", - the output is not escaped due to |raw filter at the end ) -{{ "%s"|format(var)|raw }} - -10. Don't escape escaper filter output -( the output of |format is "" ~ var ~ "", - the output is not escaped due to |raw filter at the end, - the |raw filter on var is redundant ) -{{ "%s"|format(var|raw)|raw }} - -{% endautoescape %} ---DATA-- -return array('var' => "\nTwig") ---EXPECT-- - -(escape_and_nl2br is an escaper filter) - -1. Don't escape escaper filter output -( var is escaped by |escape_and_nl2br, line-breaks are added, - the output is not escaped ) -<Fabien>
    -Twig - -2. Don't escape escaper filter output -( var is escaped by |escape_and_nl2br, line-breaks are added, - the output is not escaped, |raw is redundant ) -<Fabien>
    -Twig - -3. Explicit escape -( var is escaped by |escape_and_nl2br, line-breaks are added, - the output is explicitly escaped by |escape ) -&lt;Fabien&gt;<br /> -Twig - -4. Escape non-escaper filter output -( var is upper-cased by |upper, - the output is auto-escaped ) -<FABIEN> -TWIG - -5. Escape if last filter is not an escaper -( var is escaped by |escape_and_nl2br, line-breaks are added, - the output is upper-cased by |upper, - the output is auto-escaped as |upper is not an escaper ) -&LT;FABIEN&GT;<BR /> -TWIG - -6. Don't escape escaper filter output -( var is upper cased by upper, - the output is escaped by |escape_and_nl2br, line-breaks are added, - the output is not escaped as |escape_and_nl2br is an escaper ) -<FABIEN>
    -TWIG - -7. Escape if last filter is not an escaper -( the output of |format is "" ~ var ~ "", - the output is auto-escaped ) -<b><Fabien> -Twig</b> - -8. Escape if last filter is not an escaper -( the output of |format is "" ~ var ~ "", - |raw is redundant, - the output is auto-escaped ) -<b><Fabien> -Twig</b> - -9. Don't escape escaper filter output -( the output of |format is "" ~ var ~ "", - the output is not escaped due to |raw filter at the end ) - -Twig - -10. Don't escape escaper filter output -( the output of |format is "" ~ var ~ "", - the output is not escaped due to |raw filter at the end, - the |raw filter on var is redundant ) - -Twig diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/with_filters_arguments.test b/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/with_filters_arguments.test deleted file mode 100755 index 0ff1ad3..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/with_filters_arguments.test +++ /dev/null @@ -1,23 +0,0 @@ ---TEST-- -"autoescape" tag do not applies escaping on filter arguments ---TEMPLATE-- -{% autoescape true %} -{{ var|nl2br("
    ") }} -{{ var|nl2br("
    "|escape) }} -{{ var|nl2br(sep) }} -{{ var|nl2br(sep|raw) }} -{{ var|nl2br(sep|escape) }} -{% endautoescape %} ---DATA-- -return array('var' => "\nTwig", 'sep' => '
    ') ---EXPECT-- -<Fabien>
    -Twig -<Fabien><br /> -Twig -<Fabien>
    -Twig -<Fabien>
    -Twig -<Fabien><br /> -Twig diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/with_pre_escape_filters.test b/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/with_pre_escape_filters.test deleted file mode 100755 index 44d42e7..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/autoescape/with_pre_escape_filters.test +++ /dev/null @@ -1,68 +0,0 @@ ---TEST-- -"autoescape" tag applies escaping after calling filters, and before calling pre_escape filters ---TEMPLATE-- -{% autoescape true %} - -(nl2br is pre_escaped for "html" and declared safe for "html") - -1. Pre-escape and don't post-escape -( var|escape|nl2br ) -{{ var|nl2br }} - -2. Don't double-pre-escape -( var|escape|nl2br ) -{{ var|escape|nl2br }} - -3. Don't escape safe values -( var|raw|nl2br ) -{{ var|raw|nl2br }} - -4. Don't escape safe values -( var|escape|nl2br|nl2br ) -{{ var|nl2br|nl2br }} - -5. Re-escape values that are escaped for an other contexts -( var|escape_something|escape|nl2br ) -{{ var|escape_something|nl2br }} - -6. Still escape when using filters not declared safe -( var|escape|nl2br|upper|escape ) -{{ var|nl2br|upper }} - -{% endautoescape %} ---DATA-- -return array('var' => "\nTwig") ---EXPECT-- - -(nl2br is pre_escaped for "html" and declared safe for "html") - -1. Pre-escape and don't post-escape -( var|escape|nl2br ) -<Fabien>
    -Twig - -2. Don't double-pre-escape -( var|escape|nl2br ) -<Fabien>
    -Twig - -3. Don't escape safe values -( var|raw|nl2br ) -
    -Twig - -4. Don't escape safe values -( var|escape|nl2br|nl2br ) -<Fabien>

    -Twig - -5. Re-escape values that are escaped for an other contexts -( var|escape_something|escape|nl2br ) -<FABIEN>
    -TWIG - -6. Still escape when using filters not declared safe -( var|escape|nl2br|upper|escape ) -&LT;FABIEN&GT;<BR /> -TWIG - diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/block/basic.test b/lib/twig/test/Twig/Tests/Fixtures/tags/block/basic.test deleted file mode 100755 index 360dcf0..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/block/basic.test +++ /dev/null @@ -1,11 +0,0 @@ ---TEST-- -"block" tag ---TEMPLATE-- -{% block title1 %}FOO{% endblock %} -{% block title2 foo|lower %} ---TEMPLATE(foo.twig)-- -{% block content %}{% endblock %} ---DATA-- -return array('foo' => 'bar') ---EXPECT-- -FOObar diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/block/special_chars.test b/lib/twig/test/Twig/Tests/Fixtures/tags/block/special_chars.test deleted file mode 100755 index 441570c..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/block/special_chars.test +++ /dev/null @@ -1,10 +0,0 @@ ---TEST-- -"☃" special chars in a block name ---TEMPLATE-- -{% block ☃ %} -☃ -{% endblock ☃ %} ---DATA-- -return array() ---EXPECT-- -☃ diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/filter/basic.test b/lib/twig/test/Twig/Tests/Fixtures/tags/filter/basic.test deleted file mode 100755 index 82094f2..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/filter/basic.test +++ /dev/null @@ -1,10 +0,0 @@ ---TEST-- -"filter" tag applies a filter on its children ---TEMPLATE-- -{% filter upper %} -Some text with a {{ var }} -{% endfilter %} ---DATA-- -return array('var' => 'var') ---EXPECT-- -SOME TEXT WITH A VAR diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/filter/json_encode.test b/lib/twig/test/Twig/Tests/Fixtures/tags/filter/json_encode.test deleted file mode 100755 index 3e7148b..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/filter/json_encode.test +++ /dev/null @@ -1,8 +0,0 @@ ---TEST-- -"filter" tag applies a filter on its children ---TEMPLATE-- -{% filter json_encode|raw %}test{% endfilter %} ---DATA-- -return array() ---EXPECT-- -"test" diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/filter/multiple.test b/lib/twig/test/Twig/Tests/Fixtures/tags/filter/multiple.test deleted file mode 100755 index 75512ef..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/filter/multiple.test +++ /dev/null @@ -1,10 +0,0 @@ ---TEST-- -"filter" tags accept multiple chained filters ---TEMPLATE-- -{% filter lower|title %} - {{ var }} -{% endfilter %} ---DATA-- -return array('var' => 'VAR') ---EXPECT-- - Var diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/filter/nested.test b/lib/twig/test/Twig/Tests/Fixtures/tags/filter/nested.test deleted file mode 100755 index 7e4e4eb..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/filter/nested.test +++ /dev/null @@ -1,16 +0,0 @@ ---TEST-- -"filter" tags can be nested at will ---TEMPLATE-- -{% filter lower|title %} - {{ var }} - {% filter upper %} - {{ var }} - {% endfilter %} - {{ var }} -{% endfilter %} ---DATA-- -return array('var' => 'var') ---EXPECT-- - Var - Var - Var diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/filter/with_for_tag.test b/lib/twig/test/Twig/Tests/Fixtures/tags/filter/with_for_tag.test deleted file mode 100755 index 22745ea..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/filter/with_for_tag.test +++ /dev/null @@ -1,13 +0,0 @@ ---TEST-- -"filter" tag applies the filter on "for" tags ---TEMPLATE-- -{% filter upper %} -{% for item in items %} -{{ item }} -{% endfor %} -{% endfilter %} ---DATA-- -return array('items' => array('a', 'b')) ---EXPECT-- -A -B diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/filter/with_if_tag.test b/lib/twig/test/Twig/Tests/Fixtures/tags/filter/with_if_tag.test deleted file mode 100755 index afd95b2..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/filter/with_if_tag.test +++ /dev/null @@ -1,29 +0,0 @@ ---TEST-- -"filter" tag applies the filter on "if" tags ---TEMPLATE-- -{% filter upper %} -{% if items %} -{{ items|join(', ') }} -{% endif %} - -{% if items.3 is defined %} -FOO -{% else %} -{{ items.1 }} -{% endif %} - -{% if items.3 is defined %} -FOO -{% elseif items.1 %} -{{ items.0 }} -{% endif %} - -{% endfilter %} ---DATA-- -return array('items' => array('a', 'b')) ---EXPECT-- -A, B - -B - -A diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/for/condition.test b/lib/twig/test/Twig/Tests/Fixtures/tags/for/condition.test deleted file mode 100755 index 9e4eb9b..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/for/condition.test +++ /dev/null @@ -1,14 +0,0 @@ ---TEST-- -"for" tag takes a condition ---TEMPLATE-- -{% for i in 1..5 if i is odd -%} - {{ loop.index }}.{{ i }} -{% endfor %} ---DATA-- -return array() ---CONFIG-- -return array('strict_variables' => false) ---EXPECT-- -1.1 -2.3 -3.5 diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/for/context.test b/lib/twig/test/Twig/Tests/Fixtures/tags/for/context.test deleted file mode 100755 index ddc6930..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/for/context.test +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -"for" tag keeps the context safe ---TEMPLATE-- -{% for item in items %} - {% for item in items %} - * {{ item }} - {% endfor %} - * {{ item }} -{% endfor %} ---DATA-- -return array('items' => array('a', 'b')) ---EXPECT-- - * a - * b - * a - * a - * b - * b diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/for/else.test b/lib/twig/test/Twig/Tests/Fixtures/tags/for/else.test deleted file mode 100755 index 20ccc88..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/for/else.test +++ /dev/null @@ -1,23 +0,0 @@ ---TEST-- -"for" tag can use an "else" clause ---TEMPLATE-- -{% for item in items %} - * {{ item }} -{% else %} - no item -{% endfor %} ---DATA-- -return array('items' => array('a', 'b')) ---EXPECT-- - * a - * b ---DATA-- -return array('items' => array()) ---EXPECT-- - no item ---DATA-- -return array() ---CONFIG-- -return array('strict_variables' => false) ---EXPECT-- - no item diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/for/inner_variables.test b/lib/twig/test/Twig/Tests/Fixtures/tags/for/inner_variables.test deleted file mode 100755 index 49fb9ca..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/for/inner_variables.test +++ /dev/null @@ -1,17 +0,0 @@ ---TEST-- -"for" tag does not reset inner variables ---TEMPLATE-- -{% for i in 1..2 %} - {% for j in 0..2 %} - {{k}}{% set k = k+1 %} {{ loop.parent.loop.index }} - {% endfor %} -{% endfor %} ---DATA-- -return array('k' => 0) ---EXPECT-- - 0 1 - 1 1 - 2 1 - 3 2 - 4 2 - 5 2 diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/for/keys.test b/lib/twig/test/Twig/Tests/Fixtures/tags/for/keys.test deleted file mode 100755 index 4e22cb4..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/for/keys.test +++ /dev/null @@ -1,11 +0,0 @@ ---TEST-- -"for" tag can iterate over keys ---TEMPLATE-- -{% for key in items|keys %} - * {{ key }} -{% endfor %} ---DATA-- -return array('items' => array('a', 'b')) ---EXPECT-- - * 0 - * 1 diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/for/keys_and_values.test b/lib/twig/test/Twig/Tests/Fixtures/tags/for/keys_and_values.test deleted file mode 100755 index 4c21168..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/for/keys_and_values.test +++ /dev/null @@ -1,11 +0,0 @@ ---TEST-- -"for" tag can iterate over keys and values ---TEMPLATE-- -{% for key, item in items %} - * {{ key }}/{{ item }} -{% endfor %} ---DATA-- -return array('items' => array('a', 'b')) ---EXPECT-- - * 0/a - * 1/b diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/for/loop_context.test b/lib/twig/test/Twig/Tests/Fixtures/tags/for/loop_context.test deleted file mode 100755 index 93bc76a..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/for/loop_context.test +++ /dev/null @@ -1,19 +0,0 @@ ---TEST-- -"for" tag adds a loop variable to the context ---TEMPLATE-- -{% for item in items %} - * {{ loop.index }}/{{ loop.index0 }} - * {{ loop.revindex }}/{{ loop.revindex0 }} - * {{ loop.first }}/{{ loop.last }}/{{ loop.length }} - -{% endfor %} ---DATA-- -return array('items' => array('a', 'b')) ---EXPECT-- - * 1/0 - * 2/1 - * 1//2 - - * 2/1 - * 1/0 - * /1/2 diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/for/loop_context_local.test b/lib/twig/test/Twig/Tests/Fixtures/tags/for/loop_context_local.test deleted file mode 100755 index 58af2c3..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/for/loop_context_local.test +++ /dev/null @@ -1,10 +0,0 @@ ---TEST-- -"for" tag adds a loop variable to the context locally ---TEMPLATE-- -{% for item in items %} -{% endfor %} -{% if loop is not defined %}WORKS{% endif %} ---DATA-- -return array('items' => array()) ---EXPECT-- -WORKS diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/for/nested_else.test b/lib/twig/test/Twig/Tests/Fixtures/tags/for/nested_else.test deleted file mode 100755 index f8b9f6b..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/for/nested_else.test +++ /dev/null @@ -1,17 +0,0 @@ ---TEST-- -"for" tag can use an "else" clause ---TEMPLATE-- -{% for item in items %} - {% for item in items1 %} - * {{ item }} - {% else %} - no {{ item }} - {% endfor %} -{% else %} - no item1 -{% endfor %} ---DATA-- -return array('items' => array('a', 'b'), 'items1' => array()) ---EXPECT-- -no a - no b diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/for/objects.test b/lib/twig/test/Twig/Tests/Fixtures/tags/for/objects.test deleted file mode 100755 index 5034437..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/for/objects.test +++ /dev/null @@ -1,43 +0,0 @@ ---TEST-- -"for" tag iterates over iterable objects ---TEMPLATE-- -{% for item in items %} - * {{ item }} - * {{ loop.index }}/{{ loop.index0 }} - * {{ loop.first }} - -{% endfor %} - -{% for key, value in items %} - * {{ key }}/{{ value }} -{% endfor %} - -{% for key in items|keys %} - * {{ key }} -{% endfor %} ---DATA-- -class ItemsIterator implements Iterator -{ - protected $values = array('foo' => 'bar', 'bar' => 'foo'); - public function current() { return current($this->values); } - public function key() { return key($this->values); } - public function next() { return next($this->values); } - public function rewind() { return reset($this->values); } - public function valid() { return false !== current($this->values); } -} -return array('items' => new ItemsIterator()) ---EXPECT-- - * bar - * 1/0 - * 1 - - * foo - * 2/1 - * - - - * foo/bar - * bar/foo - - * foo - * bar diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/for/objects_countable.test b/lib/twig/test/Twig/Tests/Fixtures/tags/for/objects_countable.test deleted file mode 100755 index 4a1ff61..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/for/objects_countable.test +++ /dev/null @@ -1,47 +0,0 @@ ---TEST-- -"for" tag iterates over iterable and countable objects ---TEMPLATE-- -{% for item in items %} - * {{ item }} - * {{ loop.index }}/{{ loop.index0 }} - * {{ loop.revindex }}/{{ loop.revindex0 }} - * {{ loop.first }}/{{ loop.last }}/{{ loop.length }} - -{% endfor %} - -{% for key, value in items %} - * {{ key }}/{{ value }} -{% endfor %} - -{% for key in items|keys %} - * {{ key }} -{% endfor %} ---DATA-- -class ItemsIteratorCountable implements Iterator, Countable -{ - protected $values = array('foo' => 'bar', 'bar' => 'foo'); - public function current() { return current($this->values); } - public function key() { return key($this->values); } - public function next() { return next($this->values); } - public function rewind() { return reset($this->values); } - public function valid() { return false !== current($this->values); } - public function count() { return count($this->values); } -} -return array('items' => new ItemsIteratorCountable()) ---EXPECT-- - * bar - * 1/0 - * 2/1 - * 1//2 - - * foo - * 2/1 - * 1/0 - * /1/2 - - - * foo/bar - * bar/foo - - * foo - * bar diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/for/recursive.test b/lib/twig/test/Twig/Tests/Fixtures/tags/for/recursive.test deleted file mode 100755 index 17b2e22..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/for/recursive.test +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -"for" tags can be nested ---TEMPLATE-- -{% for key, item in items %} -* {{ key }} ({{ loop.length }}): -{% for value in item %} - * {{ value }} ({{ loop.length }}) -{% endfor %} -{% endfor %} ---DATA-- -return array('items' => array('a' => array('a1', 'a2', 'a3'), 'b' => array('b1'))) ---EXPECT-- -* a (2): - * a1 (3) - * a2 (3) - * a3 (3) -* b (2): - * b1 (1) diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/for/values.test b/lib/twig/test/Twig/Tests/Fixtures/tags/for/values.test deleted file mode 100755 index 82f2ae8..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/for/values.test +++ /dev/null @@ -1,11 +0,0 @@ ---TEST-- -"for" tag iterates over item values ---TEMPLATE-- -{% for item in items %} - * {{ item }} -{% endfor %} ---DATA-- -return array('items' => array('a', 'b')) ---EXPECT-- - * a - * b diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/from.test b/lib/twig/test/Twig/Tests/Fixtures/tags/from.test deleted file mode 100755 index 5f5da0e..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/from.test +++ /dev/null @@ -1,14 +0,0 @@ ---TEST-- -global variables ---TEMPLATE-- -{% include "included.twig" %} -{% from "included.twig" import foobar %} -{{ foobar() }} ---TEMPLATE(included.twig)-- -{% macro foobar() %} -called foobar -{% endmacro %} ---DATA-- -return array(); ---EXPECT-- -called foobar diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/if/basic.test b/lib/twig/test/Twig/Tests/Fixtures/tags/if/basic.test deleted file mode 100755 index c1c3d27..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/if/basic.test +++ /dev/null @@ -1,22 +0,0 @@ ---TEST-- -"if" creates a condition ---TEMPLATE-- -{% if a is defined %} - {{ a }} -{% elseif b is defined %} - {{ b }} -{% else %} - NOTHING -{% endif %} ---DATA-- -return array('a' => 'a') ---EXPECT-- - a ---DATA-- -return array('b' => 'b') ---EXPECT-- - b ---DATA-- -return array() ---EXPECT-- - NOTHING diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/if/expression.test b/lib/twig/test/Twig/Tests/Fixtures/tags/if/expression.test deleted file mode 100755 index edfb73d..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/if/expression.test +++ /dev/null @@ -1,22 +0,0 @@ ---TEST-- -"if" takes an expression as a test ---TEMPLATE-- -{% if a < 2 %} - A1 -{% elseif a > 10 %} - A2 -{% else %} - A3 -{% endif %} ---DATA-- -return array('a' => 1) ---EXPECT-- - A1 ---DATA-- -return array('a' => 12) ---EXPECT-- - A2 ---DATA-- -return array('a' => 7) ---EXPECT-- - A3 diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/include/basic.test b/lib/twig/test/Twig/Tests/Fixtures/tags/include/basic.test deleted file mode 100755 index 8fe1a6c..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/include/basic.test +++ /dev/null @@ -1,16 +0,0 @@ ---TEST-- -"include" tag ---TEMPLATE-- -FOO -{% include "foo.twig" %} - -BAR ---TEMPLATE(foo.twig)-- -FOOBAR ---DATA-- -return array() ---EXPECT-- -FOO - -FOOBAR -BAR diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/include/expression.test b/lib/twig/test/Twig/Tests/Fixtures/tags/include/expression.test deleted file mode 100755 index eaeeb11..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/include/expression.test +++ /dev/null @@ -1,16 +0,0 @@ ---TEST-- -"include" tag allows expressions for the template to include ---TEMPLATE-- -FOO -{% include foo %} - -BAR ---TEMPLATE(foo.twig)-- -FOOBAR ---DATA-- -return array('foo' => 'foo.twig') ---EXPECT-- -FOO - -FOOBAR -BAR diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/include/ignore_missing.test b/lib/twig/test/Twig/Tests/Fixtures/tags/include/ignore_missing.test deleted file mode 100755 index 24aed06..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/include/ignore_missing.test +++ /dev/null @@ -1,10 +0,0 @@ ---TEST-- -"include" tag ---TEMPLATE-- -{% include ["foo.twig", "bar.twig"] ignore missing %} -{% include "foo.twig" ignore missing %} -{% include "foo.twig" ignore missing with {} %} -{% include "foo.twig" ignore missing with {} only %} ---DATA-- -return array() ---EXPECT-- diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/include/only.test b/lib/twig/test/Twig/Tests/Fixtures/tags/include/only.test deleted file mode 100755 index 22e3d0f..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/include/only.test +++ /dev/null @@ -1,16 +0,0 @@ ---TEST-- -"include" tag accept variables and only ---TEMPLATE-- -{% include "foo.twig" %} -{% include "foo.twig" only %} -{% include "foo.twig" with {'foo1': 'bar'} %} -{% include "foo.twig" with {'foo1': 'bar'} only %} ---TEMPLATE(foo.twig)-- -{% for k, v in _context %}{{ k }},{% endfor %} ---DATA-- -return array('foo' => 'bar') ---EXPECT-- -foo,_parent, -_parent, -foo,foo1,_parent, -foo1,_parent, diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/include/template_instance.test b/lib/twig/test/Twig/Tests/Fixtures/tags/include/template_instance.test deleted file mode 100755 index 6ba064a..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/include/template_instance.test +++ /dev/null @@ -1,10 +0,0 @@ ---TEST-- -"include" tag accepts Twig_Template instance ---TEMPLATE-- -{% include foo %} FOO ---TEMPLATE(foo.twig)-- -BAR ---DATA-- -return array('foo' => $twig->loadTemplate('foo.twig')) ---EXPECT-- -BAR FOO diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/include/templates_as_array.test b/lib/twig/test/Twig/Tests/Fixtures/tags/include/templates_as_array.test deleted file mode 100755 index ab670ee..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/include/templates_as_array.test +++ /dev/null @@ -1,12 +0,0 @@ ---TEST-- -"include" tag ---TEMPLATE-- -{% include ["foo.twig", "bar.twig"] %} -{% include ["bar.twig", "foo.twig"] %} ---TEMPLATE(foo.twig)-- -foo ---DATA-- -return array() ---EXPECT-- -foo -foo diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/include/with_variables.test b/lib/twig/test/Twig/Tests/Fixtures/tags/include/with_variables.test deleted file mode 100755 index 41384ac..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/include/with_variables.test +++ /dev/null @@ -1,12 +0,0 @@ ---TEST-- -"include" tag accept variables ---TEMPLATE-- -{% include "foo.twig" with {'foo': 'bar'} %} -{% include "foo.twig" with vars %} ---TEMPLATE(foo.twig)-- -{{ foo }} ---DATA-- -return array('vars' => array('foo' => 'bar')) ---EXPECT-- -bar -bar diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/basic.test b/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/basic.test deleted file mode 100755 index 0778a4b..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/basic.test +++ /dev/null @@ -1,14 +0,0 @@ ---TEST-- -"extends" tag ---TEMPLATE-- -{% extends "foo.twig" %} - -{% block content %} -FOO -{% endblock %} ---TEMPLATE(foo.twig)-- -{% block content %}{% endblock %} ---DATA-- -return array() ---EXPECT-- -FOO diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/conditional.test b/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/conditional.test deleted file mode 100755 index 8576e77..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/conditional.test +++ /dev/null @@ -1,14 +0,0 @@ ---TEST-- -"extends" tag ---TEMPLATE-- -{% extends standalone ? foo : 'bar.twig' %} - -{% block content %}{{ parent() }}FOO{% endblock %} ---TEMPLATE(foo.twig)-- -{% block content %}FOO{% endblock %} ---TEMPLATE(bar.twig)-- -{% block content %}BAR{% endblock %} ---DATA-- -return array('foo' => 'foo.twig', 'standalone' => true) ---EXPECT-- -FOOFOO diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/dynamic.test b/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/dynamic.test deleted file mode 100755 index ee06ddc..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/dynamic.test +++ /dev/null @@ -1,14 +0,0 @@ ---TEST-- -"extends" tag ---TEMPLATE-- -{% extends foo %} - -{% block content %} -FOO -{% endblock %} ---TEMPLATE(foo.twig)-- -{% block content %}{% endblock %} ---DATA-- -return array('foo' => 'foo.twig') ---EXPECT-- -FOO diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/extends_as_array.test b/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/extends_as_array.test deleted file mode 100755 index a1cb1ce..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/extends_as_array.test +++ /dev/null @@ -1,12 +0,0 @@ ---TEST-- -"extends" tag ---TEMPLATE-- -{% extends ["foo.twig", "bar.twig"] %} ---TEMPLATE(bar.twig)-- -{% block content %} -foo -{% endblock %} ---DATA-- -return array() ---EXPECT-- -foo diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/multiple.test b/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/multiple.test deleted file mode 100755 index dfc2b6c..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/multiple.test +++ /dev/null @@ -1,12 +0,0 @@ ---TEST-- -"extends" tag ---TEMPLATE-- -{% extends "layout.twig" %}{% block content %}{{ parent() }}index {% endblock %} ---TEMPLATE(layout.twig)-- -{% extends "base.twig" %}{% block content %}{{ parent() }}layout {% endblock %} ---TEMPLATE(base.twig)-- -{% block content %}base {% endblock %} ---DATA-- -return array() ---EXPECT-- -base layout index diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/nested_inheritance.test b/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/nested_inheritance.test deleted file mode 100755 index 71e3cdf..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/nested_inheritance.test +++ /dev/null @@ -1,16 +0,0 @@ ---TEST-- -"extends" tag ---TEMPLATE-- -{% extends "layout.twig" %} -{% block inside %}INSIDE{% endblock inside %} ---TEMPLATE(layout.twig)-- -{% extends "base.twig" %} -{% block body %} - {% block inside '' %} -{% endblock body %} ---TEMPLATE(base.twig)-- -{% block body '' %} ---DATA-- -return array() ---EXPECT-- -INSIDE diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent.test b/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent.test deleted file mode 100755 index 4f975db..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent.test +++ /dev/null @@ -1,12 +0,0 @@ ---TEST-- -"extends" tag ---TEMPLATE-- -{% extends "foo.twig" %} - -{% block content %}{{ parent() }}FOO{{ parent() }}{% endblock %} ---TEMPLATE(foo.twig)-- -{% block content %}BAR{% endblock %} ---DATA-- -return array() ---EXPECT-- -BARFOOBAR diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_change.test b/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_change.test deleted file mode 100755 index a8bc90c..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_change.test +++ /dev/null @@ -1,16 +0,0 @@ ---TEST-- -"extends" tag ---TEMPLATE-- -{% extends foo ? 'foo.twig' : 'bar.twig' %} ---TEMPLATE(foo.twig)-- -FOO ---TEMPLATE(bar.twig)-- -BAR ---DATA-- -return array('foo' => true) ---EXPECT-- -FOO ---DATA-- -return array('foo' => false) ---EXPECT-- -BAR diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_in_a_block.test b/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_in_a_block.test deleted file mode 100755 index c9e86b1..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_in_a_block.test +++ /dev/null @@ -1,8 +0,0 @@ ---TEST-- -"extends" tag ---TEMPLATE-- -{% block content %} - {% extends "foo.twig" %} -{% endblock %} ---EXCEPTION-- -Twig_Error_Syntax: Cannot extend from a block in "index.twig" at line 3 diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_isolation.test b/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_isolation.test deleted file mode 100755 index 6281671..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_isolation.test +++ /dev/null @@ -1,20 +0,0 @@ ---TEST-- -"extends" tag ---TEMPLATE-- -{% extends "base.twig" %} -{% block content %}{% include "included.twig" %}{% endblock %} - -{% block footer %}Footer{% endblock %} ---TEMPLATE(included.twig)-- -{% extends "base.twig" %} -{% block content %}Included Content{% endblock %} ---TEMPLATE(base.twig)-- -{% block content %}Default Content{% endblock %} - -{% block footer %}Default Footer{% endblock %} ---DATA-- -return array() ---EXPECT-- -Included Content -Default Footer -Footer diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_nested.test b/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_nested.test deleted file mode 100755 index 71e7c20..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_nested.test +++ /dev/null @@ -1,28 +0,0 @@ ---TEST-- -"extends" tag ---TEMPLATE-- -{% extends "foo.twig" %} - -{% block content %} - {% block inside %} - INSIDE OVERRIDDEN - {% endblock %} - - BEFORE - {{ parent() }} - AFTER -{% endblock %} ---TEMPLATE(foo.twig)-- -{% block content %} - BAR -{% endblock %} ---DATA-- -return array() ---EXPECT-- - -INSIDE OVERRIDDEN - - BEFORE - BAR - - AFTER diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_without_extends.test b/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_without_extends.test deleted file mode 100755 index a9eaa4c..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_without_extends.test +++ /dev/null @@ -1,8 +0,0 @@ ---TEST-- -"parent" tag ---TEMPLATE-- -{% block content %} - {{ parent() }} -{% endblock %} ---EXCEPTION-- -Twig_Error_Syntax: Calling "parent" on a template that does not extend nor "use" another template is forbidden in "index.twig" at line 3 diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_without_extends_but_traits.test b/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_without_extends_but_traits.test deleted file mode 100755 index 63c7305..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/parent_without_extends_but_traits.test +++ /dev/null @@ -1,14 +0,0 @@ ---TEST-- -"parent" tag ---TEMPLATE-- -{% use 'foo.twig' %} - -{% block content %} - {{ parent() }} -{% endblock %} ---TEMPLATE(foo.twig)-- -{% block content %}BAR{% endblock %} ---DATA-- -return array() ---EXPECT-- -BAR diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/template_instance.test b/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/template_instance.test deleted file mode 100755 index d1876a5..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/template_instance.test +++ /dev/null @@ -1,14 +0,0 @@ ---TEST-- -"extends" tag accepts Twig_Template instance ---TEMPLATE-- -{% extends foo %} - -{% block content %} -{{ parent() }}FOO -{% endblock %} ---TEMPLATE(foo.twig)-- -{% block content %}BAR{% endblock %} ---DATA-- -return array('foo' => $twig->loadTemplate('foo.twig')) ---EXPECT-- -BARFOO diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/use.test b/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/use.test deleted file mode 100755 index 8f9ece7..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/inheritance/use.test +++ /dev/null @@ -1,44 +0,0 @@ ---TEST-- -"parent" function ---TEMPLATE-- -{% extends "parent.twig" %} - -{% use "use1.twig" %} -{% use "use2.twig" %} - -{% block content_parent %} - {{ parent() }} -{% endblock %} - -{% block content_use1 %} - {{ parent() }} -{% endblock %} - -{% block content_use2 %} - {{ parent() }} -{% endblock %} - -{% block content %} - {{ block('content_use1_only') }} - {{ block('content_use2_only') }} -{% endblock %} ---TEMPLATE(parent.twig)-- -{% block content_parent 'content_parent' %} -{% block content_use1 'content_parent' %} -{% block content_use2 'content_parent' %} -{% block content '' %} ---TEMPLATE(use1.twig)-- -{% block content_use1 'content_use1' %} -{% block content_use2 'content_use1' %} -{% block content_use1_only 'content_use1_only' %} ---TEMPLATE(use2.twig)-- -{% block content_use2 'content_use2' %} -{% block content_use2_only 'content_use2_only' %} ---DATA-- -return array() ---EXPECT-- - content_parent - content_use1 - content_use2 - content_use1_only - content_use2_only diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/macro/basic.test b/lib/twig/test/Twig/Tests/Fixtures/tags/macro/basic.test deleted file mode 100755 index ef59a57..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/macro/basic.test +++ /dev/null @@ -1,15 +0,0 @@ ---TEST-- -"macro" tag ---TEMPLATE-- -{{ _self.input('username') }} -{{ _self.input('password', null, 'password', 1) }} - -{% macro input(name, value, type, size) %} - -{% endmacro %} ---DATA-- -return array() ---EXPECT-- - - - diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/macro/endmacro_name.test b/lib/twig/test/Twig/Tests/Fixtures/tags/macro/endmacro_name.test deleted file mode 100755 index fa81189..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/macro/endmacro_name.test +++ /dev/null @@ -1,14 +0,0 @@ ---TEST-- -"macro" tag supports name for endmacro ---TEMPLATE-- -{{ _self.foo() }} -{{ _self.bar() }} - -{% macro foo() %}foo{% endmacro %} -{% macro bar() %}bar{% endmacro bar %} ---DATA-- -return array() ---EXPECT-- -foo -bar - diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/macro/external.test b/lib/twig/test/Twig/Tests/Fixtures/tags/macro/external.test deleted file mode 100755 index 5cd3dae..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/macro/external.test +++ /dev/null @@ -1,17 +0,0 @@ ---TEST-- -"macro" tag ---TEMPLATE-- -{% import 'forms.twig' as forms %} - -{{ forms.input('username') }} -{{ forms.input('password', null, 'password', 1) }} ---TEMPLATE(forms.twig)-- -{% macro input(name, value, type, size) %} - -{% endmacro %} ---DATA-- -return array() ---EXPECT-- - - - diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/macro/from.test b/lib/twig/test/Twig/Tests/Fixtures/tags/macro/from.test deleted file mode 100755 index 205f591..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/macro/from.test +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -"macro" tag ---TEMPLATE-- -{% from 'forms.twig' import foo %} -{% from 'forms.twig' import foo as foobar, bar %} - -{{ foo('foo') }} -{{ foobar('foo') }} -{{ bar('foo') }} ---TEMPLATE(forms.twig)-- -{% macro foo(name) %}foo{{ name }}{% endmacro %} -{% macro bar(name) %}bar{{ name }}{% endmacro %} ---DATA-- -return array() ---EXPECT-- -foofoo -foofoo -barfoo diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/macro/self_import.test b/lib/twig/test/Twig/Tests/Fixtures/tags/macro/self_import.test deleted file mode 100755 index 17756cb..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/macro/self_import.test +++ /dev/null @@ -1,17 +0,0 @@ ---TEST-- -"macro" tag ---TEMPLATE-- -{% import _self as forms %} - -{{ forms.input('username') }} -{{ forms.input('password', null, 'password', 1) }} - -{% macro input(name, value, type, size) %} - -{% endmacro %} ---DATA-- -return array() ---EXPECT-- - - - diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/macro/special_chars.test b/lib/twig/test/Twig/Tests/Fixtures/tags/macro/special_chars.test deleted file mode 100755 index e61716e..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/macro/special_chars.test +++ /dev/null @@ -1,12 +0,0 @@ ---TEST-- -"☃" as a macro name ---TEMPLATE-- -{{ _self.☃('foo') }} - -{% macro ☃(foo) %} - ☃{{ foo }}☃ -{% endmacro %} ---DATA-- -return array() ---EXPECT-- -☃foo☃ diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/raw/basic.test b/lib/twig/test/Twig/Tests/Fixtures/tags/raw/basic.test deleted file mode 100755 index 0445e85..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/raw/basic.test +++ /dev/null @@ -1,10 +0,0 @@ ---TEST-- -"raw" tag ---TEMPLATE-- -{% raw %} -{{ foo }} -{% endraw %} ---DATA-- -return array() ---EXPECT-- -{{ foo }} diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/raw/whitespace_control.test b/lib/twig/test/Twig/Tests/Fixtures/tags/raw/whitespace_control.test deleted file mode 100755 index 352bb18..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/raw/whitespace_control.test +++ /dev/null @@ -1,56 +0,0 @@ ---TEST-- -"raw" tag ---TEMPLATE-- -1*** - -{%- raw %} - {{ 'bla' }} -{% endraw %} - -1*** -2*** - -{%- raw -%} - {{ 'bla' }} -{% endraw %} - -2*** -3*** - -{%- raw -%} - {{ 'bla' }} -{% endraw -%} - -3*** -4*** - -{%- raw -%} - {{ 'bla' }} -{%- endraw %} - -4*** -5*** - -{%- raw -%} - {{ 'bla' }} -{%- endraw -%} - -5*** ---DATA-- -return array() ---EXPECT-- -1*** - {{ 'bla' }} - - -1*** -2***{{ 'bla' }} - - -2*** -3***{{ 'bla' }} -3*** -4***{{ 'bla' }} - -4*** -5***{{ 'bla' }}5*** diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/set/basic.test b/lib/twig/test/Twig/Tests/Fixtures/tags/set/basic.test deleted file mode 100755 index a5a9f83..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/set/basic.test +++ /dev/null @@ -1,20 +0,0 @@ ---TEST-- -"set" tag ---TEMPLATE-- -{% set foo = 'foo' %} -{% set bar = 'foo
    ' %} - -{{ foo }} -{{ bar }} - -{% set foo, bar = 'foo', 'bar' %} - -{{ foo }}{{ bar }} ---DATA-- -return array() ---EXPECT-- -foo -foo<br /> - - -foobar diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/set/capture-empty.test b/lib/twig/test/Twig/Tests/Fixtures/tags/set/capture-empty.test deleted file mode 100755 index ec657f0..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/set/capture-empty.test +++ /dev/null @@ -1,9 +0,0 @@ ---TEST-- -"set" tag block empty capture ---TEMPLATE-- -{% set foo %}{% endset %} - -{% if foo %}FAIL{% endif %} ---DATA-- -return array() ---EXPECT-- diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/set/capture.test b/lib/twig/test/Twig/Tests/Fixtures/tags/set/capture.test deleted file mode 100755 index f156a1a..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/set/capture.test +++ /dev/null @@ -1,10 +0,0 @@ ---TEST-- -"set" tag block capture ---TEMPLATE-- -{% set foo %}f
    o
    o{% endset %} - -{{ foo }} ---DATA-- -return array() ---EXPECT-- -f
    o
    o diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/set/expression.test b/lib/twig/test/Twig/Tests/Fixtures/tags/set/expression.test deleted file mode 100755 index 8ff434a..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/set/expression.test +++ /dev/null @@ -1,12 +0,0 @@ ---TEST-- -"set" tag ---TEMPLATE-- -{% set foo, bar = 'foo' ~ 'bar', 'bar' ~ 'foo' %} - -{{ foo }} -{{ bar }} ---DATA-- -return array() ---EXPECT-- -foobar -barfoo diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/spaceless/simple.test b/lib/twig/test/Twig/Tests/Fixtures/tags/spaceless/simple.test deleted file mode 100755 index dd06dec..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/spaceless/simple.test +++ /dev/null @@ -1,12 +0,0 @@ ---TEST-- -"spaceless" tag removes whites between HTML tags ---TEMPLATE-- -{% spaceless %} - -
    foo
    - -{% endspaceless %} ---DATA-- -return array() ---EXPECT-- -
    foo
    diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/special_chars.test b/lib/twig/test/Twig/Tests/Fixtures/tags/special_chars.test deleted file mode 100755 index d584d9e..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/special_chars.test +++ /dev/null @@ -1,8 +0,0 @@ ---TEST-- -"☃" custom tag ---TEMPLATE-- -{% ☃ %} ---DATA-- -return array() ---EXPECT-- -☃ diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/trim_block.test b/lib/twig/test/Twig/Tests/Fixtures/tags/trim_block.test deleted file mode 100755 index 1d2273f..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/trim_block.test +++ /dev/null @@ -1,74 +0,0 @@ ---TEST-- -Whitespace trimming on tags. ---TEMPLATE-- -{{ 5 * '{#-'|length }} -{{ '{{-'|length * 5 + '{%-'|length }} - -Trim on control tag: -{% for i in range(1, 9) -%} - {{ i }} -{%- endfor %} - - -Trim on output tag: -{% for i in range(1, 9) %} - {{- i -}} -{% endfor %} - - -Trim comments: - -{#- Invisible -#} - -After the comment. - -Trim leading space: -{% if leading %} - - {{- leading }} -{% endif %} - -{%- if leading %} - {{- leading }} - -{%- endif %} - - -Trim trailing space: -{% if trailing -%} - {{ trailing -}} - -{% endif -%} - -Combined: - -{%- if both -%} -
      -
    • {{- both -}}
    • -
    - -{%- endif -%} - -end ---DATA-- -return array('leading' => 'leading space', 'trailing' => 'trailing space', 'both' => 'both') ---EXPECT-- -15 -18 - -Trim on control tag: -123456789 - -Trim on output tag: -123456789 - -Trim comments:After the comment. - -Trim leading space: -leading space -leading space - -Trim trailing space: -trailing spaceCombined:
      -
    • both
    • -
    end diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/use/aliases.test b/lib/twig/test/Twig/Tests/Fixtures/tags/use/aliases.test deleted file mode 100755 index f887006..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/use/aliases.test +++ /dev/null @@ -1,12 +0,0 @@ ---TEST-- -"use" tag ---TEMPLATE-- -{% use "blocks.twig" with content as foo %} - -{{ block('foo') }} ---TEMPLATE(blocks.twig)-- -{% block content 'foo' %} ---DATA-- -return array() ---EXPECT-- -foo diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/use/basic.test b/lib/twig/test/Twig/Tests/Fixtures/tags/use/basic.test deleted file mode 100755 index 7364d76..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/use/basic.test +++ /dev/null @@ -1,12 +0,0 @@ ---TEST-- -"use" tag ---TEMPLATE-- -{% use "blocks.twig" %} - -{{ block('content') }} ---TEMPLATE(blocks.twig)-- -{% block content 'foo' %} ---DATA-- -return array() ---EXPECT-- -foo diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/use/deep.test b/lib/twig/test/Twig/Tests/Fixtures/tags/use/deep.test deleted file mode 100755 index b551a1e..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/use/deep.test +++ /dev/null @@ -1,22 +0,0 @@ ---TEST-- -"use" tag ---TEMPLATE-- -{% use "foo.twig" %} - -{{ block('content') }} -{{ block('foo') }} -{{ block('bar') }} ---TEMPLATE(foo.twig)-- -{% use "bar.twig" %} - -{% block content 'foo' %} -{% block foo 'foo' %} ---TEMPLATE(bar.twig)-- -{% block content 'bar' %} -{% block bar 'bar' %} ---DATA-- -return array() ---EXPECT-- -foo -foo -bar diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/use/deep_empty.test b/lib/twig/test/Twig/Tests/Fixtures/tags/use/deep_empty.test deleted file mode 100755 index 05cca68..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/use/deep_empty.test +++ /dev/null @@ -1,10 +0,0 @@ ---TEST-- -"use" tag ---TEMPLATE-- -{% use "foo.twig" %} ---TEMPLATE(foo.twig)-- -{% use "bar.twig" %} ---TEMPLATE(bar.twig)-- ---DATA-- -return array() ---EXPECT-- diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/use/multiple.test b/lib/twig/test/Twig/Tests/Fixtures/tags/use/multiple.test deleted file mode 100755 index 198be0c..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/use/multiple.test +++ /dev/null @@ -1,21 +0,0 @@ ---TEST-- -"use" tag ---TEMPLATE-- -{% use "foo.twig" %} -{% use "bar.twig" %} - -{{ block('content') }} -{{ block('foo') }} -{{ block('bar') }} ---TEMPLATE(foo.twig)-- -{% block content 'foo' %} -{% block foo 'foo' %} ---TEMPLATE(bar.twig)-- -{% block content 'bar' %} -{% block bar 'bar' %} ---DATA-- -return array() ---EXPECT-- -bar -foo -bar diff --git a/lib/twig/test/Twig/Tests/Fixtures/tags/use/multiple_aliases.test b/lib/twig/test/Twig/Tests/Fixtures/tags/use/multiple_aliases.test deleted file mode 100755 index 8de871a..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tags/use/multiple_aliases.test +++ /dev/null @@ -1,23 +0,0 @@ ---TEST-- -"use" tag ---TEMPLATE-- -{% use "foo.twig" with content as foo_content %} -{% use "bar.twig" %} - -{{ block('content') }} -{{ block('foo') }} -{{ block('bar') }} -{{ block('foo_content') }} ---TEMPLATE(foo.twig)-- -{% block content 'foo' %} -{% block foo 'foo' %} ---TEMPLATE(bar.twig)-- -{% block content 'bar' %} -{% block bar 'bar' %} ---DATA-- -return array() ---EXPECT-- -bar -foo -bar -foo diff --git a/lib/twig/test/Twig/Tests/Fixtures/tests/array.test b/lib/twig/test/Twig/Tests/Fixtures/tests/array.test deleted file mode 100755 index 1429d37..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tests/array.test +++ /dev/null @@ -1,24 +0,0 @@ ---TEST-- -array index test ---TEMPLATE-- -{% for key, value in days %} -{{ key }} -{% endfor %} ---DATA-- -return array('days' => array( - 1 => array('money' => 9), - 2 => array('money' => 21), - 3 => array('money' => 38), - 4 => array('money' => 6), - 18 => array('money' => 6), - 19 => array('money' => 3), - 31 => array('money' => 11), -)); ---EXPECT-- -1 -2 -3 -4 -18 -19 -31 diff --git a/lib/twig/test/Twig/Tests/Fixtures/tests/constant.test b/lib/twig/test/Twig/Tests/Fixtures/tests/constant.test deleted file mode 100755 index fb3d288..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tests/constant.test +++ /dev/null @@ -1,12 +0,0 @@ ---TEST-- -"const" test ---TEMPLATE-- -{{ 8 is constant('E_NOTICE') ? 'ok' : 'no' }} -{{ 'bar' is constant('Foo::BAR_NAME') ? 'ok' : 'no' }} -{{ value is constant('Foo::BAR_NAME') ? 'ok' : 'no' }} ---DATA-- -return array('value' => 'bar'); ---EXPECT-- -ok -ok -ok \ No newline at end of file diff --git a/lib/twig/test/Twig/Tests/Fixtures/tests/defined.test b/lib/twig/test/Twig/Tests/Fixtures/tests/defined.test deleted file mode 100755 index 2fbaa86..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tests/defined.test +++ /dev/null @@ -1,108 +0,0 @@ ---TEST-- -"defined" test ---TEMPLATE-- -{{ definedVar is defined ? 'ok' : 'ko' }} -{{ definedVar is not defined ? 'ko' : 'ok' }} -{{ undefinedVar is defined ? 'ko' : 'ok' }} -{{ undefinedVar is not defined ? 'ok' : 'ko' }} -{{ zeroVar is defined ? 'ok' : 'ko' }} -{{ nullVar is defined ? 'ok' : 'ko' }} -{{ nested.definedVar is defined ? 'ok' : 'ko' }} -{{ nested['definedVar'] is defined ? 'ok' : 'ko' }} -{{ nested.definedVar is not defined ? 'ko' : 'ok' }} -{{ nested.undefinedVar is defined ? 'ko' : 'ok' }} -{{ nested['undefinedVar'] is defined ? 'ko' : 'ok' }} -{{ nested.undefinedVar is not defined ? 'ok' : 'ko' }} -{{ nested.zeroVar is defined ? 'ok' : 'ko' }} -{{ nested.nullVar is defined ? 'ok' : 'ko' }} -{{ nested.definedArray.0 is defined ? 'ok' : 'ko' }} -{{ nested['definedArray'][0] is defined ? 'ok' : 'ko' }} -{{ object.foo is defined ? 'ok' : 'ko' }} -{{ object.undefinedMethod is defined ? 'ko' : 'ok' }} -{{ object.getFoo() is defined ? 'ok' : 'ko' }} -{{ object.getFoo('a') is defined ? 'ok' : 'ko' }} -{{ object.undefinedMethod() is defined ? 'ko' : 'ok' }} -{{ object.undefinedMethod('a') is defined ? 'ko' : 'ok' }} -{{ object.self.foo is defined ? 'ok' : 'ko' }} -{{ object.self.undefinedMethod is defined ? 'ko' : 'ok' }} -{{ object.undefinedMethod.self is defined ? 'ko' : 'ok' }} ---DATA-- -return array( - 'definedVar' => 'defined', - 'zeroVar' => 0, - 'nullVar' => null, - 'nested' => array( - 'definedVar' => 'defined', - 'zeroVar' => 0, - 'nullVar' => null, - 'definedArray' => array(0), - ), - 'object' => new Foo(), -); ---EXPECT-- -ok -ok -ok -ok -ok -ok -ok -ok -ok -ok -ok -ok -ok -ok -ok -ok -ok -ok -ok -ok -ok -ok -ok -ok -ok ---DATA-- -return array( - 'definedVar' => 'defined', - 'zeroVar' => 0, - 'nullVar' => null, - 'nested' => array( - 'definedVar' => 'defined', - 'zeroVar' => 0, - 'nullVar' => null, - 'definedArray' => array(0), - ), - 'object' => new Foo(), -); ---CONFIG-- -return array('strict_variables' => false) ---EXPECT-- -ok -ok -ok -ok -ok -ok -ok -ok -ok -ok -ok -ok -ok -ok -ok -ok -ok -ok -ok -ok -ok -ok -ok -ok -ok diff --git a/lib/twig/test/Twig/Tests/Fixtures/tests/empty.test b/lib/twig/test/Twig/Tests/Fixtures/tests/empty.test deleted file mode 100755 index a776d03..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tests/empty.test +++ /dev/null @@ -1,45 +0,0 @@ ---TEST-- -"empty" test ---TEMPLATE-- -{{ foo is empty ? 'ok' : 'ko' }} -{{ bar is empty ? 'ok' : 'ko' }} -{{ foobar is empty ? 'ok' : 'ko' }} -{{ array is empty ? 'ok' : 'ko' }} -{{ zero is empty ? 'ok' : 'ko' }} -{{ string is empty ? 'ok' : 'ko' }} -{{ countable_empty is empty ? 'ok' : 'ko' }} -{{ countable_not_empty is empty ? 'ok' : 'ko' }} -{{ markup_empty is empty ? 'ok' : 'ko' }} -{{ markup_not_empty is empty ? 'ok' : 'ko' }} ---DATA-- - -class CountableStub implements Countable -{ - private $items; - - public function __construct(array $items) - { - $this->items = $items; - } - - public function count() - { - return count($this->items); - } -} -return array( - 'foo' => '', 'bar' => null, 'foobar' => false, 'array' => array(), 'zero' => 0, 'string' => '0', - 'countable_empty' => new CountableStub(array()), 'countable_not_empty' => new CountableStub(array(1, 2)), - 'markup_empty' => new Twig_Markup('', 'UTF-8'), 'markup_not_empty' => new Twig_Markup('test', 'UTF-8'), -); ---EXPECT-- -ok -ok -ok -ok -ko -ko -ok -ko -ok -ko diff --git a/lib/twig/test/Twig/Tests/Fixtures/tests/even.test b/lib/twig/test/Twig/Tests/Fixtures/tests/even.test deleted file mode 100755 index 695b4c2..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tests/even.test +++ /dev/null @@ -1,14 +0,0 @@ ---TEST-- -"even" test ---TEMPLATE-- -{{ 1 is even ? 'ko' : 'ok' }} -{{ 2 is even ? 'ok' : 'ko' }} -{{ 1 is not even ? 'ok' : 'ko' }} -{{ 2 is not even ? 'ko' : 'ok' }} ---DATA-- -return array() ---EXPECT-- -ok -ok -ok -ok diff --git a/lib/twig/test/Twig/Tests/Fixtures/tests/in.test b/lib/twig/test/Twig/Tests/Fixtures/tests/in.test deleted file mode 100755 index 45c72fd..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tests/in.test +++ /dev/null @@ -1,48 +0,0 @@ ---TEST-- -Twig supports the in operator ---TEMPLATE-- -{% if bar in foo %} -TRUE -{% endif %} -{% if not (bar in foo) %} -{% else %} -TRUE -{% endif %} -{% if bar not in foo %} -{% else %} -TRUE -{% endif %} -{% if 'a' in bar %} -TRUE -{% endif %} -{% if 'c' not in bar %} -TRUE -{% endif %} -{% if '' not in bar %} -TRUE -{% endif %} -{% if '' in '' %} -TRUE -{% endif %} -{% if '0' not in '' %} -TRUE -{% endif %} -{% if 'a' not in '0' %} -TRUE -{% endif %} -{% if '0' in '0' %} -TRUE -{% endif %} ---DATA-- -return array('bar' => 'bar', 'foo' => array('bar' => 'bar')) ---EXPECT-- -TRUE -TRUE -TRUE -TRUE -TRUE -TRUE -TRUE -TRUE -TRUE -TRUE diff --git a/lib/twig/test/Twig/Tests/Fixtures/tests/odd.test b/lib/twig/test/Twig/Tests/Fixtures/tests/odd.test deleted file mode 100755 index 1b8311e..0000000 --- a/lib/twig/test/Twig/Tests/Fixtures/tests/odd.test +++ /dev/null @@ -1,10 +0,0 @@ ---TEST-- -"odd" test ---TEMPLATE-- -{{ 1 is odd ? 'ok' : 'ko' }} -{{ 2 is odd ? 'ko' : 'ok' }} ---DATA-- -return array() ---EXPECT-- -ok -ok \ No newline at end of file diff --git a/lib/twig/test/Twig/Tests/LexerTest.php b/lib/twig/test/Twig/Tests/LexerTest.php deleted file mode 100755 index ce87898..0000000 --- a/lib/twig/test/Twig/Tests/LexerTest.php +++ /dev/null @@ -1,249 +0,0 @@ -tokenize($template); - - $stream->expect(Twig_Token::BLOCK_START_TYPE); - $this->assertSame('☃', $stream->expect(Twig_Token::NAME_TYPE)->getValue()); - } - - public function testNameLabelForFunction() - { - $template = '{{ ☃() }}'; - - $lexer = new Twig_Lexer(new Twig_Environment()); - $stream = $lexer->tokenize($template); - - $stream->expect(Twig_Token::VAR_START_TYPE); - $this->assertSame('☃', $stream->expect(Twig_Token::NAME_TYPE)->getValue()); - } - - public function testBracketsNesting() - { - $template = '{{ {"a":{"b":"c"}} }}'; - - $this->assertEquals(2, $this->countToken($template, Twig_Token::PUNCTUATION_TYPE, '{')); - $this->assertEquals(2, $this->countToken($template, Twig_Token::PUNCTUATION_TYPE, '}')); - } - - protected function countToken($template, $type, $value = null) - { - $lexer = new Twig_Lexer(new Twig_Environment()); - $stream = $lexer->tokenize($template); - - $count = 0; - $tokens = array(); - while (!$stream->isEOF()) { - $token = $stream->next(); - if ($type === $token->getType()) { - if (null === $value || $value === $token->getValue()) { - ++$count; - } - } - } - - return $count; - } - - public function testLineDirective() - { - $template = "foo\n" - . "bar\n" - . "{% line 10 %}\n" - . "{{\n" - . "baz\n" - . "}}\n"; - - $lexer = new Twig_Lexer(new Twig_Environment()); - $stream = $lexer->tokenize($template); - - // foo\nbar\n - $this->assertSame(1, $stream->expect(Twig_Token::TEXT_TYPE)->getLine()); - // \n (after {% line %}) - $this->assertSame(10, $stream->expect(Twig_Token::TEXT_TYPE)->getLine()); - // {{ - $this->assertSame(11, $stream->expect(Twig_Token::VAR_START_TYPE)->getLine()); - // baz - $this->assertSame(12, $stream->expect(Twig_Token::NAME_TYPE)->getLine()); - } - - public function testLineDirectiveInline() - { - $template = "foo\n" - . "bar{% line 10 %}{{\n" - . "baz\n" - . "}}\n"; - - $lexer = new Twig_Lexer(new Twig_Environment()); - $stream = $lexer->tokenize($template); - - // foo\nbar - $this->assertSame(1, $stream->expect(Twig_Token::TEXT_TYPE)->getLine()); - // {{ - $this->assertSame(10, $stream->expect(Twig_Token::VAR_START_TYPE)->getLine()); - // baz - $this->assertSame(11, $stream->expect(Twig_Token::NAME_TYPE)->getLine()); - } - - public function testLongComments() - { - $template = '{# '.str_repeat('*', 100000).' #}'; - - $lexer = new Twig_Lexer(new Twig_Environment()); - $lexer->tokenize($template); - - // should not throw an exception - } - - public function testLongRaw() - { - $template = '{% raw %}'.str_repeat('*', 100000).'{% endraw %}'; - - $lexer = new Twig_Lexer(new Twig_Environment()); - $stream = $lexer->tokenize($template); - - // should not throw an exception - } - - public function testLongVar() - { - $template = '{{ '.str_repeat('x', 100000).' }}'; - - $lexer = new Twig_Lexer(new Twig_Environment()); - $stream = $lexer->tokenize($template); - - // should not throw an exception - } - - public function testLongBlock() - { - $template = '{% '.str_repeat('x', 100000).' %}'; - - $lexer = new Twig_Lexer(new Twig_Environment()); - $stream = $lexer->tokenize($template); - - // should not throw an exception - } - - public function testBigNumbers() - { - $template = '{{ 922337203685477580700 }}'; - - $lexer = new Twig_Lexer(new Twig_Environment()); - $stream = $lexer->tokenize($template); - $node = $stream->next(); - $node = $stream->next(); - $this->assertEquals(922337203685477580700, $node->getValue()); - } - - public function testString() - { - $template = 'foo {{ "bar #{ baz + 1 }" }}'; - - $lexer = new Twig_Lexer(new Twig_Environment()); - $stream = $lexer->tokenize($template); - $stream->expect(Twig_Token::TEXT_TYPE, 'foo '); - $stream->expect(Twig_Token::VAR_START_TYPE); - $stream->expect(Twig_Token::STRING_TYPE, 'bar '); - $stream->expect(Twig_Token::INTERPOLATION_START_TYPE); - $stream->expect(Twig_Token::NAME_TYPE, 'baz'); - $stream->expect(Twig_Token::OPERATOR_TYPE, '+'); - $stream->expect(Twig_Token::NUMBER_TYPE, '1'); - $stream->expect(Twig_Token::INTERPOLATION_END_TYPE); - $stream->expect(Twig_Token::VAR_END_TYPE); - } - - public function testStringWithEscapedInterpolation() - { - $template = '{{ "bar \#{baz+1}" }}'; - - $lexer = new Twig_Lexer(new Twig_Environment()); - $stream = $lexer->tokenize($template); - $stream->expect(Twig_Token::VAR_START_TYPE); - $stream->expect(Twig_Token::STRING_TYPE, 'bar #{baz+1}'); - $stream->expect(Twig_Token::VAR_END_TYPE); - } - - public function testStringWithHash() - { - $template = '{{ "bar # baz" }}'; - - $lexer = new Twig_Lexer(new Twig_Environment()); - $stream = $lexer->tokenize($template); - $stream->expect(Twig_Token::VAR_START_TYPE); - $stream->expect(Twig_Token::STRING_TYPE, 'bar # baz'); - $stream->expect(Twig_Token::VAR_END_TYPE); - } - - /** - * @expectedException Twig_Error_Syntax - * @expectedExceptionMessage Unclosed """ - */ - public function testStringWithUnterminatedInterpolation() - { - $template = '{{ "bar #{x" }}'; - - $lexer = new Twig_Lexer(new Twig_Environment()); - $stream = $lexer->tokenize($template); - } - - public function testStringWithNestedInterpolations() - { - $template = '{{ "bar #{ "foo#{bar}" }" }}'; - - $lexer = new Twig_Lexer(new Twig_Environment()); - $stream = $lexer->tokenize($template); - $stream->expect(Twig_Token::VAR_START_TYPE); - $stream->expect(Twig_Token::STRING_TYPE, 'bar '); - $stream->expect(Twig_Token::INTERPOLATION_START_TYPE); - $stream->expect(Twig_Token::STRING_TYPE, 'foo'); - $stream->expect(Twig_Token::INTERPOLATION_START_TYPE); - $stream->expect(Twig_Token::NAME_TYPE, 'bar'); - $stream->expect(Twig_Token::INTERPOLATION_END_TYPE); - $stream->expect(Twig_Token::INTERPOLATION_END_TYPE); - $stream->expect(Twig_Token::VAR_END_TYPE); - } - - public function testStringWithNestedInterpolationsInBlock() - { - $template = '{% foo "bar #{ "foo#{bar}" }" %}'; - - $lexer = new Twig_Lexer(new Twig_Environment()); - $stream = $lexer->tokenize($template); - $stream->expect(Twig_Token::BLOCK_START_TYPE); - $stream->expect(Twig_Token::NAME_TYPE, 'foo'); - $stream->expect(Twig_Token::STRING_TYPE, 'bar '); - $stream->expect(Twig_Token::INTERPOLATION_START_TYPE); - $stream->expect(Twig_Token::STRING_TYPE, 'foo'); - $stream->expect(Twig_Token::INTERPOLATION_START_TYPE); - $stream->expect(Twig_Token::NAME_TYPE, 'bar'); - $stream->expect(Twig_Token::INTERPOLATION_END_TYPE); - $stream->expect(Twig_Token::INTERPOLATION_END_TYPE); - $stream->expect(Twig_Token::BLOCK_END_TYPE); - } - - public function testOperatorEndingWithALetterAtTheEndOfALine() - { - $template = "{{ 1 and\n0}}"; - - $lexer = new Twig_Lexer(new Twig_Environment()); - $stream = $lexer->tokenize($template); - $stream->expect(Twig_Token::VAR_START_TYPE); - $stream->expect(Twig_Token::NUMBER_TYPE, 1); - $stream->expect(Twig_Token::OPERATOR_TYPE, 'and'); - } -} diff --git a/lib/twig/test/Twig/Tests/Loader/ArrayTest.php b/lib/twig/test/Twig/Tests/Loader/ArrayTest.php deleted file mode 100755 index 1369a6b..0000000 --- a/lib/twig/test/Twig/Tests/Loader/ArrayTest.php +++ /dev/null @@ -1,97 +0,0 @@ - 'bar')); - - $this->assertEquals('bar', $loader->getSource('foo')); - } - - /** - * @expectedException Twig_Error_Loader - */ - public function testGetSourceWhenTemplateDoesNotExist() - { - $loader = new Twig_Loader_Array(array()); - - $loader->getSource('foo'); - } - - public function testGetCacheKey() - { - $loader = new Twig_Loader_Array(array('foo' => 'bar')); - - $this->assertEquals('bar', $loader->getCacheKey('foo')); - } - - /** - * @expectedException Twig_Error_Loader - */ - public function testGetCacheKeyWhenTemplateDoesNotExist() - { - $loader = new Twig_Loader_Array(array()); - - $loader->getCacheKey('foo'); - } - - public function testSetTemplate() - { - $loader = new Twig_Loader_Array(array()); - $loader->setTemplate('foo', 'bar'); - - $this->assertEquals('bar', $loader->getSource('foo')); - } - - public function testIsFresh() - { - $loader = new Twig_Loader_Array(array('foo' => 'bar')); - $this->assertTrue($loader->isFresh('foo', time())); - } - - /** - * @expectedException Twig_Error_Loader - */ - public function testIsFreshWhenTemplateDoesNotExist() - { - $loader = new Twig_Loader_Array(array()); - - $loader->isFresh('foo', time()); - } - - public function testTemplateReference() - { - $name = new Twig_Test_Loader_TemplateReference('foo'); - $loader = new Twig_Loader_Array(array('foo' => 'bar')); - - $loader->getCacheKey($name); - $loader->getSource($name); - $loader->isFresh($name, time()); - $loader->setTemplate($name, 'foobar'); - } -} - -class Twig_Test_Loader_TemplateReference -{ - private $name; - - public function __construct($name) - { - $this->name = $name; - } - - public function __toString() - { - return $this->name; - } -} diff --git a/lib/twig/test/Twig/Tests/Loader/ChainTest.php b/lib/twig/test/Twig/Tests/Loader/ChainTest.php deleted file mode 100755 index 580ae10..0000000 --- a/lib/twig/test/Twig/Tests/Loader/ChainTest.php +++ /dev/null @@ -1,63 +0,0 @@ - 'bar')), - new Twig_Loader_Array(array('foo' => 'foobar', 'bar' => 'foo')), - )); - - $this->assertEquals('bar', $loader->getSource('foo')); - $this->assertEquals('foo', $loader->getSource('bar')); - } - - /** - * @expectedException Twig_Error_Loader - */ - public function testGetSourceWhenTemplateDoesNotExist() - { - $loader = new Twig_Loader_Chain(array()); - - $loader->getSource('foo'); - } - - public function testGetCacheKey() - { - $loader = new Twig_Loader_Chain(array( - new Twig_Loader_Array(array('foo' => 'bar')), - new Twig_Loader_Array(array('foo' => 'foobar', 'bar' => 'foo')), - )); - - $this->assertEquals('bar', $loader->getCacheKey('foo')); - $this->assertEquals('foo', $loader->getCacheKey('bar')); - } - - /** - * @expectedException Twig_Error_Loader - */ - public function testGetCacheKeyWhenTemplateDoesNotExist() - { - $loader = new Twig_Loader_Chain(array()); - - $loader->getCacheKey('foo'); - } - - public function testAddLoader() - { - $loader = new Twig_Loader_Chain(); - $loader->addLoader(new Twig_Loader_Array(array('foo' => 'bar'))); - - $this->assertEquals('bar', $loader->getSource('foo')); - } -} diff --git a/lib/twig/test/Twig/Tests/Loader/FilesystemTest.php b/lib/twig/test/Twig/Tests/Loader/FilesystemTest.php deleted file mode 100755 index 22ae5aa..0000000 --- a/lib/twig/test/Twig/Tests/Loader/FilesystemTest.php +++ /dev/null @@ -1,52 +0,0 @@ -getCacheKey($template); - $this->fail(); - } catch (Twig_Error_Loader $e) { - $this->assertNotContains('Unable to find template', $e->getMessage()); - } - } - - public function getSecurityTests() - { - return array( - array("AutoloaderTest\0.php"), - array('..\\AutoloaderTest.php'), - array('..\\\\\\AutoloaderTest.php'), - array('../AutoloaderTest.php'), - array('..////AutoloaderTest.php'), - array('./../AutoloaderTest.php'), - array('.\\..\\AutoloaderTest.php'), - array('././././././../AutoloaderTest.php'), - array('.\\./.\\./.\\./../AutoloaderTest.php'), - array('foo/../../AutoloaderTest.php'), - array('foo\\..\\..\\AutoloaderTest.php'), - array('foo/../bar/../../AutoloaderTest.php'), - array('foo/bar/../../../AutoloaderTest.php'), - array('filters/../../AutoloaderTest.php'), - array('filters//..//..//AutoloaderTest.php'), - array('filters\\..\\..\\AutoloaderTest.php'), - array('filters\\\\..\\\\..\\\\AutoloaderTest.php'), - array('filters\\//../\\/\\..\\AutoloaderTest.php'), - ); - } -} diff --git a/lib/twig/test/Twig/Tests/Node/AutoEscapeTest.php b/lib/twig/test/Twig/Tests/Node/AutoEscapeTest.php deleted file mode 100755 index ebfcb48..0000000 --- a/lib/twig/test/Twig/Tests/Node/AutoEscapeTest.php +++ /dev/null @@ -1,46 +0,0 @@ -assertEquals($body, $node->getNode('body')); - $this->assertEquals(true, $node->getAttribute('value')); - } - - /** - * @covers Twig_Node_AutoEscape::compile - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $body = new Twig_Node(array(new Twig_Node_Text('foo', 0))); - $node = new Twig_Node_AutoEscape(true, $body, 0); - - return array( - array($node, 'echo "foo";'), - ); - } -} diff --git a/lib/twig/test/Twig/Tests/Node/BlockReferenceTest.php b/lib/twig/test/Twig/Tests/Node/BlockReferenceTest.php deleted file mode 100755 index f1c5ab1..0000000 --- a/lib/twig/test/Twig/Tests/Node/BlockReferenceTest.php +++ /dev/null @@ -1,41 +0,0 @@ -assertEquals('foo', $node->getAttribute('name')); - } - - /** - * @covers Twig_Node_BlockReference::compile - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - return array( - array(new Twig_Node_BlockReference('foo', 0), '$this->displayBlock(\'foo\', $context, $blocks);'), - ); - } -} diff --git a/lib/twig/test/Twig/Tests/Node/BlockTest.php b/lib/twig/test/Twig/Tests/Node/BlockTest.php deleted file mode 100755 index 6bc5e79..0000000 --- a/lib/twig/test/Twig/Tests/Node/BlockTest.php +++ /dev/null @@ -1,52 +0,0 @@ -assertEquals($body, $node->getNode('body')); - $this->assertEquals('foo', $node->getAttribute('name')); - } - - /** - * @covers Twig_Node_Block::compile - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $body = new Twig_Node_Text('foo', 0); - $node = new Twig_Node_Block('foo', $body, 0); - - return array( - array($node, <<assertEquals($expr, $node->getNode('expr')); - } - - /** - * @covers Twig_Node_Do::compile - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $tests = array(); - - $expr = new Twig_Node_Expression_Constant('foo', 0); - $node = new Twig_Node_Do($expr, 0); - $tests[] = array($node, '"foo";'); - - return $tests; - } -} diff --git a/lib/twig/test/Twig/Tests/Node/Expression/ArrayTest.php b/lib/twig/test/Twig/Tests/Node/Expression/ArrayTest.php deleted file mode 100755 index 06b30e9..0000000 --- a/lib/twig/test/Twig/Tests/Node/Expression/ArrayTest.php +++ /dev/null @@ -1,51 +0,0 @@ -assertEquals($foo, $node->getNode(1)); - } - - /** - * @covers Twig_Node_Expression_Array::compile - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $elements = array( - new Twig_Node_Expression_Constant('foo', 0), - new Twig_Node_Expression_Constant('bar', 0), - - new Twig_Node_Expression_Constant('bar', 0), - new Twig_Node_Expression_Constant('foo', 0), - ); - $node = new Twig_Node_Expression_Array($elements, 0); - - return array( - array($node, 'array("foo" => "bar", "bar" => "foo")'), - ); - } -} diff --git a/lib/twig/test/Twig/Tests/Node/Expression/AssignNameTest.php b/lib/twig/test/Twig/Tests/Node/Expression/AssignNameTest.php deleted file mode 100755 index fc92b0d..0000000 --- a/lib/twig/test/Twig/Tests/Node/Expression/AssignNameTest.php +++ /dev/null @@ -1,43 +0,0 @@ -assertEquals('foo', $node->getAttribute('name')); - } - - /** - * @covers Twig_Node_Expression_AssignName::compile - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $node = new Twig_Node_Expression_AssignName('foo', 0); - - return array( - array($node, '$context["foo"]'), - ); - } -} diff --git a/lib/twig/test/Twig/Tests/Node/Expression/Binary/AddTest.php b/lib/twig/test/Twig/Tests/Node/Expression/Binary/AddTest.php deleted file mode 100755 index 80d318f..0000000 --- a/lib/twig/test/Twig/Tests/Node/Expression/Binary/AddTest.php +++ /dev/null @@ -1,49 +0,0 @@ -assertEquals($left, $node->getNode('left')); - $this->assertEquals($right, $node->getNode('right')); - } - - /** - * @covers Twig_Node_Expression_Binary_Add::compile - * @covers Twig_Node_Expression_Binary_Add::operator - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $left = new Twig_Node_Expression_Constant(1, 0); - $right = new Twig_Node_Expression_Constant(2, 0); - $node = new Twig_Node_Expression_Binary_Add($left, $right, 0); - - return array( - array($node, '(1 + 2)'), - ); - } -} diff --git a/lib/twig/test/Twig/Tests/Node/Expression/Binary/AndTest.php b/lib/twig/test/Twig/Tests/Node/Expression/Binary/AndTest.php deleted file mode 100755 index a6ed4f2..0000000 --- a/lib/twig/test/Twig/Tests/Node/Expression/Binary/AndTest.php +++ /dev/null @@ -1,49 +0,0 @@ -assertEquals($left, $node->getNode('left')); - $this->assertEquals($right, $node->getNode('right')); - } - - /** - * @covers Twig_Node_Expression_Binary_And::compile - * @covers Twig_Node_Expression_Binary_And::operator - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $left = new Twig_Node_Expression_Constant(1, 0); - $right = new Twig_Node_Expression_Constant(2, 0); - $node = new Twig_Node_Expression_Binary_And($left, $right, 0); - - return array( - array($node, '(1 && 2)'), - ); - } -} diff --git a/lib/twig/test/Twig/Tests/Node/Expression/Binary/ConcatTest.php b/lib/twig/test/Twig/Tests/Node/Expression/Binary/ConcatTest.php deleted file mode 100755 index a04edc9..0000000 --- a/lib/twig/test/Twig/Tests/Node/Expression/Binary/ConcatTest.php +++ /dev/null @@ -1,49 +0,0 @@ -assertEquals($left, $node->getNode('left')); - $this->assertEquals($right, $node->getNode('right')); - } - - /** - * @covers Twig_Node_Expression_Binary_Concat::compile - * @covers Twig_Node_Expression_Binary_Concat::operator - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $left = new Twig_Node_Expression_Constant(1, 0); - $right = new Twig_Node_Expression_Constant(2, 0); - $node = new Twig_Node_Expression_Binary_Concat($left, $right, 0); - - return array( - array($node, '(1 . 2)'), - ); - } -} diff --git a/lib/twig/test/Twig/Tests/Node/Expression/Binary/DivTest.php b/lib/twig/test/Twig/Tests/Node/Expression/Binary/DivTest.php deleted file mode 100755 index 42002fc..0000000 --- a/lib/twig/test/Twig/Tests/Node/Expression/Binary/DivTest.php +++ /dev/null @@ -1,49 +0,0 @@ -assertEquals($left, $node->getNode('left')); - $this->assertEquals($right, $node->getNode('right')); - } - - /** - * @covers Twig_Node_Expression_Binary_Div::compile - * @covers Twig_Node_Expression_Binary_Div::operator - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $left = new Twig_Node_Expression_Constant(1, 0); - $right = new Twig_Node_Expression_Constant(2, 0); - $node = new Twig_Node_Expression_Binary_Div($left, $right, 0); - - return array( - array($node, '(1 / 2)'), - ); - } -} diff --git a/lib/twig/test/Twig/Tests/Node/Expression/Binary/FloorDivTest.php b/lib/twig/test/Twig/Tests/Node/Expression/Binary/FloorDivTest.php deleted file mode 100755 index 94ff2f6..0000000 --- a/lib/twig/test/Twig/Tests/Node/Expression/Binary/FloorDivTest.php +++ /dev/null @@ -1,49 +0,0 @@ -assertEquals($left, $node->getNode('left')); - $this->assertEquals($right, $node->getNode('right')); - } - - /** - * @covers Twig_Node_Expression_Binary_FloorDiv::compile - * @covers Twig_Node_Expression_Binary_FloorDiv::operator - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $left = new Twig_Node_Expression_Constant(1, 0); - $right = new Twig_Node_Expression_Constant(2, 0); - $node = new Twig_Node_Expression_Binary_FloorDiv($left, $right, 0); - - return array( - array($node, 'intval(floor((1 / 2)))'), - ); - } -} diff --git a/lib/twig/test/Twig/Tests/Node/Expression/Binary/ModTest.php b/lib/twig/test/Twig/Tests/Node/Expression/Binary/ModTest.php deleted file mode 100755 index 67612a5..0000000 --- a/lib/twig/test/Twig/Tests/Node/Expression/Binary/ModTest.php +++ /dev/null @@ -1,49 +0,0 @@ -assertEquals($left, $node->getNode('left')); - $this->assertEquals($right, $node->getNode('right')); - } - - /** - * @covers Twig_Node_Expression_Binary_Mod::compile - * @covers Twig_Node_Expression_Binary_Mod::operator - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $left = new Twig_Node_Expression_Constant(1, 0); - $right = new Twig_Node_Expression_Constant(2, 0); - $node = new Twig_Node_Expression_Binary_Mod($left, $right, 0); - - return array( - array($node, '(1 % 2)'), - ); - } -} diff --git a/lib/twig/test/Twig/Tests/Node/Expression/Binary/MulTest.php b/lib/twig/test/Twig/Tests/Node/Expression/Binary/MulTest.php deleted file mode 100755 index c817d02..0000000 --- a/lib/twig/test/Twig/Tests/Node/Expression/Binary/MulTest.php +++ /dev/null @@ -1,49 +0,0 @@ -assertEquals($left, $node->getNode('left')); - $this->assertEquals($right, $node->getNode('right')); - } - - /** - * @covers Twig_Node_Expression_Binary_Mul::compile - * @covers Twig_Node_Expression_Binary_Mul::operator - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $left = new Twig_Node_Expression_Constant(1, 0); - $right = new Twig_Node_Expression_Constant(2, 0); - $node = new Twig_Node_Expression_Binary_Mul($left, $right, 0); - - return array( - array($node, '(1 * 2)'), - ); - } -} diff --git a/lib/twig/test/Twig/Tests/Node/Expression/Binary/OrTest.php b/lib/twig/test/Twig/Tests/Node/Expression/Binary/OrTest.php deleted file mode 100755 index d8e2f8d..0000000 --- a/lib/twig/test/Twig/Tests/Node/Expression/Binary/OrTest.php +++ /dev/null @@ -1,49 +0,0 @@ -assertEquals($left, $node->getNode('left')); - $this->assertEquals($right, $node->getNode('right')); - } - - /** - * @covers Twig_Node_Expression_Binary_Or::compile - * @covers Twig_Node_Expression_Binary_Or::operator - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $left = new Twig_Node_Expression_Constant(1, 0); - $right = new Twig_Node_Expression_Constant(2, 0); - $node = new Twig_Node_Expression_Binary_Or($left, $right, 0); - - return array( - array($node, '(1 || 2)'), - ); - } -} diff --git a/lib/twig/test/Twig/Tests/Node/Expression/Binary/SubTest.php b/lib/twig/test/Twig/Tests/Node/Expression/Binary/SubTest.php deleted file mode 100755 index 6583d09..0000000 --- a/lib/twig/test/Twig/Tests/Node/Expression/Binary/SubTest.php +++ /dev/null @@ -1,49 +0,0 @@ -assertEquals($left, $node->getNode('left')); - $this->assertEquals($right, $node->getNode('right')); - } - - /** - * @covers Twig_Node_Expression_Binary_Sub::compile - * @covers Twig_Node_Expression_Binary_Sub::operator - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $left = new Twig_Node_Expression_Constant(1, 0); - $right = new Twig_Node_Expression_Constant(2, 0); - $node = new Twig_Node_Expression_Binary_Sub($left, $right, 0); - - return array( - array($node, '(1 - 2)'), - ); - } -} diff --git a/lib/twig/test/Twig/Tests/Node/Expression/ConditionalTest.php b/lib/twig/test/Twig/Tests/Node/Expression/ConditionalTest.php deleted file mode 100755 index 4a05e4e..0000000 --- a/lib/twig/test/Twig/Tests/Node/Expression/ConditionalTest.php +++ /dev/null @@ -1,52 +0,0 @@ -assertEquals($expr1, $node->getNode('expr1')); - $this->assertEquals($expr2, $node->getNode('expr2')); - $this->assertEquals($expr3, $node->getNode('expr3')); - } - - /** - * @covers Twig_Node_Expression_Conditional::compile - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $tests = array(); - - $expr1 = new Twig_Node_Expression_Constant(1, 0); - $expr2 = new Twig_Node_Expression_Constant(2, 0); - $expr3 = new Twig_Node_Expression_Constant(3, 0); - $node = new Twig_Node_Expression_Conditional($expr1, $expr2, $expr3, 0); - $tests[] = array($node, '((1) ? (2) : (3))'); - - return $tests; - } -} diff --git a/lib/twig/test/Twig/Tests/Node/Expression/ConstantTest.php b/lib/twig/test/Twig/Tests/Node/Expression/ConstantTest.php deleted file mode 100755 index 0cf3867..0000000 --- a/lib/twig/test/Twig/Tests/Node/Expression/ConstantTest.php +++ /dev/null @@ -1,44 +0,0 @@ -assertEquals('foo', $node->getAttribute('value')); - } - - /** - * @covers Twig_Node_Expression_Constant::compile - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $tests = array(); - - $node = new Twig_Node_Expression_Constant('foo', 0); - $tests[] = array($node, '"foo"'); - - return $tests; - } -} diff --git a/lib/twig/test/Twig/Tests/Node/Expression/FilterTest.php b/lib/twig/test/Twig/Tests/Node/Expression/FilterTest.php deleted file mode 100755 index 2c52482..0000000 --- a/lib/twig/test/Twig/Tests/Node/Expression/FilterTest.php +++ /dev/null @@ -1,85 +0,0 @@ -assertEquals($expr, $node->getNode('node')); - $this->assertEquals($name, $node->getNode('filter')); - $this->assertEquals($args, $node->getNode('arguments')); - } - - /** - * @covers Twig_Node_Expression_Filter::compile - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - - $expr = new Twig_Node_Expression_Constant('foo', 0); - $node = $this->createFilter($expr, 'foobar', array(new Twig_Node_Expression_Constant('bar', 0), new Twig_Node_Expression_Constant('foobar', 0))); - - try { - $node->compile($this->getCompiler()); - $this->fail(); - } catch (Exception $e) { - $this->assertEquals('Twig_Error_Syntax', get_class($e)); - } - } - - public function getTests() - { - $tests = array(); - - $expr = new Twig_Node_Expression_Constant('foo', 0); - $node = $this->createFilter($expr, 'upper'); - $node = $this->createFilter($node, 'lower', array(new Twig_Node_Expression_Constant('bar', 0), new Twig_Node_Expression_Constant('foobar', 0))); - - if (function_exists('mb_get_info')) { - $tests[] = array($node, 'twig_lower_filter($this->env, twig_upper_filter($this->env, "foo"), "bar", "foobar")'); - } else { - $tests[] = array($node, 'strtolower(strtoupper("foo"), "bar", "foobar")'); - } - - return $tests; - } - - /** - * @covers Twig_Node_Expression_Filter::compile - * @expectedException Twig_Error_Syntax - * @expectedExceptionMessage The filter "uppe" does not exist. Did you mean "upper" at line 0 - */ - public function testUnknownFilter() - { - $node = $this->createFilter(new Twig_Node_Expression_Constant('foo', 0), 'uppe'); - $node->compile($this->getCompiler()); - } - - protected function createFilter($node, $name, array $arguments = array()) - { - $name = new Twig_Node_Expression_Constant($name, 0); - $arguments = new Twig_Node($arguments); - - return new Twig_Node_Expression_Filter($node, $name, $arguments, 0); - } -} diff --git a/lib/twig/test/Twig/Tests/Node/Expression/FunctionTest.php b/lib/twig/test/Twig/Tests/Node/Expression/FunctionTest.php deleted file mode 100755 index 68c5c61..0000000 --- a/lib/twig/test/Twig/Tests/Node/Expression/FunctionTest.php +++ /dev/null @@ -1,90 +0,0 @@ -assertEquals($name, $node->getAttribute('name')); - $this->assertEquals($args, $node->getNode('arguments')); - } - - /** - * @covers Twig_Node_Expression_Function::compile - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - /** - * @covers Twig_Node_Expression_Filter::compile - * @expectedException Twig_Error_Syntax - * @expectedExceptionMessage The function "cycl" does not exist. Did you mean "cycle" at line 0 - */ - public function testUnknownFunction() - { - $node = $this->createFunction('cycl', array()); - $node->compile($this->getCompiler()); - } - - public function getTests() - { - $environment = new Twig_Environment(); - $environment->addFunction('foo', new Twig_Function_Function('foo', array())); - $environment->addFunction('bar', new Twig_Function_Function('bar', array('needs_environment' => true))); - $environment->addFunction('foofoo', new Twig_Function_Function('foofoo', array('needs_context' => true))); - $environment->addFunction('foobar', new Twig_Function_Function('foobar', array('needs_environment' => true, 'needs_context' => true))); - - $tests = array(); - - $node = $this->createFunction('foo'); - $tests[] = array($node, 'foo()', $environment); - - $node = $this->createFunction('foo', array(new Twig_Node_Expression_Constant('bar', 0), new Twig_Node_Expression_Constant('foobar', 0))); - $tests[] = array($node, 'foo("bar", "foobar")', $environment); - - $node = $this->createFunction('bar'); - $tests[] = array($node, 'bar($this->env)', $environment); - - $node = $this->createFunction('bar', array(new Twig_Node_Expression_Constant('bar', 0))); - $tests[] = array($node, 'bar($this->env, "bar")', $environment); - - $node = $this->createFunction('foofoo'); - $tests[] = array($node, 'foofoo($context)', $environment); - - $node = $this->createFunction('foofoo', array(new Twig_Node_Expression_Constant('bar', 0))); - $tests[] = array($node, 'foofoo($context, "bar")', $environment); - - $node = $this->createFunction('foobar'); - $tests[] = array($node, 'foobar($this->env, $context)', $environment); - - $node = $this->createFunction('foobar', array(new Twig_Node_Expression_Constant('bar', 0))); - $tests[] = array($node, 'foobar($this->env, $context, "bar")', $environment); - - return $tests; - } - - protected function createFunction($name, array $arguments = array()) - { - return new Twig_Node_Expression_Function($name, new Twig_Node($arguments), 0); - } -} diff --git a/lib/twig/test/Twig/Tests/Node/Expression/GetAttrTest.php b/lib/twig/test/Twig/Tests/Node/Expression/GetAttrTest.php deleted file mode 100755 index 6df143d..0000000 --- a/lib/twig/test/Twig/Tests/Node/Expression/GetAttrTest.php +++ /dev/null @@ -1,64 +0,0 @@ -addElement(new Twig_Node_Expression_Name('foo', 0)); - $args->addElement(new Twig_Node_Expression_Constant('bar', 0)); - $node = new Twig_Node_Expression_GetAttr($expr, $attr, $args, Twig_TemplateInterface::ARRAY_CALL, 0); - - $this->assertEquals($expr, $node->getNode('node')); - $this->assertEquals($attr, $node->getNode('attribute')); - $this->assertEquals($args, $node->getNode('arguments')); - $this->assertEquals(Twig_TemplateInterface::ARRAY_CALL, $node->getAttribute('type')); - } - - /** - * @covers Twig_Node_Expression_GetAttr::compile - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $tests = array(); - - $expr = new Twig_Node_Expression_Name('foo', 0); - $attr = new Twig_Node_Expression_Constant('bar', 0); - $args = new Twig_Node_Expression_Array(array(), 0); - $node = new Twig_Node_Expression_GetAttr($expr, $attr, $args, Twig_TemplateInterface::ANY_CALL, 0); - $tests[] = array($node, sprintf('%s%s, "bar")', $this->getAttributeGetter(), $this->getVariableGetter('foo'))); - - $node = new Twig_Node_Expression_GetAttr($expr, $attr, $args, Twig_TemplateInterface::ARRAY_CALL, 0); - $tests[] = array($node, sprintf('%s%s, "bar", array(), "array")', $this->getAttributeGetter(), $this->getVariableGetter('foo'))); - - $args = new Twig_Node_Expression_Array(array(), 0); - $args->addElement(new Twig_Node_Expression_Name('foo', 0)); - $args->addElement(new Twig_Node_Expression_Constant('bar', 0)); - $node = new Twig_Node_Expression_GetAttr($expr, $attr, $args, Twig_TemplateInterface::METHOD_CALL, 0); - $tests[] = array($node, sprintf('%s%s, "bar", array(0 => %s, 1 => "bar"), "method")', $this->getAttributeGetter(), $this->getVariableGetter('foo'), $this->getVariableGetter('foo'))); - - return $tests; - } -} diff --git a/lib/twig/test/Twig/Tests/Node/Expression/NameTest.php b/lib/twig/test/Twig/Tests/Node/Expression/NameTest.php deleted file mode 100755 index e77b432..0000000 --- a/lib/twig/test/Twig/Tests/Node/Expression/NameTest.php +++ /dev/null @@ -1,51 +0,0 @@ -assertEquals('foo', $node->getAttribute('name')); - } - - /** - * @covers Twig_Node_Expression_Name::compile - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $node = new Twig_Node_Expression_Name('foo', 0); - $self = new Twig_Node_Expression_Name('_self', 0); - $context = new Twig_Node_Expression_Name('_context', 0); - - $env = new Twig_Environment(null, array('strict_variables' => true)); - $env1 = new Twig_Environment(null, array('strict_variables' => false)); - - return array( - array($node, '$this->getContext($context, "foo")', $env), - array($node, $this->getVariableGetter('foo'), $env1), - array($self, '$this'), - array($context, '$context'), - ); - } -} diff --git a/lib/twig/test/Twig/Tests/Node/Expression/ParentTest.php b/lib/twig/test/Twig/Tests/Node/Expression/ParentTest.php deleted file mode 100755 index 7efbe03..0000000 --- a/lib/twig/test/Twig/Tests/Node/Expression/ParentTest.php +++ /dev/null @@ -1,42 +0,0 @@ -assertEquals('foo', $node->getAttribute('name')); - } - - /** - * @covers Twig_Node_Expression_Parent::compile - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $tests = array(); - $tests[] = array(new Twig_Node_Expression_Parent('foo', 0), '$this->renderParentBlock("foo", $context, $blocks)'); - - return $tests; - } -} diff --git a/lib/twig/test/Twig/Tests/Node/Expression/TestTest.php b/lib/twig/test/Twig/Tests/Node/Expression/TestTest.php deleted file mode 100755 index 08668c0..0000000 --- a/lib/twig/test/Twig/Tests/Node/Expression/TestTest.php +++ /dev/null @@ -1,67 +0,0 @@ -assertEquals($expr, $node->getNode('node')); - $this->assertEquals($args, $node->getNode('arguments')); - $this->assertEquals($name, $node->getAttribute('name')); - } - - /** - * @covers Twig_Node_Expression_Test::compile - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $tests = array(); - - $expr = new Twig_Node_Expression_Constant('foo', 0); - $node = new Twig_Node_Expression_Test_Null($expr, 'null', new Twig_Node(array()), 0); - - $tests[] = array($node, '(null === "foo")'); - - return $tests; - } - - /** - * @covers Twig_Node_Expression_Filter::compile - * @expectedException Twig_Error_Syntax - * @expectedExceptionMessage The test "nul" does not exist. Did you mean "null" at line 0 - */ - public function testUnknownTest() - { - $node = $this->createTest(new Twig_Node_Expression_Constant('foo', 0), 'nul'); - $node->compile($this->getCompiler()); - } - - protected function createTest($node, $name, array $arguments = array()) - { - return new Twig_Node_Expression_Test($node, $name, new Twig_Node($arguments), 0); - } -} diff --git a/lib/twig/test/Twig/Tests/Node/Expression/Unary/NegTest.php b/lib/twig/test/Twig/Tests/Node/Expression/Unary/NegTest.php deleted file mode 100755 index 218de6e..0000000 --- a/lib/twig/test/Twig/Tests/Node/Expression/Unary/NegTest.php +++ /dev/null @@ -1,46 +0,0 @@ -assertEquals($expr, $node->getNode('node')); - } - - /** - * @covers Twig_Node_Expression_Unary_Neg::compile - * @covers Twig_Node_Expression_Unary_Neg::operator - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $node = new Twig_Node_Expression_Constant(1, 0); - $node = new Twig_Node_Expression_Unary_Neg($node, 0); - - return array( - array($node, '(-1)'), - ); - } -} diff --git a/lib/twig/test/Twig/Tests/Node/Expression/Unary/NotTest.php b/lib/twig/test/Twig/Tests/Node/Expression/Unary/NotTest.php deleted file mode 100755 index ed6349c..0000000 --- a/lib/twig/test/Twig/Tests/Node/Expression/Unary/NotTest.php +++ /dev/null @@ -1,46 +0,0 @@ -assertEquals($expr, $node->getNode('node')); - } - - /** - * @covers Twig_Node_Expression_Unary_Not::compile - * @covers Twig_Node_Expression_Unary_Not::operator - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $node = new Twig_Node_Expression_Constant(1, 0); - $node = new Twig_Node_Expression_Unary_Not($node, 0); - - return array( - array($node, '(!1)'), - ); - } -} diff --git a/lib/twig/test/Twig/Tests/Node/Expression/Unary/PosTest.php b/lib/twig/test/Twig/Tests/Node/Expression/Unary/PosTest.php deleted file mode 100755 index 6a414bc..0000000 --- a/lib/twig/test/Twig/Tests/Node/Expression/Unary/PosTest.php +++ /dev/null @@ -1,46 +0,0 @@ -assertEquals($expr, $node->getNode('node')); - } - - /** - * @covers Twig_Node_Expression_Unary_Pos::compile - * @covers Twig_Node_Expression_Unary_Pos::operator - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $node = new Twig_Node_Expression_Constant(1, 0); - $node = new Twig_Node_Expression_Unary_Pos($node, 0); - - return array( - array($node, '(+1)'), - ); - } -} diff --git a/lib/twig/test/Twig/Tests/Node/ForTest.php b/lib/twig/test/Twig/Tests/Node/ForTest.php deleted file mode 100755 index ef3be82..0000000 --- a/lib/twig/test/Twig/Tests/Node/ForTest.php +++ /dev/null @@ -1,201 +0,0 @@ -setAttribute('with_loop', false); - - $this->assertEquals($keyTarget, $node->getNode('key_target')); - $this->assertEquals($valueTarget, $node->getNode('value_target')); - $this->assertEquals($seq, $node->getNode('seq')); - $this->assertTrue($node->getAttribute('ifexpr')); - $this->assertEquals('Twig_Node_If', get_class($node->getNode('body'))); - $this->assertEquals($body, $node->getNode('body')->getNode('tests')->getNode(1)->getNode(0)); - $this->assertEquals(null, $node->getNode('else')); - - $else = new Twig_Node_Print(new Twig_Node_Expression_Name('foo', 0), 0); - $node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, 0); - $node->setAttribute('with_loop', false); - $this->assertEquals($else, $node->getNode('else')); - } - - /** - * @covers Twig_Node_For::compile - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $tests = array(); - - $keyTarget = new Twig_Node_Expression_AssignName('key', 0); - $valueTarget = new Twig_Node_Expression_AssignName('item', 0); - $seq = new Twig_Node_Expression_Name('items', 0); - $ifexpr = null; - $body = new Twig_Node(array(new Twig_Node_Print(new Twig_Node_Expression_Name('foo', 0), 0)), array(), 0); - $else = null; - $node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, 0); - $node->setAttribute('with_loop', false); - - $tests[] = array($node, <<getVariableGetter('items')}); -foreach (\$context['_seq'] as \$context["key"] => \$context["item"]) { - echo {$this->getVariableGetter('foo')}; -} -\$_parent = \$context['_parent']; -unset(\$context['_seq'], \$context['_iterated'], \$context['key'], \$context['item'], \$context['_parent'], \$context['loop']); -\$context = array_merge(\$_parent, array_intersect_key(\$context, \$_parent)); -EOF - ); - - $keyTarget = new Twig_Node_Expression_AssignName('k', 0); - $valueTarget = new Twig_Node_Expression_AssignName('v', 0); - $seq = new Twig_Node_Expression_Name('values', 0); - $ifexpr = null; - $body = new Twig_Node(array(new Twig_Node_Print(new Twig_Node_Expression_Name('foo', 0), 0)), array(), 0); - $else = null; - $node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, 0); - $node->setAttribute('with_loop', true); - - $tests[] = array($node, <<getVariableGetter('values')}); -\$context['loop'] = array( - 'parent' => \$context['_parent'], - 'index0' => 0, - 'index' => 1, - 'first' => true, -); -if (is_array(\$context['_seq']) || (is_object(\$context['_seq']) && \$context['_seq'] instanceof Countable)) { - \$length = count(\$context['_seq']); - \$context['loop']['revindex0'] = \$length - 1; - \$context['loop']['revindex'] = \$length; - \$context['loop']['length'] = \$length; - \$context['loop']['last'] = 1 === \$length; -} -foreach (\$context['_seq'] as \$context["k"] => \$context["v"]) { - echo {$this->getVariableGetter('foo')}; - ++\$context['loop']['index0']; - ++\$context['loop']['index']; - \$context['loop']['first'] = false; - if (isset(\$context['loop']['length'])) { - --\$context['loop']['revindex0']; - --\$context['loop']['revindex']; - \$context['loop']['last'] = 0 === \$context['loop']['revindex0']; - } -} -\$_parent = \$context['_parent']; -unset(\$context['_seq'], \$context['_iterated'], \$context['k'], \$context['v'], \$context['_parent'], \$context['loop']); -\$context = array_merge(\$_parent, array_intersect_key(\$context, \$_parent)); -EOF - ); - - $keyTarget = new Twig_Node_Expression_AssignName('k', 0); - $valueTarget = new Twig_Node_Expression_AssignName('v', 0); - $seq = new Twig_Node_Expression_Name('values', 0); - $ifexpr = new Twig_Node_Expression_Constant(true, 0); - $body = new Twig_Node(array(new Twig_Node_Print(new Twig_Node_Expression_Name('foo', 0), 0)), array(), 0); - $else = null; - $node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, 0); - $node->setAttribute('with_loop', true); - - $tests[] = array($node, <<getVariableGetter('values')}); -\$context['loop'] = array( - 'parent' => \$context['_parent'], - 'index0' => 0, - 'index' => 1, - 'first' => true, -); -foreach (\$context['_seq'] as \$context["k"] => \$context["v"]) { - if (true) { - echo {$this->getVariableGetter('foo')}; - ++\$context['loop']['index0']; - ++\$context['loop']['index']; - \$context['loop']['first'] = false; - } -} -\$_parent = \$context['_parent']; -unset(\$context['_seq'], \$context['_iterated'], \$context['k'], \$context['v'], \$context['_parent'], \$context['loop']); -\$context = array_merge(\$_parent, array_intersect_key(\$context, \$_parent)); -EOF - ); - - $keyTarget = new Twig_Node_Expression_AssignName('k', 0); - $valueTarget = new Twig_Node_Expression_AssignName('v', 0); - $seq = new Twig_Node_Expression_Name('values', 0); - $ifexpr = null; - $body = new Twig_Node(array(new Twig_Node_Print(new Twig_Node_Expression_Name('foo', 0), 0)), array(), 0); - $else = new Twig_Node_Print(new Twig_Node_Expression_Name('foo', 0), 0); - $node = new Twig_Node_For($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, 0); - $node->setAttribute('with_loop', true); - - $tests[] = array($node, <<getVariableGetter('values')}); -\$context['_iterated'] = false; -\$context['loop'] = array( - 'parent' => \$context['_parent'], - 'index0' => 0, - 'index' => 1, - 'first' => true, -); -if (is_array(\$context['_seq']) || (is_object(\$context['_seq']) && \$context['_seq'] instanceof Countable)) { - \$length = count(\$context['_seq']); - \$context['loop']['revindex0'] = \$length - 1; - \$context['loop']['revindex'] = \$length; - \$context['loop']['length'] = \$length; - \$context['loop']['last'] = 1 === \$length; -} -foreach (\$context['_seq'] as \$context["k"] => \$context["v"]) { - echo {$this->getVariableGetter('foo')}; - \$context['_iterated'] = true; - ++\$context['loop']['index0']; - ++\$context['loop']['index']; - \$context['loop']['first'] = false; - if (isset(\$context['loop']['length'])) { - --\$context['loop']['revindex0']; - --\$context['loop']['revindex']; - \$context['loop']['last'] = 0 === \$context['loop']['revindex0']; - } -} -if (!\$context['_iterated']) { - echo {$this->getVariableGetter('foo')}; -} -\$_parent = \$context['_parent']; -unset(\$context['_seq'], \$context['_iterated'], \$context['k'], \$context['v'], \$context['_parent'], \$context['loop']); -\$context = array_merge(\$_parent, array_intersect_key(\$context, \$_parent)); -EOF - ); - - return $tests; - } -} diff --git a/lib/twig/test/Twig/Tests/Node/IfTest.php b/lib/twig/test/Twig/Tests/Node/IfTest.php deleted file mode 100755 index 04b92e7..0000000 --- a/lib/twig/test/Twig/Tests/Node/IfTest.php +++ /dev/null @@ -1,99 +0,0 @@ -assertEquals($t, $node->getNode('tests')); - $this->assertEquals(null, $node->getNode('else')); - - $else = new Twig_Node_Print(new Twig_Node_Expression_Name('bar', 0), 0); - $node = new Twig_Node_If($t, $else, 0); - $this->assertEquals($else, $node->getNode('else')); - } - - /** - * @covers Twig_Node_If::compile - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $tests = array(); - - $t = new Twig_Node(array( - new Twig_Node_Expression_Constant(true, 0), - new Twig_Node_Print(new Twig_Node_Expression_Name('foo', 0), 0), - ), array(), 0); - $else = null; - $node = new Twig_Node_If($t, $else, 0); - - $tests[] = array($node, <<getVariableGetter('foo')}; -} -EOF - ); - - $t = new Twig_Node(array( - new Twig_Node_Expression_Constant(true, 0), - new Twig_Node_Print(new Twig_Node_Expression_Name('foo', 0), 0), - new Twig_Node_Expression_Constant(false, 0), - new Twig_Node_Print(new Twig_Node_Expression_Name('bar', 0), 0), - ), array(), 0); - $else = null; - $node = new Twig_Node_If($t, $else, 0); - - $tests[] = array($node, <<getVariableGetter('foo')}; -} elseif (false) { - echo {$this->getVariableGetter('bar')}; -} -EOF - ); - - $t = new Twig_Node(array( - new Twig_Node_Expression_Constant(true, 0), - new Twig_Node_Print(new Twig_Node_Expression_Name('foo', 0), 0), - ), array(), 0); - $else = new Twig_Node_Print(new Twig_Node_Expression_Name('bar', 0), 0); - $node = new Twig_Node_If($t, $else, 0); - - $tests[] = array($node, <<getVariableGetter('foo')}; -} else { - echo {$this->getVariableGetter('bar')}; -} -EOF - ); - - return $tests; - } -} diff --git a/lib/twig/test/Twig/Tests/Node/ImportTest.php b/lib/twig/test/Twig/Tests/Node/ImportTest.php deleted file mode 100755 index 6a89195..0000000 --- a/lib/twig/test/Twig/Tests/Node/ImportTest.php +++ /dev/null @@ -1,50 +0,0 @@ -assertEquals($macro, $node->getNode('expr')); - $this->assertEquals($var, $node->getNode('var')); - } - - /** - * @covers Twig_Node_Import::compile - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $tests = array(); - - $macro = new Twig_Node_Expression_Constant('foo.twig', 0); - $var = new Twig_Node_Expression_AssignName('macro', 0); - $node = new Twig_Node_Import($macro, $var, 0); - - $tests[] = array($node, '$context["macro"] = $this->env->loadTemplate("foo.twig");'); - - return $tests; - } -} diff --git a/lib/twig/test/Twig/Tests/Node/IncludeTest.php b/lib/twig/test/Twig/Tests/Node/IncludeTest.php deleted file mode 100755 index d068392..0000000 --- a/lib/twig/test/Twig/Tests/Node/IncludeTest.php +++ /dev/null @@ -1,84 +0,0 @@ -assertEquals(null, $node->getNode('variables')); - $this->assertEquals($expr, $node->getNode('expr')); - $this->assertFalse($node->getAttribute('only')); - - $vars = new Twig_Node_Expression_Array(array(new Twig_Node_Expression_Constant('foo', 0), new Twig_Node_Expression_Constant(true, 0)), 0); - $node = new Twig_Node_Include($expr, $vars, true, false, 0); - $this->assertEquals($vars, $node->getNode('variables')); - $this->assertTrue($node->getAttribute('only')); - } - - /** - * @covers Twig_Node_Include::compile - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $tests = array(); - - $expr = new Twig_Node_Expression_Constant('foo.twig', 0); - $node = new Twig_Node_Include($expr, null, false, false, 0); - $tests[] = array($node, '$this->env->loadTemplate("foo.twig")->display($context);'); - - $expr = new Twig_Node_Expression_Conditional( - new Twig_Node_Expression_Constant(true, 0), - new Twig_Node_Expression_Constant('foo', 0), - new Twig_Node_Expression_Constant('foo', 0), - 0 - ); - $node = new Twig_Node_Include($expr, null, false, false, 0); - $tests[] = array($node, <<env->resolveTemplate(((true) ? ("foo") : ("foo"))); -\$template->display(\$context); -EOF - ); - - $expr = new Twig_Node_Expression_Constant('foo.twig', 0); - $vars = new Twig_Node_Expression_Array(array(new Twig_Node_Expression_Constant('foo', 0), new Twig_Node_Expression_Constant(true, 0)), 0); - $node = new Twig_Node_Include($expr, $vars, false, false, 0); - $tests[] = array($node, '$this->env->loadTemplate("foo.twig")->display(array_merge($context, array("foo" => true)));'); - - $node = new Twig_Node_Include($expr, $vars, true, false, 0); - $tests[] = array($node, '$this->env->loadTemplate("foo.twig")->display(array("foo" => true));'); - - $node = new Twig_Node_Include($expr, $vars, true, true, 0); - $tests[] = array($node, <<env->loadTemplate("foo.twig")->display(array("foo" => true)); -} catch (Twig_Error_Loader \$e) { - // ignore missing template -} -EOF - ); - - return $tests; - } -} diff --git a/lib/twig/test/Twig/Tests/Node/MacroTest.php b/lib/twig/test/Twig/Tests/Node/MacroTest.php deleted file mode 100755 index ddb67d1..0000000 --- a/lib/twig/test/Twig/Tests/Node/MacroTest.php +++ /dev/null @@ -1,70 +0,0 @@ -assertEquals($body, $node->getNode('body')); - $this->assertEquals($arguments, $node->getNode('arguments')); - $this->assertEquals('foo', $node->getAttribute('name')); - } - - /** - * @covers Twig_Node_Macro::compile - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $body = new Twig_Node_Text('foo', 0); - $arguments = new Twig_Node(array(new Twig_Node_Expression_Name('foo', 0)), array(), 0); - $node = new Twig_Node_Macro('foo', $body, $arguments, 0); - - return array( - array($node, <<env->getGlobals(), array( - "foo" => \$foo, - )); - - \$blocks = array(); - - ob_start(); - try { - echo "foo"; - } catch(Exception \$e) { - ob_end_clean(); - - throw \$e; - } - - return ob_get_clean(); -} -EOF - ), - ); - } -} diff --git a/lib/twig/test/Twig/Tests/Node/ModuleTest.php b/lib/twig/test/Twig/Tests/Node/ModuleTest.php deleted file mode 100755 index 4b2b2e9..0000000 --- a/lib/twig/test/Twig/Tests/Node/ModuleTest.php +++ /dev/null @@ -1,176 +0,0 @@ -assertEquals($body, $node->getNode('body')); - $this->assertEquals($blocks, $node->getNode('blocks')); - $this->assertEquals($macros, $node->getNode('macros')); - $this->assertEquals($parent, $node->getNode('parent')); - $this->assertEquals($filename, $node->getAttribute('filename')); - } - - /** - * @covers Twig_Node_Module::compile - * @covers Twig_Node_Module::compileTemplate - * @covers Twig_Node_Module::compileMacros - * @covers Twig_Node_Module::compileClassHeader - * @covers Twig_Node_Module::compileDisplayHeader - * @covers Twig_Node_Module::compileDisplayBody - * @covers Twig_Node_Module::compileDisplayFooter - * @covers Twig_Node_Module::compileClassFooter - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $twig = new Twig_Environment(new Twig_Loader_String()); - - $tests = array(); - - $body = new Twig_Node_Text('foo', 0); - $extends = null; - $blocks = new Twig_Node(); - $macros = new Twig_Node(); - $traits = new Twig_Node(); - $filename = 'foo.twig'; - - $node = new Twig_Node_Module($body, $extends, $blocks, $macros, $traits, $filename); - $tests[] = array($node, <<env->loadTemplate("foo.twig"); - \$this->parent->display(\$context, array_merge(\$this->blocks, \$blocks)); - } - - public function getTemplateName() - { - return "foo.twig"; - } - - public function isTraitable() - { - return false; - } - - public function getDebugInfo() - { - return array (); - } -} -EOF - , $twig); - - $body = new Twig_Node(); - $extends = new Twig_Node_Expression_Conditional( - new Twig_Node_Expression_Constant(true, 0), - new Twig_Node_Expression_Constant('foo', 0), - new Twig_Node_Expression_Constant('foo', 0), - 0 - ); - - $node = new Twig_Node_Module($body, $extends, $blocks, $macros, $traits, $filename); - $tests[] = array($node, <<env->resolveTemplate(((true) ? ("foo") : ("foo"))); - } - - protected function doDisplay(array \$context, array \$blocks = array()) - { - \$this->getParent(\$context)->display(\$context, array_merge(\$this->blocks, \$blocks)); - } - - public function getTemplateName() - { - return "foo.twig"; - } - - public function isTraitable() - { - return false; - } - - public function getDebugInfo() - { - return array (); - } -} -EOF - , $twig); - - return $tests; - } -} diff --git a/lib/twig/test/Twig/Tests/Node/PrintTest.php b/lib/twig/test/Twig/Tests/Node/PrintTest.php deleted file mode 100755 index 168663c..0000000 --- a/lib/twig/test/Twig/Tests/Node/PrintTest.php +++ /dev/null @@ -1,43 +0,0 @@ -assertEquals($expr, $node->getNode('expr')); - } - - /** - * @covers Twig_Node_Print::compile - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $tests = array(); - $tests[] = array(new Twig_Node_Print(new Twig_Node_Expression_Constant('foo', 0), 0), 'echo "foo";'); - - return $tests; - } -} diff --git a/lib/twig/test/Twig/Tests/Node/SandboxTest.php b/lib/twig/test/Twig/Tests/Node/SandboxTest.php deleted file mode 100755 index 1610873..0000000 --- a/lib/twig/test/Twig/Tests/Node/SandboxTest.php +++ /dev/null @@ -1,57 +0,0 @@ -assertEquals($body, $node->getNode('body')); - } - - /** - * @covers Twig_Node_Sandbox::compile - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $tests = array(); - - $body = new Twig_Node_Text('foo', 0); - $node = new Twig_Node_Sandbox($body, 0); - - $tests[] = array($node, <<env->getExtension('sandbox'); -if (!\$alreadySandboxed = \$sandbox->isSandboxed()) { - \$sandbox->enableSandbox(); -} -echo "foo"; -if (!\$alreadySandboxed) { - \$sandbox->disableSandbox(); -} -EOF - ); - - return $tests; - } -} diff --git a/lib/twig/test/Twig/Tests/Node/SandboxedModuleTest.php b/lib/twig/test/Twig/Tests/Node/SandboxedModuleTest.php deleted file mode 100755 index f86442b..0000000 --- a/lib/twig/test/Twig/Tests/Node/SandboxedModuleTest.php +++ /dev/null @@ -1,152 +0,0 @@ -assertEquals($body, $node->getNode('body')); - $this->assertEquals($blocks, $node->getNode('blocks')); - $this->assertEquals($macros, $node->getNode('macros')); - $this->assertEquals($parent, $node->getNode('parent')); - $this->assertEquals($filename, $node->getAttribute('filename')); - } - - /** - * @covers Twig_Node_SandboxedModule::compile - * @covers Twig_Node_SandboxedModule::compileDisplayBody - * @covers Twig_Node_SandboxedModule::compileDisplayFooter - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $twig = new Twig_Environment(new Twig_Loader_String()); - - $tests = array(); - - $body = new Twig_Node_Text('foo', 0); - $extends = null; - $blocks = new Twig_Node(); - $macros = new Twig_Node(); - $traits = new Twig_Node(); - $filename = 'foo.twig'; - - $node = new Twig_Node_Module($body, $extends, $blocks, $macros, $traits, $filename); - $node = new Twig_Node_SandboxedModule($node, array('for'), array('upper'), array('cycle')); - - $tests[] = array($node, <<checkSecurity(); - echo "foo"; - } - - protected function checkSecurity() { - \$this->env->getExtension('sandbox')->checkSecurity( - array('upper'), - array('for'), - array('cycle') - ); - } - - public function getTemplateName() - { - return "foo.twig"; - } - - public function getDebugInfo() - { - return array (); - } -} -EOF - , $twig); - - $body = new Twig_Node(); - $extends = new Twig_Node_Expression_Constant('layout.twig', 0); - $blocks = new Twig_Node(); - $macros = new Twig_Node(); - $traits = new Twig_Node(); - $filename = 'foo.twig'; - - $node = new Twig_Node_Module($body, $extends, $blocks, $macros, $traits, $filename); - $node = new Twig_Node_SandboxedModule($node, array('for'), array('upper'), array('cycle')); - - $tests[] = array($node, <<checkSecurity(); - \$this->parent->display(\$context, array_merge(\$this->blocks, \$blocks)); - } - - protected function checkSecurity() { - \$this->env->getExtension('sandbox')->checkSecurity( - array('upper'), - array('for'), - array('cycle') - ); - } - - public function getTemplateName() - { - return "foo.twig"; - } - - public function isTraitable() - { - return false; - } - - public function getDebugInfo() - { - return array (); - } -} -EOF - , $twig); - - return $tests; - } -} diff --git a/lib/twig/test/Twig/Tests/Node/SandboxedPrintTest.php b/lib/twig/test/Twig/Tests/Node/SandboxedPrintTest.php deleted file mode 100755 index 85adddf..0000000 --- a/lib/twig/test/Twig/Tests/Node/SandboxedPrintTest.php +++ /dev/null @@ -1,46 +0,0 @@ -assertEquals($expr, $node->getNode('expr')); - } - - /** - * @covers Twig_Node_SandboxedPrint::compile - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $tests = array(); - - $tests[] = array(new Twig_Node_SandboxedPrint(new Twig_Node_Expression_Constant('foo', 0), 0), <<env->getExtension('sandbox')->ensureToStringAllowed("foo"); -EOF - ); - - return $tests; - } -} diff --git a/lib/twig/test/Twig/Tests/Node/SetTest.php b/lib/twig/test/Twig/Tests/Node/SetTest.php deleted file mode 100755 index 6319fb6..0000000 --- a/lib/twig/test/Twig/Tests/Node/SetTest.php +++ /dev/null @@ -1,73 +0,0 @@ -assertEquals($names, $node->getNode('names')); - $this->assertEquals($values, $node->getNode('values')); - $this->assertEquals(false, $node->getAttribute('capture')); - } - - /** - * @covers Twig_Node_Set::compile - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $tests = array(); - - $names = new Twig_Node(array(new Twig_Node_Expression_AssignName('foo', 0)), array(), 0); - $values = new Twig_Node(array(new Twig_Node_Expression_Constant('foo', 0)), array(), 0); - $node = new Twig_Node_Set(false, $names, $values, 0); - $tests[] = array($node, '$context["foo"] = "foo";'); - - $names = new Twig_Node(array(new Twig_Node_Expression_AssignName('foo', 0)), array(), 0); - $values = new Twig_Node(array(new Twig_Node_Print(new Twig_Node_Expression_Constant('foo', 0), 0)), array(), 0); - $node = new Twig_Node_Set(true, $names, $values, 0); - $tests[] = array($node, <<env->getCharset()); -EOF - ); - - $names = new Twig_Node(array(new Twig_Node_Expression_AssignName('foo', 0)), array(), 0); - $values = new Twig_Node_Text('foo', 0); - $node = new Twig_Node_Set(true, $names, $values, 0); - $tests[] = array($node, '$context["foo"] = (\'\' === $tmp = "foo") ? \'\' : new Twig_Markup($tmp, $this->env->getCharset());'); - - $names = new Twig_Node(array(new Twig_Node_Expression_AssignName('foo', 0), new Twig_Node_Expression_AssignName('bar', 0)), array(), 0); - $values = new Twig_Node(array(new Twig_Node_Expression_Constant('foo', 0), new Twig_Node_Expression_Name('bar', 0)), array(), 0); - $node = new Twig_Node_Set(false, $names, $values, 0); - $tests[] = array($node, <<getVariableGetter('bar')}); -EOF - ); - - return $tests; - } -} diff --git a/lib/twig/test/Twig/Tests/Node/SpacelessTest.php b/lib/twig/test/Twig/Tests/Node/SpacelessTest.php deleted file mode 100755 index 55892f4..0000000 --- a/lib/twig/test/Twig/Tests/Node/SpacelessTest.php +++ /dev/null @@ -1,50 +0,0 @@ -
    foo
    ', 0))); - $node = new Twig_Node_Spaceless($body, 0); - - $this->assertEquals($body, $node->getNode('body')); - } - - /** - * @covers Twig_Node_Spaceless::compile - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $body = new Twig_Node(array(new Twig_Node_Text('
    foo
    ', 0))); - $node = new Twig_Node_Spaceless($body, 0); - - return array( - array($node, <<
    foo
    "; -echo trim(preg_replace('/>\s+<', ob_get_clean())); -EOF - ), - ); - } -} diff --git a/lib/twig/test/Twig/Tests/Node/TextTest.php b/lib/twig/test/Twig/Tests/Node/TextTest.php deleted file mode 100755 index 87e0337..0000000 --- a/lib/twig/test/Twig/Tests/Node/TextTest.php +++ /dev/null @@ -1,42 +0,0 @@ -assertEquals('foo', $node->getAttribute('data')); - } - - /** - * @covers Twig_Node_Text::compile - * @dataProvider getTests - */ - public function testCompile($node, $source, $environment = null) - { - parent::testCompile($node, $source, $environment); - } - - public function getTests() - { - $tests = array(); - $tests[] = array(new Twig_Node_Text('foo', 0), 'echo "foo";'); - - return $tests; - } -} diff --git a/lib/twig/test/Twig/Tests/NodeVisitor/OptimizerTest.php b/lib/twig/test/Twig/Tests/NodeVisitor/OptimizerTest.php deleted file mode 100755 index a55d98e..0000000 --- a/lib/twig/test/Twig/Tests/NodeVisitor/OptimizerTest.php +++ /dev/null @@ -1,118 +0,0 @@ - false, 'autoescape' => false)); - $env->addExtension(new Twig_Extension_Optimizer()); - - $stream = $env->parse($env->tokenize('{{ block("foo") }}', 'index')); - - $node = $stream->getNode('body')->getNode(0); - - $this->assertEquals('Twig_Node_Expression_BlockReference', get_class($node)); - $this->assertTrue($node->getAttribute('output')); - } - - public function testRenderParentBlockOptimizer() - { - $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false)); - $env->addExtension(new Twig_Extension_Optimizer()); - - $stream = $env->parse($env->tokenize('{% extends "foo" %}{% block content %}{{ parent() }}{% endblock %}', 'index')); - - $node = $stream->getNode('blocks')->getNode('content')->getNode(0)->getNode('body'); - - $this->assertEquals('Twig_Node_Expression_Parent', get_class($node)); - $this->assertTrue($node->getAttribute('output')); - } - - public function testRenderVariableBlockOptimizer() - { - if (version_compare(phpversion(), '5.4.0RC1', '>=')) { - return; - } - - $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false, 'autoescape' => false)); - $env->addExtension(new Twig_Extension_Optimizer()); - $stream = $env->parse($env->tokenize('{{ block(name|lower) }}', 'index')); - - $node = $stream->getNode('body')->getNode(0)->getNode(1); - - $this->assertEquals('Twig_Node_Expression_BlockReference', get_class($node)); - $this->assertTrue($node->getAttribute('output')); - } - - /** - * @dataProvider getTestsForForOptimizer - */ - public function testForOptimizer($template, $expected) - { - $env = new Twig_Environment(new Twig_Loader_String(), array('cache' => false)); - $env->addExtension(new Twig_Extension_Optimizer()); - - $stream = $env->parse($env->tokenize($template, 'index')); - - foreach ($expected as $target => $withLoop) { - $this->assertTrue($this->checkForConfiguration($stream, $target, $withLoop), sprintf('variable %s is %soptimized', $target, $withLoop ? 'not ' : '')); - } - } - - public function getTestsForForOptimizer() - { - return array( - array('{% for i in foo %}{% endfor %}', array('i' => false)), - - array('{% for i in foo %}{{ loop.index }}{% endfor %}', array('i' => true)), - - array('{% for i in foo %}{% for j in foo %}{% endfor %}{% endfor %}', array('i' => false, 'j' => false)), - - array('{% for i in foo %}{% include "foo" %}{% endfor %}', array('i' => true)), - - array('{% for i in foo %}{% include "foo" only %}{% endfor %}', array('i' => false)), - - array('{% for i in foo %}{% include "foo" with { "foo": "bar" } only %}{% endfor %}', array('i' => false)), - - array('{% for i in foo %}{% include "foo" with { "foo": loop.index } only %}{% endfor %}', array('i' => true)), - - array('{% for i in foo %}{% for j in foo %}{{ loop.index }}{% endfor %}{% endfor %}', array('i' => false, 'j' => true)), - - array('{% for i in foo %}{% for j in foo %}{{ loop.parent.loop.index }}{% endfor %}{% endfor %}', array('i' => true, 'j' => true)), - - array('{% for i in foo %}{% set l = loop %}{% for j in foo %}{{ l.index }}{% endfor %}{% endfor %}', array('i' => true, 'j' => false)), - - array('{% for i in foo %}{% for j in foo %}{{ foo.parent.loop.index }}{% endfor %}{% endfor %}', array('i' => false, 'j' => false)), - - array('{% for i in foo %}{% for j in foo %}{{ loop["parent"].loop.index }}{% endfor %}{% endfor %}', array('i' => true, 'j' => true)), - ); - } - - public function checkForConfiguration(Twig_NodeInterface $node = null, $target, $withLoop) - { - if (null === $node) { - return; - } - - foreach ($node as $n) { - if ($n instanceof Twig_Node_For) { - if ($target === $n->getNode('value_target')->getAttribute('name')) { - return $withLoop == $n->getAttribute('with_loop'); - } - } - - $ret = $this->checkForConfiguration($n, $target, $withLoop); - if (null !== $ret) { - return $ret; - } - } - } -} diff --git a/lib/twig/test/Twig/Tests/ParserTest.php b/lib/twig/test/Twig/Tests/ParserTest.php deleted file mode 100755 index 76f257a..0000000 --- a/lib/twig/test/Twig/Tests/ParserTest.php +++ /dev/null @@ -1,160 +0,0 @@ -setMacro('display', $this->getMock('Twig_Node_Macro', array(), array(), '', null)); - } - - /** - * @expectedException Twig_Error_Syntax - * @expectedExceptionMessage Unknown tag name "foo". Did you mean "for" at line 0 - */ - public function testUnkownTag() - { - $stream = new Twig_TokenStream(array( - new Twig_Token(Twig_Token::BLOCK_START_TYPE, '', 0), - new Twig_Token(Twig_Token::NAME_TYPE, 'foo', 0), - new Twig_Token(Twig_Token::BLOCK_END_TYPE, '', 0), - new Twig_Token(Twig_Token::EOF_TYPE, '', 0), - )); - $parser = new Twig_Parser(new Twig_Environment()); - $parser->parse($stream); - } - - /** - * @dataProvider getFilterBodyNodesData - */ - public function testFilterBodyNodes($input, $expected) - { - $parser = $this->getParserForFilterBodyNodes(); - - $this->assertEquals($expected, $parser->filterBodyNodes($input)); - } - - public function getFilterBodyNodesData() - { - return array( - array( - new Twig_Node(array(new Twig_Node_Text(' ', 0))), - new Twig_Node(array()), - ), - array( - $input = new Twig_Node(array(new Twig_Node_Set(false, new Twig_Node(), new Twig_Node(), 0))), - $input, - ), - array( - $input = new Twig_Node(array(new Twig_Node_Set(true, new Twig_Node(), new Twig_Node(array(new Twig_Node(array(new Twig_Node_Text('foo', 0))))), 0))), - $input, - ), - ); - } - - /** - * @dataProvider getFilterBodyNodesDataThrowsException - * @expectedException Twig_Error_Syntax - */ - public function testFilterBodyNodesThrowsException($input) - { - $parser = $this->getParserForFilterBodyNodes(); - - $parser->filterBodyNodes($input); - } - - public function getFilterBodyNodesDataThrowsException() - { - return array( - array(new Twig_Node_Text('foo', 0)), - array(new Twig_Node(array(new Twig_Node(array(new Twig_Node_Text('foo', 0)))))), - ); - } - - /** - * @expectedException Twig_Error_Syntax - * @expectedExceptionMessage A template that extends another one cannot have a body but a byte order mark (BOM) has been detected; it must be removed at line 0. - */ - public function testFilterBodyNodesWithBOM() - { - $parser = $this->getParserForFilterBodyNodes(); - $parser->filterBodyNodes(new Twig_Node_Text(chr(0xEF).chr(0xBB).chr(0xBF), 0)); - } - - public function testParseIsReentrant() - { - $twig = new Twig_Environment(null, array( - 'autoescape' => false, - 'optimizations' => 0, - )); - $twig->addTokenParser(new TestTokenParser()); - - $parser = new Twig_Parser($twig); - - $parser->parse(new Twig_TokenStream(array( - new Twig_Token(Twig_Token::BLOCK_START_TYPE, '', 0), - new Twig_Token(Twig_Token::NAME_TYPE, 'test', 0), - new Twig_Token(Twig_Token::BLOCK_END_TYPE, '', 0), - new Twig_Token(Twig_Token::VAR_START_TYPE, '', 0), - new Twig_Token(Twig_Token::NAME_TYPE, 'foo', 0), - new Twig_Token(Twig_Token::VAR_END_TYPE, '', 0), - new Twig_Token(Twig_Token::EOF_TYPE, '', 0), - ))); - - $this->assertEquals(null, $parser->getParent()); - } - - protected function getParserForFilterBodyNodes() - { - $parser = new TestParser(new Twig_Environment()); - $parser->setParent(new Twig_Node()); - $parser->stream = $this->getMockBuilder('Twig_TokenStream')->disableOriginalConstructor()->getMock(); - - return $parser; - } -} - -class TestParser extends Twig_Parser -{ - public $stream; - - public function filterBodyNodes(Twig_NodeInterface $node) - { - return parent::filterBodyNodes($node); - } -} - -class TestTokenParser extends Twig_TokenParser -{ - public function parse(Twig_Token $token) - { - // simulate the parsing of another template right in the middle of the parsing of the current template - $this->parser->parse(new Twig_TokenStream(array( - new Twig_Token(Twig_Token::BLOCK_START_TYPE, '', 0), - new Twig_Token(Twig_Token::NAME_TYPE, 'extends', 0), - new Twig_Token(Twig_Token::STRING_TYPE, 'base', 0), - new Twig_Token(Twig_Token::BLOCK_END_TYPE, '', 0), - new Twig_Token(Twig_Token::EOF_TYPE, '', 0), - ))); - - $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); - - return new Twig_Node(array()); - } - - public function getTag() - { - return 'test'; - } -} diff --git a/lib/twig/test/Twig/Tests/TemplateTest.php b/lib/twig/test/Twig/Tests/TemplateTest.php deleted file mode 100755 index a4e658f..0000000 --- a/lib/twig/test/Twig/Tests/TemplateTest.php +++ /dev/null @@ -1,363 +0,0 @@ -assertEquals($value, $template->getAttribute($object, $item, $arguments, $type)); - } - - /** - * @dataProvider getGetAttributeTests - */ - public function testGetAttributeStrict($defined, $value, $object, $item, $arguments, $type, $useExt = false, $exceptionMessage = null) - { - $template = new Twig_TemplateTest( - new Twig_Environment(null, array('strict_variables' => true)), - $useExt - ); - - if ($defined) { - $this->assertEquals($value, $template->getAttribute($object, $item, $arguments, $type)); - } else { - try { - $this->assertEquals($value, $template->getAttribute($object, $item, $arguments, $type)); - - throw new Exception('Expected Twig_Error_Runtime exception.'); - } catch (Twig_Error_Runtime $e) { - if (null !== $exceptionMessage) { - $this->assertSame($exceptionMessage, $e->getMessage()); - } - } - } - } - - /** - * @dataProvider getGetAttributeTests - */ - public function testGetAttributeDefined($defined, $value, $object, $item, $arguments, $type, $useExt = false) - { - $template = new Twig_TemplateTest( - new Twig_Environment(), - $useExt - ); - - $this->assertEquals($defined, $template->getAttribute($object, $item, $arguments, $type, true)); - } - - /** - * @dataProvider getGetAttributeTests - */ - public function testGetAttributeDefinedStrict($defined, $value, $object, $item, $arguments, $type, $useExt = false) - { - $template = new Twig_TemplateTest( - new Twig_Environment(null, array('strict_variables' => true)), - $useExt - ); - - $this->assertEquals($defined, $template->getAttribute($object, $item, $arguments, $type, true)); - } - - public function getGetAttributeTests() - { - $array = array( - 'defined' => 'defined', - 'zero' => 0, - 'null' => null, - '1' => 1, - ); - - $objectArray = new Twig_TemplateArrayAccessObject(); - $stdObject = (object) $array; - $magicPropertyObject = new Twig_TemplateMagicPropertyObject(); - $propertyObject = new Twig_TemplatePropertyObject(); - $propertyObject1 = new Twig_TemplatePropertyObjectAndIterator(); - $methodObject = new Twig_TemplateMethodObject(); - $magicMethodObject = new Twig_TemplateMagicMethodObject(); - - $anyType = Twig_TemplateInterface::ANY_CALL; - $methodType = Twig_TemplateInterface::METHOD_CALL; - $arrayType = Twig_TemplateInterface::ARRAY_CALL; - - $basicTests = array( - // array(defined, value, property to fetch) - array(true, 'defined', 'defined'), - array(false, null, 'undefined'), - array(false, null, 'protected'), - array(true, 0, 'zero'), - array(true, 1, 1), - array(true, 1, 1.0), - array(true, null, 'null'), - ); - $testObjects = array( - // array(object, type of fetch) - array($array, $arrayType), - array($objectArray, $arrayType), - array($stdObject, $anyType), - array($magicPropertyObject, $anyType), - array($methodObject, $methodType), - array($methodObject, $anyType), - array($propertyObject, $anyType), - array($propertyObject1, $anyType), - ); - - $tests = array(); - foreach ($testObjects as $testObject) { - foreach ($basicTests as $test) { - // properties cannot be numbers - if (($testObject[0] instanceof stdClass || $testObject[0] instanceof Twig_TemplatePropertyObject) && is_numeric($test[2])) { - continue; - } - - $tests[] = array($test[0], $test[1], $testObject[0], $test[2], array(), $testObject[1]); - } - } - - // additional method tests - $tests = array_merge($tests, array( - array(true, 'defined', $methodObject, 'defined', array(), $methodType), - array(true, 'defined', $methodObject, 'DEFINED', array(), $methodType), - array(true, 'defined', $methodObject, 'getDefined', array(), $methodType), - array(true, 'defined', $methodObject, 'GETDEFINED', array(), $methodType), - array(true, 'static', $methodObject, 'static', array(), $methodType), - array(true, 'static', $methodObject, 'getStatic', array(), $methodType), - - array(true, '__call_undefined', $magicMethodObject, 'undefined', array(), $methodType), - array(true, '__call_UNDEFINED', $magicMethodObject, 'UNDEFINED', array(), $methodType), - )); - - // add the same tests for the any type - foreach ($tests as $test) { - if ($anyType !== $test[5]) { - $test[5] = $anyType; - $tests[] = $test; - } - } - - $methodAndPropObject = new Twig_TemplateMethodAndPropObject; - - // additional method tests - $tests = array_merge($tests, array( - array(true, 'a', $methodAndPropObject, 'a', array(), $anyType), - array(true, 'a', $methodAndPropObject, 'a', array(), $methodType), - array(false, null, $methodAndPropObject, 'a', array(), $arrayType), - - array(true, 'b_prop', $methodAndPropObject, 'b', array(), $anyType), - array(true, 'b', $methodAndPropObject, 'B', array(), $anyType), - array(true, 'b', $methodAndPropObject, 'b', array(), $methodType), - array(true, 'b', $methodAndPropObject, 'B', array(), $methodType), - array(false, null, $methodAndPropObject, 'b', array(), $arrayType), - - array(false, null, $methodAndPropObject, 'c', array(), $anyType), - array(false, null, $methodAndPropObject, 'c', array(), $methodType), - array(false, null, $methodAndPropObject, 'c', array(), $arrayType), - - )); - - // tests when input is not an array or object - $tests = array_merge($tests, array( - array(false, null, 42, 'a', array(), $anyType, false, 'Item "a" for "42" does not exist'), - array(false, null, "string", 'a', array(), $anyType, false, 'Item "a" for "string" does not exist'), - array(false, null, array(), 'a', array(), $anyType, false, 'Item "a" for "Array" does not exist'), - )); - - // add twig_template_get_attributes tests - - if (function_exists('twig_template_get_attributes')) { - foreach(array_slice($tests, 0) as $test) { - $test = array_pad($test, 7, null); - $test[6] = true; - $tests[] = $test; - } - } - - return $tests; - } - - public function useExtGetAttribute() - { - return false; - } -} - -class Twig_TemplateTest extends Twig_Template -{ - protected $useExtGetAttribute = false; - - public function __construct(Twig_Environment $env, $useExtGetAttribute = false) - { - parent::__construct($env); - $this->useExtGetAttribute = $useExtGetAttribute; - Twig_Template::clearCache(); - } - - public function getTemplateName() - { - } - - public function getDebugInfo() - { - return array(); - } - - protected function doGetParent(array $context) - { - } - - protected function doDisplay(array $context, array $blocks = array()) - { - } - - public function getAttribute($object, $item, array $arguments = array(), $type = Twig_TemplateInterface::ANY_CALL, $isDefinedTest = false, $ignoreStrictCheck = false) - { - if ($this->useExtGetAttribute) { - return twig_template_get_attributes($this, $object, $item, $arguments, $type, $isDefinedTest, $ignoreStrictCheck); - } else { - return parent::getAttribute($object, $item, $arguments, $type, $isDefinedTest, $ignoreStrictCheck); - } - } -} - -class Twig_TemplateArrayAccessObject implements ArrayAccess -{ - protected $protected = 'protected'; - - public $attributes = array( - 'defined' => 'defined', - 'zero' => 0, - 'null' => null, - '1' => 1, - ); - - public function offsetExists($name) - { - return array_key_exists($name, $this->attributes); - } - - public function offsetGet($name) - { - return array_key_exists($name, $this->attributes) ? $this->attributes[$name] : null; - } - - public function offsetSet($name, $value) - { - } - - public function offsetUnset($name) - { - } -} - -class Twig_TemplateMagicPropertyObject -{ - public $defined = 'defined'; - - public $attributes = array( - 'zero' => 0, - 'null' => null, - '1' => 1, - ); - - protected $protected = 'protected'; - - public function __isset($name) - { - return array_key_exists($name, $this->attributes); - } - - public function __get($name) - { - return array_key_exists($name, $this->attributes) ? $this->attributes[$name] : null; - } -} - -class Twig_TemplatePropertyObject -{ - public $defined = 'defined'; - public $zero = 0; - public $null = null; - - protected $protected = 'protected'; -} - -class Twig_TemplatePropertyObjectAndIterator extends Twig_TemplatePropertyObject implements IteratorAggregate -{ - public function getIterator() - { - return new ArrayIterator(array('foo', 'bar')); - } -} - -class Twig_TemplateMethodObject -{ - public function getDefined() - { - return 'defined'; - } - - public function get1() - { - return 1; - } - - public function getZero() - { - return 0; - } - - public function getNull() - { - return null; - } - - protected function getProtected() - { - return 'protected'; - } - - static public function getStatic() - { - return 'static'; - } -} - -class Twig_TemplateMethodAndPropObject -{ - private $a = 'a_prop'; - public function getA() { - return 'a'; - } - - public $b = 'b_prop'; - public function getB() { - return 'b'; - } - - private $c = 'c_prop'; - private function getC() { - return 'c'; - } -} - -class Twig_TemplateMagicMethodObject -{ - public function __call($method, $arguments) { - return '__call_'.$method; - } -} diff --git a/lib/twig/test/Twig/Tests/TokenStreamTest.php b/lib/twig/test/Twig/Tests/TokenStreamTest.php deleted file mode 100755 index 794a037..0000000 --- a/lib/twig/test/Twig/Tests/TokenStreamTest.php +++ /dev/null @@ -1,41 +0,0 @@ -isEOF()) { - $token = $stream->next(); - - $repr[] = $token->getValue(); - } - $this->assertEquals('1, 2, 3, 4, 5, 6, 7', implode(', ', $repr), '->next() advances the pointer and returns the current token'); - } -} diff --git a/lib/twig/test/Twig/Tests/integrationTest.php b/lib/twig/test/Twig/Tests/integrationTest.php deleted file mode 100755 index 2045097..0000000 --- a/lib/twig/test/Twig/Tests/integrationTest.php +++ /dev/null @@ -1,294 +0,0 @@ -getRealpath()); - - if (preg_match('/ - --TEST--\s*(.*?)\s*(?:--CONDITION--\s*(.*))?\s*((?:--TEMPLATE(?:\(.*?\))?--(?:.*))+)\s*--EXCEPTION--\s*(.*)/sx', $test, $match)) { - $message = $match[1]; - $condition = $match[2]; - $templates = $this->parseTemplates($match[3]); - $exception = $match[4]; - $outputs = array(); - } 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; - } - - /** - * @dataProvider getTests - */ - public function testIntegration($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->addExtension(new TestExtension()); - $twig->addExtension(new Twig_Extension_Debug()); - - 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($e->getMessage().' (in '.$file.')'); - } - - try { - $output = trim($template->render(eval($match[1].';')), "\n "); - } catch (Exception $e) { - $output = trim(sprintf('%s: %s', get_class($e), $e->getMessage())); - } - $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 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; - } -} - -function test_foo($value = 'foo') -{ - return $value; -} - -class Foo implements Iterator -{ - const BAR_NAME = 'bar'; - - public $position = 0; - public $array = array(1, 2); - - public function bar($param1 = null, $param2 = null) - { - return 'bar'.($param1 ? '_'.$param1 : '').($param2 ? '-'.$param2 : ''); - } - - public function getFoo() - { - return 'foo'; - } - - public function getSelf() - { - return $this; - } - - public function is() - { - return 'is'; - } - - public function in() - { - return 'in'; - } - - public function not() - { - return 'not'; - } - - public function strToLower($value) - { - return strtolower($value); - } - - public function rewind() - { - $this->position = 0; - } - - public function current() - { - return $this->array[$this->position]; - } - - public function key() - { - return 'a'; - } - - public function next() - { - ++$this->position; - } - - public function valid() - { - return isset($this->array[$this->position]); - } -} - -class TestTokenParser_☃ extends Twig_TokenParser -{ - public function parse(Twig_Token $token) - { - $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE); - - return new Twig_Node_Print(new Twig_Node_Expression_Constant('☃', -1), -1); - } - - public function getTag() - { - return '☃'; - } -} - -class TestExtension extends Twig_Extension -{ - public function getTokenParsers() - { - return array( - new TestTokenParser_☃(), - ); - } - - public function getFilters() - { - return array( - '☃' => new Twig_Filter_Method($this, '☃Filter'), - 'escape_and_nl2br' => new Twig_Filter_Method($this, 'escape_and_nl2br', array('needs_environment' => true, 'is_safe' => array('html'))), - 'nl2br' => new Twig_Filter_Method($this, 'nl2br', array('pre_escape' => 'html', 'is_safe' => array('html'))), - 'escape_something' => new Twig_Filter_Method($this, 'escape_something', array('is_safe' => array('something'))), - '*_path' => new Twig_Filter_Method($this, 'dynamic_path'), - '*_foo_*_bar' => new Twig_Filter_Method($this, 'dynamic_foo'), - ); - } - - public function getFunctions() - { - return array( - '☃' => new Twig_Function_Method($this, '☃Function'), - 'safe_br' => new Twig_Function_Method($this, 'br', array('is_safe' => array('html'))), - 'unsafe_br' => new Twig_Function_Method($this, 'br'), - '*_path' => new Twig_Function_Method($this, 'dynamic_path'), - '*_foo_*_bar' => new Twig_Function_Method($this, 'dynamic_foo'), - ); - } - - public function ☃Filter($value) - { - return "☃{$value}☃"; - } - - public function ☃Function($value) - { - return "☃{$value}☃"; - } - - /** - * nl2br which also escapes, for testing escaper filters - */ - public function escape_and_nl2br($env, $value, $sep = '
    ') - { - return $this->nl2br(twig_escape_filter($env, $value, 'html'), $sep); - } - - /** - * nl2br only, for testing filters with pre_escape - */ - public function nl2br($value, $sep = '
    ') - { - // not secure if $value contains html tags (not only entities) - // don't use - return str_replace("\n", "$sep\n", $value); - } - - public function dynamic_path($element, $item) - { - return $element.'/'.$item; - } - - public function dynamic_foo($foo, $bar, $item) - { - return $foo.'/'.$bar.'/'.$item; - } - - public function escape_something($value) - { - return strtoupper($value); - } - - public function br() - { - return '
    '; - } - - public function getName() - { - return 'test'; - } -} diff --git a/lib/twig/test/bootstrap.php b/lib/twig/test/bootstrap.php deleted file mode 100755 index 36eb46a..0000000 --- a/lib/twig/test/bootstrap.php +++ /dev/null @@ -1,13 +0,0 @@ - + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0 class loader + * + * See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier + * @author Jordi Boggiano + */ +class ClassLoader +{ + private $prefixes = array(); + private $fallbackDirs = array(); + private $useIncludePath = false; + private $classMap = array(); + + public function getPrefixes() + { + return $this->prefixes; + } + + public function getFallbackDirs() + { + return $this->fallbackDirs; + } + + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param array $classMap Class to filename map + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of classes, merging with any others previously set. + * + * @param string $prefix The classes prefix + * @param array|string $paths The location(s) of the classes + * @param bool $prepend Prepend the location(s) + */ + public function add($prefix, $paths, $prepend = false) + { + if (!$prefix) { + if ($prepend) { + $this->fallbackDirs = array_merge( + (array) $paths, + $this->fallbackDirs + ); + } else { + $this->fallbackDirs = array_merge( + $this->fallbackDirs, + (array) $paths + ); + } + + return; + } + if (!isset($this->prefixes[$prefix])) { + $this->prefixes[$prefix] = (array) $paths; + + return; + } + if ($prepend) { + $this->prefixes[$prefix] = array_merge( + (array) $paths, + $this->prefixes[$prefix] + ); + } else { + $this->prefixes[$prefix] = array_merge( + $this->prefixes[$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of classes, replacing any others previously set. + * + * @param string $prefix The classes prefix + * @param array|string $paths The location(s) of the classes + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirs = (array) $paths; + + return; + } + $this->prefixes[$prefix] = (array) $paths; + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + } + + /** + * Unregisters this instance as an autoloader. + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return bool|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + include $file; + + return true; + } + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + if ('\\' == $class[0]) { + $class = substr($class, 1); + } + + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $classPath = str_replace('\\', DIRECTORY_SEPARATOR, substr($class, 0, $pos)) . DIRECTORY_SEPARATOR; + $className = substr($class, $pos + 1); + } else { + // PEAR-like class name + $classPath = null; + $className = $class; + } + + $classPath .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php'; + + foreach ($this->prefixes as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($dir . DIRECTORY_SEPARATOR . $classPath)) { + return $dir . DIRECTORY_SEPARATOR . $classPath; + } + } + } + } + + foreach ($this->fallbackDirs as $dir) { + if (file_exists($dir . DIRECTORY_SEPARATOR . $classPath)) { + return $dir . DIRECTORY_SEPARATOR . $classPath; + } + } + + if ($this->useIncludePath && $file = stream_resolve_include_path($classPath)) { + return $file; + } + + return $this->classMap[$class] = false; + } +} diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php new file mode 100644 index 0000000..af4ad58 --- /dev/null +++ b/vendor/composer/autoload_classmap.php @@ -0,0 +1,9 @@ + $vendorDir . '/twig/twig/lib', +); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php new file mode 100644 index 0000000..f157e8e --- /dev/null +++ b/vendor/composer/autoload_real.php @@ -0,0 +1,43 @@ + $path) { + $loader->add($namespace, $path); + } + + $classMap = require __DIR__ . '/autoload_classmap.php'; + if ($classMap) { + $loader->addClassMap($classMap); + } + + $loader->register(true); + + return $loader; + } +} diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json new file mode 100644 index 0000000..cfa8f1d --- /dev/null +++ b/vendor/composer/installed.json @@ -0,0 +1,53 @@ +[ + { + "name": "twig/twig", + "version": "v1.12.3", + "version_normalized": "1.12.3.0", + "source": { + "type": "git", + "url": "https://github.com/fabpot/Twig.git", + "reference": "v1.12.3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fabpot/Twig/zipball/v1.12.3", + "reference": "v1.12.3", + "shasum": "" + }, + "require": { + "php": ">=5.2.4" + }, + "time": "2013-04-08 12:40:11", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.12-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-0": { + "Twig_": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Armin Ronacher", + "email": "armin.ronacher@active-4.com" + } + ], + "description": "Twig, the flexible, fast, and secure template language for PHP", + "homepage": "http://twig.sensiolabs.org", + "keywords": [ + "templating" + ] + } +] diff --git a/vendor/twig/twig/.editorconfig b/vendor/twig/twig/.editorconfig new file mode 100644 index 0000000..270f1d1 --- /dev/null +++ b/vendor/twig/twig/.editorconfig @@ -0,0 +1,18 @@ +; top-most EditorConfig file +root = true + +; Unix-style newlines +[*] +end_of_line = LF + +[*.php] +indent_style = space +indent_size = 4 + +[*.test] +indent_style = space +indent_size = 4 + +[*.rst] +indent_style = space +indent_size = 4 diff --git a/vendor/twig/twig/.gitignore b/vendor/twig/twig/.gitignore new file mode 100644 index 0000000..840b78e --- /dev/null +++ b/vendor/twig/twig/.gitignore @@ -0,0 +1,2 @@ +/ext/twig/autom4te.cache/ + diff --git a/vendor/twig/twig/.travis.yml b/vendor/twig/twig/.travis.yml new file mode 100644 index 0000000..e6d3b61 --- /dev/null +++ b/vendor/twig/twig/.travis.yml @@ -0,0 +1,14 @@ +language: php + +php: + - 5.2 + - 5.3 + - 5.4 + +env: + - TWIG_EXT=no + - TWIG_EXT=yes + +before_script: + - if [ "$TWIG_EXT" == "yes" ]; then sh -c "cd ext/twig && phpize && ./configure --enable-twig && make && sudo make install"; fi + - if [ "$TWIG_EXT" == "yes" ]; then echo "extension=twig.so" >> `php --ini | grep "Loaded Configuration" | sed -e "s|.*:\s*||"`; fi diff --git a/lib/twig/AUTHORS b/vendor/twig/twig/AUTHORS old mode 100755 new mode 100644 similarity index 100% rename from lib/twig/AUTHORS rename to vendor/twig/twig/AUTHORS diff --git a/lib/twig/CHANGELOG b/vendor/twig/twig/CHANGELOG old mode 100755 new mode 100644 similarity index 79% rename from lib/twig/CHANGELOG rename to vendor/twig/twig/CHANGELOG index 7521789..6b2af3e --- a/lib/twig/CHANGELOG +++ b/vendor/twig/twig/CHANGELOG @@ -1,3 +1,144 @@ +* 1.12.3 (2013-04-08) + + * fixed a security issue in the filesystem loader where it was possible to include a template one + level above the configured path + * fixed fatal error that should be an exception when adding a filter/function/test too late + * added a batch filter + * added support for encoding an array as query string in the url_encode filter + +* 1.12.2 (2013-02-09) + + * fixed the timezone used by the date filter and function when the given date contains a timezone (like 2010-01-28T15:00:00+02:00) + * fixed globals when getGlobals is called early on + * added the first and last filter + +* 1.12.1 (2013-01-15) + + * added support for object instances as the second argument of the constant function + * relaxed globals management to avoid a BC break + * added support for {{ some_string[:2] }} + +* 1.12.0 (2013-01-08) + + * added verbatim as an alias for the raw tag to avoid confusion with the raw filter + * fixed registration of tests and functions as anonymous functions + * fixed globals management + +* 1.12.0-RC1 (2012-12-29) + + * added an include function (does the same as the include tag but in a more flexible way) + * added the ability to use any PHP callable to define filters, functions, and tests + * added a syntax error when using a loop variable that is not defined + * added the ability to set default values for macro arguments + * added support for named arguments for filters, tests, and functions + * moved filters/functions/tests syntax errors to the parser + * added support for extended ternary operator syntaxes + +* 1.11.1 (2012-11-11) + + * fixed debug info line numbering (was off by 2) + * fixed escaping when calling a macro inside another one (regression introduced in 1.9.1) + * optimized variable access on PHP 5.4 + * fixed a crash of the C extension when an exception was thrown from a macro called without being imported (using _self.XXX) + +* 1.11.0 (2012-11-07) + + * fixed macro compilation when a variable name is a PHP reserved keyword + * changed the date filter behavior to always apply the default timezone, except if false is passed as the timezone + * fixed bitwise operator precedences + * added the template_from_string function + * fixed default timezone usage for the date function + * optimized the way Twig exceptions are managed (to make them faster) + * added Twig_ExistsLoaderInterface (implementing this interface in your loader make the chain loader much faster) + +* 1.10.3 (2012-10-19) + + * fixed wrong template location in some error messages + * reverted a BC break introduced in 1.10.2 + * added a split filter + +* 1.10.2 (2012-10-15) + + * fixed macro calls on PHP 5.4 + +* 1.10.1 (2012-10-15) + + * made a speed optimization to macro calls when imported via the "import" tag + * fixed C extension compilation on Windows + * fixed a segfault in the C extension when using DateTime objects + +* 1.10.0 (2012-09-28) + + * extracted functional tests framework to make it reusable for third-party extensions + * added namespaced templates support in Twig_Loader_Filesystem + * added Twig_Loader_Filesystem::prependPath() + * fixed an error when a token parser pass a closure as a test to the subparse() method + +* 1.9.2 (2012-08-25) + + * fixed the in operator for objects that contain circular references + * fixed the C extension when accessing a public property of an object implementing the \ArrayAccess interface + +* 1.9.1 (2012-07-22) + + * optimized macro calls when auto-escaping is on + * fixed wrong parent class for Twig_Function_Node + * made Twig_Loader_Chain more explicit about problems + +* 1.9.0 (2012-07-13) + + * made the parsing independent of the template loaders + * fixed exception trace when an error occurs when rendering a child template + * added escaping strategies for CSS, URL, and HTML attributes + * fixed nested embed tag calls + * added the date_modify filter + +* 1.8.3 (2012-06-17) + + * fixed paths in the filesystem loader when passing a path that ends with a slash or a backslash + * fixed escaping when a project defines a function named html or js + * fixed chmod mode to apply the umask correctly + +* 1.8.2 (2012-05-30) + + * added the abs filter + * fixed a regression when using a number in template attributes + * fixed compiler when mbstring.func_overload is set to 2 + * fixed DateTimeZone support in date filter + +* 1.8.1 (2012-05-17) + + * fixed a regression when dealing with SimpleXMLElement instances in templates + * fixed "is_safe" value for the "dump" function when "html_errors" is not defined in php.ini + * switched to use mbstring whenever possible instead of iconv (you might need to update your encoding as mbstring and iconv encoding names sometimes differ) + +* 1.8.0 (2012-05-08) + + * enforced interface when adding tests, filters, functions, and node visitors from extensions + * fixed a side-effect of the date filter where the timezone might be changed + * simplified usage of the autoescape tag; the only (optional) argument is now the escaping strategy or false (with a BC layer) + * added a way to dynamically change the auto-escaping strategy according to the template "filename" + * changed the autoescape option to also accept a supported escaping strategy (for BC, true is equivalent to html) + * added an embed tag + +* 1.7.0 (2012-04-24) + + * fixed a PHP warning when using CIFS + * fixed template line number in some exceptions + * added an iterable test + * added an error when defining two blocks with the same name in a template + * added the preserves_safety option for filters + * fixed a PHP notice when trying to access a key on a non-object/array variable + * enhanced error reporting when the template file is an instance of SplFileInfo + * added Twig_Environment::mergeGlobals() + * added compilation checks to avoid misuses of the sandbox tag + * fixed filesystem loader freshness logic for high traffic websites + * fixed random function when charset is null + +* 1.6.5 (2012-04-11) + + * fixed a regression when a template only extends another one without defining any blocks + * 1.6.4 (2012-04-02) * fixed PHP notice in Twig_Error::guessTemplateLine() introduced in 1.6.3 @@ -248,7 +389,7 @@ Changes: * enhanced error messages when an unexpected token is parsed in an expression * fixed filename not being added to syntax error messages * added the autoescape option to enable/disable autoescaping - * removed the newline after a comment (mimicks PHP behavior) + * removed the newline after a comment (mimics PHP behavior) * added a syntax error exception when parent block is used on a template that does not extend another one * made the Escaper extension enabled by default * fixed sandbox extension when used with auto output escaping diff --git a/lib/twig/LICENSE b/vendor/twig/twig/LICENSE old mode 100755 new mode 100644 similarity index 95% rename from lib/twig/LICENSE rename to vendor/twig/twig/LICENSE index 5063d8d..3384cc5 --- a/lib/twig/LICENSE +++ b/vendor/twig/twig/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2009 by the Twig Team, see AUTHORS for more details. +Copyright (c) 2009-2013 by the Twig Team, see AUTHORS for more details. Some rights reserved. diff --git a/lib/twig/README.markdown b/vendor/twig/twig/README.markdown old mode 100755 new mode 100644 similarity index 72% rename from lib/twig/README.markdown rename to vendor/twig/twig/README.markdown index 832394b..88d6fab --- a/lib/twig/README.markdown +++ b/vendor/twig/twig/README.markdown @@ -1,6 +1,8 @@ Twig, the flexible, fast, and secure template language for PHP ============================================================== +[![Build Status](https://secure.travis-ci.org/fabpot/Twig.png?branch=master)](http://travis-ci.org/fabpot/Twig) + Twig is a template language for PHP, released under the new BSD license (code and documentation). @@ -12,4 +14,4 @@ More Information Read the [documentation][1] for more information. -[1]: http://twig.sensiolabs.org/documentation \ No newline at end of file +[1]: http://twig.sensiolabs.org/documentation diff --git a/lib/twig/composer.json b/vendor/twig/twig/composer.json old mode 100755 new mode 100644 similarity index 83% rename from lib/twig/composer.json rename to vendor/twig/twig/composer.json index 87662b8..5530d28 --- a/lib/twig/composer.json +++ b/vendor/twig/twig/composer.json @@ -4,8 +4,7 @@ "description": "Twig, the flexible, fast, and secure template language for PHP", "keywords": ["templating"], "homepage": "http://twig.sensiolabs.org", - "version": "1.6.4", - "license": "BSD", + "license": "BSD-3", "authors": [ { "name": "Fabien Potencier", @@ -23,5 +22,10 @@ "psr-0" : { "Twig_" : "lib/" } + }, + "extra": { + "branch-alias": { + "dev-master": "1.12-dev" + } } } diff --git a/lib/twig/lib/Twig/Autoloader.php b/vendor/twig/twig/lib/Twig/Autoloader.php old mode 100755 new mode 100644 similarity index 74% rename from lib/twig/lib/Twig/Autoloader.php rename to vendor/twig/twig/lib/Twig/Autoloader.php index a93b8ca..d1e005b --- a/lib/twig/lib/Twig/Autoloader.php +++ b/vendor/twig/twig/lib/Twig/Autoloader.php @@ -12,15 +12,14 @@ /** * Autoloads Twig classes. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_Autoloader { /** * Registers Twig_Autoloader as an SPL autoloader. */ - static public function register() + public static function register() { ini_set('unserialize_callback_func', 'spl_autoload_call'); spl_autoload_register(array(new self, 'autoload')); @@ -29,11 +28,9 @@ class Twig_Autoloader /** * Handles autoloading of classes. * - * @param string $class A class name. - * - * @return boolean Returns true if the class has been loaded + * @param string $class A class name. */ - static public function autoload($class) + public static function autoload($class) { if (0 !== strpos($class, 'Twig')) { return; diff --git a/lib/twig/lib/Twig/Compiler.php b/vendor/twig/twig/lib/Twig/Compiler.php old mode 100755 new mode 100644 similarity index 78% rename from lib/twig/lib/Twig/Compiler.php rename to vendor/twig/twig/lib/Twig/Compiler.php index ae415a2..99aecbc --- a/lib/twig/lib/Twig/Compiler.php +++ b/vendor/twig/twig/lib/Twig/Compiler.php @@ -13,8 +13,7 @@ /** * Compiles a node to PHP code. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_Compiler implements Twig_CompilerInterface { @@ -25,6 +24,7 @@ class Twig_Compiler implements Twig_CompilerInterface protected $debugInfo; protected $sourceOffset; protected $sourceLine; + protected $filename; /** * Constructor. @@ -37,6 +37,11 @@ class Twig_Compiler implements Twig_CompilerInterface $this->debugInfo = array(); } + public function getFilename() + { + return $this->filename; + } + /** * Returns the environment instance related to this compiler. * @@ -70,9 +75,14 @@ class Twig_Compiler implements Twig_CompilerInterface $this->lastLine = null; $this->source = ''; $this->sourceOffset = 0; - $this->sourceLine = 0; + // source code starts at 1 (as we then increment it when we encounter new lines) + $this->sourceLine = 1; $this->indentation = $indentation; + if ($node instanceof Twig_Node_Module) { + $this->filename = $node->getAttribute('filename'); + } + $node->compile($this); return $this; @@ -92,7 +102,7 @@ class Twig_Compiler implements Twig_CompilerInterface /** * Adds a raw string to the compiled code. * - * @param string $string The string + * @param string $string The string * * @return Twig_Compiler The current compiler instance */ @@ -119,6 +129,11 @@ class Twig_Compiler implements Twig_CompilerInterface return $this; } + /** + * Appends an indentation to the current PHP code after compilation. + * + * @return Twig_Compiler The current compiler instance + */ public function addIndentation() { $this->source .= str_repeat(' ', $this->indentation * 4); @@ -129,7 +144,7 @@ class Twig_Compiler implements Twig_CompilerInterface /** * Adds a quoted string to the compiled code. * - * @param string $value The string + * @param string $value The string * * @return Twig_Compiler The current compiler instance */ @@ -143,7 +158,7 @@ class Twig_Compiler implements Twig_CompilerInterface /** * Returns a PHP representation of a given value. * - * @param mixed $value The value to convert + * @param mixed $value The value to convert * * @return Twig_Compiler The current compiler instance */ @@ -192,12 +207,21 @@ class Twig_Compiler implements Twig_CompilerInterface public function addDebugInfo(Twig_NodeInterface $node) { if ($node->getLine() != $this->lastLine) { - $this->sourceLine += substr_count($this->source, "\n", $this->sourceOffset); + $this->write("// line {$node->getLine()}\n"); + + // when mbstring.func_overload is set to 2 + // mb_substr_count() replaces substr_count() + // but they have different signatures! + if (((int) ini_get('mbstring.func_overload')) & 2) { + // this is much slower than the "right" version + $this->sourceLine += mb_substr_count(mb_substr($this->source, $this->sourceOffset), "\n"); + } else { + $this->sourceLine += substr_count($this->source, "\n", $this->sourceOffset); + } $this->sourceOffset = strlen($this->source); $this->debugInfo[$this->sourceLine] = $node->getLine(); $this->lastLine = $node->getLine(); - $this->write("// line {$node->getLine()}\n"); } return $this; @@ -231,12 +255,13 @@ class Twig_Compiler implements Twig_CompilerInterface */ public function outdent($step = 1) { - $this->indentation -= $step; - - if ($this->indentation < 0) { - throw new Twig_Error('Unable to call outdent() as the indentation would become negative'); + // can't outdent by more steps than the current indentation level + if ($this->indentation < $step) { + throw new LogicException('Unable to call outdent() as the indentation would become negative'); } + $this->indentation -= $step; + return $this; } } diff --git a/lib/twig/lib/Twig/CompilerInterface.php b/vendor/twig/twig/lib/Twig/CompilerInterface.php old mode 100755 new mode 100644 similarity index 68% rename from lib/twig/lib/Twig/CompilerInterface.php rename to vendor/twig/twig/lib/Twig/CompilerInterface.php index 0a13edf..e293ec9 --- a/lib/twig/lib/Twig/CompilerInterface.php +++ b/vendor/twig/twig/lib/Twig/CompilerInterface.php @@ -12,24 +12,24 @@ /** * Interface implemented by compiler classes. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier + * @deprecated since 1.12 (to be removed in 2.0) */ interface Twig_CompilerInterface { /** * Compiles a node. * - * @param Twig_NodeInterface $node The node to compile + * @param Twig_NodeInterface $node The node to compile * * @return Twig_CompilerInterface The current compiler instance */ - function compile(Twig_NodeInterface $node); + public function compile(Twig_NodeInterface $node); /** * Gets the current PHP code after compilation. * * @return string The PHP code */ - function getSource(); + public function getSource(); } diff --git a/lib/twig/lib/Twig/Environment.php b/vendor/twig/twig/lib/Twig/Environment.php old mode 100755 new mode 100644 similarity index 67% rename from lib/twig/lib/Twig/Environment.php rename to vendor/twig/twig/lib/Twig/Environment.php index 596c867..0a4ff32 --- a/lib/twig/lib/Twig/Environment.php +++ b/vendor/twig/twig/lib/Twig/Environment.php @@ -12,12 +12,11 @@ /** * Stores the Twig configuration. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_Environment { - const VERSION = '1.6.4'; + const VERSION = '1.12.3'; protected $charset; protected $loader; @@ -36,6 +35,7 @@ class Twig_Environment protected $functions; protected $globals; protected $runtimeInitialized; + protected $extensionInitialized; protected $loadedTemplates; protected $strictVariables; protected $unaryOperators; @@ -50,9 +50,8 @@ class Twig_Environment * * Available options: * - * * debug: When set to `true`, the generated templates have a __toString() - * method that you can use to display the generated nodes (default to - * false). + * * debug: When set to true, it automatically set "auto_reload" to true as + * well (default to false). * * * charset: The charset used by the templates (default to utf-8). * @@ -60,7 +59,7 @@ class Twig_Environment * templates (default to Twig_Template). * * * cache: An absolute path where to store the compiled templates, or - * false to disable compilation cache (default) + * false to disable compilation cache (default). * * * auto_reload: Whether to reload the template is the original source changed. * If you don't provide the auto_reload option, it will be @@ -69,14 +68,18 @@ class Twig_Environment * * strict_variables: Whether to ignore invalid variables in templates * (default to false). * - * * autoescape: Whether to enable auto-escaping (default to true); + * * autoescape: Whether to enable auto-escaping (default to html): + * * false: disable auto-escaping + * * true: equivalent to html + * * html, js: set the autoescaping to one of the supported strategies + * * PHP callback: a PHP callback that returns an escaping strategy based on the template "filename" * * * optimizations: A flag that indicates which optimizations to apply * (default to -1 which means that all optimizations are enabled; - * set it to 0 to disable) + * set it to 0 to disable). * - * @param Twig_LoaderInterface $loader A Twig_LoaderInterface instance - * @param array $options An array of options + * @param Twig_LoaderInterface $loader A Twig_LoaderInterface instance + * @param array $options An array of options */ public function __construct(Twig_LoaderInterface $loader = null, $options = array()) { @@ -89,7 +92,7 @@ class Twig_Environment 'charset' => 'UTF-8', 'base_template_class' => 'Twig_Template', 'strict_variables' => false, - 'autoescape' => true, + 'autoescape' => 'html', 'cache' => false, 'auto_reload' => null, 'optimizations' => -1, @@ -99,16 +102,17 @@ class Twig_Environment $this->charset = $options['charset']; $this->baseTemplateClass = $options['base_template_class']; $this->autoReload = null === $options['auto_reload'] ? $this->debug : (bool) $options['auto_reload']; - $this->extensions = array( - 'core' => new Twig_Extension_Core(), - 'escaper' => new Twig_Extension_Escaper((bool) $options['autoescape']), - 'optimizer' => new Twig_Extension_Optimizer($options['optimizations']), - ); $this->strictVariables = (bool) $options['strict_variables']; $this->runtimeInitialized = false; $this->setCache($options['cache']); $this->functionCallbacks = array(); $this->filterCallbacks = array(); + + $this->addExtension(new Twig_Extension_Core()); + $this->addExtension(new Twig_Extension_Escaper($options['autoescape'])); + $this->addExtension(new Twig_Extension_Optimizer($options['optimizations'])); + $this->extensionInitialized = false; + $this->staging = new Twig_Extension_Staging(); } /** @@ -251,13 +255,14 @@ class Twig_Environment /** * Gets the template class associated with the given string. * - * @param string $name The name for which to calculate the template class name + * @param string $name The name for which to calculate the template class name + * @param integer $index The index if it is an embedded template * * @return string The template class name */ - public function getTemplateClass($name) + public function getTemplateClass($name, $index = null) { - return $this->templateClassPrefix.md5($this->loader->getCacheKey($name)); + return $this->templateClassPrefix.md5($this->getLoader()->getCacheKey($name)).(null === $index ? '' : '_'.$index); } /** @@ -297,13 +302,14 @@ class Twig_Environment /** * Loads a template by name. * - * @param string $name The template name + * @param string $name The template name + * @param integer $index The index if it is an embedded template * * @return Twig_TemplateInterface A template instance representing the given template name */ - public function loadTemplate($name) + public function loadTemplate($name, $index = null) { - $cls = $this->getTemplateClass($name); + $cls = $this->getTemplateClass($name, $index); if (isset($this->loadedTemplates[$cls])) { return $this->loadedTemplates[$cls]; @@ -311,10 +317,10 @@ class Twig_Environment if (!class_exists($cls, false)) { if (false === $cache = $this->getCacheFilename($name)) { - eval('?>'.$this->compileSource($this->loader->getSource($name), $name)); + eval('?>'.$this->compileSource($this->getLoader()->getSource($name), $name)); } else { if (!is_file($cache) || ($this->isAutoReload() && !$this->isTemplateFresh($name, filemtime($cache)))) { - $this->writeCacheFile($cache, $this->compileSource($this->loader->getSource($name), $name)); + $this->writeCacheFile($cache, $this->compileSource($this->getLoader()->getSource($name), $name)); } require_once $cache; @@ -349,7 +355,7 @@ class Twig_Environment } } - return $this->loader->isFresh($name, $time); + return $this->getLoader()->isFresh($name, $time); } public function resolveTemplate($names) @@ -546,6 +552,10 @@ class Twig_Environment */ public function getLoader() { + if (null === $this->loader) { + throw new LogicException('You must set a loader first.'); + } + return $this->loader; } @@ -616,29 +626,29 @@ class Twig_Environment */ public function addExtension(Twig_ExtensionInterface $extension) { + if ($this->extensionInitialized) { + throw new LogicException(sprintf('Unable to register extension "%s" as extensions have already been initialized.', $extension->getName())); + } + $this->extensions[$extension->getName()] = $extension; - $this->parsers = null; - $this->visitors = null; - $this->filters = null; - $this->tests = null; - $this->functions = null; - $this->globals = null; } /** * Removes an extension by name. * + * This method is deprecated and you should not use it. + * * @param string $name The extension name + * + * @deprecated since 1.12 (to be removed in 2.0) */ public function removeExtension($name) { + if ($this->extensionInitialized) { + throw new LogicException(sprintf('Unable to remove extension "%s" as extensions have already been initialized.', $name)); + } + unset($this->extensions[$name]); - $this->parsers = null; - $this->visitors = null; - $this->filters = null; - $this->tests = null; - $this->functions = null; - $this->globals = null; } /** @@ -670,8 +680,11 @@ class Twig_Environment */ public function addTokenParser(Twig_TokenParserInterface $parser) { - $this->staging['token_parsers'][] = $parser; - $this->parsers = null; + if ($this->extensionInitialized) { + throw new LogicException('Unable to add a token parser as extensions have already been initialized.'); + } + + $this->staging->addTokenParser($parser); } /** @@ -681,27 +694,8 @@ class Twig_Environment */ public function getTokenParsers() { - if (null === $this->parsers) { - $this->parsers = new Twig_TokenParserBroker(); - - if (isset($this->staging['token_parsers'])) { - foreach ($this->staging['token_parsers'] as $parser) { - $this->parsers->addTokenParser($parser); - } - } - - foreach ($this->getExtensions() as $extension) { - $parsers = $extension->getTokenParsers(); - foreach($parsers as $parser) { - if ($parser instanceof Twig_TokenParserInterface) { - $this->parsers->addTokenParser($parser); - } elseif ($parser instanceof Twig_TokenParserBrokerInterface) { - $this->parsers->addTokenParserBroker($parser); - } else { - throw new Twig_Error_Runtime('getTokenParsers() must return an array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances'); - } - } - } + if (!$this->extensionInitialized) { + $this->initExtensions(); } return $this->parsers; @@ -733,8 +727,11 @@ class Twig_Environment */ public function addNodeVisitor(Twig_NodeVisitorInterface $visitor) { - $this->staging['visitors'][] = $visitor; - $this->visitors = null; + if ($this->extensionInitialized) { + throw new LogicException('Unable to add a node visitor as extensions have already been initialized.', $extension->getName()); + } + + $this->staging->addNodeVisitor($visitor); } /** @@ -744,11 +741,8 @@ class Twig_Environment */ public function getNodeVisitors() { - if (null === $this->visitors) { - $this->visitors = isset($this->staging['visitors']) ? $this->staging['visitors'] : array(); - foreach ($this->getExtensions() as $extension) { - $this->visitors = array_merge($this->visitors, $extension->getNodeVisitors()); - } + if (!$this->extensionInitialized) { + $this->initExtensions(); } return $this->visitors; @@ -757,13 +751,25 @@ class Twig_Environment /** * Registers a Filter. * - * @param string $name The filter name - * @param Twig_FilterInterface $filter A Twig_FilterInterface instance + * @param string|Twig_SimpleFilter $name The filter name or a Twig_SimpleFilter instance + * @param Twig_FilterInterface|Twig_SimpleFilter $filter A Twig_FilterInterface instance or a Twig_SimpleFilter instance */ - public function addFilter($name, Twig_FilterInterface $filter) + public function addFilter($name, $filter = null) { - $this->staging['filters'][$name] = $filter; - $this->filters = null; + if (!$name instanceof Twig_SimpleFilter && !($filter instanceof Twig_SimpleFilter || $filter instanceof Twig_FilterInterface)) { + throw new LogicException('A filter must be an instance of Twig_FilterInterface or Twig_SimpleFilter'); + } + + if ($name instanceof Twig_SimpleFilter) { + $filter = $name; + $name = $filter->getName(); + } + + if ($this->extensionInitialized) { + throw new LogicException(sprintf('Unable to add filter "%s" as extensions have already been initialized.', $name)); + } + + $this->staging->addFilter($name, $filter); } /** @@ -774,12 +780,12 @@ class Twig_Environment * * @param string $name The filter name * - * @return Twig_Filter|false A Twig_Filter instance or false if the filter does not exists + * @return Twig_Filter|false A Twig_Filter instance or false if the filter does not exist */ public function getFilter($name) { - if (null === $this->filters) { - $this->getFilters(); + if (!$this->extensionInitialized) { + $this->initExtensions(); } if (isset($this->filters[$name])) { @@ -824,11 +830,8 @@ class Twig_Environment */ public function getFilters() { - if (null === $this->filters) { - $this->filters = isset($this->staging['filters']) ? $this->staging['filters'] : array(); - foreach ($this->getExtensions() as $extension) { - $this->filters = array_merge($this->filters, $extension->getFilters()); - } + if (!$this->extensionInitialized) { + $this->initExtensions(); } return $this->filters; @@ -837,13 +840,25 @@ class Twig_Environment /** * Registers a Test. * - * @param string $name The test name - * @param Twig_TestInterface $test A Twig_TestInterface instance + * @param string|Twig_SimpleTest $name The test name or a Twig_SimpleTest instance + * @param Twig_TestInterface|Twig_SimpleTest $test A Twig_TestInterface instance or a Twig_SimpleTest instance */ - public function addTest($name, Twig_TestInterface $test) + public function addTest($name, $test = null) { - $this->staging['tests'][$name] = $test; - $this->tests = null; + if (!$name instanceof Twig_SimpleTest && !($test instanceof Twig_SimpleTest || $test instanceof Twig_TestInterface)) { + throw new LogicException('A test must be an instance of Twig_TestInterface or Twig_SimpleTest'); + } + + if ($name instanceof Twig_SimpleTest) { + $test = $name; + $name = $test->getName(); + } + + if ($this->extensionInitialized) { + throw new LogicException(sprintf('Unable to add test "%s" as extensions have already been initialized.', $name)); + } + + $this->staging->addTest($name, $test); } /** @@ -853,26 +868,55 @@ class Twig_Environment */ public function getTests() { - if (null === $this->tests) { - $this->tests = isset($this->staging['tests']) ? $this->staging['tests'] : array(); - foreach ($this->getExtensions() as $extension) { - $this->tests = array_merge($this->tests, $extension->getTests()); - } + if (!$this->extensionInitialized) { + $this->initExtensions(); } return $this->tests; } + /** + * Gets a test by name. + * + * @param string $name The test name + * + * @return Twig_Test|false A Twig_Test instance or false if the test does not exist + */ + public function getTest($name) + { + if (!$this->extensionInitialized) { + $this->initExtensions(); + } + + if (isset($this->tests[$name])) { + return $this->tests[$name]; + } + + return false; + } + /** * Registers a Function. * - * @param string $name The function name - * @param Twig_FunctionInterface $function A Twig_FunctionInterface instance + * @param string|Twig_SimpleFunction $name The function name or a Twig_SimpleFunction instance + * @param Twig_FunctionInterface|Twig_SimpleFunction $function A Twig_FunctionInterface instance or a Twig_SimpleFunction instance */ - public function addFunction($name, Twig_FunctionInterface $function) + public function addFunction($name, $function = null) { - $this->staging['functions'][$name] = $function; - $this->functions = null; + if (!$name instanceof Twig_SimpleFunction && !($function instanceof Twig_SimpleFunction || $function instanceof Twig_FunctionInterface)) { + throw new LogicException('A function must be an instance of Twig_FunctionInterface or Twig_SimpleFunction'); + } + + if ($name instanceof Twig_SimpleFunction) { + $function = $name; + $name = $function->getName(); + } + + if ($this->extensionInitialized) { + throw new LogicException(sprintf('Unable to add function "%s" as extensions have already been initialized.', $name)); + } + + $this->staging->addFunction($name, $function); } /** @@ -883,12 +927,12 @@ class Twig_Environment * * @param string $name function name * - * @return Twig_Function|false A Twig_Function instance or false if the function does not exists + * @return Twig_Function|false A Twig_Function instance or false if the function does not exist */ public function getFunction($name) { - if (null === $this->functions) { - $this->getFunctions(); + if (!$this->extensionInitialized) { + $this->initExtensions(); } if (isset($this->functions[$name])) { @@ -933,11 +977,8 @@ class Twig_Environment */ public function getFunctions() { - if (null === $this->functions) { - $this->functions = isset($this->staging['functions']) ? $this->staging['functions'] : array(); - foreach ($this->getExtensions() as $extension) { - $this->functions = array_merge($this->functions, $extension->getFunctions()); - } + if (!$this->extensionInitialized) { + $this->initExtensions(); } return $this->functions; @@ -946,13 +987,32 @@ class Twig_Environment /** * Registers a Global. * + * New globals can be added before compiling or rendering a template; + * but after, you can only update existing globals. + * * @param string $name The global name * @param mixed $value The global value */ public function addGlobal($name, $value) { - $this->staging['globals'][$name] = $value; - $this->globals = null; + if ($this->extensionInitialized || $this->runtimeInitialized) { + if (null === $this->globals) { + $this->globals = $this->initGlobals(); + } + + /* This condition must be uncommented in Twig 2.0 + if (!array_key_exists($name, $this->globals)) { + throw new LogicException(sprintf('Unable to add global "%s" as the runtime or the extensions have already been initialized.', $name)); + } + */ + } + + if ($this->extensionInitialized || $this->runtimeInitialized) { + // update the value + $this->globals[$name] = $value; + } else { + $this->staging->addGlobal($name, $value); + } } /** @@ -962,16 +1022,37 @@ class Twig_Environment */ public function getGlobals() { + if (!$this->runtimeInitialized && !$this->extensionInitialized) { + return $this->initGlobals(); + } + if (null === $this->globals) { - $this->globals = isset($this->staging['globals']) ? $this->staging['globals'] : array(); - foreach ($this->getExtensions() as $extension) { - $this->globals = array_merge($this->globals, $extension->getGlobals()); - } + $this->globals = $this->initGlobals(); } return $this->globals; } + /** + * Merges a context with the defined globals. + * + * @param array $context An array representing the context + * + * @return array The context merged with the globals + */ + public function mergeGlobals(array $context) + { + // we don't use array_merge as the context being generally + // bigger than globals, this code is faster. + foreach ($this->getGlobals() as $key => $value) { + if (!array_key_exists($key, $context)) { + $context[$key] = $value; + } + } + + return $context; + } + /** * Gets the registered unary Operators. * @@ -979,8 +1060,8 @@ class Twig_Environment */ public function getUnaryOperators() { - if (null === $this->unaryOperators) { - $this->initOperators(); + if (!$this->extensionInitialized) { + $this->initExtensions(); } return $this->unaryOperators; @@ -993,8 +1074,8 @@ class Twig_Environment */ public function getBinaryOperators() { - if (null === $this->binaryOperators) { - $this->initOperators(); + if (!$this->extensionInitialized) { + $this->initExtensions(); } return $this->binaryOperators; @@ -1014,17 +1095,93 @@ class Twig_Environment return array_keys($alternatives); } - protected function initOperators() + protected function initGlobals() { + $globals = array(); + foreach ($this->extensions as $extension) { + $globals = array_merge($globals, $extension->getGlobals()); + } + + return array_merge($globals, $this->staging->getGlobals()); + } + + protected function initExtensions() + { + if ($this->extensionInitialized) { + return; + } + + $this->extensionInitialized = true; + $this->parsers = new Twig_TokenParserBroker(); + $this->filters = array(); + $this->functions = array(); + $this->tests = array(); + $this->visitors = array(); $this->unaryOperators = array(); $this->binaryOperators = array(); - foreach ($this->getExtensions() as $extension) { - $operators = $extension->getOperators(); - if (!$operators) { - continue; + foreach ($this->extensions as $extension) { + $this->initExtension($extension); + } + $this->initExtension($this->staging); + } + + protected function initExtension(Twig_ExtensionInterface $extension) + { + // filters + foreach ($extension->getFilters() as $name => $filter) { + if ($name instanceof Twig_SimpleFilter) { + $filter = $name; + $name = $filter->getName(); + } elseif ($filter instanceof Twig_SimpleFilter) { + $name = $filter->getName(); } + $this->filters[$name] = $filter; + } + + // functions + foreach ($extension->getFunctions() as $name => $function) { + if ($name instanceof Twig_SimpleFunction) { + $function = $name; + $name = $function->getName(); + } elseif ($function instanceof Twig_SimpleFunction) { + $name = $function->getName(); + } + + $this->functions[$name] = $function; + } + + // tests + foreach ($extension->getTests() as $name => $test) { + if ($name instanceof Twig_SimpleTest) { + $test = $name; + $name = $test->getName(); + } elseif ($test instanceof Twig_SimpleTest) { + $name = $test->getName(); + } + + $this->tests[$name] = $test; + } + + // token parsers + foreach ($extension->getTokenParsers() as $parser) { + if ($parser instanceof Twig_TokenParserInterface) { + $this->parsers->addTokenParser($parser); + } elseif ($parser instanceof Twig_TokenParserBrokerInterface) { + $this->parsers->addTokenParserBroker($parser); + } else { + throw new LogicException('getTokenParsers() must return an array of Twig_TokenParserInterface or Twig_TokenParserBrokerInterface instances'); + } + } + + // node visitors + foreach ($extension->getNodeVisitors() as $visitor) { + $this->visitors[] = $visitor; + } + + // operators + if ($operators = $extension->getOperators()) { if (2 !== count($operators)) { throw new InvalidArgumentException(sprintf('"%s::getOperators()" does not return a valid operators array.', get_class($extension))); } @@ -1049,12 +1206,12 @@ class Twig_Environment if (false !== @file_put_contents($tmpFile, $content)) { // rename does not work on Win32 before 5.2.6 if (@rename($tmpFile, $file) || (@copy($tmpFile, $file) && unlink($tmpFile))) { - chmod($file, 0644); + @chmod($file, 0666 & ~umask()); return; } } - throw new Twig_Error_Runtime(sprintf('Failed to write cache file "%s".', $file)); + throw new RuntimeException(sprintf('Failed to write cache file "%s".', $file)); } } diff --git a/vendor/twig/twig/lib/Twig/Error.php b/vendor/twig/twig/lib/Twig/Error.php new file mode 100644 index 0000000..e77ec98 --- /dev/null +++ b/vendor/twig/twig/lib/Twig/Error.php @@ -0,0 +1,232 @@ + + */ +class Twig_Error extends Exception +{ + protected $lineno; + protected $filename; + protected $rawMessage; + protected $previous; + + /** + * Constructor. + * + * Set both the line number and the filename to false to + * disable automatic guessing of the original template name + * and line number. + * + * Set the line number to -1 to enable its automatic guessing. + * Set the filename to null to enable its automatic guessing. + * + * By default, automatic guessing is enabled. + * + * @param string $message The error message + * @param integer $lineno The template line where the error occurred + * @param string $filename The template file name where the error occurred + * @param Exception $previous The previous exception + */ + public function __construct($message, $lineno = -1, $filename = null, Exception $previous = null) + { + if (version_compare(PHP_VERSION, '5.3.0', '<')) { + $this->previous = $previous; + parent::__construct(''); + } else { + parent::__construct('', 0, $previous); + } + + $this->lineno = $lineno; + $this->filename = $filename; + + if (-1 === $this->lineno || null === $this->filename) { + $this->guessTemplateInfo(); + } + + $this->rawMessage = $message; + + $this->updateRepr(); + } + + /** + * Gets the raw message. + * + * @return string The raw message + */ + public function getRawMessage() + { + return $this->rawMessage; + } + + /** + * Gets the filename where the error occurred. + * + * @return string The filename + */ + public function getTemplateFile() + { + return $this->filename; + } + + /** + * Sets the filename where the error occurred. + * + * @param string $filename The filename + */ + public function setTemplateFile($filename) + { + $this->filename = $filename; + + $this->updateRepr(); + } + + /** + * Gets the template line where the error occurred. + * + * @return integer The template line + */ + public function getTemplateLine() + { + return $this->lineno; + } + + /** + * Sets the template line where the error occurred. + * + * @param integer $lineno The template line + */ + public function setTemplateLine($lineno) + { + $this->lineno = $lineno; + + $this->updateRepr(); + } + + public function guess() + { + $this->guessTemplateInfo(); + $this->updateRepr(); + } + + /** + * For PHP < 5.3.0, provides access to the getPrevious() method. + * + * @param string $method The method name + * @param array $arguments The parameters to be passed to the method + * + * @return Exception The previous exception or null + * + * @throws BadMethodCallException + */ + public function __call($method, $arguments) + { + if ('getprevious' == strtolower($method)) { + return $this->previous; + } + + throw new BadMethodCallException(sprintf('Method "Twig_Error::%s()" does not exist.', $method)); + } + + protected function updateRepr() + { + $this->message = $this->rawMessage; + + $dot = false; + if ('.' === substr($this->message, -1)) { + $this->message = substr($this->message, 0, -1); + $dot = true; + } + + if ($this->filename) { + if (is_string($this->filename) || (is_object($this->filename) && method_exists($this->filename, '__toString'))) { + $filename = sprintf('"%s"', $this->filename); + } else { + $filename = json_encode($this->filename); + } + $this->message .= sprintf(' in %s', $filename); + } + + if ($this->lineno && $this->lineno >= 0) { + $this->message .= sprintf(' at line %d', $this->lineno); + } + + if ($dot) { + $this->message .= '.'; + } + } + + protected function guessTemplateInfo() + { + $template = null; + foreach (debug_backtrace() as $trace) { + if (isset($trace['object']) && $trace['object'] instanceof Twig_Template && 'Twig_Template' !== get_class($trace['object'])) { + if (null === $this->filename || $this->filename == $trace['object']->getTemplateName()) { + $template = $trace['object']; + } + } + } + + // update template filename + if (null !== $template && null === $this->filename) { + $this->filename = $template->getTemplateName(); + } + + if (null === $template || $this->lineno > -1) { + return; + } + + $r = new ReflectionObject($template); + $file = $r->getFileName(); + + $exceptions = array($e = $this); + while (($e instanceof self || method_exists($e, 'getPrevious')) && $e = $e->getPrevious()) { + $exceptions[] = $e; + } + + while ($e = array_pop($exceptions)) { + $traces = $e->getTrace(); + while ($trace = array_shift($traces)) { + if (!isset($trace['file']) || !isset($trace['line']) || $file != $trace['file']) { + continue; + } + + foreach ($template->getDebugInfo() as $codeLine => $templateLine) { + if ($codeLine <= $trace['line']) { + // update template line + $this->lineno = $templateLine; + + return; + } + } + } + } + } +} diff --git a/vendor/twig/twig/lib/Twig/Error/Loader.php b/vendor/twig/twig/lib/Twig/Error/Loader.php new file mode 100644 index 0000000..68efb57 --- /dev/null +++ b/vendor/twig/twig/lib/Twig/Error/Loader.php @@ -0,0 +1,31 @@ + + */ +class Twig_Error_Loader extends Twig_Error +{ + public function __construct($message, $lineno = -1, $filename = null, Exception $previous = null) + { + parent::__construct($message, false, false, $previous); + } +} diff --git a/lib/twig/lib/Twig/Error/Runtime.php b/vendor/twig/twig/lib/Twig/Error/Runtime.php old mode 100755 new mode 100644 similarity index 82% rename from lib/twig/lib/Twig/Error/Runtime.php rename to vendor/twig/twig/lib/Twig/Error/Runtime.php index 8a387fa..8b6cedd --- a/lib/twig/lib/Twig/Error/Runtime.php +++ b/vendor/twig/twig/lib/Twig/Error/Runtime.php @@ -13,8 +13,7 @@ /** * Exception thrown when an error occurs at runtime. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_Error_Runtime extends Twig_Error { diff --git a/lib/twig/lib/Twig/Error/Syntax.php b/vendor/twig/twig/lib/Twig/Error/Syntax.php old mode 100755 new mode 100644 similarity index 83% rename from lib/twig/lib/Twig/Error/Syntax.php rename to vendor/twig/twig/lib/Twig/Error/Syntax.php index a2650c3..0f5c579 --- a/lib/twig/lib/Twig/Error/Syntax.php +++ b/vendor/twig/twig/lib/Twig/Error/Syntax.php @@ -13,8 +13,7 @@ /** * Exception thrown when a syntax error occurs during lexing or parsing of a template. * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_Error_Syntax extends Twig_Error { diff --git a/vendor/twig/twig/lib/Twig/ExistsLoaderInterface.php b/vendor/twig/twig/lib/Twig/ExistsLoaderInterface.php new file mode 100644 index 0000000..ce43476 --- /dev/null +++ b/vendor/twig/twig/lib/Twig/ExistsLoaderInterface.php @@ -0,0 +1,28 @@ + + * @deprecated since 1.12 (to be removed in 2.0) + */ +interface Twig_ExistsLoaderInterface +{ + /** + * Check if we have the source code of a template, given its name. + * + * @param string $name The name of the template to check if we can load + * + * @return boolean If the template source code is handled by this loader or not + */ + public function exists($name); +} diff --git a/lib/twig/lib/Twig/ExpressionParser.php b/vendor/twig/twig/lib/Twig/ExpressionParser.php old mode 100755 new mode 100644 similarity index 71% rename from lib/twig/lib/Twig/ExpressionParser.php rename to vendor/twig/twig/lib/Twig/ExpressionParser.php index 0f35930..131c6c2 --- a/lib/twig/lib/Twig/ExpressionParser.php +++ b/vendor/twig/twig/lib/Twig/ExpressionParser.php @@ -18,8 +18,7 @@ * @see http://www.engr.mun.ca/~theo/Misc/exp_parsing.htm * @see http://en.wikipedia.org/wiki/Operator-precedence_parser * - * @package twig - * @author Fabien Potencier + * @author Fabien Potencier */ class Twig_ExpressionParser { @@ -89,9 +88,19 @@ class Twig_ExpressionParser { while ($this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, '?')) { $this->parser->getStream()->next(); - $expr2 = $this->parseExpression(); - $this->parser->getStream()->expect(Twig_Token::PUNCTUATION_TYPE, ':', 'The ternary operator must have a default value'); - $expr3 = $this->parseExpression(); + if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, ':')) { + $expr2 = $this->parseExpression(); + if ($this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, ':')) { + $this->parser->getStream()->next(); + $expr3 = $this->parseExpression(); + } else { + $expr3 = new Twig_Node_Expression_Constant('', $this->parser->getCurrentToken()->getLine()); + } + } else { + $this->parser->getStream()->next(); + $expr2 = $expr; + $expr3 = $this->parseExpression(); + } $expr = new Twig_Node_Expression_Conditional($expr, $expr2, $expr3, $this->parser->getCurrentToken()->getLine()); } @@ -158,7 +167,7 @@ class Twig_ExpressionParser } elseif ($token->test(Twig_Token::PUNCTUATION_TYPE, '{')) { $node = $this->parseHashExpression(); } else { - throw new Twig_Error_Syntax(sprintf('Unexpected token "%s" of value "%s"', Twig_Token::typeToEnglish($token->getType(), $token->getLine()), $token->getValue()), $token->getLine()); + throw new Twig_Error_Syntax(sprintf('Unexpected token "%s" of value "%s"', Twig_Token::typeToEnglish($token->getType(), $token->getLine()), $token->getValue()), $token->getLine(), $this->parser->getFilename()); } } @@ -252,7 +261,7 @@ class Twig_ExpressionParser } else { $current = $stream->getCurrent(); - throw new Twig_Error_Syntax(sprintf('A hash key must be a quoted string, a number, a name, or an expression enclosed in parentheses (unexpected token "%s" of value "%s"', Twig_Token::typeToEnglish($current->getType(), $current->getLine()), $current->getValue()), $current->getLine()); + throw new Twig_Error_Syntax(sprintf('A hash key must be a quoted string, a number, a name, or an expression enclosed in parentheses (unexpected token "%s" of value "%s"', Twig_Token::typeToEnglish($current->getType(), $current->getLine()), $current->getValue()), $current->getLine(), $this->parser->getFilename()); } $stream->expect(Twig_Token::PUNCTUATION_TYPE, ':', 'A hash key must be followed by a colon (:)'); @@ -287,30 +296,31 @@ class Twig_ExpressionParser public function getFunctionNode($name, $line) { - $args = $this->parseArguments(); switch ($name) { case 'parent': + $args = $this->parseArguments(); if (!count($this->parser->getBlockStack())) { - throw new Twig_Error_Syntax('Calling "parent" outside a block is forbidden', $line); + throw new Twig_Error_Syntax('Calling "parent" outside a block is forbidden', $line, $this->parser->getFilename()); } if (!$this->parser->getParent() && !$this->parser->hasTraits()) { - throw new Twig_Error_Syntax('Calling "parent" on a template that does not extend nor "use" another template is forbidden', $line); + throw new Twig_Error_Syntax('Calling "parent" on a template that does not extend nor "use" another template is forbidden', $line, $this->parser->getFilename()); } return new Twig_Node_Expression_Parent($this->parser->peekBlockStack(), $line); case 'block': - return new Twig_Node_Expression_BlockReference($args->getNode(0), false, $line); + return new Twig_Node_Expression_BlockReference($this->parseArguments()->getNode(0), false, $line); case 'attribute': + $args = $this->parseArguments(); if (count($args) < 2) { - throw new Twig_Error_Syntax('The "attribute" function takes at least two arguments (the variable and the attributes)', $line); + throw new Twig_Error_Syntax('The "attribute" function takes at least two arguments (the variable and the attributes)', $line, $this->parser->getFilename()); } return new Twig_Node_Expression_GetAttr($args->getNode(0), $args->getNode(1), count($args) > 2 ? $args->getNode(2) : new Twig_Node_Expression_Array(array(), $line), Twig_TemplateInterface::ANY_CALL, $line); default: - if (null !== $alias = $this->parser->getImportedFunction($name)) { + if (null !== $alias = $this->parser->getImportedSymbol('function', $name)) { $arguments = new Twig_Node_Expression_Array(array(), $line); - foreach ($args as $n) { + foreach ($this->parseArguments() as $n) { $arguments->addElement($n); } @@ -320,7 +330,8 @@ class Twig_ExpressionParser return $node; } - $class = $this->getFunctionNodeClass($name); + $args = $this->parseArguments(true); + $class = $this->getFunctionNodeClass($name, $line); return new $class($name, $args, $line); } @@ -351,24 +362,44 @@ class Twig_ExpressionParser } } } else { - throw new Twig_Error_Syntax('Expected name or number', $lineno); + throw new Twig_Error_Syntax('Expected name or number', $lineno, $this->parser->getFilename()); + } + + if ($node instanceof Twig_Node_Expression_Name && null !== $alias = $this->parser->getImportedSymbol('template', $node->getAttribute('name'))) { + if (!$arg instanceof Twig_Node_Expression_Constant) { + throw new Twig_Error_Syntax(sprintf('Dynamic macro names are not supported (called on "%s")', $node->getAttribute('name')), $token->getLine(), $this->parser->getFilename()); + } + + $node = new Twig_Node_Expression_MethodCall($node, 'get'.$arg->getAttribute('value'), $arguments, $lineno); + $node->setAttribute('safe', true); + + return $node; } } else { $type = Twig_TemplateInterface::ARRAY_CALL; - $arg = $this->parseExpression(); - // slice? + $slice = false; if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ':')) { - $stream->next(); + $slice = true; + $arg = new Twig_Node_Expression_Constant(0, $token->getLine()); + } else { + $arg = $this->parseExpression(); + } + if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ':')) { + $slice = true; + $stream->next(); + } + + if ($slice) { if ($stream->test(Twig_Token::PUNCTUATION_TYPE, ']')) { $length = new Twig_Node_Expression_Constant(null, $token->getLine()); } else { $length = $this->parseExpression(); } - $class = $this->getFilterNodeClass('slice'); + $class = $this->getFilterNodeClass('slice', $token->getLine()); $arguments = new Twig_Node(array($arg, $length)); $filter = new $class($node, new Twig_Node_Expression_Constant('slice', $token->getLine()), $arguments, $token->getLine()); @@ -399,10 +430,10 @@ class Twig_ExpressionParser if (!$this->parser->getStream()->test(Twig_Token::PUNCTUATION_TYPE, '(')) { $arguments = new Twig_Node(); } else { - $arguments = $this->parseArguments(); + $arguments = $this->parseArguments(true); } - $class = $this->getFilterNodeClass($name->getAttribute('value')); + $class = $this->getFilterNodeClass($name->getAttribute('value'), $token->getLine()); $node = new $class($node, $name, $arguments, $token->getLine(), $tag); @@ -416,17 +447,62 @@ class Twig_ExpressionParser return $node; } - public function parseArguments() + /** + * Parses arguments. + * + * @param Boolean $namedArguments Whether to allow named arguments or not + * @param Boolean $definition Whether we are parsing arguments for a function definition + */ + public function parseArguments($namedArguments = false, $definition = false) { $args = array(); $stream = $this->parser->getStream(); - $stream->expect(Twig_Token::PUNCTUATION_TYPE, '(', 'A list of arguments must be opened by a parenthesis'); + $stream->expect(Twig_Token::PUNCTUATION_TYPE, '(', 'A list of arguments must begin with an opening parenthesis'); while (!$stream->test(Twig_Token::PUNCTUATION_TYPE, ')')) { if (!empty($args)) { $stream->expect(Twig_Token::PUNCTUATION_TYPE, ',', 'Arguments must be separated by a comma'); } - $args[] = $this->parseExpression(); + + if ($definition) { + $token = $stream->expect(Twig_Token::NAME_TYPE, null, 'An argument must be a name'); + $value = new Twig_Node_Expression_Name($token->getValue(), $this->parser->getCurrentToken()->getLine()); + } else { + $value = $this->parseExpression(); + } + + $name = null; + if ($namedArguments && $stream->test(Twig_Token::OPERATOR_TYPE, '=')) { + $token = $stream->next(); + if (!$value instanceof Twig_Node_Expression_Name) { + throw new Twig_Error_Syntax(sprintf('A parameter name must be a string, "%s" given', get_class($value)), $token->getLine(), $this->parser->getFilename()); + } + $name = $value->getAttribute('name'); + + if ($definition) { + $value = $this->parsePrimaryExpression(); + + if (!$this->checkConstantExpression($value)) { + throw new Twig_Error_Syntax(sprintf('A default value for an argument must be a constant (a boolean, a string, a number, or an array).'), $token->getLine(), $this->parser->getFilename()); + } + } else { + $value = $this->parseExpression(); + } + } + + if ($definition) { + if (null === $name) { + $name = $value->getAttribute('name'); + $value = new Twig_Node_Expression_Constant(null, $this->parser->getCurrentToken()->getLine()); + } + $args[$name] = $value; + } else { + if (null === $name) { + $args[] = $value; + } else { + $args[$name] = $value; + } + } } $stream->expect(Twig_Token::PUNCTUATION_TYPE, ')', 'A list of arguments must be closed by a parenthesis'); @@ -439,7 +515,7 @@ class Twig_ExpressionParser while (true) { $token = $this->parser->getStream()->expect(Twig_Token::NAME_TYPE, null, 'Only variables can be assigned to'); if (in_array($token->getValue(), array('true', 'false', 'none'))) { - throw new Twig_Error_Syntax(sprintf('You cannot assign a value to "%s"', $token->getValue()), $token->getLine()); + throw new Twig_Error_Syntax(sprintf('You cannot assign a value to "%s"', $token->getValue()), $token->getLine(), $this->parser->getFilename()); } $targets[] = new Twig_Node_Expression_AssignName($token->getValue(), $token->getLine()); @@ -466,23 +542,59 @@ class Twig_ExpressionParser return new Twig_Node($targets); } - protected function getFunctionNodeClass($name) + protected function getFunctionNodeClass($name, $line) { - $functionMap = $this->parser->getEnvironment()->getFunctions(); - if (isset($functionMap[$name]) && $functionMap[$name] instanceof Twig_Function_Node) { - return $functionMap[$name]->getClass(); + $env = $this->parser->getEnvironment(); + + if (false === $function = $env->getFunction($name)) { + $message = sprintf('The function "%s" does not exist', $name); + if ($alternatives = $env->computeAlternatives($name, array_keys($env->getFunctions()))) { + $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives)); + } + + throw new Twig_Error_Syntax($message, $line, $this->parser->getFilename()); } - return 'Twig_Node_Expression_Function'; + if ($function instanceof Twig_SimpleFunction) { + return $function->getNodeClass(); + } + + return $function instanceof Twig_Function_Node ? $function->getClass() : 'Twig_Node_Expression_Function'; } - protected function getFilterNodeClass($name) + protected function getFilterNodeClass($name, $line) { - $filterMap = $this->parser->getEnvironment()->getFilters(); - if (isset($filterMap[$name]) && $filterMap[$name] instanceof Twig_Filter_Node) { - return $filterMap[$name]->getClass(); + $env = $this->parser->getEnvironment(); + + if (false === $filter = $env->getFilter($name)) { + $message = sprintf('The filter "%s" does not exist', $name); + if ($alternatives = $env->computeAlternatives($name, array_keys($env->getFilters()))) { + $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives)); + } + + throw new Twig_Error_Syntax($message, $line, $this->parser->getFilename()); } - return 'Twig_Node_Expression_Filter'; + if ($filter instanceof Twig_SimpleFilter) { + return $filter->getNodeClass(); + } + + return $filter instanceof Twig_Filter_Node ? $filter->getClass() : 'Twig_Node_Expression_Filter'; + } + + // checks that the node only contains "constant" elements + protected function checkConstantExpression(Twig_NodeInterface $node) + { + if (!($node instanceof Twig_Node_Expression_Constant || $node instanceof Twig_Node_Expression_Array)) { + return false; + } + + foreach ($node as $n) { + if (!$this->checkConstantExpression($n)) { + return false; + } + } + + return true; } } diff --git a/lib/twig/lib/Twig/Extension.php b/vendor/twig/twig/lib/Twig/Extension.php old mode 100755 new mode 100644 similarity index 100% rename from lib/twig/lib/Twig/Extension.php rename to vendor/twig/twig/lib/Twig/Extension.php diff --git a/lib/twig/lib/Twig/Extension/Core.php b/vendor/twig/twig/lib/Twig/Extension/Core.php old mode 100755 new mode 100644 similarity index 61% rename from lib/twig/lib/Twig/Extension/Core.php rename to vendor/twig/twig/lib/Twig/Extension/Core.php index 78787d8..26e7017 --- a/lib/twig/lib/Twig/Extension/Core.php +++ b/vendor/twig/twig/lib/Twig/Extension/Core.php @@ -48,7 +48,7 @@ class Twig_Extension_Core extends Twig_Extension /** * Sets the default timezone to be used by the date filter. * - * @param DateTimeZone|string $timezone The default timezone string or a DateTimeZone object + * @param DateTimeZone|string $timezone The default timezone string or a DateTimeZone object */ public function setTimezone($timezone) { @@ -62,15 +62,19 @@ class Twig_Extension_Core extends Twig_Extension */ public function getTimezone() { + if (null === $this->timezone) { + $this->timezone = new DateTimeZone(date_default_timezone_get()); + } + return $this->timezone; } /** * Sets the default format to be used by the number_format filter. * - * @param integer $decimal The number of decimal places to use. - * @param string $decimalPoint The character(s) to use for the decimal point. - * @param string $thousandSep The character(s) to use for the thousands separator. + * @param integer $decimal The number of decimal places to use. + * @param string $decimalPoint The character(s) to use for the decimal point. + * @param string $thousandSep The character(s) to use for the thousands separator. */ public function setNumberFormat($decimal, $decimalPoint, $thousandSep) { @@ -109,6 +113,7 @@ class Twig_Extension_Core extends Twig_Extension new Twig_TokenParser_Spaceless(), new Twig_TokenParser_Flush(), new Twig_TokenParser_Do(), + new Twig_TokenParser_Embed(), ); } @@ -121,49 +126,53 @@ class Twig_Extension_Core extends Twig_Extension { $filters = array( // formatting filters - 'date' => new Twig_Filter_Function('twig_date_format_filter', array('needs_environment' => true)), - 'format' => new Twig_Filter_Function('sprintf'), - 'replace' => new Twig_Filter_Function('strtr'), - 'number_format' => new Twig_Filter_Function('twig_number_format_filter', array('needs_environment' => true)), + new Twig_SimpleFilter('date', 'twig_date_format_filter', array('needs_environment' => true)), + new Twig_SimpleFilter('date_modify', 'twig_date_modify_filter', array('needs_environment' => true)), + new Twig_SimpleFilter('format', 'sprintf'), + new Twig_SimpleFilter('replace', 'strtr'), + new Twig_SimpleFilter('number_format', 'twig_number_format_filter', array('needs_environment' => true)), + new Twig_SimpleFilter('abs', 'abs'), // encoding - 'url_encode' => new Twig_Filter_Function('twig_urlencode_filter'), - 'json_encode' => new Twig_Filter_Function('twig_jsonencode_filter'), - 'convert_encoding' => new Twig_Filter_Function('twig_convert_encoding'), + new Twig_SimpleFilter('url_encode', 'twig_urlencode_filter'), + new Twig_SimpleFilter('json_encode', 'twig_jsonencode_filter'), + new Twig_SimpleFilter('convert_encoding', 'twig_convert_encoding'), // string filters - 'title' => new Twig_Filter_Function('twig_title_string_filter', array('needs_environment' => true)), - 'capitalize' => new Twig_Filter_Function('twig_capitalize_string_filter', array('needs_environment' => true)), - 'upper' => new Twig_Filter_Function('strtoupper'), - 'lower' => new Twig_Filter_Function('strtolower'), - 'striptags' => new Twig_Filter_Function('strip_tags'), - 'trim' => new Twig_Filter_Function('trim'), - 'nl2br' => new Twig_Filter_Function('nl2br', array('pre_escape' => 'html', 'is_safe' => array('html'))), + new Twig_SimpleFilter('title', 'twig_title_string_filter', array('needs_environment' => true)), + new Twig_SimpleFilter('capitalize', 'twig_capitalize_string_filter', array('needs_environment' => true)), + new Twig_SimpleFilter('upper', 'strtoupper'), + new Twig_SimpleFilter('lower', 'strtolower'), + new Twig_SimpleFilter('striptags', 'strip_tags'), + new Twig_SimpleFilter('trim', 'trim'), + new Twig_SimpleFilter('nl2br', 'nl2br', array('pre_escape' => 'html', 'is_safe' => array('html'))), // array helpers - 'join' => new Twig_Filter_Function('twig_join_filter'), - 'sort' => new Twig_Filter_Function('twig_sort_filter'), - 'merge' => new Twig_Filter_Function('twig_array_merge'), + new Twig_SimpleFilter('join', 'twig_join_filter'), + new Twig_SimpleFilter('split', 'twig_split_filter'), + new Twig_SimpleFilter('sort', 'twig_sort_filter'), + new Twig_SimpleFilter('merge', 'twig_array_merge'), + new Twig_SimpleFilter('batch', 'twig_array_batch'), // string/array filters - 'reverse' => new Twig_Filter_Function('twig_reverse_filter', array('needs_environment' => true)), - 'length' => new Twig_Filter_Function('twig_length_filter', array('needs_environment' => true)), - 'slice' => new Twig_Filter_Function('twig_slice', array('needs_environment' => true)), + new Twig_SimpleFilter('reverse', 'twig_reverse_filter', array('needs_environment' => true)), + new Twig_SimpleFilter('length', 'twig_length_filter', array('needs_environment' => true)), + new Twig_SimpleFilter('slice', 'twig_slice', array('needs_environment' => true)), + new Twig_SimpleFilter('first', 'twig_first', array('needs_environment' => true)), + new Twig_SimpleFilter('last', 'twig_last', array('needs_environment' => true)), // iteration and runtime - 'default' => new Twig_Filter_Node('Twig_Node_Expression_Filter_Default'), - '_default' => new Twig_Filter_Function('_twig_default_filter'), - - 'keys' => new Twig_Filter_Function('twig_get_array_keys_filter'), + new Twig_SimpleFilter('default', '_twig_default_filter', array('node_class' => 'Twig_Node_Expression_Filter_Default')), + new Twig_SimpleFilter('keys', 'twig_get_array_keys_filter'), // escaping - 'escape' => new Twig_Filter_Function('twig_escape_filter', array('needs_environment' => true, 'is_safe_callback' => 'twig_escape_filter_is_safe')), - 'e' => new Twig_Filter_Function('twig_escape_filter', array('needs_environment' => true, 'is_safe_callback' => 'twig_escape_filter_is_safe')), + new Twig_SimpleFilter('escape', 'twig_escape_filter', array('needs_environment' => true, 'is_safe_callback' => 'twig_escape_filter_is_safe')), + new Twig_SimpleFilter('e', 'twig_escape_filter', array('needs_environment' => true, 'is_safe_callback' => 'twig_escape_filter_is_safe')), ); if (function_exists('mb_get_info')) { - $filters['upper'] = new Twig_Filter_Function('twig_upper_filter', array('needs_environment' => true)); - $filters['lower'] = new Twig_Filter_Function('twig_lower_filter', array('needs_environment' => true)); + $filters[] = new Twig_SimpleFilter('upper', 'twig_upper_filter', array('needs_environment' => true)); + $filters[] = new Twig_SimpleFilter('lower', 'twig_lower_filter', array('needs_environment' => true)); } return $filters; @@ -177,11 +186,12 @@ class Twig_Extension_Core extends Twig_Extension public function getFunctions() { return array( - 'range' => new Twig_Function_Function('range'), - 'constant' => new Twig_Function_Function('constant'), - 'cycle' => new Twig_Function_Function('twig_cycle'), - 'random' => new Twig_Function_Function('twig_random', array('needs_environment' => true)), - 'date' => new Twig_Function_Function('twig_date_converter', array('needs_environment' => true)), + new Twig_SimpleFunction('range', 'range'), + new Twig_SimpleFunction('constant', 'twig_constant'), + new Twig_SimpleFunction('cycle', 'twig_cycle'), + new Twig_SimpleFunction('random', 'twig_random', array('needs_environment' => true)), + new Twig_SimpleFunction('date', 'twig_date_converter', array('needs_environment' => true)), + new Twig_SimpleFunction('include', 'twig_include', array('needs_environment' => true, 'needs_context' => true)), ); } @@ -193,15 +203,16 @@ class Twig_Extension_Core extends Twig_Extension public function getTests() { return array( - 'even' => new Twig_Test_Node('Twig_Node_Expression_Test_Even'), - 'odd' => new Twig_Test_Node('Twig_Node_Expression_Test_Odd'), - 'defined' => new Twig_Test_Node('Twig_Node_Expression_Test_Defined'), - 'sameas' => new Twig_Test_Node('Twig_Node_Expression_Test_Sameas'), - 'none' => new Twig_Test_Node('Twig_Node_Expression_Test_Null'), - 'null' => new Twig_Test_Node('Twig_Node_Expression_Test_Null'), - 'divisibleby' => new Twig_Test_Node('Twig_Node_Expression_Test_Divisibleby'), - 'constant' => new Twig_Test_Node('Twig_Node_Expression_Test_Constant'), - 'empty' => new Twig_Test_Function('twig_test_empty'), + new Twig_SimpleTest('even', null, array('node_class' => 'Twig_Node_Expression_Test_Even')), + new Twig_SimpleTest('odd', null, array('node_class' => 'Twig_Node_Expression_Test_Odd')), + new Twig_SimpleTest('defined', null, array('node_class' => 'Twig_Node_Expression_Test_Defined')), + new Twig_SimpleTest('sameas', null, array('node_class' => 'Twig_Node_Expression_Test_Sameas')), + new Twig_SimpleTest('none', null, array('node_class' => 'Twig_Node_Expression_Test_Null')), + new Twig_SimpleTest('null', null, array('node_class' => 'Twig_Node_Expression_Test_Null')), + new Twig_SimpleTest('divisibleby', null, array('node_class' => 'Twig_Node_Expression_Test_Divisibleby')), + new Twig_SimpleTest('constant', null, array('node_class' => 'Twig_Node_Expression_Test_Constant')), + new Twig_SimpleTest('empty', 'twig_test_empty'), + new Twig_SimpleTest('iterable', 'twig_test_iterable'), ); } @@ -219,11 +230,11 @@ class Twig_Extension_Core extends Twig_Extension '+' => array('precedence' => 500, 'class' => 'Twig_Node_Expression_Unary_Pos'), ), array( - 'b-and' => array('precedence' => 5, 'class' => 'Twig_Node_Expression_Binary_BitwiseAnd', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - 'b-xor' => array('precedence' => 5, 'class' => 'Twig_Node_Expression_Binary_BitwiseXor', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), - 'b-or' => array('precedence' => 5, 'class' => 'Twig_Node_Expression_Binary_BitwiseOr', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), 'or' => array('precedence' => 10, 'class' => 'Twig_Node_Expression_Binary_Or', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), 'and' => array('precedence' => 15, 'class' => 'Twig_Node_Expression_Binary_And', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + 'b-or' => array('precedence' => 16, 'class' => 'Twig_Node_Expression_Binary_BitwiseOr', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + 'b-xor' => array('precedence' => 17, 'class' => 'Twig_Node_Expression_Binary_BitwiseXor', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), + 'b-and' => array('precedence' => 18, 'class' => 'Twig_Node_Expression_Binary_BitwiseAnd', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), '==' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Equal', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), '!=' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_NotEqual', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), '<' => array('precedence' => 20, 'class' => 'Twig_Node_Expression_Binary_Less', 'associativity' => Twig_ExpressionParser::OPERATOR_LEFT), @@ -258,22 +269,32 @@ class Twig_Extension_Core extends Twig_Extension $name = $stream->expect(Twig_Token::NAME_TYPE)->getValue(); $arguments = null; if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) { - $arguments = $parser->getExpressionParser()->parseArguments(); + $arguments = $parser->getExpressionParser()->parseArguments(true); } - $class = $this->getTestNodeClass($parser->getEnvironment(), $name); + $class = $this->getTestNodeClass($parser, $name, $node->getLine()); return new $class($node, $name, $arguments, $parser->getCurrentToken()->getLine()); } - protected function getTestNodeClass(Twig_Environment $env, $name) + protected function getTestNodeClass(Twig_Parser $parser, $name, $line) { + $env = $parser->getEnvironment(); $testMap = $env->getTests(); - if (isset($testMap[$name]) && $testMap[$name] instanceof Twig_Test_Node) { - return $testMap[$name]->getClass(); + if (!isset($testMap[$name])) { + $message = sprintf('The test "%s" does not exist', $name); + if ($alternatives = $env->computeAlternatives($name, array_keys($env->getTests()))) { + $message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives)); + } + + throw new Twig_Error_Syntax($message, $line, $parser->getFilename()); } - return 'Twig_Node_Expression_Test'; + if ($testMap[$name] instanceof Twig_SimpleTest) { + return $testMap[$name]->getNodeClass(); + } + + return $testMap[$name] instanceof Twig_Test_Node ? $testMap[$name]->getClass() : 'Twig_Node_Expression_Test'; } /** @@ -290,18 +311,18 @@ class Twig_Extension_Core extends Twig_Extension /** * Cycles over a value. * - * @param ArrayAccess|array $values An array or an ArrayAccess instance - * @param integer $i The cycle value + * @param ArrayAccess|array $values An array or an ArrayAccess instance + * @param integer $position The cycle position * * @return string The next value in the cycle */ -function twig_cycle($values, $i) +function twig_cycle($values, $position) { if (!is_array($values) && !$values instanceof ArrayAccess) { return $values; } - return $values[$i % count($values)]; + return $values[$position % count($values)]; } /** @@ -310,8 +331,10 @@ function twig_cycle($values, $i) * - a random character from a string * - a random integer between 0 and the integer parameter * - * @param Twig_Environment $env A Twig_Environment instance - * @param Traversable|array|int|string $values The values to pick a random item from + * @param Twig_Environment $env A Twig_Environment instance + * @param Traversable|array|integer|string $values The values to pick a random item from + * + * @throws Twig_Error_Runtime When $values is an empty array (does not apply to an empty string which is returned as is). * * @return mixed A random value from the given sequence */ @@ -328,6 +351,9 @@ function twig_random(Twig_Environment $env, $values = null) if ($values instanceof Traversable) { $values = iterator_to_array($values); } elseif (is_string($values)) { + if ('' === $values) { + return ''; + } if (null !== $charset = $env->getCharset()) { if ('UTF-8' != $charset) { $values = twig_convert_encoding($values, 'UTF-8', $charset); @@ -370,7 +396,7 @@ function twig_random(Twig_Environment $env, $values = null) * @param string $format A format * @param DateTimeZone|string $timezone A timezone * - * @return string The formatter date + * @return string The formatted date */ function twig_date_format_filter(Twig_Environment $env, $date, $format = null, $timezone = null) { @@ -379,17 +405,34 @@ function twig_date_format_filter(Twig_Environment $env, $date, $format = null, $ $format = $date instanceof DateInterval ? $formats[1] : $formats[0]; } - if ($date instanceof DateInterval || $date instanceof DateTime) { - if (null !== $timezone) { - $date->setTimezone($timezone instanceof DateTimeZone ? $timezone : new DateTimeZone($timezone)); - } - + if ($date instanceof DateInterval) { return $date->format($format); } return twig_date_converter($env, $date, $timezone)->format($format); } +/** + * Returns a new date object modified + * + *
    + *   {{ post.published_at|date_modify("-1day")|date("m/d/Y") }}
    + * 
    + * + * @param Twig_Environment $env A Twig_Environment instance + * @param DateTime|string $date A date + * @param string $modifier A modifier string + * + * @return DateTime A new date object + */ +function twig_date_modify_filter(Twig_Environment $env, $date, $modifier) +{ + $date = twig_date_converter($env, $date, false); + $date->modify($modifier); + + return $date; +} + /** * Converts an input to a DateTime instance. * @@ -407,28 +450,32 @@ function twig_date_format_filter(Twig_Environment $env, $date, $format = null, $ */ function twig_date_converter(Twig_Environment $env, $date = null, $timezone = null) { + // determine the timezone + if (!$timezone) { + $defaultTimezone = $env->getExtension('core')->getTimezone(); + } elseif (!$timezone instanceof DateTimeZone) { + $defaultTimezone = new DateTimeZone($timezone); + } else { + $defaultTimezone = $timezone; + } + if ($date instanceof DateTime) { + $date = clone $date; + if (false !== $timezone) { + $date->setTimezone($defaultTimezone); + } + return $date; } $asString = (string) $date; - if (ctype_digit($asString) || (!empty($asString) && '-' === $asString[0] && ctype_digit(substr($asString, 1)))) { - $date = new DateTime('@'.$date); - $date->setTimezone(new DateTimeZone(date_default_timezone_get())); - } else { - $date = new DateTime($date); + $date = '@'.$date; } - // set Timezone - if (null !== $timezone) { - if (!$timezone instanceof DateTimeZone) { - $timezone = new DateTimeZone($timezone); - } - - $date->setTimezone($timezone); - } elseif (($timezone = $env->getExtension('core')->getTimezone()) instanceof DateTimeZone) { - $date->setTimezone($timezone); + $date = new DateTime($date, $defaultTimezone); + if (false !== $timezone) { + $date->setTimezone($defaultTimezone); } return $date; @@ -443,7 +490,7 @@ function twig_date_converter(Twig_Environment $env, $date = null, $timezone = nu * * @param Twig_Environment $env A Twig_Environment instance * @param mixed $number A float/int/string of the number to format - * @param int $decimal The number of decimal points to display. + * @param integer $decimal The number of decimal points to display. * @param string $decimalPoint The character(s) to use for the decimal point. * @param string $thousandSep The character(s) to use for the thousands separator. * @@ -468,15 +515,19 @@ function twig_number_format_filter(Twig_Environment $env, $number, $decimal = nu } /** - * URL encodes a string. + * URL encodes a string as a path segment or an array as a query string. * - * @param string $url A URL - * @param bool $raw true to use rawurlencode() instead of urlencode + * @param string|array $url A URL or an array of query parameters + * @param bool $raw true to use rawurlencode() instead of urlencode * * @return string The URL encoded value */ function twig_urlencode_filter($url, $raw = false) { + if (is_array($url)) { + return http_build_query($url, '', '&'); + } + if ($raw) { return rawurlencode($url); } @@ -586,6 +637,36 @@ function twig_slice(Twig_Environment $env, $item, $start, $length = null, $prese return null === $length ? substr($item, $start) : substr($item, $start, $length); } +/** + * Returns the first element of the item. + * + * @param Twig_Environment $env A Twig_Environment instance + * @param mixed $item A variable + * + * @return mixed The first element of the item + */ +function twig_first(Twig_Environment $env, $item) +{ + $elements = twig_slice($env, $item, 0, 1, false); + + return is_string($elements) ? $elements[0] : current($elements); +} + +/** + * Returns the last element of the item. + * + * @param Twig_Environment $env A Twig_Environment instance + * @param mixed $item A variable + * + * @return mixed The last element of the item + */ +function twig_last(Twig_Environment $env, $item) +{ + $elements = twig_slice($env, $item, -1, 1, false); + + return is_string($elements) ? $elements[0] : current($elements); +} + /** * Joins the values to a string. * @@ -613,6 +694,38 @@ function twig_join_filter($value, $glue = '') return implode($glue, (array) $value); } +/** + * Splits the string into an array. + * + *
    + *  {{ "one,two,three"|split(',') }}
    + *  {# returns [one, two, three] #}
    + *
    + *  {{ "one,two,three,four,five"|split(',', 3) }}
    + *  {# returns [one, two, "three,four,five"] #}
    + *
    + *  {{ "123"|split('') }}
    + *  {# returns [1, 2, 3] #}
    + *
    + *  {{ "aabbcc"|split('', 2) }}
    + *  {# returns [aa, bb, cc] #}
    + * 
    + * + * @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('&#x%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