Skip to content

Commit 8be006e

Browse files
committed
Initial commit
0 parents  commit 8be006e

26 files changed

Lines changed: 911 additions & 0 deletions

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/.idea
2+
/composer.lock
3+
/composer.phar
4+
/vendor

Extension/LambdaExtension.php

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
<?php
2+
/**
3+
* This file is part of TwigLambda
4+
*
5+
* (c) Damian Polac <damian.polac.111@gmail.com>
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
11+
namespace DPolac\TwigLambda\Extension;
12+
13+
use Underscore\Types\Arrays;
14+
15+
class LambdaExtension extends \Twig_Extension
16+
{
17+
18+
public function getOperators()
19+
{
20+
return [
21+
[
22+
'=>' => [
23+
'precedence' => 0,
24+
'class' => '\DPolac\TwigLambda\NodeExpression\Lambda'
25+
],
26+
],
27+
[]
28+
];
29+
}
30+
31+
public function getFunctions()
32+
{
33+
return [
34+
new \Twig_SimpleFunction('call', [$this, 'call']),
35+
];
36+
}
37+
38+
public function getTests()
39+
{
40+
return [
41+
new \Twig_SimpleTest('all', '\Underscore\Types\Arrays::matches'),
42+
new \Twig_SimpleTest('every', '\Underscore\Types\Arrays::matches'),
43+
44+
new \Twig_SimpleTest('any', [$this, 'any']),
45+
new \Twig_SimpleTest('some', [$this, 'any']),
46+
];
47+
}
48+
49+
public function getFilters()
50+
{
51+
return [
52+
new \Twig_SimpleFilter('map', '\Underscore\Types\Arrays::each'),
53+
new \Twig_SimpleFilter('each', '\Underscore\Types\Arrays::each'),
54+
new \Twig_SimpleFilter('select', '\Underscore\Types\Arrays::each'),
55+
56+
new \Twig_SimpleFilter('filter', '\Underscore\Types\Arrays::filter'),
57+
new \Twig_SimpleFilter('where', '\Underscore\Types\Arrays::filter'),
58+
59+
new \Twig_SimpleFilter('unique', 'array_unique'),
60+
61+
new \Twig_SimpleFilter('groupBy', '\Underscore\Types\Arrays::group'),
62+
new \Twig_SimpleFilter('sortBy', '\Underscore\Types\Arrays::sort'),
63+
new \Twig_SimpleFilter('countBy', [$this, 'countBy']),
64+
];
65+
}
66+
67+
public function countBy(array $array, $callback)
68+
{
69+
$result = [];
70+
foreach ($array as $element) {
71+
$key = $callback($element);
72+
if (is_bool($key)) {
73+
$key = $key ? 'true' : 'false';
74+
} elseif (is_null($key)) {
75+
$key = 'null';
76+
}
77+
if (!isset($result[$key])) {
78+
$result[$key] = 1;
79+
} else {
80+
++$result[$key];
81+
}
82+
}
83+
return $result;
84+
}
85+
86+
public function any(array $array, $callback)
87+
{
88+
if (!is_callable($callback)) {
89+
throw new \InvalidArgumentException(
90+
'Second argument of any must be callable.');
91+
}
92+
93+
if (count($array) === 0) {
94+
return false;
95+
}
96+
97+
return Arrays::matchesAny($array, $callback);
98+
}
99+
100+
public function call($callback, array $args = [])
101+
{
102+
if (!is_callable($callback)) {
103+
throw new \InvalidArgumentException('First argument must be callable.');
104+
}
105+
return call_user_func_array($callback, $args);
106+
}
107+
108+
public function getName()
109+
{
110+
return 'dpolac_lambda_extension';
111+
}
112+
}

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2016 Damian Połać
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

NodeExpression/Lambda.php

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
/**
3+
* This file is part of TwigLambda
4+
*
5+
* (c) Damian Polac <damian.polac.111@gmail.com>
6+
*
7+
* For the full copyright and license information, please view the LICENSE
8+
* file that was distributed with this source code.
9+
*/
10+
11+
namespace DPolac\TwigLambda\NodeExpression;
12+
13+
14+
class Lambda extends \Twig_Node_Expression
15+
{
16+
public function __construct(\Twig_Node $node, $lineno)
17+
{
18+
parent::__construct(array('node' => $node), array(), $lineno);
19+
}
20+
21+
public function compile(\Twig_Compiler $compiler)
22+
{
23+
$compiler->raw("\n");
24+
$compiler->indent();
25+
$compiler->addIndentation();
26+
$compiler->raw("function() use(&\$context) {\n");
27+
$compiler->indent();
28+
29+
// copy of _ and __ from context
30+
$compiler->addIndentation();
31+
$compiler->raw("if (isset(\$context['_'])) \$outer_ = \$context['_'];\n");
32+
$compiler->addIndentation();
33+
$compiler->raw("if (isset(\$context['__'])) \$outer__ = \$context['__'];\n");
34+
35+
// adding closure's arguments to context
36+
$compiler->addIndentation();
37+
$compiler->raw("\$context['__'] = func_get_args();\n");
38+
$compiler->addIndentation();
39+
$compiler->raw("if (func_num_args()>0) \$context['_'] = func_get_arg(0);\n");
40+
$compiler->addIndentation();
41+
$compiler->raw("else unset(\$context['_']);\n");
42+
43+
// getting call result
44+
$compiler->addIndentation();
45+
$compiler->raw("\$result = ");
46+
$compiler->subcompile($this->getNode('node'));
47+
$compiler->raw(";\n");
48+
49+
// recreating original context
50+
$compiler->addIndentation();
51+
$compiler->raw("if (isset(\$outer_)) \$context['_'] = \$outer_ ;\n");
52+
$compiler->addIndentation();
53+
$compiler->raw("else unset(\$context['_']);\n");
54+
$compiler->addIndentation();
55+
$compiler->raw("if (isset(\$outer__)) \$context['__'] = \$outer__ ;\n");
56+
$compiler->addIndentation();
57+
$compiler->raw("else unset(\$context['__']);\n");
58+
59+
// return statement
60+
$compiler->addIndentation();
61+
$compiler->raw("return \$result;");
62+
$compiler->outdent();
63+
$compiler->addIndentation();
64+
65+
$compiler->raw("}\n");
66+
$compiler->outdent();
67+
$compiler->addIndentation();
68+
}
69+
}

0 commit comments

Comments
 (0)