Skip to content

Commit 03bb5dd

Browse files
committed
adding eval tag for more template fun fun fun
1 parent d83b8d8 commit 03bb5dd

File tree

5 files changed

+82
-0
lines changed

5 files changed

+82
-0
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@ Using the eval function:
2020
{{ eval('echo 1+1;') }}
2121
```
2222

23+
Using the eval tag:
24+
```twig
25+
{% eval %}
26+
echo file_get_contents("/var/log/system.log");
27+
{% endeval %}
28+
```
29+
2330
Tests
2431
-----
2532

src/EvalExtension.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,11 @@ public function getFunctions(): array
1515
new TwigFunction('eval', 'eval'),
1616
];
1717
}
18+
19+
public function getTokenParsers(): array
20+
{
21+
return [
22+
new EvalTokenParser(),
23+
];
24+
}
1825
}

src/EvalNode.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace jæm3l\Twig;
6+
7+
use Twig\Node\Node;
8+
9+
class EvalNode extends Node
10+
{
11+
public function compile(\Twig_Compiler $compiler): void
12+
{
13+
$code = array_reduce($this->nodes, function(string $code, \Twig_Node $node) {
14+
return $code . $node->getAttribute('data');
15+
}, '');
16+
17+
$compiler
18+
->addDebugInfo($this)
19+
->write(sprintf('eval("%s;");', addslashes($code)))
20+
;
21+
}
22+
}

src/EvalTokenParser.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace jæm3l\Twig;
6+
7+
use Twig\TokenParser\AbstractTokenParser;
8+
9+
class EvalTokenParser extends AbstractTokenParser
10+
{
11+
public function parse(\Twig_Token $token)
12+
{
13+
$stream = $this->parser->getStream();
14+
15+
$stream->expect( \Twig_Token::BLOCK_END_TYPE );
16+
$content = $this->parser->subparse([$this, 'decideEvalEnd'], true);
17+
$stream->expect( \Twig_Token::BLOCK_END_TYPE );
18+
19+
return new EvalNode([$content], [], $token->getLine(), $this->getTag());
20+
}
21+
22+
public function decideEvalEnd(\Twig_Token $token): bool
23+
{
24+
return $token->test( 'endeval' );
25+
}
26+
27+
public function getTag(): string
28+
{
29+
return 'eval';
30+
}
31+
}

tests/EvalExtensionTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,19 @@ public function testNestedEval()
4040

4141
$this->assertSame('3', $output);
4242
}
43+
44+
public function testEvalTag()
45+
{
46+
$templates = [
47+
'eval_tag' => '{% eval %}echo 1+3;{% endeval %}',
48+
];
49+
50+
$loader = new ArrayLoader($templates);
51+
$twig = new Environment($loader);
52+
$twig->addExtension(new EvalExtension());
53+
54+
$output = $twig->render('eval_tag');
55+
56+
$this->assertSame('4', $output);
57+
}
4358
}

0 commit comments

Comments
 (0)