mirror of
https://github.com/twigphp/Twig.git
synced 2026-08-28 19:17:37 +00:00
Add "some" and "every" filters
This commit is contained in:
@@ -80,7 +80,7 @@ class ExpressionParser
|
||||
} elseif (isset($op['callable'])) {
|
||||
$expr = $op['callable']($this->parser, $expr);
|
||||
} else {
|
||||
$expr1 = $this->parseExpression(self::OPERATOR_LEFT === $op['associativity'] ? $op['precedence'] + 1 : $op['precedence']);
|
||||
$expr1 = $this->parseExpression(self::OPERATOR_LEFT === $op['associativity'] ? $op['precedence'] + 1 : $op['precedence'], true);
|
||||
$class = $op['class'];
|
||||
$expr = new $class($expr, $expr1, $token->getLine());
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ use Twig\Node\Expression\Binary\EqualBinary;
|
||||
use Twig\Node\Expression\Binary\FloorDivBinary;
|
||||
use Twig\Node\Expression\Binary\GreaterBinary;
|
||||
use Twig\Node\Expression\Binary\GreaterEqualBinary;
|
||||
use Twig\Node\Expression\Binary\HasEveryBinary;
|
||||
use Twig\Node\Expression\Binary\HasSomeBinary;
|
||||
use Twig\Node\Expression\Binary\InBinary;
|
||||
use Twig\Node\Expression\Binary\LessBinary;
|
||||
use Twig\Node\Expression\Binary\LessEqualBinary;
|
||||
@@ -284,6 +286,8 @@ final class CoreExtension extends AbstractExtension
|
||||
'matches' => ['precedence' => 20, 'class' => MatchesBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT],
|
||||
'starts with' => ['precedence' => 20, 'class' => StartsWithBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT],
|
||||
'ends with' => ['precedence' => 20, 'class' => EndsWithBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT],
|
||||
'has some' => ['precedence' => 20, 'class' => HasSomeBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT],
|
||||
'has every' => ['precedence' => 20, 'class' => HasEveryBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT],
|
||||
'..' => ['precedence' => 25, 'class' => RangeBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT],
|
||||
'+' => ['precedence' => 30, 'class' => AddBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT],
|
||||
'-' => ['precedence' => 30, 'class' => SubBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT],
|
||||
@@ -1678,6 +1682,32 @@ function twig_array_reduce(Environment $env, $array, $arrow, $initial = null)
|
||||
return array_reduce($array, $arrow, $initial);
|
||||
}
|
||||
|
||||
function twig_array_some(Environment $env, $array, $arrow)
|
||||
{
|
||||
twig_check_arrow_in_sandbox($env, $arrow, 'some', 'filter');
|
||||
|
||||
foreach ($array as $k => $v) {
|
||||
if ($arrow($v, $k)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function twig_array_every(Environment $env, $array, $arrow)
|
||||
{
|
||||
twig_check_arrow_in_sandbox($env, $arrow, 'every', 'filter');
|
||||
|
||||
foreach ($array as $k => $v) {
|
||||
if (!$arrow($v, $k)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function twig_check_arrow_in_sandbox(Environment $env, $arrow, $thing, $type)
|
||||
{
|
||||
if (!$arrow instanceof Closure && $env->hasExtension('\Twig\Extension\SandboxExtension') && $env->getExtension('\Twig\Extension\SandboxExtension')->isSandboxed()) {
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Twig\Node\Expression\Binary;
|
||||
|
||||
use Twig\Compiler;
|
||||
|
||||
class HasEveryBinary extends AbstractBinary
|
||||
{
|
||||
public function compile(Compiler $compiler): void
|
||||
{
|
||||
$compiler
|
||||
->raw('twig_array_every($this->env, ')
|
||||
->subcompile($this->getNode('left'))
|
||||
->raw(', ')
|
||||
->subcompile($this->getNode('right'))
|
||||
->raw(')')
|
||||
;
|
||||
}
|
||||
|
||||
public function operator(Compiler $compiler): Compiler
|
||||
{
|
||||
return $compiler->raw('');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Twig.
|
||||
*
|
||||
* (c) Fabien Potencier
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Twig\Node\Expression\Binary;
|
||||
|
||||
use Twig\Compiler;
|
||||
|
||||
class HasSomeBinary extends AbstractBinary
|
||||
{
|
||||
public function compile(Compiler $compiler): void
|
||||
{
|
||||
$compiler
|
||||
->raw('twig_array_some($this->env, ')
|
||||
->subcompile($this->getNode('left'))
|
||||
->raw(', ')
|
||||
->subcompile($this->getNode('right'))
|
||||
->raw(')')
|
||||
;
|
||||
}
|
||||
|
||||
public function operator(Compiler $compiler): Compiler
|
||||
{
|
||||
return $compiler->raw('');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
--TEST--
|
||||
Twig supports the "has every" operator
|
||||
--TEMPLATE--
|
||||
{% if [0, 2, 4] has every v => 0 == v % 2 %}Every{% else %}Not every{% endif %} items are even in array
|
||||
{{ ([0, 2, 4] has every v => 0 == v % 2) ? 'Every' : 'Not every' }} items are even in array
|
||||
{{ ({ a: 0, b: 2, c: 4 } has every v => 0 == v % 2) ? 'Every' : 'Not every' }} items are even in object
|
||||
{{ ({ a: 0, b: 2, c: 4 } has every (v, k) => "d" > k)? 'Every' : 'Not every' }} keys are before "d" in object
|
||||
{{ (it has every v => 0 == v % 2) ? 'Every' : 'Not every' }} items are even in iterator
|
||||
{{ ([0, 1, 2] has every v => 0 == v % 2) ? 'Every' : 'Not every' }} items are even in array
|
||||
--DATA--
|
||||
return ['it' => new \ArrayIterator([0, 2, 4])]
|
||||
--EXPECT--
|
||||
Every items are even in array
|
||||
Every items are even in array
|
||||
Every items are even in object
|
||||
Every keys are before "d" in object
|
||||
Every items are even in iterator
|
||||
Not every items are even in array
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
--TEST--
|
||||
Twig supports the "has some" operator
|
||||
--TEMPLATE--
|
||||
{% if [1, 2, 3] has some v => 0 == v % 2 %}At least one{% else %}No{% endif %} item is even in array
|
||||
{{ ([1, 2, 3] has some v => 0 == v % 2) ? 'At least one' : 'No' }} item is even in array
|
||||
{{ ({ a: 1, b: 2, c: 3 } has some v => 0 == v % 2) ? 'At least one' : 'No' }} item is even in object
|
||||
{{ ({ a: 1, b: 2, c: 3 } has some (v, k) => "b" == k)? 'At least one' : 'No' }} key is "b" in object
|
||||
{{ (it has some v => 0 == v % 2) ? 'At least one' : 'No' }} item is even in iterator
|
||||
{{ ([1, 3, 5] has some v => 0 == v % 2) ? 'At least one' : 'No' }} item is even in array
|
||||
--DATA--
|
||||
return ['it' => new \ArrayIterator([1, 2, 3])]
|
||||
--EXPECT--
|
||||
At least one item is even in array
|
||||
At least one item is even in array
|
||||
At least one item is even in object
|
||||
At least one key is "b" in object
|
||||
At least one item is even in iterator
|
||||
No item is even in array
|
||||
|
||||
Reference in New Issue
Block a user