Completed
Push — master ( 8c5b1a...9a26dd )
by Tomáš
17:38
created

TurnOnAutowireCompilerPass   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 122
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 82.35%

Importance

Changes 4
Bugs 2 Features 0
Metric Value
wmc 23
c 4
b 2
f 0
lcom 1
cbo 2
dl 0
loc 122
ccs 42
cts 51
cp 0.8235
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A process() 0 8 3
A hasConstructorArguments() 0 9 2
B shouldDefinitionBeAutowired() 0 26 6
B isDefinitionValid() 0 20 5
A areAllConstructorArgumentsRequired() 0 13 2
B haveMissingArgumentsTypehints() 0 17 5
1
<?php
2
3
/*
4
 * This file is part of Symplify
5
 * Copyright (c) 2016 Tomas Votruba (http://tomasvotruba.cz).
6
 */
7
8
namespace Symplify\DefaultAutowire\DependencyInjection\Compiler;
9
10
use ReflectionClass;
11
use ReflectionMethod;
12
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
13
use Symfony\Component\DependencyInjection\ContainerBuilder;
14
use Symfony\Component\DependencyInjection\Definition;
15
16
final class TurnOnAutowireCompilerPass implements CompilerPassInterface
17
{
18
    /**
19
     * {@inheritdoc}
20
     */
21 2
    public function process(ContainerBuilder $containerBuilder)
22
    {
23 2
        foreach ($containerBuilder->getDefinitions() as $name => $definition) {
24 2
            if ($this->shouldDefinitionBeAutowired($name, $definition)) {
25 2
                $definition->setAutowired(true);
26
            }
27
        }
28 2
    }
29
30
    /**
31
     * @param string $name
32
     * @param Definition $definition
33
     *
34
     * @return bool
35
     */
36 2
    private function shouldDefinitionBeAutowired($name, Definition $definition)
0 ignored issues
show
Unused Code introduced by
The parameter $name is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
37
    {
38 2
        if (!$this->isDefinitionValid($definition)) {
39 1
            return false;
40
        }
41
42 2
        $classReflection = new ReflectionClass($definition->getClass());
43 2
        if (!$classReflection->hasMethod('__construct')) {
44 1
            return false;
45
        }
46
47 2
        if (!$this->hasConstructorArguments($classReflection)) {
48
            return false;
49
        }
50
51 2
        if ($this->areAllConstructorArgumentsRequired($definition, $classReflection)) {
52 1
            return false;
53
        }
54
55 2
        $constructorReflection = $classReflection->getConstructor();
56 2
        if (!$this->haveMissingArgumentsTypehints($definition, $constructorReflection)) {
57
            return false;
58
        }
59
60 2
        return true;
61
    }
62
63
    /**
64
     * @return bool
65
     */
66 2
    private function isDefinitionValid(Definition $definition)
67
    {
68 2
        if (null === $definition->getClass()) {
69 1
            return false;
70
        }
71
72 2
        if (!$definition->isPublic()) {
73 1
            return false;
74
        }
75
76 2
        if ($definition->isAbstract()) {
77 1
            return false;
78
        }
79
80 2
        if (!class_exists($definition->getClass())) {
81 1
            return false;
82
        }
83
84 2
        return true;
85
    }
86
87
    /**
88
     * @return bool
89
     */
90 2
    private function areAllConstructorArgumentsRequired(Definition $definition, ReflectionClass $classReflection)
91
    {
92 2
        $constructorMethodReflection = $classReflection->getConstructor();
93
94 2
        $constructorArgumentsCount = count($definition->getArguments());
95 2
        $constructorRequiredArgumentsCount = $constructorMethodReflection->getNumberOfRequiredParameters();
96
97 2
        if ($constructorArgumentsCount === $constructorRequiredArgumentsCount) {
98 1
            return true;
99
        }
100
101 2
        return false;
102
    }
103
104
    /**
105
     * @return bool
106
     */
107 2
    private function hasConstructorArguments(ReflectionClass $classReflection)
108
    {
109 2
        $constructorMethodReflection = $classReflection->getConstructor();
110 2
        if ($constructorMethodReflection->getNumberOfParameters()) {
111 2
            return true;
112
        }
113
114
        return false;
115
    }
116
117
    /**
118
     * @return bool
119
     */
120 2
    private function haveMissingArgumentsTypehints(Definition $definition, ReflectionMethod $constructorReflection)
121
    {
122 2
        $arguments = $definition->getArguments();
123 2
        if (!count($arguments)) {
124 2
            return true;
125
        }
126
127
        $i = 0;
128
        foreach ($constructorReflection->getParameters() as $parameterReflection) {
129
            if ($arguments[$i] === '' && $parameterReflection->getType() !== null) {
130
                return true;
131
            }
132
            ++$i;
133
        }
134
135
        return false;
136
    }
137
}
138