Last active
May 17, 2022 13:43
-
-
Save emnsen/f9c65c6ba5ceee8e0424fe5828994201 to your computer and use it in GitHub Desktop.
twig variable extractor #symfony #twig
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php declare(strict_types=1); | |
namespace App\Twig; | |
use Twig\Environment; | |
use Twig\Node\Expression\ConditionalExpression; | |
use Twig\Node\Expression\Filter\DefaultFilter; | |
use Twig\Node\Expression\FilterExpression; | |
use Twig\Node\Expression\FunctionExpression; | |
use Twig\Node\Expression\NameExpression; | |
use Twig\Node\PrintNode; | |
use function iter\filter; | |
use function iter\flatten; | |
use function iter\func\operator; | |
use function iter\map; | |
use function iter\toArray; | |
final class VariableExtractor | |
{ | |
public function __construct( | |
private Environment $twig, | |
) { | |
} | |
public function extract(string $path): ?array | |
{ | |
$template = $this->twig->load($path); | |
$source = $template->getSourceContext(); | |
$stream = $this->twig->tokenize($source); | |
$mainNode = $this->twig->parse($stream); | |
if (!$mainNode->hasNode('body')) { | |
return null; | |
} | |
$cb = static function ($node) use (&$cb) { | |
if ($node instanceof NameExpression) { | |
return $node->getAttribute('name'); | |
} | |
if ($node instanceof ConditionalExpression) { | |
return $cb($node->getNode('expr1')->getNode('node')); | |
} | |
if ($node instanceof FilterExpression) { | |
$node = $node->getNode('node'); | |
if ($node instanceof ConditionalExpression) { | |
return $cb($node->getNode('expr1')); | |
} | |
if ($node instanceof DefaultFilter) { | |
return $cb($node->getNode('node')); | |
} | |
return $node->getAttribute('name'); | |
} | |
if ($node instanceof FunctionExpression) { | |
return map($cb, toArray($node->getNode('arguments')->getIterator())); | |
} | |
if ($node instanceof PrintNode) { | |
return $cb($node->getNode('expr')); | |
} | |
throw new \Exception('Something wrong with this node.'); | |
}; | |
return toArray( | |
flatten( | |
map( | |
$cb, | |
filter( | |
operator('instanceof', PrintNode::class), | |
$mainNode->getNode('body')->getNode('0')->getIterator(), | |
), | |
), | |
) | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment