Completed
Pull Request — master (#5)
by
unknown
11:39
created

TurnOnAutowireCompilerPass::isDefinitionValid()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 20
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 6.6

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 0
loc 20
ccs 6
cts 10
cp 0.6
rs 8.8571
cc 5
eloc 10
nc 5
nop 1
crap 6.6
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 3
    public function process(ContainerBuilder $containerBuilder)
22
    {
23 3
        foreach ($containerBuilder->getDefinitions() as $definition) {
24 3
            if ($this->shouldDefinitionBeAutowired($definition)) {
25 3
                $definition->setAutowired(true);
26
            }
27
        }
28 1
    }
29
30 3
    private function shouldDefinitionBeAutowired(Definition $definition) : bool
31
    {
32 3
        if (!$this->isDefinitionValid($definition)) {
33
            return false;
34
        }
35
36 3
        $classReflection = new ReflectionClass($definition->getClass());
37 3
        if (!$classReflection->hasMethod('__construct')) {
38 2
            return false;
39
        }
40
41 3
        if (!$this->hasConstructorArguments($classReflection)) {
42
            return false;
43
        }
44
45 3
        if ($this->areAllConstructorArgumentsRequired($definition, $classReflection)) {
46
            return false;
47
        }
48
49 3
        $constructorReflection = $classReflection->getConstructor();
50 3
        if (!$this->haveMissingArgumentsTypehints($definition, $constructorReflection)) {
51
            return false;
52
        }
53
54 3
        return true;
55
    }
56
57 3
    private function isDefinitionValid(Definition $definition) : bool
58
    {
59 3
        if (null === $definition->getClass()) {
60
            return false;
61
        }
62
63 3
        if (!$definition->isPublic()) {
64
            return false;
65
        }
66
67 3
        if ($definition->isAbstract()) {
68
            return false;
69
        }
70
71 3
        if (!class_exists($definition->getClass())) {
72
            return false;
73
        }
74
75 3
        return true;
76
    }
77
78 3
    private function areAllConstructorArgumentsRequired(Definition $definition, ReflectionClass $classReflection) : bool
79
    {
80 3
        $constructorMethodReflection = $classReflection->getConstructor();
81
82 3
        $constructorArgumentsCount = count($definition->getArguments());
83 3
        $constructorRequiredArgumentsCount = $constructorMethodReflection->getNumberOfRequiredParameters();
84
85 3
        if ($constructorArgumentsCount === $constructorRequiredArgumentsCount) {
86
            return true;
87
        }
88
89 3
        return false;
90
    }
91
92 3
    private function hasConstructorArguments(ReflectionClass $classReflection) : bool
93
    {
94 3
        $constructorMethodReflection = $classReflection->getConstructor();
95 3
        if ($constructorMethodReflection->getNumberOfParameters()) {
96 3
            return true;
97
        }
98
99
        return false;
100
    }
101
102 3
    private function haveMissingArgumentsTypehints(
103
        Definition $definition,
104
        ReflectionMethod $constructorReflection
105
    ) : bool {
106 3
        $arguments = $definition->getArguments();
107 3
        if (!count($arguments)) {
108 3
            return true;
109
        }
110
111 2
        $i = 0;
112 2
        foreach ($constructorReflection->getParameters() as $parameterReflection) {
113 2
            if ($arguments[$i] === '' && $parameterReflection->getType() !== null) {
114
                return true;
115
            }
116 2
            ++$i;
117
        }
118
119
        return false;
120
    }
121
}
122