Completed
Push — master ( 0a4015...907089 )
by Tobias
01:30
created

src/Visitor/Php/Symfony/AbstractFormType.php (10 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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 16
    public function enterNode(Node $node): ?Node
38
    {
39 16
        if ($node instanceof Node\Expr\MethodCall) {
40 16
            if (!\is_string($node->name) && !$node->name instanceof Node\Identifier) {
41 1
                return null;
42
            }
43
44 16
            $name = strtolower((string) $node->name);
45 16
            if ('setdefaults' === $name || 'replacedefaults' === $name || 'setdefault' === $name) {
46 1
                $this->parseDefaultsCall($node);
47
48 1
                return null;
49
            }
50
        }
51
52 16
        return null;
53
    }
54
55 12
    protected function lateCollect(SourceLocation $location): void
56
    {
57 12
        $this->sourceLocations[] = $location;
58 12
    }
59
60
    /**
61
     * {@inheritdoc}
62
     */
63 19
    public function leaveNode(Node $node): ?Node
64
    {
65 19
        return null;
66
    }
67
68
    /**
69
     * {@inheritdoc}
70
     */
71 19
    public function beforeTraverse(array $nodes): ?Node
72
    {
73 19
        $this->defaultDomain = null;
74 19
        $this->sourceLocations = [];
75
76 19
        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
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
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
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
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
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
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
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
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
$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
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 19
    public function afterTraverse(array $nodes): ?Node
144
    {
145
        /** @var SourceLocation $location */
146 19
        foreach ($this->sourceLocations as $location) {
147 12
            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 12
            $this->collection->addLocation($location);
155
        }
156 19
        $this->sourceLocations = [];
157
158 19
        return null;
159
    }
160
}
161