View source
<?php
namespace Drupal\Core\Template;
use Twig\Compiler;
use Twig\Error\SyntaxError;
use Twig\Node\CheckToStringNode;
use Twig\Node\Expression\AbstractExpression;
use Twig\Node\Expression\ConstantExpression;
use Twig\Node\Expression\FilterExpression;
use Twig\Node\Expression\FunctionExpression;
use Twig\Node\Expression\GetAttrExpression;
use Twig\Node\Expression\NameExpression;
use Twig\Node\Expression\TempNameExpression;
use Twig\Node\Node;
use Twig\Node\PrintNode;
class TwigNodeTrans extends Node {
public function __construct(Node $body, Node $plural = NULL, AbstractExpression $count = NULL, AbstractExpression $options = NULL, $lineno, $tag = NULL) {
$nodes['body'] = $body;
if ($count !== NULL) {
$nodes['count'] = $count;
}
if ($plural !== NULL) {
$nodes['plural'] = $plural;
}
if ($options !== NULL) {
$nodes['options'] = $options;
}
parent::__construct($nodes, [], $lineno, $tag);
}
public function compile(Compiler $compiler) {
$compiler
->addDebugInfo($this);
[
$singular,
$tokens,
] = $this
->compileString($this
->getNode('body'));
$plural = NULL;
if ($this
->hasNode('plural')) {
[
$plural,
$pluralTokens,
] = $this
->compileString($this
->getNode('plural'));
$tokens = array_merge($tokens, $pluralTokens);
}
$compiler
->write('echo ' . (empty($plural) ? 't' : '\\Drupal::translation()->formatPlural') . '(');
if (!empty($plural)) {
$compiler
->raw('abs(')
->subcompile($this
->getNode('count'))
->raw('), ');
}
$compiler
->subcompile($singular);
if (!empty($plural)) {
$compiler
->raw(', ')
->subcompile($plural);
}
$compiler
->raw(', array(');
foreach ($tokens as $token) {
$compiler
->string($token
->getAttribute('placeholder'))
->raw(' => ')
->subcompile($token)
->raw(', ');
}
$compiler
->raw(')');
if ($this
->hasNode('options')) {
$compiler
->raw(', ')
->subcompile($this
->getNode('options'));
}
$compiler
->raw(')');
$compiler
->raw(";\n");
}
protected function compileString(Node $body) {
if ($body instanceof NameExpression || $body instanceof ConstantExpression || $body instanceof TempNameExpression) {
return [
$body,
[],
];
}
$tokens = [];
if (count($body)) {
$text = '';
foreach ($body as $node) {
if ($node instanceof PrintNode) {
$n = $node
->getNode('expr');
while ($n instanceof FilterExpression) {
$n = $n
->getNode('node');
}
if ($n instanceof CheckToStringNode) {
$n = $n
->getNode('expr');
}
$args = $n;
if ($args instanceof FunctionExpression) {
$args = $n
->getNode('arguments')
->getNode(0);
}
$argPrefix = '@';
while ($args instanceof FilterExpression) {
switch ($args
->getNode('filter')
->getAttribute('value')) {
case 'placeholder':
$argPrefix = '%';
break;
}
$args = $args
->getNode('node');
}
if ($args instanceof CheckToStringNode) {
$args = $args
->getNode('expr');
}
if ($args instanceof GetAttrExpression) {
$argName = [];
$expr = $args;
$argName[] = $args
->getNode('attribute')
->getAttribute('value');
while ($args
->hasNode('node')) {
$args = $args
->getNode('node');
if ($args instanceof NameExpression) {
$argName[] = $args
->getAttribute('name');
}
else {
$argName[] = $args
->getNode('attribute')
->getAttribute('value');
}
}
$argName = array_reverse($argName);
$argName = implode('.', $argName);
}
else {
$argName = $n
->getAttribute('name');
if (!is_null($args)) {
$argName = $args
->getAttribute('name');
}
$expr = new NameExpression($argName, $n
->getTemplateLine());
}
$placeholder = sprintf('%s%s', $argPrefix, $argName);
$text .= $placeholder;
$expr
->setAttribute('placeholder', $placeholder);
$tokens[] = $expr;
}
else {
$text .= $node
->getAttribute('data');
}
}
}
elseif (!$body
->hasAttribute('data')) {
throw new SyntaxError('{% trans %} tag cannot be empty');
}
else {
$text = $body
->getAttribute('data');
}
return [
new Node([
new ConstantExpression(trim($text), $body
->getTemplateLine()),
]),
$tokens,
];
}
}