Completed
Push — master ( 9a9938...f96c7c )
by Mathieu
55:39 queued 13s
created

DefaultApplyingNodeVisitor::doEnterNode()   C

Complexity

Conditions 11
Paths 12

Size

Total Lines 72

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 28
CRAP Score 13.7164

Importance

Changes 0
Metric Value
dl 0
loc 72
ccs 28
cts 39
cp 0.7179
rs 6.4642
c 0
b 0
f 0
cc 11
nc 12
nop 2
crap 13.7164

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
    /**
40
     * @param $bool
41
     */
42
    public function setEnabled($bool)
43
    {
44
        $this->enabled = (bool) $bool;
45
    }
46
47
    /**
48
     * @return Node
49
     */
50 1
    public function doEnterNode(Node $node, Environment $env)
51
    {
52 1
        if (!$this->enabled) {
53
            return $node;
54
        }
55
56 1
        if (!($node instanceof FilterExpression && 'desc' === $node->getNode('filter')->getAttribute('value'))) {
57 1
            return $node;
58
        }
59
60 1
        $transNode = $node->getNode('node');
61 1
        while ($transNode instanceof FilterExpression
62 1
                   && 'trans' !== $transNode->getNode('filter')->getAttribute('value')
63 1
                   && 'transchoice' !== $transNode->getNode('filter')->getAttribute('value')) {
64
            $transNode = $transNode->getNode('node');
65
        }
66
67 1
        if (!$transNode instanceof FilterExpression) {
68
            throw new \RuntimeException(\sprintf('The "desc" filter must be applied after a "trans", or "transchoice" filter.'));
69
        }
70
71 1
        $wrappingNode = $node->getNode('node');
72 1
        $testNode = clone $wrappingNode;
73 1
        $defaultNode = $node->getNode('arguments')->getNode(0);
74
75
        // if the |transchoice filter is used, delegate the call to the TranslationExtension
76
        // so that we can catch a possible exception when the default translation has not yet
77
        // been extracted
78 1
        if ('transchoice' === $transNode->getNode('filter')->getAttribute('value')) {
79
            $transchoiceArguments = new ArrayExpression([], $transNode->getTemplateLine());
80
            $transchoiceArguments->addElement($wrappingNode->getNode('node'));
0 ignored issues
show
Compatibility introduced by
$wrappingNode->getNode('node') of type object<Twig\Node\Node> is not a sub-type of object<Twig\Node\Expression\AbstractExpression>. It seems like you assume a child class of the class Twig\Node\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...
81
            $transchoiceArguments->addElement($defaultNode);
0 ignored issues
show
Compatibility introduced by
$defaultNode of type object<Twig\Node\Node> is not a sub-type of object<Twig\Node\Expression\AbstractExpression>. It seems like you assume a child class of the class Twig\Node\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...
82
            foreach ($wrappingNode->getNode('arguments') as $arg) {
83
                $transchoiceArguments->addElement($arg);
84
            }
85
86
            $transchoiceNode = new Transchoice($transchoiceArguments, $transNode->getTemplateLine());
87
            $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...
88
89
            return $node;
90
        }
91
92
        // if the |trans filter has replacements parameters
93
        // (e.g. |trans({'%foo%': 'bar'}))
94 1
        if ($wrappingNode->getNode('arguments')->hasNode(0)) {
95 1
            $lineno = $wrappingNode->getTemplateLine();
96
97
            // remove the replacements from the test node
98 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\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...
99 1
            $testNode->getNode('arguments')->setNode(0, new ArrayExpression([], $lineno));
0 ignored issues
show
Documentation introduced by
new \Twig\Node\Expressio...ssion(array(), $lineno) is of type object<Twig\Node\Expression\ArrayExpression>, 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...
100
101
            // wrap the default node in a |replace filter
102 1
            $defaultNode = new FilterExpression(
103 1
                clone $node->getNode('arguments')->getNode(0),
104 1
                new ConstantExpression('replace', $lineno),
105 1
                new Node([
106 1
                    clone $wrappingNode->getNode('arguments')->getNode(0),
107
                ]),
108
                $lineno
109
            );
110
        }
111
112 1
        $condition = new ConditionalExpression(
113 1
            new EqualBinary($testNode, $transNode->getNode('node'), $wrappingNode->getTemplateLine()),
114
            $defaultNode,
0 ignored issues
show
Compatibility introduced by
$defaultNode of type object<Twig\Node\Node> is not a sub-type of object<Twig\Node\Expression\AbstractExpression>. It seems like you assume a child class of the class Twig\Node\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...
115 1
            clone $wrappingNode,
0 ignored issues
show
Compatibility introduced by
clone $wrappingNode of type object<Twig\Node\Node> is not a sub-type of object<Twig\Node\Expression\AbstractExpression>. It seems like you assume a child class of the class Twig\Node\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...
116 1
            $wrappingNode->getTemplateLine()
117
        );
118 1
        $node->setNode('node', $condition);
0 ignored issues
show
Documentation introduced by
$condition is of type object<Twig\Node\Express...\ConditionalExpression>, 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...
119
120 1
        return $node;
121
    }
122
123
    /**
124
     * @return Node
125
     */
126 1
    public function doLeaveNode(Node $node, Environment $env)
127
    {
128 1
        return $node;
129
    }
130
131
    /**
132
     * @return int
133
     */
134 1
    public function getPriority()
135
    {
136 1
        return -2;
137
    }
138
}
139