Completed
Push — master ( 8009cb...0bf5b8 )
by Olivier
03:52 queued 11s
created

AbstractKnpMenuVisitor   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 121
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Test Coverage

Coverage 68.63%

Importance

Changes 0
Metric Value
wmc 23
lcom 1
cbo 8
dl 0
loc 121
ccs 35
cts 51
cp 0.6863
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A beforeTraverse() 0 6 1
B enterNode() 0 37 10
B isKnpMenuBuildingMethod() 0 24 6
A lateCollect() 0 4 1
A leaveNode() 0 4 1
A afterTraverse() 0 20 4
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\Extractor\Visitor\Php\Knp\Menu;
13
14
use PhpParser\Node;
15
use PhpParser\NodeVisitor;
16
use Translation\Extractor\Model\SourceLocation;
17
use Translation\Extractor\Visitor\Php\BasePHPVisitor;
18
19
/**
20
 * This class provides common functionality for KnpMenu extractors.
21
 */
22
abstract class AbstractKnpMenuVisitor extends BasePHPVisitor implements NodeVisitor
23
{
24
    /**
25
     * @var bool
26
     */
27
    private $isKnpMenuBuildingMethod = false;
28
29
    /**
30
     * @var string|bool
31
     */
32
    private $domain;
33
34
    /**
35
     * @var SourceLocation[]
36
     */
37
    private $sourceLocations = [];
38
39 3
    public function beforeTraverse(array $nodes): ?Node
40
    {
41 3
        $this->sourceLocations = [];
42
43 3
        return null;
44
    }
45
46 3
    public function enterNode(Node $node): ?Node
47
    {
48 3
        if (!$this->isKnpMenuBuildingMethod($node)) {
49
            return null;
50
        }
51
52 3
        if (!$node instanceof Node\Expr\MethodCall) {
53 3
            return null;
54
        }
55
56 3
        if (!\is_string($node->name) && !$node->name instanceof Node\Identifier) {
57
            return null;
58
        }
59
60 3
        $methodName = (string) $node->name;
61 3
        if ('setExtra' !== $methodName) {
62 3
            return null;
63
        }
64
65
        $extraKey = $this->getStringArgument($node, 0);
66
        if ('translation_domain' === $extraKey) {
67
            if (
68
                $node->args[1]->value instanceof Node\Expr\ConstFetch
69
                && 'false' === $node->args[1]->value->name->toString()
70
            ) {
71
                // translation disabled
72
                $this->domain = false;
73
            } else {
74
                $extraValue = $this->getStringArgument($node, 1);
75
                if (null !== $extraValue) {
76
                    $this->domain = $extraValue;
77
                }
78
            }
79
        }
80
81
        return null;
82
    }
83
84
    /**
85
     * Checks if the given node is a class method returning a knp menu.
86
     */
87 3
    protected function isKnpMenuBuildingMethod(Node $node): bool
88
    {
89 3
        if ($node instanceof Node\Stmt\ClassMethod) {
90 3
            if (null === $node->returnType) {
91 1
                $this->isKnpMenuBuildingMethod = false;
92
            }
93 3
            if ($node->returnType instanceof Node\Identifier) {
94 1
                $this->isKnpMenuBuildingMethod = false;
95
            }
96
97 3
            $returnType = $node->returnType;
98 3
            if ($returnType instanceof Node\NullableType) {
99
                $returnType = $returnType->type;
100
            }
101
102 3
            if (!$returnType instanceof Node\Name) {
103 1
                $this->isKnpMenuBuildingMethod = false;
104
            } else {
105 3
                $this->isKnpMenuBuildingMethod = 'ItemInterface' === $returnType->toString();
106
            }
107
        }
108
109 3
        return $this->isKnpMenuBuildingMethod;
110
    }
111
112 3
    protected function lateCollect(SourceLocation $location): void
113
    {
114 3
        $this->sourceLocations[] = $location;
115 3
    }
116
117 3
    public function leaveNode(Node $node): ?Node
118
    {
119 3
        return null;
120
    }
121
122 3
    public function afterTraverse(array $nodes): ?Node
123
    {
124 3
        if (false === $this->domain) {
125
            // translation disabled
126
            return null;
127
        }
128
129
        /** @var SourceLocation $location */
130 3
        foreach ($this->sourceLocations as $location) {
131 3
            if (null !== $this->domain) {
132
                $context = $location->getContext();
133
                $context['domain'] = $this->domain;
134
                $location = new SourceLocation($location->getMessage(), $location->getPath(), $location->getLine(), $context);
135
            }
136 3
            $this->collection->addLocation($location);
137
        }
138 3
        $this->sourceLocations = [];
139
140 3
        return null;
141
    }
142
}
143