AbstractFormType   A
last analyzed

Complexity

Total Complexity 28

Size/Duplication

Total Lines 139
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Test Coverage

Coverage 82.14%

Importance

Changes 0
Metric Value
wmc 28
lcom 1
cbo 5
dl 0
loc 139
c 0
b 0
f 0
ccs 46
cts 56
cp 0.8214
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
B enterNode() 0 17 7
A lateCollect() 0 4 1
A leaveNode() 0 4 1
A beforeTraverse() 0 7 1
C parseDefaultsCall() 0 57 14
A afterTraverse() 0 17 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\Symfony;
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
 * @author Tobias Nyholm <[email protected]>
21
 */
22
abstract class AbstractFormType extends BasePHPVisitor implements NodeVisitor
23
{
24
    /**
25
     * @var SourceLocation[]
26
     */
27
    private $sourceLocations = [];
28
29
    /**
30
     * @var string|null
31
     */
32
    private $defaultDomain;
33
34
    /**
35
     * {@inheritdoc}
36
     */
37 18
    public function enterNode(Node $node): ?Node
38
    {
39 18
        if ($node instanceof Node\Expr\MethodCall) {
40 18
            if (!\is_string($node->name) && !$node->name instanceof Node\Identifier) {
41 1
                return null;
42
            }
43
44 18
            $name = strtolower((string) $node->name);
45 18
            if ('setdefaults' === $name || 'replacedefaults' === $name || 'setdefault' === $name) {
46 1
                $this->parseDefaultsCall($node);
47
48 1
                return null;
49
            }
50
        }
51
52 18
        return null;
53
    }
54
55 13
    protected function lateCollect(SourceLocation $location): void
56
    {
57 13
        $this->sourceLocations[] = $location;
58 13
    }
59
60
    /**
61
     * {@inheritdoc}
62
     */
63 22
    public function leaveNode(Node $node): ?Node
64
    {
65 22
        return null;
66
    }
67
68
    /**
69
     * {@inheritdoc}
70
     */
71 22
    public function beforeTraverse(array $nodes): ?Node
72
    {
73 22
        $this->defaultDomain = null;
74 22
        $this->sourceLocations = [];
75
76 22
        return null;
77
    }
78
79
    /**
80
     * From JMS Translation bundle.
81
     */
82 1
    private function parseDefaultsCall(Node $node): void
83
    {
84 1
        static $returningMethods = [
85
            'setdefaults' => true, 'replacedefaults' => true, 'setoptional' => true, 'setrequired' => true,
86
            'setallowedvalues' => true, 'addallowedvalues' => true, 'setallowedtypes' => true,
87
            'addallowedtypes' => true, 'setfilters' => true,
88
        ];
89
90 1
        $var = $node->var;
0 ignored issues
show
Bug introduced by
Accessing var on the interface PhpParser\Node suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
91 1
        while ($var instanceof Node\Expr\MethodCall) {
92
            if (!isset($returningMethods[strtolower($var->name)])) {
93
                return;
94
            }
95
96
            $var = $var->var;
97
        }
98
99 1
        if (!$var instanceof Node\Expr\Variable) {
100
            return;
101
        }
102
103
        // check if options were passed
104 1
        if (!isset($node->args[0])) {
0 ignored issues
show
Bug introduced by
Accessing args on the interface PhpParser\Node suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
105
            return;
106
        }
107
108 1
        if (isset($node->args[1])
0 ignored issues
show
Bug introduced by
Accessing args on the interface PhpParser\Node suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
109 1
            && $node->args[0]->value instanceof Node\Scalar\String_
0 ignored issues
show
Bug introduced by
Accessing args on the interface PhpParser\Node suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
110 1
            && $node->args[1]->value instanceof Node\Scalar\String_
0 ignored issues
show
Bug introduced by
Accessing args on the interface PhpParser\Node suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
111 1
            && 'translation_domain' === $node->args[0]->value->value
0 ignored issues
show
Bug introduced by
Accessing args on the interface PhpParser\Node suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
112
        ) {
113
            $this->defaultDomain = $node->args[1]->value->value;
0 ignored issues
show
Bug introduced by
Accessing args on the interface PhpParser\Node suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
114
115
            return;
116
        }
117
118
        // ignore everything except an array
119 1
        if (!$node->args[0]->value instanceof Node\Expr\Array_) {
0 ignored issues
show
Bug introduced by
Accessing args on the interface PhpParser\Node suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
120
            return;
121
        }
122
123
        // check if a translation_domain is set as a default option
124 1
        $domain = null;
0 ignored issues
show
Unused Code introduced by
$domain is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
125 1
        foreach ($node->args[0]->value->items as $item) {
0 ignored issues
show
Bug introduced by
Accessing args on the interface PhpParser\Node suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
126 1
            if (!$item->key instanceof Node\Scalar\String_) {
127
                continue;
128
            }
129
130 1
            if ('translation_domain' === $item->key->value) {
131 1
                if (!$item->value instanceof Node\Scalar\String_) {
132
                    continue;
133
                }
134
135 1
                $this->defaultDomain = $item->value->value;
136
            }
137
        }
138 1
    }
139
140
    /**
141
     * {@inheritdoc}
142
     */
143 22
    public function afterTraverse(array $nodes): ?Node
144
    {
145
        /** @var SourceLocation $location */
146 22
        foreach ($this->sourceLocations as $location) {
147 13
            if (null !== $this->defaultDomain) {
148 1
                $context = $location->getContext();
149 1
                if (null === $context['domain']) {
150 1
                    $context['domain'] = $this->defaultDomain;
151 1
                    $location = new SourceLocation($location->getMessage(), $location->getPath(), $location->getLine(), $context);
152
                }
153
            }
154 13
            $this->collection->addLocation($location);
155
        }
156 22
        $this->sourceLocations = [];
157
158 22
        return null;
159
    }
160
}
161