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

TurnOnAutowireCompilerPass::isDefinitionValid()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 20
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 5

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 0
loc 20
ccs 10
cts 10
cp 1
rs 8.8571
cc 5
eloc 10
nc 5
nop 1
crap 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