diff --git a/.gitignore b/.gitignore index 103eecf..495edc0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ /.idea /composer.lock -/composer.phar /vendor +.phpunit.result.cache diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a06038..a30ecf4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [3.0.0] - 2020-02- +### Changed +- minimum php version is now 7.2 +### Removed +- `|call` twig filter +- Lambda, all files in `LeonAero\NodeExpression\*` (use original twig lambda) +- `==>`, `;` twig operator + ## [2.1.0] - 2020-02-24 ### Deprecated - `|call` twig filter @@ -34,6 +42,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - `is any` and `is every` twig test - `=>`, `;` twig operator +[3.0.0]: https://github.com/leonaero/twig-lambda/compare/v3.0.0...v2.1.0 [2.1.0]: https://github.com/leonaero/twig-lambda/compare/v2.0.0...v2.1.0 [2.0.0]: https://github.com/leonaero/twig-lambda/compare/v1.1.0...v2.0.0 [1.1.0]: https://github.com/leonaero/twig-lambda/compare/v1.0.0...v1.1.0 diff --git a/README.md b/README.md index 3154a45..a67ee2c 100644 --- a/README.md +++ b/README.md @@ -1,19 +1,26 @@ # Twig Lambda -> Lambda expressions for Twig and filters that make use of them ---------------------------------------------------------------- | Version | Twig Version | Php Version | |---- |----|----| +| ^3.0 | ^3.0 | ^7.2 | | ^2.0 | ^2.10 | ^7.0 | | ^1.0 | ^1.0 || 2.9.* | ^5.6 || ^7.0 | ## Quick examples -Listing names of all authors ordered by age: +Listing names of all authors ordered by youngest: ```twig -{% for author in articles|map(v => v.author)|unique_by('===')|sort_by(v => v.age) %} +{% set articles = [ + {author: {name: 'Bar', age: 55}, text: 'Text...'}, + {author: {name: 'Bar', age: 65}, text: 'Text...'}, + {author: {name: 'Foo', age: 45}, text: 'Text...'}, + {author: {name: 'Foo', age: 45}, text: 'Text...'}, +] %} + +{% for author in articles|map(v => v.author)|unique_by('===')|sort(v => v.age)|reverse %} * {{ author.name }}, {{ author.age }} {% endfor %} ``` @@ -53,46 +60,7 @@ services: ---------------------------------------------------------------- ## Usage - - -### ~~Lambda expression~~ -##### deprecated since 1.1.0 and will be remove in 3.0.0 use original twig lambda -To create lambda expression prepend any valid Twig expression -with `==>` operator. -Inside of the lambda expression you can use -any variable from the outside. There are also two special -variables available: - * `_` (single underscore) - first argument, - * `__` (double underscore) - array of arguments counted - from zero. - -``` -==> _.name -==> _ * 2 -==> _|first -==> 'foobar' -==> _ is even -==> __[0] + __[1] -``` - -To create lambda expression with list of arguments, add it -before `==>` operator. Separate multiple arguments with -semicolons. You can use brackets for readability. - -``` -x ==> x + 1 -(book) ==> book.author -arg1; arg2 ==> arg1 ~ arg2 -(a; b; c) ==> a + b - c -``` - -Note that if you use list of arguments, `_` variable is not -longer available. - ----------------------------------------------------------------- - -Below is a list of available filters and tests. All works -with arrays and any Traversable object and preserve it keys. +Below is a list of available filters. All works with arrays and any Traversable object and preserve it keys. ---------------------------------------------------------------- @@ -199,23 +167,3 @@ Returns true if lambda returns true for every element from an array. {{ [1, 2, 3]|is_every(v => v > 0) ? "All elements in the array are positive." }} {# prints 'All elements in the array are positive.' #} ``` - ----------------------------------------------------------------- - - -### ~~call()~~ -##### deprecated since 2.0.0 -**Signature:** `call(lambda [, arguments:array])` - -Calls lambda and returns its result. You can provide array -of arguments. - -This function is provided to allow creating twig macros taking -lambda as an argument. - -```twig -{{ call(v => v * 2, [10]) }} -{# prints '20' #} -{{ call(v => v.foo, [{foo: 12}]) }} -{# prints '12' #} -``` diff --git a/Tests/Fixtures/filters/any.test b/Tests/Fixtures/filters/any.test index 92b8961..77c9614 100644 --- a/Tests/Fixtures/filters/any.test +++ b/Tests/Fixtures/filters/any.test @@ -4,7 +4,7 @@ {{ data|is_any(v => v > 6) ? 'YES':'NO' }} {{ data|is_any(v => v is even) ? 'YES':'NO' }} {{ data|is_any(v => v < 0) ? 'YES':'NO' }} -{{ data|is_any((v; i) ==> i is same as('foo')) ? 'YES':'NO' }} +{{ data|is_any((v, i) => i is same as('foo')) ? 'YES':'NO' }} --DATA-- return [ 'data' => [1, 2, 3, 4, 5, 'foo' => 6] ]; --EXPECT-- diff --git a/Tests/Fixtures/filters/count_by.test b/Tests/Fixtures/filters/count_by.test index 09e5b1b..674182d 100644 --- a/Tests/Fixtures/filters/count_by.test +++ b/Tests/Fixtures/filters/count_by.test @@ -1,7 +1,7 @@ --TEST-- "count_by" filter --TEMPLATE-- -{% for key, value in data|count_by(v ==> v.foo ) %} +{% for key, value in data|count_by(v => v.foo ) %} {{ key }}: {{ value }} {% endfor %} --DATA-- diff --git a/Tests/Fixtures/filters/count_by_key.test b/Tests/Fixtures/filters/count_by_key.test index f382621..d16353e 100644 --- a/Tests/Fixtures/filters/count_by_key.test +++ b/Tests/Fixtures/filters/count_by_key.test @@ -1,7 +1,7 @@ --TEST-- "count_by" filter counted with array key --TEMPLATE-- -{% for key, value in data|count_by((v; key) ==> key|first ) %} +{% for key, value in data|count_by((v, key) => key|first ) %} {{ key }}: {{ value }} {% endfor %} --DATA-- diff --git a/Tests/Fixtures/filters/every.test b/Tests/Fixtures/filters/every.test index a383aa4..3740a65 100644 --- a/Tests/Fixtures/filters/every.test +++ b/Tests/Fixtures/filters/every.test @@ -1,10 +1,10 @@ --TEST-- "all" test --TEMPLATE-- -{{ data|is_every(v ==> v > 6) ? 'YES':'NO' }} -{{ data|is_every(v ==> v is even) ? 'YES':'NO' }} -{{ data|is_every(v ==> v < 12) ? 'YES':'NO' }} -{{ data|is_every((v; i) ==> i >= 0) ? 'YES':'NO' }} +{{ data|is_every(v => v > 6) ? 'YES':'NO' }} +{{ data|is_every(v => v is even) ? 'YES':'NO' }} +{{ data|is_every(v => v < 12) ? 'YES':'NO' }} +{{ data|is_every((v, i) => i >= 0) ? 'YES':'NO' }} --DATA-- return [ 'data' => [] ]; --EXPECT-- diff --git a/Tests/Fixtures/filters/group_by.test b/Tests/Fixtures/filters/group_by.test index e6b4b41..be0d048 100644 --- a/Tests/Fixtures/filters/group_by.test +++ b/Tests/Fixtures/filters/group_by.test @@ -1,7 +1,7 @@ --TEST-- "group_by" filter --TEMPLATE-- -{% for key,items in data|group_by(v ==> v|first ) %} +{% for key,items in data|group_by(v => v|first ) %} = {{ key }} {% for i in items %} * {{ i }} diff --git a/Tests/Fixtures/filters/group_by_key.test b/Tests/Fixtures/filters/group_by_key.test index 2f24ad2..ceaade8 100644 --- a/Tests/Fixtures/filters/group_by_key.test +++ b/Tests/Fixtures/filters/group_by_key.test @@ -1,7 +1,7 @@ --TEST-- "group_by" filter grouping with array key --TEMPLATE-- -{% for key,items in data|group_by((v; i) ==> i|first ) %} +{% for key,items in data|group_by((v, i) => i|first ) %} = {{ key }} {% for i in items %} * {{ i }} diff --git a/Tests/Fixtures/filters/group_by_object.test b/Tests/Fixtures/filters/group_by_object.test index d4cf076..7ecadf8 100644 --- a/Tests/Fixtures/filters/group_by_object.test +++ b/Tests/Fixtures/filters/group_by_object.test @@ -1,7 +1,7 @@ --TEST-- "group_by" filter can group by object --TEMPLATE-- -{% for category, articles in array|group_by(v ==> v.category) %} +{% for category, articles in array|group_by(v => v.category) %} = {{ category.name }} {% for article in articles %} * {{ article.name }} diff --git a/Tests/Fixtures/filters/unique.test b/Tests/Fixtures/filters/unique.test index 0430279..f55b12c 100644 --- a/Tests/Fixtures/filters/unique.test +++ b/Tests/Fixtures/filters/unique.test @@ -1,7 +1,7 @@ --TEST-- "unique_by" filter --TEMPLATE-- -{% for i in data|unique_by((i1; i2) ==> i1 == i2) %} +{% for i in data|unique_by((i1, i2) => i1 == i2) %} * {{ i }} {% endfor %} --DATA-- diff --git a/Tests/Fixtures/filters/unique_by.test b/Tests/Fixtures/filters/unique_by.test new file mode 100644 index 0000000..11b604b --- /dev/null +++ b/Tests/Fixtures/filters/unique_by.test @@ -0,0 +1,18 @@ +--TEST-- +"unique_by" filter +--TEMPLATE-- +{% set articles = [ + {author: {name: 'Bar', age: 55}, text: 'Text...'}, + {author: {name: 'Bar', age: 65}, text: 'Text...'}, + {author: {name: 'Foo', age: 45}, text: 'Text...'}, + {author: {name: 'Foo', age: 45}, text: 'Text...'}, +] %} +{% for author in articles|map(v => v.author)|unique_by('===')|sort(v => v.age)|reverse %} + * {{ author.name }}, {{ author.age }} +{% endfor %} +--DATA-- +return []; +--EXPECT-- + * Bar, 55 + * Foo, 45 + * Bar, 65 diff --git a/Tests/Fixtures/filters/unique_object.test b/Tests/Fixtures/filters/unique_object.test index 9573df3..a003530 100644 --- a/Tests/Fixtures/filters/unique_object.test +++ b/Tests/Fixtures/filters/unique_object.test @@ -1,7 +1,7 @@ --TEST-- "unique_by" filter works with list of objects --TEMPLATE-- -{% for i in list|unique_by((i1; i2) ==> i1 is same as(i2)) %} +{% for i in list|unique_by((i1, i2) => i1 is same as(i2)) %} * {{ i.data }} {% endfor %} --DATA-- diff --git a/Tests/Fixtures/lambda/assigned_to_var.test b/Tests/Fixtures/lambda/assigned_to_var.test deleted file mode 100644 index cb4c4a8..0000000 --- a/Tests/Fixtures/lambda/assigned_to_var.test +++ /dev/null @@ -1,12 +0,0 @@ ---TEST-- -lambda can be assigned to variable ---TEMPLATE-- -{% set fn = ==> 'FOO' -%} -{{ call(fn) }} -{% set fn = (x; y) ==> 'BAR' -%} -{{ call(fn) }} ---DATA-- -return []; ---EXPECT-- -FOO -BAR diff --git a/Tests/Fixtures/lambda/call_passed_function.test b/Tests/Fixtures/lambda/call_passed_function.test deleted file mode 100644 index 404c3a7..0000000 --- a/Tests/Fixtures/lambda/call_passed_function.test +++ /dev/null @@ -1,15 +0,0 @@ ---TEST-- -"call" works with callable passed from PHP ---TEMPLATE-- -{{ call(write, ['FOO']) }} ---DATA-- -function write($text) { - return $text . 'BAR'; -} -return [ 'write' => 'write' ]; ---EXPECT-- -FOOBAR ---DATA-- -return [ 'write' => function($text) { return $text.'FOO'; } ]; ---EXPECT-- -FOOFOO diff --git a/Tests/Fixtures/lambda/does_not_bleed.test b/Tests/Fixtures/lambda/does_not_bleed.test deleted file mode 100644 index 4252576..0000000 --- a/Tests/Fixtures/lambda/does_not_bleed.test +++ /dev/null @@ -1,16 +0,0 @@ ---TEST-- -lambda call does not leave arguments and "__" variable set after call ---TEMPLATE-- -{% do call( ==> _ , ['FOO'] ) -%} -{{ _ is not defined ? 'WORKS' : 'FAILS' }} -{{ __ is not defined ? 'WORKS' : 'FAILS' }} -{% do call( (foo; bar) ==> foo ~ bar , ['FOO', 'BAR'] ) -%} -{{ foo is not defined ? 'WORKS' : 'FAILS' }} -{{ bar is not defined ? 'WORKS' : 'FAILS' }} ---DATA-- -return []; ---EXPECT-- -WORKS -WORKS -WORKS -WORKS diff --git a/Tests/Fixtures/lambda/mutiple_arguments.test b/Tests/Fixtures/lambda/mutiple_arguments.test deleted file mode 100644 index f2fa414..0000000 --- a/Tests/Fixtures/lambda/mutiple_arguments.test +++ /dev/null @@ -1,12 +0,0 @@ ---TEST-- -lambda can have multiple arguments ---TEMPLATE-- -{{ call(v ==> __[0] ~ __[1] ~ __[2], [ 3, 4, 5 ]) }} -{{ call(v ==> __|join(','), [6, 'FOO', 'BAR']) }} -{{ call((a;b;c) ==> a~b~c, ['A','B','C']) }} ---DATA-- -return []; ---EXPECT-- -345 -6,FOO,BAR -ABC diff --git a/Tests/Fixtures/lambda/no_arguments.test b/Tests/Fixtures/lambda/no_arguments.test deleted file mode 100644 index be71fcf..0000000 --- a/Tests/Fixtures/lambda/no_arguments.test +++ /dev/null @@ -1,12 +0,0 @@ ---TEST-- -argument variables are undefined inside of the lambda when it's called without arguments ---TEMPLATE-- -{% set _ = 'FAIL' %} -{{ call( ==> _|default('FOOBAR') ) }} -{% set a = 'FAIL' %} -{{ call((a) ==> a|default('FOOBAR') ) }} ---DATA-- -return []; ---EXPECT-- -FOOBAR -FOOBAR diff --git a/Tests/Fixtures/lambda/operator_precedence.test b/Tests/Fixtures/lambda/operator_precedence.test deleted file mode 100644 index 72e6b39..0000000 --- a/Tests/Fixtures/lambda/operator_precedence.test +++ /dev/null @@ -1,48 +0,0 @@ ---TEST-- -lambda operator have lowest priority ---TEMPLATE-- -{{ call(v ==> v + 1, [2]) }} -{{ call(v ==> v - 1, [2]) }} -{{ call(v ==> v * 2, [4]) }} -{{ call(v ==> v / 5, [10]) }} -{{ call(v ==> v % 2, [9]) }} -{{ call(v ==> v ~ 1, [1]) }} -{{ call(v ==> v b-or 5, [3]) }} -{{ call(v ==> v[0], [[1]]) }} -{{ call(v ==> v.foo, [{foo:'bar'}]) }} -{{ call(v ==> v|first, ['foobar']) }} -=== -{{ call(a ==> a + 1, [2]) }} -{{ call((a; b) ==> a - b, [2, 1]) }} -{{ call(c ==> c * 2, [4]) }} -{{ call(abc ==> abc / 5, [10]) }} -{{ call(abc ==> abc % 2, [9]) }} -{{ call(n ==> n ~ 1, [1]) }} -{{ call(num ==> num b-or 5, [3]) }} -{{ call(_ ==> _[0], [[1]]) }} -{{ call(xcv ==> xcv.foo, [{foo:'bar'}]) }} -{{ call(Aaa ==> Aaa|first, ['foobar']) }} ---DATA-- -return []; ---EXPECT-- -3 -1 -8 -2 -1 -11 -7 -1 -bar -f -=== -3 -1 -8 -2 -1 -11 -7 -1 -bar -f diff --git a/Tests/Fixtures/lambda/passed_to_macro.test b/Tests/Fixtures/lambda/passed_to_macro.test deleted file mode 100644 index 5ffd7e0..0000000 --- a/Tests/Fixtures/lambda/passed_to_macro.test +++ /dev/null @@ -1,19 +0,0 @@ ---TEST-- -lambda can be passed to macro ---TEMPLATE-- -{% import "macro.twig" as macro %} -{% set prefix = ' * ' %} -{{ macro.print(data, ==> prefix ~ _ ~ suffix) }} ---TEMPLATE(macro.twig)-- -{% macro print(list, callback) %} -{% set prefix = 'WRONG! ' %} -{% for i in list %} -{{ call(callback, [i]) }} -{% endfor %} -{% endmacro %} ---DATA-- -return [ 'suffix' => '.', 'data' => [ 'foo', 'bar', 'tet' ] ]; ---EXPECT-- - * foo. - * bar. - * tet. diff --git a/Tests/Fixtures/lambda/preserve_context.test b/Tests/Fixtures/lambda/preserve_context.test deleted file mode 100644 index f3404e4..0000000 --- a/Tests/Fixtures/lambda/preserve_context.test +++ /dev/null @@ -1,16 +0,0 @@ ---TEST-- -lambda doesn't override _ and __ variables from outside ---TEMPLATE-- -{% do call(v ==> v, ['FAIL']) -%} -{% do call((a;foo) ==> a~foo, ['FAIL', 'FAIL']) -%} -{{ _ }} -{{ __ }} -{{ a }} -{{ foo }} ---DATA-- -return [ '_' => 'WORKS', '__' => 'WORKS', 'foo' => 'WORKS', 'a' => 'WORKS' ]; ---EXPECT-- -WORKS -WORKS -WORKS -WORKS diff --git a/Tests/Fixtures/lambda/return_literal.test b/Tests/Fixtures/lambda/return_literal.test deleted file mode 100644 index b3be12c..0000000 --- a/Tests/Fixtures/lambda/return_literal.test +++ /dev/null @@ -1,12 +0,0 @@ ---TEST-- -lambda expression works when returning literal ---TEMPLATE-- -{{ call(v ==> 'WORKS') }} -{{ call((a; b; c) ==> 'WORKS') }} -{{ call(foo ==> 'WORKS') }} ---DATA-- -return []; ---EXPECT-- -WORKS -WORKS -WORKS diff --git a/Tests/Fixtures/lambda/return_outer_var.test b/Tests/Fixtures/lambda/return_outer_var.test deleted file mode 100644 index ddbc92b..0000000 --- a/Tests/Fixtures/lambda/return_outer_var.test +++ /dev/null @@ -1,13 +0,0 @@ ---TEST-- -lambda expression works when returning outer variable ---TEMPLATE-- -{% set b = 'WORKS' -%} -{{ call(v ==> a) }} -{{ call(v ==> b) }} -{{ call(a ==> a~b, ['STILL ']) }} ---DATA-- -return [ 'a' => 'WORKS' ]; ---EXPECT-- -WORKS -WORKS -STILL WORKS diff --git a/composer.json b/composer.json index ce20bbe..1e37610 100644 --- a/composer.json +++ b/composer.json @@ -9,15 +9,15 @@ "group", "extensions" ], - "minimum-stability": "dev", + "prefer-stable": true, "license": "MIT", "require": { - "php": "^7.0", - "twig/twig": "^2.10", + "php": "^7.2.5", + "twig/twig": "^3.0", "dpolac/dictionary": "^1.0" }, "require-dev": { - "phpunit/phpunit": "^6.5" + "phpunit/phpunit": "^8.5" }, "autoload": { "psr-4": { diff --git a/src/LambdaExtension.php b/src/LambdaExtension.php index 4b74872..020df39 100644 --- a/src/LambdaExtension.php +++ b/src/LambdaExtension.php @@ -1,58 +1,14 @@ - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ namespace LeonAero\TwigLambda; use DPolac\Dictionary; -use LeonAero\TwigLambda\NodeExpression\Arguments; -use LeonAero\TwigLambda\NodeExpression\LambdaWithArguments; -use LeonAero\TwigLambda\NodeExpression\SimpleLambda; use Twig\Error\RuntimeError; use Twig\Extension\AbstractExtension; use Twig\TwigFilter; -use Twig\TwigFunction; class LambdaExtension extends AbstractExtension { - - public function getOperators() - { - return [ - [ - '==>' => [ - 'precedence' => 0, - 'class' => SimpleLambda::class - ], - ], - [ - '==>' => [ - 'precedence' => 0, - 'class' => LambdaWithArguments::class, - 'associativity' => \Twig_ExpressionParser::OPERATOR_LEFT - ], - ';' => [ - 'precedence' => 5, - 'class' => Arguments::class, - 'associativity' => \Twig_ExpressionParser::OPERATOR_RIGHT - ], - ] - ]; - } - - public function getFunctions() - { - return [ - new TwigFunction('call', [$this, 'call']), - ]; - } - public function getFilters() { return [ @@ -65,20 +21,20 @@ public function getFilters() ]; } - public function unique_by($array, $callback) + public function unique_by($array, $arrow) { if (!is_array($array) && !($array instanceof \Traversable)) { throw new RuntimeError(sprintf( 'First argument of "unique_by" must be array or Traversable, but is "%s".', gettype($array))); } - if ('==' === $callback) { - $callback = static function($item1, $item2) { return $item1 == $item2; }; - } else if ('===' === $callback) { - $callback = static function($item1, $item2) { return $item1 === $item2; }; - } else if (!is_callable($callback)) { + if ('==' === $arrow) { + $arrow = static function($item1, $item2) { return $item1 == $item2; }; + } else if ('===' === $arrow) { + $arrow = static function($item1, $item2) { return $item1 === $item2; }; + } else if (!is_callable($arrow)) { throw new RuntimeError(sprintf( - 'Second argument of "unique_by" must be callable, "==" or "===", but is "%s".', gettype($callback))); + 'Second argument of "unique_by" must be callable, "==" or "===", but is "%s".', gettype($arrow))); } if ($array instanceof \Traversable) { @@ -96,7 +52,7 @@ public function unique_by($array, $callback) if ($i === $j) { // add to results if already checked every previous element $result[$i] = $item; - } elseif (isset($result[$j]) && $callback($item, $previous, $i, $j)) { + } elseif (isset($result[$j]) && $arrow($item, $previous, $i, $j)) { // skip if is identical with value which is already in results array continue 2; } @@ -105,12 +61,11 @@ public function unique_by($array, $callback) return $result; } - public function group_by($array, $callback) - { - - if (!is_callable($callback)) { + public function group_by($array, $arrow): Dictionary + { + if (!is_callable($arrow)) { throw new RuntimeError(sprintf( - 'Second argument of "group_by" must be callable, but is "%s".', gettype($callback))); + 'Second argument of "group_by" must be callable, but is "%s".', gettype($arrow))); } if (!is_array($array) && !($array instanceof \Traversable)) { @@ -121,7 +76,7 @@ public function group_by($array, $callback) $results = new Dictionary(); foreach ($array as $i => $item) { - $key = $callback($item, $i); + $key = $arrow($item, $i); if (!isset($results[$key])) { $results[$key] = [$i => $item]; @@ -134,11 +89,11 @@ public function group_by($array, $callback) return $results; } - public function count_by($array, $callback) - { - if (!is_callable($callback)) { + public function count_by($array, $arrow): array + { + if (!is_callable($arrow)) { throw new RuntimeError(sprintf( - 'Second argument of "count_by" must be callable, but is "%s".', gettype($callback))); + 'Second argument of "count_by" must be callable, but is "%s".', gettype($arrow))); } if (!is_array($array) && !($array instanceof \Traversable)) { @@ -148,7 +103,7 @@ public function count_by($array, $callback) $result = []; foreach ($array as $i => $element) { - $key = $callback($element, $i); + $key = $arrow($element, $i); if (is_bool($key)) { $key = $key ? 'true' : 'false'; } elseif ($key === null) { @@ -163,11 +118,11 @@ public function count_by($array, $callback) return $result; } - public function is_every($array, $callback): bool + public function is_every($array, $arrow): bool { - if (!is_callable($callback)) { + if (!is_callable($arrow)) { throw new RuntimeError(sprintf( - 'Second argument of "every" must be callable, but is "%s".', gettype($callback))); + 'Second argument of "every" must be callable, but is "%s".', gettype($arrow))); } if (!is_array($array) && !($array instanceof \Traversable)) { @@ -176,7 +131,7 @@ public function is_every($array, $callback): bool } foreach ($array as $i => $item) { - if (!$callback($item, $i)) { + if (!$arrow($item, $i)) { return false; } } @@ -184,11 +139,11 @@ public function is_every($array, $callback): bool return true; } - public function is_any($array, $callback): bool + public function is_any($array, $arrow): bool { - if (!is_callable($callback)) { + if (!is_callable($arrow)) { throw new RuntimeError(sprintf( - 'Second argument of "any" must be callable, but is "%s".', gettype($callback))); + 'Second argument of "any" must be callable, but is "%s".', gettype($arrow))); } if (!is_array($array) && !($array instanceof \Traversable)) { @@ -197,7 +152,7 @@ public function is_any($array, $callback): bool } foreach ($array as $i => $item) { - if ($callback($item, $i)) { + if ($arrow($item, $i)) { return true; } } @@ -205,19 +160,8 @@ public function is_any($array, $callback): bool return false; } - /** - * @deprecated since v2.0 - */ - public function call($callback, array $args = []) - { - if (!is_callable($callback)) { - throw new \InvalidArgumentException('First argument must be callable.'); - } - return call_user_func_array($callback, $args); - } - - public function getName() - { + public function getName(): string + { return 'leonaero_lambda_extension'; } } diff --git a/src/NodeExpression/Arguments.php b/src/NodeExpression/Arguments.php deleted file mode 100644 index c19c891..0000000 --- a/src/NodeExpression/Arguments.php +++ /dev/null @@ -1,47 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace LeonAero\TwigLambda\NodeExpression; - -/** - * @deprecated since v1.1.0 - */ -class Arguments extends \Twig_Node_Expression -{ - private $arguments; - - public function __construct(\Twig_Node $left, \Twig_Node $right, $lineno) - { - $arguments = []; - foreach ([$left, $right] as $node) { - if ($node instanceof Arguments) { - $arguments[] = $node->getArguments(); - } elseif ($node instanceof \Twig_Node_Expression_Name) { - $arguments[] = [$node->getAttribute('name')]; - } else { - throw new \InvalidArgumentException('Invalid argument.'); - } - } - - $this->arguments = array_merge($arguments[0], $arguments[1]); - - parent::__construct(array('left' => $left, 'right' => $right), array(), $lineno); - } - - public function compile(\Twig_Compiler $compiler) - { - throw new \Exception('Semicolon-separated list of arguments can be only used in lambda expression.'); - } - - public function getArguments() - { - return $this->arguments; - } -} diff --git a/src/NodeExpression/Lambda.php b/src/NodeExpression/Lambda.php deleted file mode 100644 index 017e352..0000000 --- a/src/NodeExpression/Lambda.php +++ /dev/null @@ -1,73 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace LeonAero\TwigLambda\NodeExpression; - -/** - * @deprecated since v1.1.0 - */ -abstract class Lambda extends \Twig_Node_Expression -{ - protected function compileWithArguments( - \Twig_Compiler $compiler, $expressionNode, array $arguments) - { - $compiler->raw("\n"); - $compiler->indent(); - $compiler->write(''); - $compiler->raw("function() use(&\$context) {\n"); - $compiler->indent(); - - // copy of arguments and __ from context - foreach ($arguments as $arg) { - $compiler->write(''); - $compiler->raw("if (isset(\$context['$arg'])) \$outer$arg = \$context['$arg'];\n"); - } - $compiler->write(''); - $compiler->raw("if (isset(\$context['__'])) \$outer__ = \$context['__'];\n"); - - // adding closure's arguments to context - $compiler->write(''); - $compiler->raw("\$context['__'] = func_get_args();\n"); - foreach ($arguments as $i => $arg) { - $compiler->write(''); - $compiler->raw("if (func_num_args()>$i) \$context['$arg'] = func_get_arg($i);\n"); - $compiler->write(''); - $compiler->raw("else unset(\$context['$arg']);\n"); - } - - // getting call result - $compiler->write(''); - $compiler->raw("\$result = "); - $compiler->subcompile($this->getNode($expressionNode)); - $compiler->raw(";\n"); - - // recreating original context - foreach ($arguments as $arg) { - $compiler->write(''); - $compiler->raw("if (isset(\$outer$arg)) \$context['$arg'] = \$outer$arg ;\n"); - $compiler->write(''); - $compiler->raw("else unset(\$context['$arg']);\n"); - } - $compiler->write(''); - $compiler->raw("if (isset(\$outer__)) \$context['__'] = \$outer__ ;\n"); - $compiler->write(''); - $compiler->raw("else unset(\$context['__']);\n"); - - // return statement - $compiler->write(''); - $compiler->raw("return \$result;\n"); - $compiler->outdent(); - $compiler->write(''); - - $compiler->raw("}\n"); - $compiler->outdent(); - $compiler->write(''); - } -} diff --git a/src/NodeExpression/LambdaWithArguments.php b/src/NodeExpression/LambdaWithArguments.php deleted file mode 100644 index e3f2a0f..0000000 --- a/src/NodeExpression/LambdaWithArguments.php +++ /dev/null @@ -1,42 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace LeonAero\TwigLambda\NodeExpression; - -/** - * @deprecated since v1.1.0 - */ -class LambdaWithArguments extends Lambda -{ - private $arguments = []; - - public function __construct(\Twig_Node $left, \Twig_Node $right, $lineno) - { - parent::__construct(array('left' => $left, 'right' => $right), array(), $lineno); - - if ($left instanceof \Twig_Node_Expression_Name) { - $this->arguments = [ $left->getAttribute('name') ]; - } elseif ($left instanceof Arguments) { - $this->arguments = $left->getArguments(); - } else { - throw new \InvalidArgumentException('Invalid argument\'s list for lambda.'); - } - - if (count($this->arguments) !== count(array_flip($this->arguments))) { - throw new \InvalidArgumentException('Each lambda argument must have unique name.'); - } - - } - - public function compile(\Twig_Compiler $compiler) - { - $this->compileWithArguments($compiler, 'right', $this->arguments); - } -} diff --git a/src/NodeExpression/SimpleLambda.php b/src/NodeExpression/SimpleLambda.php deleted file mode 100644 index 38963a0..0000000 --- a/src/NodeExpression/SimpleLambda.php +++ /dev/null @@ -1,27 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace LeonAero\TwigLambda\NodeExpression; - -/** - * @deprecated since v1.1.0 - */ -class SimpleLambda extends Lambda -{ - public function __construct(\Twig_Node $node, $lineno) - { - parent::__construct(array('node' => $node), array(), $lineno); - } - - public function compile(\Twig_Compiler $compiler) - { - $this->compileWithArguments($compiler, 'node', ['_']); - } -}