Completed
Push — master ( d3edd8...61bf89 )
by
unknown
02:52
created

ReflectionParameterAnalyzer::setOrderArguments()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 11
ccs 6
cts 6
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 7
nc 2
nop 2
crap 2
1
<?php declare(strict_types = 1);
2
/**
3
 * Created by Ruslan Molodyko.
4
 * Date: 10.09.2016
5
 * Time: 15:33
6
 */
7
namespace samsonframework\container\definition\analyzer\reflection;
8
9
use samsonframework\container\definition\analyzer\DefinitionAnalyzer;
10
use samsonframework\container\definition\analyzer\ParameterAnalyzerInterface;
11
use samsonframework\container\definition\builder\exception\ReferenceNotImplementsException;
12
use samsonframework\container\definition\ClassDefinition;
13
use samsonframework\container\definition\exception\MethodDefinitionNotFoundException;
14
use samsonframework\container\definition\exception\ParameterDefinitionAlreadyExistsException;
15
use samsonframework\container\definition\exception\ParameterDefinitionNotFoundException;
16
use samsonframework\container\definition\MethodDefinition;
17
use samsonframework\container\definition\ParameterDefinition;
18
use samsonframework\container\definition\reference\ClassReference;
19
use samsonframework\container\definition\reference\CollectionReference;
20
use samsonframework\container\definition\reference\ConstantReference;
21
use samsonframework\container\definition\reference\UndefinedReference;
22
23
/**
24
 * Class ReflectionParameterAnalyzer
25
 *
26
 * @author Ruslan Molodyko <[email protected]>
27
 */
28
class ReflectionParameterAnalyzer implements ParameterAnalyzerInterface
29
{
30
    /**
31
     * {@inheritdoc}
32
     * @throws ParameterDefinitionAlreadyExistsException
33
     * @throws ReferenceNotImplementsException
34
     * @throws MethodDefinitionNotFoundException
35
     * @throws ParameterDefinitionNotFoundException
36
     * @throws \InvalidArgumentException
37
     */
38 4
    public function analyze(
39
        DefinitionAnalyzer $analyzer,
40
        ClassDefinition $classDefinition,
41
        \ReflectionParameter $reflectionParameter
42
    ) {
43 4
        $methodName = $reflectionParameter->getDeclaringFunction()->getName();
0 ignored issues
show
Bug introduced by
Consider using $reflectionParameter->ge...claringFunction()->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
44 4
        $parameterName = $reflectionParameter->getName();
0 ignored issues
show
Bug introduced by
Consider using $reflectionParameter->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
45
        // Define parameter only if method definition is available
46 4
        if ($classDefinition->hasMethod($methodName)) {
47 4
            $methodDefinition = $classDefinition->getMethod($methodName);
48
49
            // Define parameter definition if not exists
50 4
            $parameterDefinition = $methodDefinition->setupParameter($parameterName);
51 4
            $this->setReflectionMetadata($parameterDefinition, $reflectionParameter);
52
53 4
            $dependency = $parameterDefinition->getDependency();
54
            // If dependency was not set
55
            // UndefinedReference is the default value of dependency which was not use before
56 4
            if (!$dependency || ($dependency instanceof UndefinedReference)) {
57 1
                $this->setDependencyByReflection($parameterDefinition, $reflectionParameter);
58
            }
59
60 4
            $this->setOrderArguments($methodDefinition, $reflectionParameter->getDeclaringFunction());
61
        }
62 4
    }
63
64
    /**
65
     * Set correct order of arguments
66
     *
67
     * @param MethodDefinition $methodDefinition
68
     * @param \ReflectionFunctionAbstract $reflectionMethod
69
     * @throws \InvalidArgumentException
70
     */
71 4
    public function setOrderArguments(
72
        MethodDefinition $methodDefinition,
73
        \ReflectionFunctionAbstract $reflectionMethod
74
    ) {
75 4
        $parameters = [];
76
        // Get parameter names
77 4
        foreach ($reflectionMethod->getParameters() as $reflectionParameter) {
78 4
            $parameters[] = $reflectionParameter->getName();
0 ignored issues
show
Bug introduced by
Consider using $reflectionParameter->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
79
        }
80 4
        $methodDefinition->setParametersCollectionOrder($parameters);
81 4
    }
82
83
    /**
84
     * Set initial reflection metadata into the parameter definition
85
     *
86
     * @param ParameterDefinition $parameterDefinition
87
     * @param \ReflectionParameter $reflectionParameter
88
     */
89 4
    public function setReflectionMetadata(
90
        ParameterDefinition $parameterDefinition,
91
        \ReflectionParameter $reflectionParameter
92
    ) {
93
        // Set parameter metadata
94 4
        if ($reflectionParameter->isDefaultValueAvailable()) {
95 1
            $parameterDefinition->setValue($reflectionParameter->getDefaultValue());
96
        }
97 4
        if ($reflectionParameter->getType()) {
98 4
            $parameterDefinition->setTypeHint($reflectionParameter->getType());
99
        }
100 4
        $parameterDefinition->setIsOptional($reflectionParameter->isOptional());
101 4
    }
102
103
    /**
104
     * Set dependency value by reflection
105
     *
106
     * @param ParameterDefinition $parameterDefinition
107
     * @param \ReflectionParameter $reflectionParameter
108
     * @throws \InvalidArgumentException
109
     * @throws ReferenceNotImplementsException
110
     */
111 1
    public function setDependencyByReflection(
112
        ParameterDefinition $parameterDefinition,
113
        \ReflectionParameter $reflectionParameter
114
    ) {
115
        // If default value available
116 1
        if ($reflectionParameter->isDefaultValueAvailable()) {
117
            // There is a constant
118 1
            if ($reflectionParameter->isDefaultValueConstant()) {
119
                $parameterDefinition->setDependency(
120
                    new ConstantReference($reflectionParameter->getDefaultValueConstantName())
121
                );
122
            } else { // There is some php types
123 1
                $parameterDefinition->setDependency(
124 1
                    CollectionReference::convertValueToReference($reflectionParameter->getDefaultValue())
125
                );
126
            }
127
            // There is class dependency
128 1
        } elseif ($this->checkIfTypeHingIsClass($parameterDefinition)) {
129 1
            $class = (string)$parameterDefinition->getTypeHint();
130 1
            $parameterDefinition->setDependency(new ClassReference($class));
131
        }
132 1
    }
133
134
    /**
135
     * Check if type hint can be as class reference dependency
136
     *
137
     * @param ParameterDefinition $parameterDefinition
138
     * @return bool
139
     */
140 1
    protected function checkIfTypeHingIsClass(ParameterDefinition $parameterDefinition)
141
    {
142 1
        return is_object($parameterDefinition->getTypeHint()) &&
143 1
            (string)$parameterDefinition->getTypeHint() !== '' &&
144 1
            !$parameterDefinition->getTypeHint()->isBuiltin();
145
    }
146
}
147