mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-13 19:06:40 +00:00
Merge branch '1.x' into 2.x
* 1.x: Update .travis.yml Fix possible array to string conversion concealing actual error Make variable names deterministic Be able to count on iterator made it clear that placeholders are free-forms for the replace filter contents -> content
This commit is contained in:
@@ -11,6 +11,7 @@ matrix:
|
||||
include:
|
||||
- php: 7.0
|
||||
- php: 7.1
|
||||
- php: 7.2
|
||||
- php: nightly
|
||||
fast_finish: true
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@ return value of the ``count()`` method.
|
||||
For objects that implement the ``__toString()`` magic method (and not ``Countable``),
|
||||
it will return the length of the string provided by that method.
|
||||
|
||||
For objects that implement the ``IteratorAggregate`` interface, ``length`` will use the return value of the ``iterator_count()`` method.
|
||||
|
||||
.. code-block:: jinja
|
||||
|
||||
{% if users|length > 10 %}
|
||||
|
||||
@@ -11,6 +11,12 @@ The ``replace`` filter formats a given string by replacing the placeholders
|
||||
{# outputs I like foo and bar
|
||||
if the foo parameter equals to the foo string. #}
|
||||
|
||||
{# using % as a delimiter is purely conventional and optional #}
|
||||
|
||||
{{ "I like this and --that--."|replace({'this': foo, '--that--': "bar"}) }}
|
||||
|
||||
{# outputs I like foo and bar #}
|
||||
|
||||
Arguments
|
||||
---------
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ class Twig_Compiler
|
||||
private $debugInfo = array();
|
||||
private $sourceOffset;
|
||||
private $sourceLine;
|
||||
private $varNameSalt = 0;
|
||||
|
||||
public function __construct(Twig_Environment $env)
|
||||
{
|
||||
@@ -67,6 +68,7 @@ class Twig_Compiler
|
||||
// source code starts at 1 (as we then increment it when we encounter new lines)
|
||||
$this->sourceLine = 1;
|
||||
$this->indentation = $indentation;
|
||||
$this->varNameSalt = 0;
|
||||
|
||||
$node->compile($this);
|
||||
|
||||
@@ -233,7 +235,7 @@ class Twig_Compiler
|
||||
|
||||
public function getVarName()
|
||||
{
|
||||
return sprintf('__internal_%s', hash('sha256', uniqid(mt_rand(), true), false));
|
||||
return sprintf('__internal_%s', hash('sha256', __METHOD__.$this->varNameSalt++));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1152,6 +1152,10 @@ function twig_length_filter(Twig_Environment $env, $thing)
|
||||
return count($thing);
|
||||
}
|
||||
|
||||
if ($thing instanceof \IteratorAggregate) {
|
||||
return iterator_count($thing);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1490,6 +1494,8 @@ function twig_get_attribute(Twig_Environment $env, Twig_Source $source, $object,
|
||||
|
||||
if (null === $object) {
|
||||
$message = sprintf('Impossible to invoke a method ("%s") on a null variable.', $item);
|
||||
} elseif (is_array($object)) {
|
||||
$message = sprintf('Impossible to invoke a method ("%s") on an array.', $item);
|
||||
} else {
|
||||
$message = sprintf('Impossible to invoke a method ("%s") on a %s variable ("%s").', $item, gettype($object), $object);
|
||||
}
|
||||
|
||||
+4
-2
@@ -30,6 +30,7 @@ class Twig_Parser
|
||||
private $importedSymbols;
|
||||
private $traits;
|
||||
private $embeddedTemplates = array();
|
||||
private $varNameSalt = 0;
|
||||
|
||||
public function __construct(Twig_Environment $env)
|
||||
{
|
||||
@@ -38,7 +39,7 @@ class Twig_Parser
|
||||
|
||||
public function getVarName()
|
||||
{
|
||||
return sprintf('__internal_%s', hash('sha256', uniqid(mt_rand(), true), false));
|
||||
return sprintf('__internal_%s', hash('sha256', __METHOD__.$this->varNameSalt++));
|
||||
}
|
||||
|
||||
public function parse(Twig_TokenStream $stream, $test = null, $dropNeedle = false)
|
||||
@@ -74,6 +75,7 @@ class Twig_Parser
|
||||
$this->blockStack = array();
|
||||
$this->importedSymbols = array(array());
|
||||
$this->embeddedTemplates = array();
|
||||
$this->varNameSalt = 0;
|
||||
|
||||
try {
|
||||
$body = $this->subparse($test, $dropNeedle);
|
||||
@@ -323,7 +325,7 @@ class Twig_Parser
|
||||
throw new Twig_Error_Syntax('A template that extends another one cannot start with a byte order mark (BOM); it must be removed.', $node->getTemplateLine(), $this->stream->getSourceContext());
|
||||
}
|
||||
|
||||
throw new Twig_Error_Syntax('A template that extends another one cannot include contents outside Twig blocks. Did you forget to put the contents inside a {% block %} tag?', $node->getTemplateLine(), $this->stream->getSourceContext());
|
||||
throw new Twig_Error_Syntax('A template that extends another one cannot include content outside Twig blocks. Did you forget to put the content inside a {% block %} tag?', $node->getTemplateLine(), $this->stream->getSourceContext());
|
||||
}
|
||||
|
||||
// bypass nodes that will "capture" the output
|
||||
|
||||
@@ -53,7 +53,7 @@ final class Twig_Profiler_NodeVisitor_Profiler extends Twig_BaseNodeVisitor
|
||||
|
||||
private function getVarName()
|
||||
{
|
||||
return sprintf('__internal_%s', hash('sha256', uniqid(mt_rand(), true), false));
|
||||
return sprintf('__internal_%s', hash('sha256', __METHOD__));
|
||||
}
|
||||
|
||||
public function getPriority()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
--TEST--
|
||||
Exception for child templates defining contents outside blocks defined by parent
|
||||
Exception for child templates defining content outside blocks defined by parent
|
||||
--TEMPLATE--
|
||||
{% extends 'base.twig' %}
|
||||
|
||||
@@ -12,4 +12,4 @@ Content outside a block.
|
||||
{% block sidebar %}
|
||||
{% endblock %}
|
||||
--EXCEPTION--
|
||||
Twig_Error_Syntax: A template that extends another one cannot include contents outside Twig blocks. Did you forget to put the contents inside a {% block %} tag in "index.twig" at line 3?
|
||||
Twig_Error_Syntax: A template that extends another one cannot include content outside Twig blocks. Did you forget to put the content inside a {% block %} tag in "index.twig" at line 3?
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
{{ number|length }}
|
||||
{{ to_string_able|length }}
|
||||
{{ countable|length }}
|
||||
{{ iterator_aggregate|length }}
|
||||
{{ null|length }}
|
||||
{{ magic|length }}
|
||||
{{ non_countable|length }}
|
||||
@@ -16,6 +17,7 @@ return array(
|
||||
'number' => 1000,
|
||||
'to_string_able' => new ToStringStub('foobar'),
|
||||
'countable' => new CountableStub(42), /* also asserts we do *not* call __toString() */
|
||||
'iterator_aggregate' => new IteratorAggregateStub(array('a', 'b', 'c')), /* also asserts we do *not* call __toString() */
|
||||
'null' => null,
|
||||
'magic' => new MagicCallStub(), /* used to assert we do *not* call __call */
|
||||
'non_countable' => new \StdClass(),
|
||||
@@ -26,6 +28,7 @@ return array(
|
||||
4
|
||||
6
|
||||
42
|
||||
3
|
||||
0
|
||||
1
|
||||
1
|
||||
|
||||
@@ -309,3 +309,21 @@ class CountableStub implements \Countable
|
||||
throw new Exception('__toString shall not be called on \Countables');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This class is used in tests for the length filter
|
||||
*/
|
||||
class IteratorAggregateStub implements \IteratorAggregate
|
||||
{
|
||||
private $data;
|
||||
|
||||
public function __construct(array $data)
|
||||
{
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
public function getIterator()
|
||||
{
|
||||
return new ArrayIterator($this->data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@ class Twig_Tests_TemplateTest extends \PHPUnit\Framework\TestCase
|
||||
array('{{ string.a() }}', 'Impossible to invoke a method ("a") on a string variable ("foo") in "%s" at line 1.'),
|
||||
array('{{ null.a }}', 'Impossible to access an attribute ("a") on a null variable in "%s" at line 1.'),
|
||||
array('{{ null.a() }}', 'Impossible to invoke a method ("a") on a null variable in "%s" at line 1.'),
|
||||
array('{{ array.a() }}', 'Impossible to invoke a method ("a") on an array in "%s" at line 1.'),
|
||||
array('{{ empty_array.a }}', 'Key "a" does not exist as the array is empty in "%s" at line 1.'),
|
||||
array('{{ array.a }}', 'Key "a" for array with keys "foo" does not exist in "%s" at line 1.'),
|
||||
array('{{ attribute(array, -10) }}', 'Key "-10" for array with keys "foo" does not exist in "%s" at line 1.'),
|
||||
|
||||
Reference in New Issue
Block a user