DefaultApplyingNodeVisitor::doLeaveNode()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
3
/*
4
 * This file is part of the PHP Translation package.
5
 *
6
 * (c) PHP Translation team <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Translation\Bundle\Twig\Visitor;
13
14
use Translation\Bundle\Twig\Node\Transchoice;
15
use Twig\Environment;
16
use Twig\Node\Expression\ArrayExpression;
17
use Twig\Node\Expression\Binary\EqualBinary;
18
use Twig\Node\Expression\ConditionalExpression;
19
use Twig\Node\Expression\ConstantExpression;
20
use Twig\Node\Expression\FilterExpression;
21
use Twig\Node\Node;
22
use Twig\NodeVisitor\AbstractNodeVisitor;
23
24
/**
25
 * Applies the value of the "desc" filter if the "trans" filter has no
26
 * translations.
27
 *
28
 * This is only active in your development environment.
29
 *
30
 * @author Johannes M. Schmitt <[email protected]>
31
 */
32
final class DefaultApplyingNodeVisitor extends AbstractNodeVisitor
33
{
34
    /**
35
     * @var bool
36
     */
37
    private $enabled = true;
38
39
    public function setEnabled(bool $bool): void
40
    {
41
        $this->enabled = $bool;
42
    }
43
44 1
    public function doEnterNode(Node $node, Environment $env): Node
45
    {
46 1
        if (!$this->enabled) {
47
            return $node;
48
        }
49
50 1
        if (!($node instanceof FilterExpression && 'desc' === $node->getNode('filter')->getAttribute('value'))) {
51 1
            return $node;
52
        }
53
54 1
        $transNode = $node->getNode('node');
55 1
        while ($transNode instanceof FilterExpression
56 1
                   && 'trans' !== $transNode->getNode('filter')->getAttribute('value')
57 1
                   && 'transchoice' !== $transNode->getNode('filter')->getAttribute('value')) {
58
            $transNode = $transNode->getNode('node');
59
        }
60
61 1
        if (!$transNode instanceof FilterExpression) {
62
            throw new \RuntimeException('The "desc" filter must be applied after a "trans", or "transchoice" filter.');
63
        }
64
65 1
        $wrappingNode = $node->getNode('node');
66 1
        $testNode = clone $wrappingNode;
67 1
        $defaultNode = $node->getNode('arguments')->getNode(0);
68
69
        // if the |transchoice filter is used, delegate the call to the TranslationExtension
70
        // so that we can catch a possible exception when the default translation has not yet
71
        // been extracted
72 1
        if ('transchoice' === $transNode->getNode('filter')->getAttribute('value')) {
73
            $transchoiceArguments = new ArrayExpression([], $transNode->getTemplateLine());
74
            $transchoiceArguments->addElement($wrappingNode->getNode('node'));
75
            $transchoiceArguments->addElement($defaultNode);
76
            foreach ($wrappingNode->getNode('arguments') as $arg) {
77
                $transchoiceArguments->addElement($arg);
78
            }
79
80
            $transchoiceNode = new Transchoice($transchoiceArguments, $transNode->getTemplateLine());
81
            $node->setNode('node', $transchoiceNode);
82
83
            return $node;
84
        }
85
86
        // if the |trans filter has replacements parameters
87
        // (e.g. |trans({'%foo%': 'bar'}))
88 1
        if ($wrappingNode->getNode('arguments')->hasNode(0)) {
89 1
            $lineno = $wrappingNode->getTemplateLine();
90
91
            // remove the replacements from the test node
92 1
            $testNode->setNode('arguments', clone $testNode->getNode('arguments'));
93 1
            $testNode->getNode('arguments')->setNode(0, new ArrayExpression([], $lineno));
94
95
            // wrap the default node in a |replace filter
96 1
            $defaultNode = new FilterExpression(
97 1
                clone $node->getNode('arguments')->getNode(0),
98 1
                new ConstantExpression('replace', $lineno),
99 1
                new Node([
100 1
                    clone $wrappingNode->getNode('arguments')->getNode(0),
101
                ]),
102
                $lineno
103
            );
104
        }
105
106 1
        $condition = new ConditionalExpression(
107 1
            new EqualBinary($testNode, $transNode->getNode('node'), $wrappingNode->getTemplateLine()),
108
            $defaultNode,
109 1
            clone $wrappingNode,
110 1
            $wrappingNode->getTemplateLine()
111
        );
112 1
        $node->setNode('node', $condition);
113
114 1
        return $node;
115
    }
116
117 1
    public function doLeaveNode(Node $node, Environment $env): Node
118
    {
119 1
        return $node;
120
    }
121
122 1
    public function getPriority(): int
123
    {
124 1
        return -2;
125
    }
126
}
127