Issue #2363741 by joelpittet: Upgrade Twig to 1.16.* from 1.15.*.
parent
455a6a6fac
commit
ddfd70a726
|
@ -16,7 +16,7 @@
|
|||
"symfony/serializer": "2.5.*",
|
||||
"symfony/validator": "2.5.*",
|
||||
"symfony/yaml": "dev-master#499f7d7aa96747ad97940089bd7a1fb24ad8182a",
|
||||
"twig/twig": "1.15.*",
|
||||
"twig/twig": "1.16.*",
|
||||
"doctrine/common": "dev-master#a45d110f71c323e29f41eb0696fa230e3fa1b1b5",
|
||||
"doctrine/annotations": "1.2.*",
|
||||
"guzzlehttp/guzzle": "~5.0",
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"hash": "838f4566f4f537d5f71fa46b66f263b0",
|
||||
"hash": "4378dea31ef5185651bc10bd9a40e591",
|
||||
"packages": [
|
||||
{
|
||||
"name": "doctrine/annotations",
|
||||
|
@ -2373,16 +2373,16 @@
|
|||
},
|
||||
{
|
||||
"name": "twig/twig",
|
||||
"version": "v1.15.1",
|
||||
"version": "v1.16.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/fabpot/Twig.git",
|
||||
"reference": "1fb5784662f438d7d96a541e305e28b812e2eeed"
|
||||
"reference": "42f758d9fe2146d1f0470604fc05ee43580873fc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/fabpot/Twig/zipball/1fb5784662f438d7d96a541e305e28b812e2eeed",
|
||||
"reference": "1fb5784662f438d7d96a541e305e28b812e2eeed",
|
||||
"url": "https://api.github.com/repos/fabpot/Twig/zipball/42f758d9fe2146d1f0470604fc05ee43580873fc",
|
||||
"reference": "42f758d9fe2146d1f0470604fc05ee43580873fc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2391,7 +2391,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.15-dev"
|
||||
"dev-master": "1.16-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
@ -2426,7 +2426,7 @@
|
|||
"keywords": [
|
||||
"templating"
|
||||
],
|
||||
"time": "2014-02-13 10:19:29"
|
||||
"time": "2014-10-17 12:53:44"
|
||||
},
|
||||
{
|
||||
"name": "zendframework/zend-escaper",
|
||||
|
|
|
@ -1304,65 +1304,6 @@
|
|||
"spl"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "twig/twig",
|
||||
"version": "v1.15.1",
|
||||
"version_normalized": "1.15.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/fabpot/Twig.git",
|
||||
"reference": "1fb5784662f438d7d96a541e305e28b812e2eeed"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/fabpot/Twig/zipball/1fb5784662f438d7d96a541e305e28b812e2eeed",
|
||||
"reference": "1fb5784662f438d7d96a541e305e28b812e2eeed",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.2.4"
|
||||
},
|
||||
"time": "2014-02-13 10:19:29",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.15-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Twig_": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com",
|
||||
"homepage": "http://fabien.potencier.org",
|
||||
"role": "Lead Developer"
|
||||
},
|
||||
{
|
||||
"name": "Armin Ronacher",
|
||||
"email": "armin.ronacher@active-4.com",
|
||||
"role": "Project Founder"
|
||||
},
|
||||
{
|
||||
"name": "Twig Team",
|
||||
"homepage": "https://github.com/fabpot/Twig/graphs/contributors",
|
||||
"role": "Contributors"
|
||||
}
|
||||
],
|
||||
"description": "Twig, the flexible, fast, and secure template language for PHP",
|
||||
"homepage": "http://twig.sensiolabs.org",
|
||||
"keywords": [
|
||||
"templating"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "doctrine/annotations",
|
||||
"version": "v1.2.1",
|
||||
|
@ -2646,5 +2587,64 @@
|
|||
"rest",
|
||||
"web service"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "twig/twig",
|
||||
"version": "v1.16.2",
|
||||
"version_normalized": "1.16.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/fabpot/Twig.git",
|
||||
"reference": "42f758d9fe2146d1f0470604fc05ee43580873fc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/fabpot/Twig/zipball/42f758d9fe2146d1f0470604fc05ee43580873fc",
|
||||
"reference": "42f758d9fe2146d1f0470604fc05ee43580873fc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.2.4"
|
||||
},
|
||||
"time": "2014-10-17 12:53:44",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.16-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Twig_": "lib/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com",
|
||||
"homepage": "http://fabien.potencier.org",
|
||||
"role": "Lead Developer"
|
||||
},
|
||||
{
|
||||
"name": "Armin Ronacher",
|
||||
"email": "armin.ronacher@active-4.com",
|
||||
"role": "Project Founder"
|
||||
},
|
||||
{
|
||||
"name": "Twig Team",
|
||||
"homepage": "https://github.com/fabpot/Twig/graphs/contributors",
|
||||
"role": "Contributors"
|
||||
}
|
||||
],
|
||||
"description": "Twig, the flexible, fast, and secure template language for PHP",
|
||||
"homepage": "http://twig.sensiolabs.org",
|
||||
"keywords": [
|
||||
"templating"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
|
@ -5,6 +5,7 @@ php:
|
|||
- 5.3
|
||||
- 5.4
|
||||
- 5.5
|
||||
- 5.6
|
||||
- hhvm
|
||||
|
||||
env:
|
||||
|
|
|
@ -1,4 +1,32 @@
|
|||
* 1.15.1 (2013-02-13)
|
||||
* 1.16.2 (2014-10-17)
|
||||
|
||||
* fixed timezone on dates as strings
|
||||
* fixed 2-words test names when a custom node class is not used
|
||||
* fixed macros when using an argument named like a PHP super global (like GET or POST)
|
||||
* fixed date_modify when working with DateTimeImmutable
|
||||
* optimized for loops
|
||||
* fixed multi-byte characters handling in the split filter
|
||||
* fixed a regression in the in operator
|
||||
* fixed a regression in the slice filter
|
||||
|
||||
* 1.16.1 (2014-10-10)
|
||||
|
||||
* improved error reporting in a sandboxed template
|
||||
* fixed missing error file/line information under certain circumstances
|
||||
* fixed wrong error line number in some error messages
|
||||
* fixed the in operator to use strict comparisons
|
||||
* sped up the slice filter
|
||||
* fixed for mb function overload mb_substr acting different
|
||||
* fixed the attribute() function when passing a variable for the arguments
|
||||
|
||||
* 1.16.0 (2014-07-05)
|
||||
|
||||
* changed url_encode to always encode according to RFC 3986
|
||||
* fixed inheritance in a 'use'-hierarchy
|
||||
* removed the __toString policy check when the sandbox is disabled
|
||||
* fixed recursively calling blocks in templates with inheritance
|
||||
|
||||
* 1.15.1 (2014-02-13)
|
||||
|
||||
* fixed the conversion of the special '0000-00-00 00:00' date
|
||||
* added an error message when trying to import an undefined block from a trait
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.15-dev"
|
||||
"dev-master": "1.16-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -166,21 +166,6 @@ Namespaced templates can be accessed via the special
|
|||
|
||||
$twig->render('@admin/index.html', array());
|
||||
|
||||
``Twig_Loader_String``
|
||||
......................
|
||||
|
||||
``Twig_Loader_String`` loads templates from strings. It's a dummy loader as
|
||||
the template reference is the template source code::
|
||||
|
||||
$loader = new Twig_Loader_String();
|
||||
$twig = new Twig_Environment($loader);
|
||||
|
||||
echo $twig->render('Hello {{ name }}!', array('name' => 'Fabien'));
|
||||
|
||||
This loader should only be used for unit testing as it has severe limitations:
|
||||
several tags, like ``extends`` or ``include`` do not make sense to use as the
|
||||
reference to the template is the template source code itself.
|
||||
|
||||
``Twig_Loader_Array``
|
||||
.....................
|
||||
|
||||
|
@ -214,7 +199,7 @@ projects where storing all templates in a single PHP file might make sense.
|
|||
'base.html' => '{% block content %}{% endblock %}',
|
||||
));
|
||||
$loader2 = new Twig_Loader_Array(array(
|
||||
'index.html' => '{% extends "base.twig" %}{% block content %}Hello {{ name }}{% endblock %}',
|
||||
'index.html' => '{% extends "base.html" %}{% block content %}Hello {{ name }}{% endblock %}',
|
||||
'base.html' => 'Will never be loaded',
|
||||
));
|
||||
|
||||
|
@ -268,26 +253,6 @@ All loaders implement the ``Twig_LoaderInterface``::
|
|||
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.
|
||||
|
||||
|
|
|
@ -23,8 +23,8 @@ Extensions
|
|||
PEAR
|
||||
----
|
||||
|
||||
PEAR support will be discontinued in Twig 2.0, and no PEAR packages will be
|
||||
provided. Use Composer instead.
|
||||
PEAR support has been discontinued in Twig 1.15.1, and no PEAR packages are
|
||||
provided anymore. Use Composer instead.
|
||||
|
||||
Filters
|
||||
-------
|
||||
|
@ -80,6 +80,12 @@ Tests
|
|||
* The ``sameas`` and ``divisibleby`` tests are deprecated in favor of ``same
|
||||
as`` and ``divisible by`` respectively.
|
||||
|
||||
Nodes
|
||||
-----
|
||||
|
||||
* As of Twig 1.x, ``Node::toXml()`` is deprecated and will be removed in Twig
|
||||
2.0.
|
||||
|
||||
Interfaces
|
||||
----------
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
=========
|
||||
|
||||
.. versionadded:: 1.12.3
|
||||
The batch filter was added in Twig 1.12.3.
|
||||
The ``batch`` filter was added in Twig 1.12.3.
|
||||
|
||||
The ``batch`` filter "batches" items by returning a list of lists with the
|
||||
given number of items. If you provide a second parameter, it is used to fill
|
||||
|
|
|
@ -21,8 +21,8 @@ is the input charset:
|
|||
Arguments
|
||||
---------
|
||||
|
||||
* ``from``: The input charset
|
||||
* ``to``: The output charset
|
||||
* ``from``: The input charset
|
||||
|
||||
.. _`iconv`: http://php.net/iconv
|
||||
.. _`mbstring`: http://php.net/mbstring
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
=========
|
||||
|
||||
.. versionadded:: 1.12.2
|
||||
The first filter was added in Twig 1.12.2.
|
||||
The ``first`` filter was added in Twig 1.12.2.
|
||||
|
||||
The ``first`` filter returns the first "element" of a sequence, a mapping, or
|
||||
a string:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
``json_encode``
|
||||
===============
|
||||
|
||||
The ``json_encode`` filter returns the JSON representation of a string:
|
||||
The ``json_encode`` filter returns the JSON representation of a value:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
========
|
||||
|
||||
.. versionadded:: 1.12.2
|
||||
The last filter was added in Twig 1.12.2.
|
||||
The ``last`` filter was added in Twig 1.12.2.
|
||||
|
||||
The ``last`` filter returns the last "element" of a sequence, a mapping, or
|
||||
a string:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
``length``
|
||||
==========
|
||||
|
||||
The ``length`` filters returns the number of items of a sequence or mapping, or
|
||||
The ``length`` filter returns the number of items of a sequence or mapping, or
|
||||
the length of a string:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
|
|
@ -39,3 +39,9 @@ overridden.
|
|||
{% set items = { 'apple': 'unknown' }|merge(items) %}
|
||||
|
||||
{# items now contains { 'apple': 'fruit', 'orange': 'fruit' } #}
|
||||
|
||||
.. note::
|
||||
|
||||
Internally, Twig uses the PHP `array_merge`_ function.
|
||||
|
||||
.. _`array_merge`: http://php.net/array_merge
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
=========
|
||||
|
||||
.. versionadded:: 1.5
|
||||
The nl2br filter was added in Twig 1.5.
|
||||
The ``nl2br`` filter was added in Twig 1.5.
|
||||
|
||||
The ``nl2br`` filter inserts HTML line breaks before all newlines in a string:
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
=================
|
||||
|
||||
.. versionadded:: 1.5
|
||||
The number_format filter was added in Twig 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:
|
||||
|
|
|
@ -10,3 +10,27 @@ if ``raw`` is the last filter applied to it:
|
|||
{% autoescape %}
|
||||
{{ var|raw }} {# var won't be escaped #}
|
||||
{% endautoescape %}
|
||||
|
||||
.. note::
|
||||
|
||||
Be careful when using the ``raw`` filter inside expressions:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% autoescape %}
|
||||
{% set hello = '<strong>Hello</strong>' %}
|
||||
{% set hola = '<strong>Hola</strong>' %}
|
||||
|
||||
{{ false ? '<strong>Hola</strong>' : hello|raw }}
|
||||
does not render the same as
|
||||
{{ false ? hola : hello|raw }}
|
||||
but renders the same as
|
||||
{{ (false ? hola : hello)|raw }}
|
||||
{% endautoescape %}
|
||||
|
||||
The first ternary statement is not escaped: ``hello`` is marked as being
|
||||
safe and Twig does not escape static values (see
|
||||
:doc:`escape<../tags/autoescape>`). In the second ternary statement, even
|
||||
if ``hello`` is marked as safe, ``hola`` remains unsafe and so is the whole
|
||||
expression. The third ternary statement is marked as safe and the result is
|
||||
not escaped.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
===========
|
||||
|
||||
.. versionadded:: 1.6
|
||||
The slice filter was added in Twig 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:
|
||||
|
||||
|
@ -41,7 +41,7 @@ As syntactic sugar, you can also use the ``[]`` notation:
|
|||
{{ '12345'[2:] }} {# will display "345" #}
|
||||
|
||||
The ``slice`` filter works as the `array_slice`_ PHP function for arrays and
|
||||
`substr`_ for strings.
|
||||
`mb_substr`_ for strings with a fallback to `substr`_.
|
||||
|
||||
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
|
||||
|
@ -67,4 +67,5 @@ Arguments
|
|||
|
||||
.. _`Traversable`: http://php.net/manual/en/class.traversable.php
|
||||
.. _`array_slice`: http://php.net/array_slice
|
||||
.. _`mb_substr` : http://php.net/mb-substr
|
||||
.. _`substr`: http://php.net/substr
|
||||
|
|
|
@ -2,15 +2,15 @@
|
|||
=========
|
||||
|
||||
.. versionadded:: 1.10.3
|
||||
The split filter was added in Twig 1.10.3.
|
||||
The ``split`` filter was added in Twig 1.10.3.
|
||||
|
||||
The ``split`` filter splits a string by the given delimiter and returns a list
|
||||
of strings:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
{{ "one,two,three"|split(',') }}
|
||||
{# returns ['one', 'two', 'three'] #}
|
||||
{% set foo = "one,two,three"|split(',') %}
|
||||
{# foo contains ['one', 'two', 'three'] #}
|
||||
|
||||
You can also pass a ``limit`` argument:
|
||||
|
||||
|
@ -24,19 +24,19 @@ You can also pass a ``limit`` argument:
|
|||
|
||||
.. code-block:: jinja
|
||||
|
||||
{{ "one,two,three,four,five"|split(',', 3) }}
|
||||
{# returns ['one', 'two', 'three,four,five'] #}
|
||||
{% set foo = "one,two,three,four,five"|split(',', 3) %}
|
||||
{# foo contains ['one', 'two', 'three,four,five'] #}
|
||||
|
||||
If the ``delimiter`` is an empty string, then value will be split by equal
|
||||
chunks. Length is set by the ``limit`` argument (one character by default).
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
{{ "123"|split('') }}
|
||||
{# returns ['1', '2', '3'] #}
|
||||
{% set foo = "123"|split('') %}
|
||||
{# foo contains ['1', '2', '3'] #}
|
||||
|
||||
{{ "aabbcc"|split('', 2) }}
|
||||
{# returns ['aa', 'bb', 'cc'] #}
|
||||
{% set bar = "aabbcc"|split('', 2) %}
|
||||
{# bar contains ['aa', 'bb', 'cc'] #}
|
||||
|
||||
.. note::
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
========
|
||||
|
||||
.. versionadded:: 1.6.2
|
||||
The trim filter was added in Twig 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:
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
.. versionadded:: 1.12.3
|
||||
Support for encoding an array as query string was added in Twig 1.12.3.
|
||||
|
||||
.. versionadded:: 1.16.0
|
||||
The ``raw`` argument was removed in Twig 1.16.0. Twig now always encodes
|
||||
according to RFC 3986.
|
||||
|
||||
The ``url_encode`` filter percent encodes a given string as URL segment
|
||||
or an array as query string:
|
||||
|
||||
|
@ -12,7 +16,7 @@ or an array as query string:
|
|||
{{ "path-seg*ment"|url_encode }}
|
||||
{# outputs "path-seg%2Ament" #}
|
||||
|
||||
{{ "string with spaces"|url_encode(true) }}
|
||||
{{ "string with spaces"|url_encode }}
|
||||
{# outputs "string%20with%20spaces" #}
|
||||
|
||||
{{ {'param': 'value', 'foo': 'bar'}|url_encode }}
|
||||
|
@ -21,7 +25,9 @@ or an array as query string:
|
|||
.. note::
|
||||
|
||||
Internally, Twig uses the PHP `urlencode`_ (or `rawurlencode`_ if you pass
|
||||
``true`` as the first parameter) or the `http_build_query`_ function.
|
||||
``true`` as the first parameter) or the `http_build_query`_ function. Note
|
||||
that as of Twig 1.16.0, ``urlencode`` **always** uses ``rawurlencode`` (the
|
||||
``raw`` argument was removed.)
|
||||
|
||||
.. _`urlencode`: http://php.net/urlencode
|
||||
.. _`rawurlencode`: http://php.net/rawurlencode
|
||||
|
|
|
@ -15,7 +15,7 @@ Converts an argument to a date to allow date comparison:
|
|||
{# do something #}
|
||||
{% endif %}
|
||||
|
||||
The argument must be in a format supported by the `date`_ function.
|
||||
The argument must be in one of PHP’s supported `date and time formats`_.
|
||||
|
||||
You can pass a timezone as the second argument:
|
||||
|
||||
|
@ -49,4 +49,4 @@ Arguments
|
|||
* ``date``: The date
|
||||
* ``timezone``: The timezone
|
||||
|
||||
.. _`date`: http://www.php.net/date
|
||||
.. _`date and time formats`: http://php.net/manual/en/datetime.formats.php
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
========
|
||||
|
||||
.. versionadded:: 1.5
|
||||
The dump function was added in Twig 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
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
===========
|
||||
|
||||
.. versionadded:: 1.12
|
||||
The include function was added in Twig 1.12.
|
||||
The ``include`` function was added in Twig 1.12.
|
||||
|
||||
The ``include`` function returns the rendered content of a template:
|
||||
|
||||
|
|
|
@ -15,5 +15,6 @@ When called with a mapping, max ignores keys and only compares values:
|
|||
|
||||
.. code-block:: jinja
|
||||
|
||||
{{ max({2: "two", 1: "one", 3: "three", 5: "five", 4: "for"}) }}
|
||||
{# return "two" #}
|
||||
{{ max({2: "e", 1: "a", 3: "b", 5: "d", 4: "c"}) }}
|
||||
{# returns "e" #}
|
||||
|
||||
|
|
|
@ -15,5 +15,6 @@ When called with a mapping, min ignores keys and only compares values:
|
|||
|
||||
.. code-block:: jinja
|
||||
|
||||
{{ min({2: "two", 1: "one", 3: "three", 5: "five", 4: "for"}) }}
|
||||
{# return "five" #}
|
||||
{{ min({2: "e", 3: "a", 1: "b", 5: "d", 4: "c"}) }}
|
||||
{# returns "a" #}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
==========
|
||||
|
||||
.. versionadded:: 1.5
|
||||
The random function was added in Twig 1.5.
|
||||
The ``random`` function was added in Twig 1.5.
|
||||
|
||||
.. versionadded:: 1.6
|
||||
String and integer handling was added in Twig 1.6.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
==========
|
||||
|
||||
.. versionadded:: 1.15
|
||||
The source function was added in Twig 1.15.
|
||||
The ``source`` function was added in Twig 1.15.
|
||||
|
||||
The ``source`` function returns the content of a template without rendering it:
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
========================
|
||||
|
||||
.. versionadded:: 1.11
|
||||
The template_from_string function was added in Twig 1.11.
|
||||
The ``template_from_string`` function was added in Twig 1.11.
|
||||
|
||||
The ``template_from_string`` function loads a template from a string:
|
||||
|
||||
|
|
|
@ -5,15 +5,15 @@ Twig
|
|||
:maxdepth: 2
|
||||
|
||||
intro
|
||||
installation
|
||||
templates
|
||||
api
|
||||
advanced
|
||||
internals
|
||||
deprecated
|
||||
recipes
|
||||
coding_standards
|
||||
tags/index
|
||||
filters/index
|
||||
functions/index
|
||||
tests/index
|
||||
installation
|
||||
deprecated
|
||||
|
|
|
@ -9,51 +9,39 @@ Installing the Twig PHP package
|
|||
Installing via Composer (recommended)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
1. Install Composer in your project:
|
||||
Install `Composer`_ and run the following command to get the latest version:
|
||||
|
||||
.. 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.*"
|
||||
}
|
||||
}
|
||||
|
||||
3. Install via Composer
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
php composer.phar install
|
||||
|
||||
.. note::
|
||||
If you want to learn more about Composer, the ``composer.json`` file syntax
|
||||
and its usage, you can read the `online documentation`_.
|
||||
composer require twig/twig:~1.0
|
||||
|
||||
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
|
||||
2. Verify the integrity of the tarball http://fabien.potencier.org/article/73/signing-project-releases
|
||||
3. Unpack the tarball
|
||||
4. Move the files somewhere in your project
|
||||
|
||||
Installing the development version
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
1. Install Git
|
||||
2. ``git clone git://github.com/fabpot/Twig.git``
|
||||
.. code-block:: bash
|
||||
|
||||
git clone git://github.com/fabpot/Twig.git
|
||||
|
||||
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``)
|
||||
.. note::
|
||||
|
||||
Using PEAR for installing Twig is deprecated and Twig 1.15.1 was the last
|
||||
version published on the PEAR channel; use Composer instead.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
pear channel-discover pear.twig-project.org
|
||||
pear install twig/Twig
|
||||
|
||||
Installing the C extension
|
||||
--------------------------
|
||||
|
@ -61,24 +49,31 @@ Installing the C extension
|
|||
.. versionadded:: 1.4
|
||||
The C extension was added in Twig 1.4.
|
||||
|
||||
.. note::
|
||||
The C extension is **optional** but as it brings some nice performance
|
||||
improvements, you might want to install it in your production environment.
|
||||
|
||||
Twig comes with a C extension that enhances the performance of the Twig
|
||||
runtime engine.
|
||||
|
||||
You can install it via PEAR:
|
||||
|
||||
1. Install PEAR
|
||||
2. ``pear channel-discover pear.twig-project.org``
|
||||
3. ``pear install twig/CTwig`` (or ``pear install twig/CTwig-beta``)
|
||||
|
||||
Or manually like any other PHP extension:
|
||||
runtime engine; install it like any other PHP extensions:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ cd ext/twig
|
||||
$ phpize
|
||||
$ ./configure
|
||||
$ make
|
||||
$ make install
|
||||
cd ext/twig
|
||||
phpize
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
|
||||
.. note::
|
||||
|
||||
You can also install the C extension via PEAR (note that this method is
|
||||
deprecated and newer versions of Twig are not available on the PEAR
|
||||
channel):
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
pear channel-discover pear.twig-project.org
|
||||
pear install twig/CTwig
|
||||
|
||||
For Windows:
|
||||
|
||||
|
@ -90,15 +85,15 @@ For Windows:
|
|||
|
||||
.. tip::
|
||||
|
||||
For Windows ZendServer, TS is not enabled as mentionned in `Zend Server
|
||||
For Windows ZendServer, ZTS is not enabled as mentioned in `Zend Server
|
||||
FAQ`_.
|
||||
|
||||
You have to use `configure --disable-all --disable-zts --enable-cli
|
||||
--enable-twig=shared` to be able to build the twig C extension for
|
||||
You have to use ``configure --disable-all --disable-zts --enable-cli
|
||||
--enable-twig=shared`` to be able to build the twig C extension for
|
||||
ZendServer.
|
||||
|
||||
The built DLL will be available in
|
||||
C:\\php-sdk\\phpdev\\vcXX\\x86\\php-source-directory\\Release
|
||||
``C:\\php-sdk\\phpdev\\vcXX\\x86\\php-source-directory\\Release``
|
||||
|
||||
Finally, enable the extension in your ``php.ini`` configuration file:
|
||||
|
||||
|
@ -113,6 +108,6 @@ PHP code but only provides an optimized version of the
|
|||
``Twig_Template::getAttribute()`` method.
|
||||
|
||||
.. _`download page`: https://github.com/fabpot/Twig/tags
|
||||
.. _`online documentation`: http://getcomposer.org/doc
|
||||
.. _`Composer`: https://getcomposer.org/download/
|
||||
.. _`PHP documentation`: https://wiki.php.net/internals/windows/stepbystepbuild
|
||||
.. _`Zend Server FAQ`: http://www.zend.com/en/products/server/faq#faqD6
|
||||
|
|
|
@ -124,7 +124,7 @@ using)::
|
|||
{
|
||||
// line 1
|
||||
echo "Hello ";
|
||||
echo twig_escape_filter($this->env, $this->getContext($context, "name"), "ndex", null, true);
|
||||
echo twig_escape_filter($this->env, $this->getContext($context, "name"), "html", null, true);
|
||||
}
|
||||
|
||||
// some more code
|
||||
|
|
|
@ -33,7 +33,7 @@ The recommended way to install Twig is via Composer:
|
|||
|
||||
.. code-block:: bash
|
||||
|
||||
composer require twig/twig:1.*
|
||||
composer require "twig/twig:~1.0"
|
||||
|
||||
.. note::
|
||||
|
||||
|
@ -50,12 +50,14 @@ This section gives you a brief introduction to the PHP API for Twig.
|
|||
|
||||
require_once '/path/to/vendor/autoload.php';
|
||||
|
||||
$loader = new Twig_Loader_String();
|
||||
$loader = new Twig_Loader_Array(
|
||||
'index' => 'Hello {{ name }}!',
|
||||
);
|
||||
$twig = new Twig_Environment($loader);
|
||||
|
||||
echo $twig->render('Hello {{ name }}!', array('name' => 'Fabien'));
|
||||
echo $twig->render('index', array('name' => 'Fabien'));
|
||||
|
||||
Twig uses a loader (``Twig_Loader_String``) to locate templates, and an
|
||||
Twig uses a loader (``Twig_Loader_Array``) to locate templates, and an
|
||||
environment (``Twig_Environment``) to store the configuration.
|
||||
|
||||
The ``render()`` method loads the template passed as a first argument and
|
||||
|
|
|
@ -242,7 +242,7 @@ does not return ``false``.
|
|||
Validating the Template Syntax
|
||||
------------------------------
|
||||
|
||||
When template code is providing by a third-party (through a web interface for
|
||||
When template code is provided 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::
|
||||
|
|
|
@ -65,6 +65,18 @@ Functions returning template data (like :doc:`macros<macro>` and
|
|||
Twig is smart enough to not escape an already escaped value by the
|
||||
:doc:`escape<../filters/escape>` filter.
|
||||
|
||||
.. note::
|
||||
|
||||
Twig does not escape static expressions:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% set hello = "<strong>Hello</strong>" %}
|
||||
{{ hello }}
|
||||
{{ "<strong>world</strong>" }}
|
||||
|
||||
Will be rendered "<strong>Hello</strong> **world**".
|
||||
|
||||
.. note::
|
||||
|
||||
The chapter :doc:`Twig for Developers<../api>` gives more information
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
======
|
||||
|
||||
.. versionadded:: 1.5
|
||||
The do tag was added in Twig 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:
|
||||
|
|
|
@ -186,8 +186,8 @@ In this example, the template will extend the "minimum.html" layout template
|
|||
if the ``standalone`` variable evaluates to ``true``, and "base.html"
|
||||
otherwise.
|
||||
|
||||
How blocks work?
|
||||
----------------
|
||||
How do blocks work?
|
||||
-------------------
|
||||
|
||||
A block provides a way to change how a certain part of a template is rendered
|
||||
but it does not interfere in any way with the logic around it.
|
||||
|
|
|
@ -41,3 +41,20 @@ more complex ``expressions`` there too:
|
|||
{% else %}
|
||||
Kenny looks okay --- so far
|
||||
{% endif %}
|
||||
|
||||
.. note::
|
||||
|
||||
The rules to determine if an expression is ``true`` or ``false`` are the
|
||||
same as in PHP; here are the edge cases rules:
|
||||
|
||||
====================== ====================
|
||||
Value Boolean evaluation
|
||||
====================== ====================
|
||||
empty string false
|
||||
numeric zero false
|
||||
whitespace-only string true
|
||||
empty array false
|
||||
null false
|
||||
non-empty array true
|
||||
object true
|
||||
====================== ====================
|
||||
|
|
|
@ -39,7 +39,8 @@ The ``use`` statement tells Twig to import the blocks defined in
|
|||
|
||||
.. code-block:: jinja
|
||||
|
||||
# blocks.html
|
||||
{# blocks.html #}
|
||||
|
||||
{% block sidebar %}{% endblock %}
|
||||
|
||||
In this example, the ``use`` statement imports the ``sidebar`` block into the
|
||||
|
|
|
@ -15,7 +15,7 @@ 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
|
||||
Below is a minimal template that illustrates a few basics. We will cover further
|
||||
details later on:
|
||||
|
||||
.. code-block:: html+jinja
|
||||
|
@ -58,14 +58,15 @@ Many IDEs support syntax highlighting and auto-completion for Twig:
|
|||
* *Komodo* and *Komodo Edit* via the Twig highlight/syntax check mode
|
||||
* *Notepad++* via the `Notepad++ Twig Highlighter`_
|
||||
* *Emacs* via `web-mode.el`_
|
||||
* *Atom* via the `PHP-twig for atom`_
|
||||
|
||||
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.
|
||||
The application passes variables to the templates for manipulation in the
|
||||
template. Variables may have attributes or elements you can access,
|
||||
too. The visual representation of a variable depends heavily on the application providing
|
||||
it.
|
||||
|
||||
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
|
||||
|
@ -88,16 +89,16 @@ access the variable attribute:
|
|||
.. 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.
|
||||
variable but the print statement. When accessing variables inside tags,
|
||||
don't put the braces around them.
|
||||
|
||||
If a variable or attribute does not exist, you will get back a ``null`` value
|
||||
when the ``strict_variables`` option is set to ``false``, otherwise Twig will
|
||||
throw an error (see :ref:`environment options<environment_options>`).
|
||||
If a variable or attribute does not exist, you will receive a ``null`` value
|
||||
when the ``strict_variables`` option is set to ``false``; alternatively, if ``strict_variables``
|
||||
is set, Twig will throw an error (see :ref:`environment options<environment_options>`).
|
||||
|
||||
.. sidebar:: Implementation
|
||||
|
||||
For convenience sake ``foo.bar`` does the following things on the PHP
|
||||
For convenience's sake ``foo.bar`` does the following things on the PHP
|
||||
layer:
|
||||
|
||||
* check if ``foo`` is an array and ``bar`` a valid element;
|
||||
|
@ -115,7 +116,7 @@ throw an error (see :ref:`environment options<environment_options>`).
|
|||
|
||||
.. note::
|
||||
|
||||
If you want to get a dynamic attribute on a variable, use the
|
||||
If you want to access a dynamic attribute of a variable, use the
|
||||
:doc:`attribute<functions/attribute>` function instead.
|
||||
|
||||
Global Variables
|
||||
|
@ -161,7 +162,7 @@ example will join a list by commas:
|
|||
|
||||
{{ list|join(', ') }}
|
||||
|
||||
To apply a filter on a section of code, wrap it with the
|
||||
To apply a filter on a section of code, wrap it in the
|
||||
:doc:`filter<tags/filter>` tag:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
@ -170,7 +171,7 @@ To apply a filter on a section of code, wrap it with the
|
|||
This text becomes uppercase
|
||||
{% endfilter %}
|
||||
|
||||
Go to the :doc:`filters<filters/index>` page to learn more about the built-in
|
||||
Go to the :doc:`filters<filters/index>` page to learn more about built-in
|
||||
filters.
|
||||
|
||||
Functions
|
||||
|
@ -222,7 +223,7 @@ to change the default value:
|
|||
{# the first argument is the date format, which defaults to the global date format if null is passed #}
|
||||
{{ "now"|date(null, "Europe/Paris") }}
|
||||
|
||||
{# or skip the format value by using a named argument for the timezone #}
|
||||
{# or skip the format value by using a named argument for the time zone #}
|
||||
{{ "now"|date(timezone="Europe/Paris") }}
|
||||
|
||||
You can also use both positional and named arguments in one call, in which
|
||||
|
@ -327,7 +328,7 @@ 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 easier to understand it by
|
||||
Sounds complicated but it is very basic. It's easier to understand it by
|
||||
starting with an example.
|
||||
|
||||
Let's define a base template, ``base.html``, which defines a simple HTML
|
||||
|
@ -692,7 +693,7 @@ string:
|
|||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% if phone matches '{^[\d\.]+$}' %}
|
||||
{% if phone matches '/^[\\d\\.]+$/' %}
|
||||
{% endif %}
|
||||
|
||||
Containment Operator
|
||||
|
@ -871,3 +872,4 @@ Extension<creating_extensions>` chapter.
|
|||
.. _`Notepad++ Twig Highlighter`: https://github.com/Banane9/notepadplusplus-twig
|
||||
.. _`web-mode.el`: http://web-mode.org/
|
||||
.. _`regular expressions`: http://php.net/manual/en/pcre.pattern.php
|
||||
.. _`PHP-twig for atom`: https://github.com/reesef/php-twig
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
.. versionadded:: 1.14.2
|
||||
The ``same as`` test was added in Twig 1.14.2 as an alias for ``sameas``.
|
||||
|
||||
``same as`` checks if a variable points to the same memory address than
|
||||
another variable:
|
||||
``same as`` checks if a variable is the same as another variable.
|
||||
This is the equivalent to ``===`` in PHP:
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
Copyright (c) 2009-2013 by the Twig Team, see AUTHORS for more details.
|
||||
|
||||
Some 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.
|
||||
|
||||
* The names of the contributors may not be used to endorse or
|
||||
promote products derived from this software without specific
|
||||
prior written permission.
|
||||
|
||||
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.
|
|
@ -15,7 +15,7 @@
|
|||
#ifndef PHP_TWIG_H
|
||||
#define PHP_TWIG_H
|
||||
|
||||
#define PHP_TWIG_VERSION "1.15.1"
|
||||
#define PHP_TWIG_VERSION "1.16.2"
|
||||
|
||||
#include "php.h"
|
||||
|
||||
|
|
|
@ -830,7 +830,11 @@ PHP_FUNCTION(twig_template_get_attributes)
|
|||
} elseif (is_object($object)) {
|
||||
$message = sprintf('Impossible to access a key "%s" on an object of class "%s" that does not implement ArrayAccess interface', $item, get_class($object));
|
||||
} elseif (is_array($object)) {
|
||||
$message = sprintf('Key "%s" for array with keys "%s" does not exist', $arrayItem, implode(', ', array_keys($object)));
|
||||
if (empty($object)) {
|
||||
$message = sprintf('Key "%s" does not exist as the array is empty', $arrayItem);
|
||||
} else {
|
||||
$message = sprintf('Key "%s" for array with keys "%s" does not exist', $arrayItem, implode(', ', array_keys($object)));
|
||||
}
|
||||
} elseif (Twig_Template::ARRAY_CALL === $type) {
|
||||
$message = sprintf('Impossible to access a key ("%s") on a %s variable ("%s")', $item, gettype($object), $object);
|
||||
} else {
|
||||
|
@ -845,7 +849,11 @@ PHP_FUNCTION(twig_template_get_attributes)
|
|||
} else if (Z_TYPE_P(object) == IS_OBJECT) {
|
||||
TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Impossible to access a key \"%s\" on an object of class \"%s\" that does not implement ArrayAccess interface", item, TWIG_GET_CLASS_NAME(object TSRMLS_CC));
|
||||
} else if (Z_TYPE_P(object) == IS_ARRAY) {
|
||||
TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Key \"%s\" for array with keys \"%s\" does not exist", item, TWIG_IMPLODE_ARRAY_KEYS(", ", object TSRMLS_CC));
|
||||
if (0 == zend_hash_num_elements(Z_ARRVAL_P(object))) {
|
||||
TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Key \"%s\" does not exist as the array is empty", item);
|
||||
} else {
|
||||
TWIG_RUNTIME_ERROR(template TSRMLS_CC, "Key \"%s\" for array with keys \"%s\" does not exist", item, TWIG_IMPLODE_ARRAY_KEYS(", ", object TSRMLS_CC));
|
||||
}
|
||||
} else {
|
||||
char *type_name = zend_zval_type_name(object);
|
||||
Z_ADDREF_P(object);
|
||||
|
|
|
@ -19,7 +19,7 @@ class Twig_Autoloader
|
|||
/**
|
||||
* Registers Twig_Autoloader as an SPL autoloader.
|
||||
*
|
||||
* @param Boolean $prepend Whether to prepend the autoloader or not.
|
||||
* @param bool $prepend Whether to prepend the autoloader or not.
|
||||
*/
|
||||
public static function register($prepend = false)
|
||||
{
|
||||
|
|
|
@ -66,7 +66,7 @@ class Twig_Compiler implements Twig_CompilerInterface
|
|||
* Compiles a node.
|
||||
*
|
||||
* @param Twig_NodeInterface $node The node to compile
|
||||
* @param integer $indentation The current indentation
|
||||
* @param int $indentation The current indentation
|
||||
*
|
||||
* @return Twig_Compiler The current compiler instance
|
||||
*/
|
||||
|
@ -74,6 +74,7 @@ class Twig_Compiler implements Twig_CompilerInterface
|
|||
{
|
||||
$this->lastLine = null;
|
||||
$this->source = '';
|
||||
$this->debugInfo = array();
|
||||
$this->sourceOffset = 0;
|
||||
// source code starts at 1 (as we then increment it when we encounter new lines)
|
||||
$this->sourceLine = 1;
|
||||
|
@ -181,14 +182,14 @@ class Twig_Compiler implements Twig_CompilerInterface
|
|||
} elseif (is_array($value)) {
|
||||
$this->raw('array(');
|
||||
$first = true;
|
||||
foreach ($value as $key => $value) {
|
||||
foreach ($value as $key => $v) {
|
||||
if (!$first) {
|
||||
$this->raw(', ');
|
||||
}
|
||||
$first = false;
|
||||
$this->repr($key);
|
||||
$this->raw(' => ');
|
||||
$this->repr($value);
|
||||
$this->repr($v);
|
||||
}
|
||||
$this->raw(')');
|
||||
} else {
|
||||
|
@ -236,7 +237,7 @@ class Twig_Compiler implements Twig_CompilerInterface
|
|||
/**
|
||||
* Indents the generated code.
|
||||
*
|
||||
* @param integer $step The number of indentation to add
|
||||
* @param int $step The number of indentation to add
|
||||
*
|
||||
* @return Twig_Compiler The current compiler instance
|
||||
*/
|
||||
|
@ -250,7 +251,7 @@ class Twig_Compiler implements Twig_CompilerInterface
|
|||
/**
|
||||
* Outdents the generated code.
|
||||
*
|
||||
* @param integer $step The number of indentation to remove
|
||||
* @param int $step The number of indentation to remove
|
||||
*
|
||||
* @return Twig_Compiler The current compiler instance
|
||||
*
|
||||
|
@ -267,4 +268,9 @@ class Twig_Compiler implements Twig_CompilerInterface
|
|||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getVarName()
|
||||
{
|
||||
return sprintf('__internal_%s', hash('sha256', uniqid(mt_rand(), true), false));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
* Interface implemented by compiler classes.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @deprecated since 1.12 (to be removed in 2.0)
|
||||
*
|
||||
* @deprecated since 1.12 (to be removed in 3.0)
|
||||
*/
|
||||
interface Twig_CompilerInterface
|
||||
{
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
*/
|
||||
class Twig_Environment
|
||||
{
|
||||
const VERSION = '1.15.1';
|
||||
const VERSION = '1.16.2';
|
||||
|
||||
protected $charset;
|
||||
protected $loader;
|
||||
|
@ -154,7 +154,7 @@ class Twig_Environment
|
|||
/**
|
||||
* Checks if debug mode is enabled.
|
||||
*
|
||||
* @return Boolean true if debug mode is enabled, false otherwise
|
||||
* @return bool true if debug mode is enabled, false otherwise
|
||||
*/
|
||||
public function isDebug()
|
||||
{
|
||||
|
@ -180,7 +180,7 @@ class Twig_Environment
|
|||
/**
|
||||
* Checks if the auto_reload option is enabled.
|
||||
*
|
||||
* @return Boolean true if auto_reload is enabled, false otherwise
|
||||
* @return bool true if auto_reload is enabled, false otherwise
|
||||
*/
|
||||
public function isAutoReload()
|
||||
{
|
||||
|
@ -206,7 +206,7 @@ class Twig_Environment
|
|||
/**
|
||||
* Checks if the strict_variables option is enabled.
|
||||
*
|
||||
* @return Boolean true if strict_variables is enabled, false otherwise
|
||||
* @return bool true if strict_variables is enabled, false otherwise
|
||||
*/
|
||||
public function isStrictVariables()
|
||||
{
|
||||
|
@ -256,7 +256,7 @@ 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 integer $index The index if it is an embedded template
|
||||
* @param int $index The index if it is an embedded template
|
||||
*
|
||||
* @return string The template class name
|
||||
*/
|
||||
|
@ -311,7 +311,7 @@ class Twig_Environment
|
|||
* Loads a template by name.
|
||||
*
|
||||
* @param string $name The template name
|
||||
* @param integer $index The index if it is an embedded template
|
||||
* @param int $index The index if it is an embedded template
|
||||
*
|
||||
* @return Twig_TemplateInterface A template instance representing the given template name
|
||||
*
|
||||
|
@ -355,7 +355,7 @@ class Twig_Environment
|
|||
* @param string $name The template name
|
||||
* @param timestamp $time The last modification time of the cached template
|
||||
*
|
||||
* @return Boolean true if the template is fresh, false otherwise
|
||||
* @return bool true if the template is fresh, false otherwise
|
||||
*/
|
||||
public function isTemplateFresh($name, $time)
|
||||
{
|
||||
|
@ -626,7 +626,7 @@ class Twig_Environment
|
|||
*
|
||||
* @param string $name The extension name
|
||||
*
|
||||
* @return Boolean Whether the extension is registered or not
|
||||
* @return bool Whether the extension is registered or not
|
||||
*/
|
||||
public function hasExtension($name)
|
||||
{
|
||||
|
|
|
@ -51,7 +51,7 @@ class Twig_Error extends Exception
|
|||
* By default, automatic guessing is enabled.
|
||||
*
|
||||
* @param string $message The error message
|
||||
* @param integer $lineno The template line where the error occurred
|
||||
* @param int $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
|
||||
*/
|
||||
|
@ -111,7 +111,7 @@ class Twig_Error extends Exception
|
|||
/**
|
||||
* Gets the template line where the error occurred.
|
||||
*
|
||||
* @return integer The template line
|
||||
* @return int The template line
|
||||
*/
|
||||
public function getTemplateLine()
|
||||
{
|
||||
|
@ -121,7 +121,7 @@ class Twig_Error extends Exception
|
|||
/**
|
||||
* Sets the template line where the error occurred.
|
||||
*
|
||||
* @param integer $lineno The template line
|
||||
* @param int $lineno The template line
|
||||
*/
|
||||
public function setTemplateLine($lineno)
|
||||
{
|
||||
|
@ -229,6 +229,8 @@ class Twig_Error extends Exception
|
|||
|
||||
while ($e = array_pop($exceptions)) {
|
||||
$traces = $e->getTrace();
|
||||
array_unshift($traces, array('file' => $e->getFile(), 'line' => $e->getLine()));
|
||||
|
||||
while ($trace = array_shift($traces)) {
|
||||
if (!isset($trace['file']) || !isset($trace['line']) || $file != $trace['file']) {
|
||||
continue;
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
* Adds an exists() method for loaders.
|
||||
*
|
||||
* @author Florin Patan <florinpatan@gmail.com>
|
||||
* @deprecated since 1.12 (to be removed in 2.0)
|
||||
*
|
||||
* @deprecated since 1.12 (to be removed in 3.0)
|
||||
*/
|
||||
interface Twig_ExistsLoaderInterface
|
||||
{
|
||||
|
@ -22,7 +23,7 @@ interface Twig_ExistsLoaderInterface
|
|||
*
|
||||
* @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
|
||||
* @return bool If the template source code is handled by this loader or not
|
||||
*/
|
||||
public function exists($name);
|
||||
}
|
||||
|
|
|
@ -318,7 +318,7 @@ class Twig_ExpressionParser
|
|||
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_Template::ANY_CALL, $line);
|
||||
return new Twig_Node_Expression_GetAttr($args->getNode(0), $args->getNode(1), count($args) > 2 ? $args->getNode(2) : null, Twig_Template::ANY_CALL, $line);
|
||||
default:
|
||||
if (null !== $alias = $this->parser->getImportedSymbol('function', $name)) {
|
||||
$arguments = new Twig_Node_Expression_Array(array(), $line);
|
||||
|
@ -451,8 +451,8 @@ class Twig_ExpressionParser
|
|||
/**
|
||||
* Parses arguments.
|
||||
*
|
||||
* @param Boolean $namedArguments Whether to allow named arguments or not
|
||||
* @param Boolean $definition Whether we are parsing arguments for a function definition
|
||||
* @param bool $namedArguments Whether to allow named arguments or not
|
||||
* @param bool $definition Whether we are parsing arguments for a function definition
|
||||
*/
|
||||
public function parseArguments($namedArguments = false, $definition = false)
|
||||
{
|
||||
|
|
|
@ -95,7 +95,7 @@ class Twig_Extension_Core extends Twig_Extension
|
|||
/**
|
||||
* Sets the default format to be used by the number_format filter.
|
||||
*
|
||||
* @param integer $decimal The number of decimal places to use.
|
||||
* @param int $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.
|
||||
*/
|
||||
|
@ -173,7 +173,7 @@ class Twig_Extension_Core extends Twig_Extension
|
|||
|
||||
// array helpers
|
||||
new Twig_SimpleFilter('join', 'twig_join_filter'),
|
||||
new Twig_SimpleFilter('split', 'twig_split_filter'),
|
||||
new Twig_SimpleFilter('split', 'twig_split_filter', array('needs_environment' => true)),
|
||||
new Twig_SimpleFilter('sort', 'twig_sort_filter'),
|
||||
new Twig_SimpleFilter('merge', 'twig_array_merge'),
|
||||
new Twig_SimpleFilter('batch', 'twig_array_batch'),
|
||||
|
@ -298,8 +298,8 @@ class Twig_Extension_Core extends Twig_Extension
|
|||
public function parseTestExpression(Twig_Parser $parser, Twig_NodeInterface $node)
|
||||
{
|
||||
$stream = $parser->getStream();
|
||||
$name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
|
||||
$class = $this->getTestNodeClass($parser, $name, $node->getLine());
|
||||
$name = $this->getTestName($parser, $node->getLine());
|
||||
$class = $this->getTestNodeClass($parser, $name);
|
||||
$arguments = null;
|
||||
if ($stream->test(Twig_Token::PUNCTUATION_TYPE, '(')) {
|
||||
$arguments = $parser->getExpressionParser()->parseArguments(true);
|
||||
|
@ -308,33 +308,41 @@ class Twig_Extension_Core extends Twig_Extension
|
|||
return new $class($node, $name, $arguments, $parser->getCurrentToken()->getLine());
|
||||
}
|
||||
|
||||
protected function getTestNodeClass(Twig_Parser $parser, $name, $line)
|
||||
protected function getTestName(Twig_Parser $parser, $line)
|
||||
{
|
||||
$stream = $parser->getStream();
|
||||
$name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();
|
||||
$env = $parser->getEnvironment();
|
||||
$testMap = $env->getTests();
|
||||
$testName = null;
|
||||
|
||||
if (isset($testMap[$name])) {
|
||||
$testName = $name;
|
||||
} elseif ($parser->getStream()->test(Twig_Token::NAME_TYPE)) {
|
||||
return $name;
|
||||
}
|
||||
|
||||
if ($stream->test(Twig_Token::NAME_TYPE)) {
|
||||
// try 2-words tests
|
||||
$name = $name.' '.$parser->getCurrentToken()->getValue();
|
||||
|
||||
if (isset($testMap[$name])) {
|
||||
$parser->getStream()->next();
|
||||
|
||||
$testName = $name;
|
||||
return $name;
|
||||
}
|
||||
}
|
||||
|
||||
if (null === $testName) {
|
||||
$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());
|
||||
$message = sprintf('The test "%s" does not exist', $name);
|
||||
if ($alternatives = $env->computeAlternatives($name, array_keys($testMap))) {
|
||||
$message = sprintf('%s. Did you mean "%s"', $message, implode('", "', $alternatives));
|
||||
}
|
||||
|
||||
throw new Twig_Error_Syntax($message, $line, $parser->getFilename());
|
||||
}
|
||||
|
||||
protected function getTestNodeClass(Twig_Parser $parser, $name)
|
||||
{
|
||||
$env = $parser->getEnvironment();
|
||||
$testMap = $env->getTests();
|
||||
|
||||
if ($testMap[$name] instanceof Twig_SimpleTest) {
|
||||
return $testMap[$name]->getNodeClass();
|
||||
}
|
||||
|
@ -357,7 +365,7 @@ class Twig_Extension_Core extends Twig_Extension
|
|||
* Cycles over a value.
|
||||
*
|
||||
* @param ArrayAccess|array $values An array or an ArrayAccess instance
|
||||
* @param integer $position The cycle position
|
||||
* @param int $position The cycle position
|
||||
*
|
||||
* @return string The next value in the cycle
|
||||
*/
|
||||
|
@ -377,7 +385,7 @@ function twig_cycle($values, $position)
|
|||
* - a random integer between 0 and the integer parameter
|
||||
*
|
||||
* @param Twig_Environment $env A Twig_Environment instance
|
||||
* @param Traversable|array|integer|string $values The values to pick a random item from
|
||||
* @param Traversable|array|int|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).
|
||||
*
|
||||
|
@ -436,10 +444,10 @@ function twig_random(Twig_Environment $env, $values = null)
|
|||
* {{ post.published_at|date("m/d/Y") }}
|
||||
* </pre>
|
||||
*
|
||||
* @param Twig_Environment $env A Twig_Environment instance
|
||||
* @param DateTime|DateInterval|string $date A date
|
||||
* @param string $format A format
|
||||
* @param DateTimeZone|string $timezone A timezone
|
||||
* @param Twig_Environment $env A Twig_Environment instance
|
||||
* @param DateTime|DateTimeInterface|DateInterval|string $date A date
|
||||
* @param string|null $format The target format, null to use the default
|
||||
* @param DateTimeZone|string|null|false $timezone The target timezone, null to use the default, false to leave unchanged
|
||||
*
|
||||
* @return string The formatted date
|
||||
*/
|
||||
|
@ -473,9 +481,12 @@ function twig_date_format_filter(Twig_Environment $env, $date, $format = null, $
|
|||
function twig_date_modify_filter(Twig_Environment $env, $date, $modifier)
|
||||
{
|
||||
$date = twig_date_converter($env, $date, false);
|
||||
$date->modify($modifier);
|
||||
$resultDate = $date->modify($modifier);
|
||||
|
||||
return $date;
|
||||
// This is a hack to ensure PHP 5.2 support and support for DateTimeImmutable
|
||||
// DateTime::modify does not return the modified DateTime object < 5.3.0
|
||||
// and DateTimeImmutable does not modify $date.
|
||||
return null === $resultDate ? $date : $resultDate;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -487,32 +498,32 @@ function twig_date_modify_filter(Twig_Environment $env, $date, $modifier)
|
|||
* {% endif %}
|
||||
* </pre>
|
||||
*
|
||||
* @param Twig_Environment $env A Twig_Environment instance
|
||||
* @param DateTime|string $date A date
|
||||
* @param DateTimeZone|string $timezone A timezone
|
||||
* @param Twig_Environment $env A Twig_Environment instance
|
||||
* @param DateTime|DateTimeInterface|string|null $date A date
|
||||
* @param DateTimeZone|string|null|false $timezone The target timezone, null to use the default, false to leave unchanged
|
||||
*
|
||||
* @return DateTime A DateTime instance
|
||||
*/
|
||||
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 (false !== $timezone) {
|
||||
if (null === $timezone) {
|
||||
$timezone = $env->getExtension('core')->getTimezone();
|
||||
} elseif (!$timezone instanceof DateTimeZone) {
|
||||
$timezone = new DateTimeZone($timezone);
|
||||
}
|
||||
}
|
||||
|
||||
// immutable dates
|
||||
if ($date instanceof DateTimeImmutable) {
|
||||
return false !== $timezone ? $date->setTimezone($defaultTimezone) : $date;
|
||||
return false !== $timezone ? $date->setTimezone($timezone) : $date;
|
||||
}
|
||||
|
||||
if ($date instanceof DateTime || $date instanceof DateTimeInterface) {
|
||||
$date = clone $date;
|
||||
if (false !== $timezone) {
|
||||
$date->setTimezone($defaultTimezone);
|
||||
$date->setTimezone($timezone);
|
||||
}
|
||||
|
||||
return $date;
|
||||
|
@ -523,9 +534,9 @@ function twig_date_converter(Twig_Environment $env, $date = null, $timezone = nu
|
|||
$date = '@'.$date;
|
||||
}
|
||||
|
||||
$date = new DateTime($date, $defaultTimezone);
|
||||
$date = new DateTime($date, $env->getExtension('core')->getTimezone());
|
||||
if (false !== $timezone) {
|
||||
$date->setTimezone($defaultTimezone);
|
||||
$date->setTimezone($timezone);
|
||||
}
|
||||
|
||||
return $date;
|
||||
|
@ -534,11 +545,11 @@ function twig_date_converter(Twig_Environment $env, $date = null, $timezone = nu
|
|||
/**
|
||||
* Rounds a number.
|
||||
*
|
||||
* @param integer|float $value The value to round
|
||||
* @param integer|float $precision The rounding precision
|
||||
* @param int|float $value The value to round
|
||||
* @param int|float $precision The rounding precision
|
||||
* @param string $method The method to use for rounding
|
||||
*
|
||||
* @return integer|float The rounded number
|
||||
* @return int|float The rounded number
|
||||
*/
|
||||
function twig_round($value, $precision = 0, $method = 'common')
|
||||
{
|
||||
|
@ -562,7 +573,7 @@ function twig_round($value, $precision = 0, $method = 'common')
|
|||
*
|
||||
* @param Twig_Environment $env A Twig_Environment instance
|
||||
* @param mixed $number A float/int/string of the number to format
|
||||
* @param integer $decimal The number of decimal points to display.
|
||||
* @param int $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.
|
||||
*
|
||||
|
@ -587,24 +598,23 @@ function twig_number_format_filter(Twig_Environment $env, $number, $decimal = nu
|
|||
}
|
||||
|
||||
/**
|
||||
* URL encodes a string as a path segment or an array as a query string.
|
||||
* URL encodes (RFC 3986) a string as a path segment or an array as a query string.
|
||||
*
|
||||
* @param string|array $url A URL or an array of query parameters
|
||||
* @param Boolean $raw true to use rawurlencode() instead of urlencode
|
||||
*
|
||||
* @return string The URL encoded value
|
||||
*/
|
||||
function twig_urlencode_filter($url, $raw = false)
|
||||
function twig_urlencode_filter($url)
|
||||
{
|
||||
if (is_array($url)) {
|
||||
if (defined('PHP_QUERY_RFC3986')) {
|
||||
return http_build_query($url, '', '&', PHP_QUERY_RFC3986);
|
||||
}
|
||||
|
||||
return http_build_query($url, '', '&');
|
||||
}
|
||||
|
||||
if ($raw) {
|
||||
return rawurlencode($url);
|
||||
}
|
||||
|
||||
return urlencode($url);
|
||||
return rawurlencode($url);
|
||||
}
|
||||
|
||||
if (version_compare(PHP_VERSION, '5.3.0', '<')) {
|
||||
|
@ -612,7 +622,7 @@ if (version_compare(PHP_VERSION, '5.3.0', '<')) {
|
|||
* JSON encodes a variable.
|
||||
*
|
||||
* @param mixed $value The value to encode.
|
||||
* @param integer $options Not used on PHP 5.2.x
|
||||
* @param int $options Not used on PHP 5.2.x
|
||||
*
|
||||
* @return mixed The JSON encoded value
|
||||
*/
|
||||
|
@ -631,7 +641,7 @@ if (version_compare(PHP_VERSION, '5.3.0', '<')) {
|
|||
* JSON encodes a variable.
|
||||
*
|
||||
* @param mixed $value The value to encode.
|
||||
* @param integer $options Bitmask consisting of JSON_HEX_QUOT, JSON_HEX_TAG, JSON_HEX_AMP, JSON_HEX_APOS, JSON_NUMERIC_CHECK, JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, JSON_FORCE_OBJECT
|
||||
* @param int $options Bitmask consisting of JSON_HEX_QUOT, JSON_HEX_TAG, JSON_HEX_AMP, JSON_HEX_APOS, JSON_NUMERIC_CHECK, JSON_PRETTY_PRINT, JSON_UNESCAPED_SLASHES, JSON_FORCE_OBJECT
|
||||
*
|
||||
* @return mixed The JSON encoded value
|
||||
*/
|
||||
|
@ -673,7 +683,7 @@ function _twig_markup2string(&$value)
|
|||
function twig_array_merge($arr1, $arr2)
|
||||
{
|
||||
if (!is_array($arr1) || !is_array($arr2)) {
|
||||
throw new Twig_Error_Runtime('The merge filter only works with arrays or hashes.');
|
||||
throw new Twig_Error_Runtime(sprintf('The merge filter only works with arrays or hashes; %s and %s given.', gettype($arr1), gettype($arr2)));
|
||||
}
|
||||
|
||||
return array_merge($arr1, $arr2);
|
||||
|
@ -684,16 +694,24 @@ function twig_array_merge($arr1, $arr2)
|
|||
*
|
||||
* @param Twig_Environment $env A Twig_Environment instance
|
||||
* @param mixed $item A variable
|
||||
* @param integer $start Start of the slice
|
||||
* @param integer $length Size of the slice
|
||||
* @param Boolean $preserveKeys Whether to preserve key or not (when the input is an array)
|
||||
* @param int $start Start of the slice
|
||||
* @param int $length Size of the slice
|
||||
* @param bool $preserveKeys Whether to preserve key or not (when the input is an array)
|
||||
*
|
||||
* @return mixed The sliced variable
|
||||
*/
|
||||
function twig_slice(Twig_Environment $env, $item, $start, $length = null, $preserveKeys = false)
|
||||
{
|
||||
if ($item instanceof Traversable) {
|
||||
$item = iterator_to_array($item, false);
|
||||
if ($item instanceof IteratorAggregate) {
|
||||
$item = $item->getIterator();
|
||||
}
|
||||
|
||||
if ($start >= 0 && $length >= 0) {
|
||||
return iterator_to_array(new LimitIterator($item, $start, $length === null ? -1 : $length), $preserveKeys);
|
||||
}
|
||||
|
||||
$item = iterator_to_array($item, $preserveKeys);
|
||||
}
|
||||
|
||||
if (is_array($item)) {
|
||||
|
@ -703,10 +721,10 @@ function twig_slice(Twig_Environment $env, $item, $start, $length = null, $prese
|
|||
$item = (string) $item;
|
||||
|
||||
if (function_exists('mb_get_info') && null !== $charset = $env->getCharset()) {
|
||||
return mb_substr($item, $start, null === $length ? mb_strlen($item, $charset) - $start : $length, $charset);
|
||||
return (string) mb_substr($item, $start, null === $length ? mb_strlen($item, $charset) - $start : $length, $charset);
|
||||
}
|
||||
|
||||
return null === $length ? substr($item, $start) : substr($item, $start, $length);
|
||||
return (string) (null === $length ? substr($item, $start) : substr($item, $start, $length));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -785,17 +803,35 @@ function twig_join_filter($value, $glue = '')
|
|||
*
|
||||
* @param string $value A string
|
||||
* @param string $delimiter The delimiter
|
||||
* @param integer $limit The limit
|
||||
* @param int $limit The limit
|
||||
*
|
||||
* @return array The split string as an array
|
||||
*/
|
||||
function twig_split_filter($value, $delimiter, $limit = null)
|
||||
function twig_split_filter(Twig_Environment $env, $value, $delimiter, $limit = null)
|
||||
{
|
||||
if (empty($delimiter)) {
|
||||
if (!empty($delimiter)) {
|
||||
return null === $limit ? explode($delimiter, $value) : explode($delimiter, $value, $limit);
|
||||
}
|
||||
|
||||
if (!function_exists('mb_get_info') || null === $charset = $env->getCharset()) {
|
||||
return str_split($value, null === $limit ? 1 : $limit);
|
||||
}
|
||||
|
||||
return null === $limit ? explode($delimiter, $value) : explode($delimiter, $value, $limit);
|
||||
if ($limit <= 1) {
|
||||
return preg_split('/(?<!^)(?!$)/u', $value);
|
||||
}
|
||||
|
||||
$length = mb_strlen($value, $charset);
|
||||
if ($length < $limit) {
|
||||
return array($value);
|
||||
}
|
||||
|
||||
$r = array();
|
||||
for ($i = 0; $i < $length; $i += $limit) {
|
||||
$r[] = mb_substr($value, $i, $limit, $charset);
|
||||
}
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
// The '_default' filter is used internally to avoid using the ternary operator
|
||||
|
@ -843,7 +879,7 @@ function twig_get_array_keys_filter($array)
|
|||
*
|
||||
* @param Twig_Environment $env A Twig_Environment instance
|
||||
* @param array|Traversable|string $item An array, a Traversable instance, or a string
|
||||
* @param Boolean $preserveKeys Whether to preserve key or not
|
||||
* @param bool $preserveKeys Whether to preserve key or not
|
||||
*
|
||||
* @return mixed The reversed input
|
||||
*/
|
||||
|
@ -915,7 +951,7 @@ function twig_in_filter($value, $compare)
|
|||
* @param string $string The value to be escaped
|
||||
* @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)
|
||||
* @param bool $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, $strategy = 'html', $charset = null, $autoescape = false)
|
||||
{
|
||||
|
@ -945,7 +981,7 @@ function twig_escape_filter(Twig_Environment $env, $string, $strategy = 'html',
|
|||
static $htmlspecialcharsCharsets;
|
||||
|
||||
if (null === $htmlspecialcharsCharsets) {
|
||||
if ('hiphop' === substr(PHP_VERSION, -6)) {
|
||||
if (defined('HHVM_VERSION')) {
|
||||
$htmlspecialcharsCharsets = array('utf-8' => true, 'UTF-8' => true);
|
||||
} else {
|
||||
$htmlspecialcharsCharsets = array(
|
||||
|
@ -1192,7 +1228,7 @@ if (function_exists('mb_get_info')) {
|
|||
* @param Twig_Environment $env A Twig_Environment instance
|
||||
* @param mixed $thing A variable
|
||||
*
|
||||
* @return integer The length of the value
|
||||
* @return int The length of the value
|
||||
*/
|
||||
function twig_length_filter(Twig_Environment $env, $thing)
|
||||
{
|
||||
|
@ -1276,7 +1312,7 @@ else {
|
|||
* @param Twig_Environment $env A Twig_Environment instance
|
||||
* @param mixed $thing A variable
|
||||
*
|
||||
* @return integer The length of the value
|
||||
* @return int The length of the value
|
||||
*/
|
||||
function twig_length_filter(Twig_Environment $env, $thing)
|
||||
{
|
||||
|
@ -1332,7 +1368,7 @@ function twig_ensure_traversable($seq)
|
|||
*
|
||||
* @param mixed $value A variable
|
||||
*
|
||||
* @return Boolean true if the value is empty, false otherwise
|
||||
* @return bool true if the value is empty, false otherwise
|
||||
*/
|
||||
function twig_test_empty($value)
|
||||
{
|
||||
|
@ -1355,7 +1391,7 @@ function twig_test_empty($value)
|
|||
*
|
||||
* @param mixed $value A variable
|
||||
*
|
||||
* @return Boolean true if the value is traversable
|
||||
* @return bool true if the value is traversable
|
||||
*/
|
||||
function twig_test_iterable($value)
|
||||
{
|
||||
|
@ -1367,9 +1403,9 @@ function twig_test_iterable($value)
|
|||
*
|
||||
* @param string|array $template The template to render or an array of templates to try consecutively
|
||||
* @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
|
||||
* @param bool $with_context Whether to pass the current context variables or not
|
||||
* @param bool $ignore_missing Whether to ignore missing templates or not
|
||||
* @param bool $sandboxed Whether to sandbox the template or not
|
||||
*
|
||||
* @return string The rendered template
|
||||
*/
|
||||
|
@ -1434,7 +1470,7 @@ function twig_constant($constant, $object = null)
|
|||
* Batches item.
|
||||
*
|
||||
* @param array $items An array of items
|
||||
* @param integer $size The size of the batch
|
||||
* @param int $size The size of the batch
|
||||
* @param mixed $fill A value used to fill missing items
|
||||
*
|
||||
* @return array
|
||||
|
|
|
@ -93,7 +93,7 @@ class Twig_Extension_Sandbox extends Twig_Extension
|
|||
|
||||
public function ensureToStringAllowed($obj)
|
||||
{
|
||||
if (is_object($obj)) {
|
||||
if ($this->isSandboxed() && is_object($obj)) {
|
||||
$this->policy->checkMethodAllowed($obj, '__toString');
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
* Interface implemented by lexer classes.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @deprecated since 1.12 (to be removed in 2.0)
|
||||
*
|
||||
* @deprecated since 1.12 (to be removed in 3.0)
|
||||
*/
|
||||
interface Twig_LexerInterface
|
||||
{
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
* 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.
|
||||
*
|
||||
* This loader should only be used for unit testing.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
*/
|
||||
class Twig_Loader_Array implements Twig_LoaderInterface, Twig_ExistsLoaderInterface
|
||||
|
|
|
@ -176,16 +176,7 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
|
|||
|
||||
$this->validateName($name);
|
||||
|
||||
$namespace = self::MAIN_NAMESPACE;
|
||||
$shortname = $name;
|
||||
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);
|
||||
$shortname = substr($name, $pos + 1);
|
||||
}
|
||||
list($namespace, $shortname) = $this->parseName($name);
|
||||
|
||||
if (!isset($this->paths[$namespace])) {
|
||||
throw new Twig_Error_Loader(sprintf('There are no registered paths for namespace "%s".', $namespace));
|
||||
|
@ -200,6 +191,22 @@ class Twig_Loader_Filesystem implements Twig_LoaderInterface, Twig_ExistsLoaderI
|
|||
throw new Twig_Error_Loader(sprintf('Unable to find template "%s" (looked into: %s).', $name, implode(', ', $this->paths[$namespace])));
|
||||
}
|
||||
|
||||
protected function parseName($name, $default = self::MAIN_NAMESPACE)
|
||||
{
|
||||
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);
|
||||
$shortname = substr($name, $pos + 1);
|
||||
|
||||
return array($namespace, $shortname);
|
||||
}
|
||||
|
||||
return array($default, $name);
|
||||
}
|
||||
|
||||
protected function normalizeName($name)
|
||||
{
|
||||
return preg_replace('#/{2,}#', '/', strtr((string) $name, '\\', '/'));
|
||||
|
|
|
@ -12,9 +12,7 @@
|
|||
/**
|
||||
* 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).
|
||||
* This loader should NEVER be used. It only exists for Twig internal purposes.
|
||||
*
|
||||
* 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
|
||||
|
|
|
@ -44,7 +44,7 @@ interface Twig_LoaderInterface
|
|||
* @param string $name The template name
|
||||
* @param timestamp $time The last modification time of the cached template
|
||||
*
|
||||
* @return Boolean true if the template is fresh, false otherwise
|
||||
* @return bool true if the template is fresh, false otherwise
|
||||
*
|
||||
* @throws Twig_Error_Loader When $name is not found
|
||||
*/
|
||||
|
|
|
@ -30,7 +30,7 @@ class Twig_Node implements Twig_NodeInterface
|
|||
*
|
||||
* @param array $nodes An array of named nodes
|
||||
* @param array $attributes An array of attributes (should not be nodes)
|
||||
* @param integer $lineno The line number
|
||||
* @param int $lineno The line number
|
||||
* @param string $tag The tag name associated with the Node
|
||||
*/
|
||||
public function __construct(array $nodes = array(), array $attributes = array(), $lineno = 0, $tag = null)
|
||||
|
@ -69,6 +69,9 @@ class Twig_Node implements Twig_NodeInterface
|
|||
return implode("\n", $repr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since 1.16.1 (to be removed in 2.0)
|
||||
*/
|
||||
public function toXml($asDom = false)
|
||||
{
|
||||
$dom = new DOMDocument('1.0', 'UTF-8');
|
||||
|
@ -121,7 +124,7 @@ class Twig_Node implements Twig_NodeInterface
|
|||
*
|
||||
* @param string The attribute name
|
||||
*
|
||||
* @return Boolean true if the attribute is defined, false otherwise
|
||||
* @return bool true if the attribute is defined, false otherwise
|
||||
*/
|
||||
public function hasAttribute($name)
|
||||
{
|
||||
|
@ -170,7 +173,7 @@ class Twig_Node implements Twig_NodeInterface
|
|||
*
|
||||
* @param string The node name
|
||||
*
|
||||
* @return Boolean true if the node with the given name exists, false otherwise
|
||||
* @return bool true if the node with the given name exists, false otherwise
|
||||
*/
|
||||
public function hasNode($name)
|
||||
{
|
||||
|
|
|
@ -30,7 +30,7 @@ class Twig_Node_AutoEscape extends Twig_Node
|
|||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
|
|
|
@ -25,7 +25,7 @@ class Twig_Node_Block extends Twig_Node
|
|||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
|
|
|
@ -25,7 +25,7 @@ class Twig_Node_BlockReference extends Twig_Node implements Twig_NodeOutputInter
|
|||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
|
|
|
@ -24,7 +24,7 @@ class Twig_Node_Do extends Twig_Node
|
|||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
|
|
|
@ -63,7 +63,7 @@ class Twig_Node_Expression_Array extends Twig_Node_Expression
|
|||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
|
|
|
@ -15,7 +15,7 @@ class Twig_Node_Expression_AssignName extends Twig_Node_Expression_Name
|
|||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
|
|
|
@ -19,7 +19,7 @@ abstract class Twig_Node_Expression_Binary extends Twig_Node_Expression
|
|||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
|
|
|
@ -12,14 +12,14 @@ class Twig_Node_Expression_Binary_EndsWith extends Twig_Node_Expression_Binary
|
|||
{
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$left = $compiler->getVarName();
|
||||
$right = $compiler->getVarName();
|
||||
$compiler
|
||||
->raw('(0 === substr_compare(')
|
||||
->raw(sprintf('(is_string($%s = ', $left))
|
||||
->subcompile($this->getNode('left'))
|
||||
->raw(', ')
|
||||
->raw(sprintf(') && is_string($%s = ', $right))
|
||||
->subcompile($this->getNode('right'))
|
||||
->raw(', -strlen(')
|
||||
->subcompile($this->getNode('right'))
|
||||
->raw(')))')
|
||||
->raw(sprintf(') && (\'\' === $%2$s || $%2$s === substr($%1$s, -strlen($%2$s))))', $left, $right))
|
||||
;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ class Twig_Node_Expression_Binary_FloorDiv extends Twig_Node_Expression_Binary
|
|||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
|
|
|
@ -13,7 +13,7 @@ class Twig_Node_Expression_Binary_In extends Twig_Node_Expression_Binary
|
|||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
|
|
|
@ -13,7 +13,7 @@ class Twig_Node_Expression_Binary_NotIn extends Twig_Node_Expression_Binary
|
|||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
|
|
|
@ -13,7 +13,7 @@ class Twig_Node_Expression_Binary_Power extends Twig_Node_Expression_Binary
|
|||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
|
|
|
@ -13,7 +13,7 @@ class Twig_Node_Expression_Binary_Range extends Twig_Node_Expression_Binary
|
|||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
|
|
|
@ -12,12 +12,14 @@ class Twig_Node_Expression_Binary_StartsWith extends Twig_Node_Expression_Binary
|
|||
{
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
$left = $compiler->getVarName();
|
||||
$right = $compiler->getVarName();
|
||||
$compiler
|
||||
->raw('(0 === strpos(')
|
||||
->raw(sprintf('(is_string($%s = ', $left))
|
||||
->subcompile($this->getNode('left'))
|
||||
->raw(', ')
|
||||
->raw(sprintf(') && is_string($%s = ', $right))
|
||||
->subcompile($this->getNode('right'))
|
||||
->raw('))')
|
||||
->raw(sprintf(') && (\'\' === $%2$s || 0 === strpos($%1$s, $%2$s)))', $left, $right))
|
||||
;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ class Twig_Node_Expression_BlockReference extends Twig_Node_Expression
|
|||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
|
|
|
@ -12,10 +12,8 @@ abstract class Twig_Node_Expression_Call extends Twig_Node_Expression
|
|||
{
|
||||
protected function compileCallable(Twig_Compiler $compiler)
|
||||
{
|
||||
$callable = $this->getAttribute('callable');
|
||||
|
||||
$closingParenthesis = false;
|
||||
if ($callable) {
|
||||
if ($this->hasAttribute('callable') && $callable = $this->getAttribute('callable')) {
|
||||
if (is_string($callable)) {
|
||||
$compiler->raw($callable);
|
||||
} elseif (is_array($callable) && $callable[0] instanceof Twig_ExtensionInterface) {
|
||||
|
|
|
@ -24,7 +24,7 @@ class Twig_Node_Expression_ExtensionReference extends Twig_Node_Expression
|
|||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
*/
|
||||
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)
|
||||
public function __construct(Twig_Node_Expression $node, Twig_Node_Expression $attribute, Twig_Node_Expression $arguments = null, $type, $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);
|
||||
}
|
||||
|
@ -32,20 +32,30 @@ class Twig_Node_Expression_GetAttr extends Twig_Node_Expression
|
|||
|
||||
$compiler->raw(', ')->subcompile($this->getNode('attribute'));
|
||||
|
||||
if (count($this->getNode('arguments')) || Twig_Template::ANY_CALL !== $this->getAttribute('type') || $this->getAttribute('is_defined_test') || $this->getAttribute('ignore_strict_check')) {
|
||||
$compiler->raw(', ')->subcompile($this->getNode('arguments'));
|
||||
// only generate optional arguments when needed (to make generated code more readable)
|
||||
$needFourth = $this->getAttribute('ignore_strict_check');
|
||||
$needThird = $needFourth || $this->getAttribute('is_defined_test');
|
||||
$needSecond = $needThird || Twig_Template::ANY_CALL !== $this->getAttribute('type');
|
||||
$needFirst = $needSecond || null !== $this->getNode('arguments');
|
||||
|
||||
if (Twig_Template::ANY_CALL !== $this->getAttribute('type') || $this->getAttribute('is_defined_test') || $this->getAttribute('ignore_strict_check')) {
|
||||
$compiler->raw(', ')->repr($this->getAttribute('type'));
|
||||
if ($needFirst) {
|
||||
if (null !== $this->getNode('arguments')) {
|
||||
$compiler->raw(', ')->subcompile($this->getNode('arguments'));
|
||||
} else {
|
||||
$compiler->raw(', array()');
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->getAttribute('is_defined_test') || $this->getAttribute('ignore_strict_check')) {
|
||||
$compiler->raw(', '.($this->getAttribute('is_defined_test') ? 'true' : 'false'));
|
||||
}
|
||||
if ($needSecond) {
|
||||
$compiler->raw(', ')->repr($this->getAttribute('type'));
|
||||
}
|
||||
|
||||
if ($this->getAttribute('ignore_strict_check')) {
|
||||
$compiler->raw(', '.($this->getAttribute('ignore_strict_check') ? 'true' : 'false'));
|
||||
}
|
||||
if ($needThird) {
|
||||
$compiler->raw(', ')->repr($this->getAttribute('is_defined_test'));
|
||||
}
|
||||
|
||||
if ($needFourth) {
|
||||
$compiler->raw(', ')->repr($this->getAttribute('ignore_strict_check'));
|
||||
}
|
||||
|
||||
$compiler->raw(')');
|
||||
|
|
|
@ -25,7 +25,7 @@ class Twig_Node_Expression_Parent extends Twig_Node_Expression
|
|||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
* Checks if a variable is divisible by a number.
|
||||
*
|
||||
* <pre>
|
||||
* {% if loop.index is divisibleby(3) %}
|
||||
* {% if loop.index is divisible by(3) %}
|
||||
* </pre>
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
|
|
|
@ -24,7 +24,7 @@ class Twig_Node_Flush extends Twig_Node
|
|||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
|
|
|
@ -33,7 +33,7 @@ class Twig_Node_For extends Twig_Node
|
|||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
|
|
|
@ -24,7 +24,7 @@ class Twig_Node_ForLoop extends Twig_Node
|
|||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
|
|
|
@ -25,7 +25,7 @@ class Twig_Node_If extends Twig_Node
|
|||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
|
|
|
@ -24,7 +24,7 @@ class Twig_Node_Import extends Twig_Node
|
|||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
|
|
|
@ -19,13 +19,13 @@ class Twig_Node_Include extends Twig_Node implements Twig_NodeOutputInterface
|
|||
{
|
||||
public function __construct(Twig_Node_Expression $expr, Twig_Node_Expression $variables = null, $only = false, $ignoreMissing = false, $lineno, $tag = null)
|
||||
{
|
||||
parent::__construct(array('expr' => $expr, 'variables' => $variables), array('only' => (Boolean) $only, 'ignore_missing' => (Boolean) $ignoreMissing), $lineno, $tag);
|
||||
parent::__construct(array('expr' => $expr, 'variables' => $variables), array('only' => (bool) $only, 'ignore_missing' => (bool) $ignoreMissing), $lineno, $tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
|
@ -60,40 +60,26 @@ class Twig_Node_Include extends Twig_Node implements Twig_NodeOutputInterface
|
|||
|
||||
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(")")
|
||||
;
|
||||
} else {
|
||||
$compiler
|
||||
->write("\$template = \$this->env->resolveTemplate(")
|
||||
->subcompile($this->getNode('expr'))
|
||||
->raw(");\n")
|
||||
->write('$template')
|
||||
;
|
||||
}
|
||||
$method = $this->getNode('expr') instanceof Twig_Node_Expression_Constant ? 'loadTemplate' : 'resolveTemplate';
|
||||
$compiler
|
||||
->write(sprintf('$this->env->%s(', $method))
|
||||
->subcompile($this->getNode('expr'))
|
||||
->raw(')')
|
||||
;
|
||||
}
|
||||
|
||||
protected function addTemplateArguments(Twig_Compiler $compiler)
|
||||
{
|
||||
if (false === $this->getAttribute('only')) {
|
||||
if (null === $this->getNode('variables')) {
|
||||
$compiler->raw('$context');
|
||||
} else {
|
||||
$compiler
|
||||
->raw('array_merge($context, ')
|
||||
->subcompile($this->getNode('variables'))
|
||||
->raw(')')
|
||||
;
|
||||
}
|
||||
if (null === $this->getNode('variables')) {
|
||||
$compiler->raw(false === $this->getAttribute('only') ? '$context' : 'array()');
|
||||
} elseif (false === $this->getAttribute('only')) {
|
||||
$compiler
|
||||
->raw('array_merge($context, ')
|
||||
->subcompile($this->getNode('variables'))
|
||||
->raw(')')
|
||||
;
|
||||
} else {
|
||||
if (null === $this->getNode('variables')) {
|
||||
$compiler->raw('array()');
|
||||
} else {
|
||||
$compiler->subcompile($this->getNode('variables'));
|
||||
}
|
||||
$compiler->subcompile($this->getNode('variables'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ class Twig_Node_Macro extends Twig_Node
|
|||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
|
@ -37,7 +37,7 @@ class Twig_Node_Macro extends Twig_Node
|
|||
$pos = 0;
|
||||
foreach ($this->getNode('arguments') as $name => $default) {
|
||||
$compiler
|
||||
->raw('$_'.$name.' = ')
|
||||
->raw('$__'.$name.'__ = ')
|
||||
->subcompile($default)
|
||||
;
|
||||
|
||||
|
@ -64,7 +64,7 @@ class Twig_Node_Macro extends Twig_Node
|
|||
$compiler
|
||||
->write('')
|
||||
->string($name)
|
||||
->raw(' => $_'.$name)
|
||||
->raw(' => $__'.$name.'__')
|
||||
->raw(",\n")
|
||||
;
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ class Twig_Node_Module extends Twig_Node
|
|||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
|
|
|
@ -25,7 +25,7 @@ class Twig_Node_Print extends Twig_Node implements Twig_NodeOutputInterface
|
|||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
|
|
|
@ -24,7 +24,7 @@ class Twig_Node_Sandbox extends Twig_Node
|
|||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
|
|
|
@ -23,7 +23,7 @@ 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('embedded_templates'), $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'));
|
||||
|
||||
$this->setAttribute('index', $node->getAttribute('index'));
|
||||
|
||||
|
@ -43,17 +43,53 @@ class Twig_Node_SandboxedModule extends Twig_Node_Module
|
|||
{
|
||||
parent::compileDisplayFooter($compiler);
|
||||
|
||||
$tags = $filters = $functions = array();
|
||||
foreach (array('tags', 'filters', 'functions') as $type) {
|
||||
foreach ($this->{'used'.ucfirst($type)} as $name => $node) {
|
||||
if ($node instanceof Twig_Node) {
|
||||
${$type}[$name] = $node->getLine();
|
||||
} else {
|
||||
${$type}[$node] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$compiler
|
||||
->write("protected function checkSecurity()\n", "{\n")
|
||||
->indent()
|
||||
->write("\$tags = ")->repr(array_filter($tags))->raw(";\n")
|
||||
->write("\$filters = ")->repr(array_filter($filters))->raw(";\n")
|
||||
->write("\$functions = ")->repr(array_filter($functions))->raw(";\n\n")
|
||||
->write("try {\n")
|
||||
->indent()
|
||||
->write("\$this->env->getExtension('sandbox')->checkSecurity(\n")
|
||||
->indent()
|
||||
->write(!$this->usedTags ? "array(),\n" : "array('".implode('\', \'', $this->usedTags)."'),\n")
|
||||
->write(!$this->usedFilters ? "array(),\n" : "array('".implode('\', \'', $this->usedFilters)."'),\n")
|
||||
->write(!$this->usedFunctions ? "array()\n" : "array('".implode('\', \'', $this->usedFunctions)."')\n")
|
||||
->write(!$tags ? "array(),\n" : "array('".implode("', '", array_keys($tags))."'),\n")
|
||||
->write(!$filters ? "array(),\n" : "array('".implode("', '", array_keys($filters))."'),\n")
|
||||
->write(!$functions ? "array()\n" : "array('".implode("', '", array_keys($functions))."')\n")
|
||||
->outdent()
|
||||
->write(");\n")
|
||||
->outdent()
|
||||
->write("} catch (Twig_Sandbox_SecurityError \$e) {\n")
|
||||
->indent()
|
||||
->write("\$e->setTemplateFile(\$this->getTemplateName());\n\n")
|
||||
->write("if (\$e instanceof Twig_Sandbox_SecurityNotAllowedTagError && isset(\$tags[\$e->getTagName()])) {\n")
|
||||
->indent()
|
||||
->write("\$e->setTemplateLine(\$tags[\$e->getTagName()]);\n")
|
||||
->outdent()
|
||||
->write("} elseif (\$e instanceof Twig_Sandbox_SecurityNotAllowedFilterError && isset(\$filters[\$e->getFilterName()])) {\n")
|
||||
->indent()
|
||||
->write("\$e->setTemplateLine(\$filters[\$e->getFilterName()]);\n")
|
||||
->outdent()
|
||||
->write("} elseif (\$e instanceof Twig_Sandbox_SecurityNotAllowedFunctionError && isset(\$functions[\$e->getFunctionName()])) {\n")
|
||||
->indent()
|
||||
->write("\$e->setTemplateLine(\$functions[\$e->getFunctionName()]);\n")
|
||||
->outdent()
|
||||
->write("}\n\n")
|
||||
->write("throw \$e;\n")
|
||||
->outdent()
|
||||
->write("}\n")
|
||||
->outdent()
|
||||
->write("}\n\n")
|
||||
;
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ class Twig_Node_SandboxedPrint extends Twig_Node_Print
|
|||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
|
|
|
@ -39,7 +39,7 @@ class Twig_Node_Set extends Twig_Node
|
|||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
|
|
|
@ -26,7 +26,7 @@ class Twig_Node_Spaceless extends Twig_Node
|
|||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
|
|
|
@ -25,7 +25,7 @@ class Twig_Node_Text extends Twig_Node implements Twig_NodeOutputInterface
|
|||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler)
|
||||
{
|
||||
|
|
|
@ -13,14 +13,15 @@
|
|||
* Represents a node in the AST.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @deprecated since 1.12 (to be removed in 2.0)
|
||||
*
|
||||
* @deprecated since 1.12 (to be removed in 3.0)
|
||||
*/
|
||||
interface Twig_NodeInterface extends Countable, IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
*
|
||||
* @param Twig_Compiler A Twig_Compiler instance
|
||||
* @param Twig_Compiler $compiler A Twig_Compiler instance
|
||||
*/
|
||||
public function compile(Twig_Compiler $compiler);
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ class Twig_NodeTraverser
|
|||
protected function traverseForVisitor(Twig_NodeVisitorInterface $visitor, Twig_NodeInterface $node = null)
|
||||
{
|
||||
if (null === $node) {
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
|
||||
$node = $visitor->enterNode($node, $this->env);
|
||||
|
|
|
@ -28,6 +28,7 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface
|
|||
const OPTIMIZE_VAR_ACCESS = 8;
|
||||
|
||||
protected $loops = array();
|
||||
protected $loopsTargets = array();
|
||||
protected $optimizers;
|
||||
protected $prependedNodes = array();
|
||||
protected $inABody = false;
|
||||
|
@ -35,7 +36,7 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface
|
|||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param integer $optimizers The optimizer mode
|
||||
* @param int $optimizers The optimizer mode
|
||||
*/
|
||||
public function __construct($optimizers = -1)
|
||||
{
|
||||
|
@ -174,6 +175,8 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface
|
|||
// disable the loop variable by default
|
||||
$node->setAttribute('with_loop', false);
|
||||
array_unshift($this->loops, $node);
|
||||
array_unshift($this->loopsTargets, $node->getNode('value_target')->getAttribute('name'));
|
||||
array_unshift($this->loopsTargets, $node->getNode('key_target')->getAttribute('name'));
|
||||
} elseif (!$this->loops) {
|
||||
// we are outside a loop
|
||||
return;
|
||||
|
@ -183,9 +186,15 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface
|
|||
|
||||
// the loop variable is referenced for the current loop
|
||||
elseif ($node instanceof Twig_Node_Expression_Name && 'loop' === $node->getAttribute('name')) {
|
||||
$node->setAttribute('always_defined', true);
|
||||
$this->addLoopToCurrent();
|
||||
}
|
||||
|
||||
// optimize access to loop targets
|
||||
elseif ($node instanceof Twig_Node_Expression_Name && in_array($node->getAttribute('name'), $this->loopsTargets)) {
|
||||
$node->setAttribute('always_defined', true);
|
||||
}
|
||||
|
||||
// block reference
|
||||
elseif ($node instanceof Twig_Node_BlockReference || $node instanceof Twig_Node_Expression_BlockReference) {
|
||||
$this->addLoopToCurrent();
|
||||
|
@ -221,6 +230,8 @@ class Twig_NodeVisitor_Optimizer implements Twig_NodeVisitorInterface
|
|||
{
|
||||
if ($node instanceof Twig_Node_For) {
|
||||
array_shift($this->loops);
|
||||
array_shift($this->loopsTargets);
|
||||
array_shift($this->loopsTargets);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,18 +40,18 @@ class Twig_NodeVisitor_Sandbox implements Twig_NodeVisitorInterface
|
|||
return $node;
|
||||
} elseif ($this->inAModule) {
|
||||
// look for tags
|
||||
if ($node->getNodeTag()) {
|
||||
$this->tags[] = $node->getNodeTag();
|
||||
if ($node->getNodeTag() && !isset($this->tags[$node->getNodeTag()])) {
|
||||
$this->tags[$node->getNodeTag()] = $node;
|
||||
}
|
||||
|
||||
// look for filters
|
||||
if ($node instanceof Twig_Node_Expression_Filter) {
|
||||
$this->filters[] = $node->getNode('filter')->getAttribute('value');
|
||||
if ($node instanceof Twig_Node_Expression_Filter && !isset($this->filters[$node->getNode('filter')->getAttribute('value')])) {
|
||||
$this->filters[$node->getNode('filter')->getAttribute('value')] = $node;
|
||||
}
|
||||
|
||||
// look for functions
|
||||
if ($node instanceof Twig_Node_Expression_Function) {
|
||||
$this->functions[] = $node->getAttribute('name');
|
||||
if ($node instanceof Twig_Node_Expression_Function && !isset($this->functions[$node->getAttribute('name')])) {
|
||||
$this->functions[$node->getAttribute('name')] = $node;
|
||||
}
|
||||
|
||||
// wrap print to check __toString() calls
|
||||
|
@ -76,7 +76,7 @@ class Twig_NodeVisitor_Sandbox implements Twig_NodeVisitorInterface
|
|||
if ($node instanceof Twig_Node_Module) {
|
||||
$this->inAModule = false;
|
||||
|
||||
return new Twig_Node_SandboxedModule($node, array_unique($this->filters), array_unique($this->tags), array_unique($this->functions));
|
||||
return new Twig_Node_SandboxedModule($node, $this->filters, $this->tags, $this->functions);
|
||||
}
|
||||
|
||||
return $node;
|
||||
|
|
|
@ -41,7 +41,7 @@ interface Twig_NodeVisitorInterface
|
|||
*
|
||||
* Priority should be between -10 and 10 (0 is the default).
|
||||
*
|
||||
* @return integer The priority level
|
||||
* @return int The priority level
|
||||
*/
|
||||
public function getPriority();
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue