Completed
Push — master ( 130d29...c9c04e )
by Tobias
187:22 queued 181:29
created

DefaultApplyingNodeVisitor::doLeaveNode()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 1
b 0
f 0
cc 1
nc 1
nop 2
crap 1
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
16
/**
17
 * Applies the value of the "desc" filter if the "trans" filter has no
18
 * translations.
19
 *
20
 * This is only active in your development environment.
21
 *
22
 * @author Johannes M. Schmitt <[email protected]>
23
 */
24
final class DefaultApplyingNodeVisitor extends \Twig_BaseNodeVisitor
25
{
26
    /**
27
     * @var bool
28
     */
29
    private $enabled = true;
30
31
    /**
32
     * @param $bool
33
     */
34
    public function setEnabled($bool)
35
    {
36
        $this->enabled = (bool) $bool;
37
    }
38
39
    /**
40
     * @param \Twig_Node        $node
41
     * @param \Twig_Environment $env
42
     *
43
     * @return \Twig_Node
44
     */
45 1
    public function doEnterNode(\Twig_Node $node, \Twig_Environment $env)
46
    {
47 1
        if (!$this->enabled) {
48
            return $node;
49
        }
50
51 1
        if (!($node instanceof \Twig_Node_Expression_Filter && 'desc' === $node->getNode('filter')->getAttribute('value'))) {
52 1
            return $node;
53
        }
54
55 1
        $transNode = $node->getNode('node');
56 1
        while ($transNode instanceof \Twig_Node_Expression_Filter
57 1
                   && 'trans' !== $transNode->getNode('filter')->getAttribute('value')
58 1
                   && 'transchoice' !== $transNode->getNode('filter')->getAttribute('value')) {
59
            $transNode = $transNode->getNode('node');
60
        }
61
62 1
        if (!$transNode instanceof \Twig_Node_Expression_Filter) {
63
            throw new \RuntimeException(sprintf('The "desc" filter must be applied after a "trans", or "transchoice" filter.'));
64
        }
65
66 1
        $wrappingNode = $node->getNode('node');
67 1
        $testNode = clone $wrappingNode;
68 1
        $defaultNode = $node->getNode('arguments')->getNode(0);
69
70
        // if the |transchoice filter is used, delegate the call to the TranslationExtension
71
        // so that we can catch a possible exception when the default translation has not yet
72
        // been extracted
73 1
        if ('transchoice' === $transNode->getNode('filter')->getAttribute('value')) {
74
            $transchoiceArguments = new \Twig_Node_Expression_Array([], $transNode->getTemplateLine());
75
            $transchoiceArguments->addElement($wrappingNode->getNode('node'));
0 ignored issues
show
Compatibility introduced by
$wrappingNode->getNode('node') of type object<Twig_Node> is not a sub-type of object<Twig_Node_Expression>. It seems like you assume a child class of the class Twig_Node to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
76
            $transchoiceArguments->addElement($defaultNode);
0 ignored issues
show
Compatibility introduced by
$defaultNode of type object<Twig_Node> is not a sub-type of object<Twig_Node_Expression>. It seems like you assume a child class of the class Twig_Node to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
77
            foreach ($wrappingNode->getNode('arguments') as $arg) {
78
                $transchoiceArguments->addElement($arg);
79
            }
80
81
            $transchoiceNode = new Transchoice($transchoiceArguments, $transNode->getTemplateLine());
82
            $node->setNode('node', $transchoiceNode);
0 ignored issues
show
Documentation introduced by
$transchoiceNode is of type object<Translation\Bundle\Twig\Node\Transchoice>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
83
84
            return $node;
85
        }
86
87
        // if the |trans filter has replacements parameters
88
        // (e.g. |trans({'%foo%': 'bar'}))
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
89 1
        if ($wrappingNode->getNode('arguments')->hasNode(0)) {
90 1
            $lineno = $wrappingNode->getTemplateLine();
91
92
            // remove the replacements from the test node
93 1
            $testNode->setNode('arguments', clone $testNode->getNode('arguments'));
0 ignored issues
show
Documentation introduced by
clone $testNode->getNode('arguments') is of type object<Twig_Node>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
94 1
            $testNode->getNode('arguments')->setNode(0, new \Twig_Node_Expression_Array([], $lineno));
0 ignored issues
show
Documentation introduced by
new \Twig_Node_Expression_Array(array(), $lineno) is of type object<Twig_Node_Expression_Array>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
95
96
            // wrap the default node in a |replace filter
97 1
            $defaultNode = new \Twig_Node_Expression_Filter(
98 1
                clone $node->getNode('arguments')->getNode(0),
99 1
                new \Twig_Node_Expression_Constant('replace', $lineno),
100 1
                new \Twig_Node([
101 1
                    clone $wrappingNode->getNode('arguments')->getNode(0),
102
                ]),
103 1
                $lineno
104
            );
105
        }
106
107 1
        $condition = new \Twig_Node_Expression_Conditional(
108 1
            new \Twig_Node_Expression_Binary_Equal($testNode, $transNode->getNode('node'), $wrappingNode->getTemplateLine()),
109 1
            $defaultNode,
0 ignored issues
show
Compatibility introduced by
$defaultNode of type object<Twig_Node> is not a sub-type of object<Twig_Node_Expression>. It seems like you assume a child class of the class Twig_Node to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
110 1
            clone $wrappingNode,
0 ignored issues
show
Compatibility introduced by
clone $wrappingNode of type object<Twig_Node> is not a sub-type of object<Twig_Node_Expression>. It seems like you assume a child class of the class Twig_Node to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
111 1
            $wrappingNode->getTemplateLine()
112
        );
113 1
        $node->setNode('node', $condition);
0 ignored issues
show
Documentation introduced by
$condition is of type object<Twig_Node_Expression_Conditional>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
114
115 1
        return $node;
116
    }
117
118
    /**
119
     * @param \Twig_Node        $node
120
     * @param \Twig_Environment $env
121
     *
122
     * @return \Twig_Node
123
     */
124 1
    public function doLeaveNode(\Twig_Node $node, \Twig_Environment $env)
125
    {
126 1
        return $node;
127
    }
128
129
    /**
130
     * @return int
131
     */
132 1
    public function getPriority()
133
    {
134 1
        return -2;
135
    }
136
}
137