injectDependenciesToProperties()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 8
cts 8
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 6
nc 2
nop 2
crap 2
1
<?php
2
3
/*
4
 * Copyright (c) 2011-2015, Celestino Diaz <[email protected]>
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24
25
namespace Brickoo\Component\IoC\Resolver;
26
27
use Brickoo\Component\IoC\Definition\ArgumentDefinition;
28
use Brickoo\Component\IoC\Definition\DependencyDefinition;
29
use Brickoo\Component\IoC\Definition\Container\ArgumentDefinitionContainer;
30
use Brickoo\Component\IoC\Definition\InjectionDefinition;
31
use Brickoo\Component\IoC\DIContainer;
32
33
/**
34
 * DependencyResolver
35
 *
36
 * Defines an abstract dependency resolver.
37
 * @author Celestino Diaz <[email protected]>
38
 */
39
abstract class DependencyResolver {
40
41
    /** @var string */
42
    protected $definitionPrefix;
43
44
    /** @var \Brickoo\Component\IoC\DIContainer */
45
    protected $diContainer;
46
47
    /**
48
     * Class constructor.
49
     * @param \Brickoo\Component\IoC\DIContainer $diContainer
50
     * @param string $dependencyPrefix
51
     */
52 3
    public function __construct(DIContainer $diContainer, $dependencyPrefix = "@") {
53 3
        $this->diContainer = $diContainer;
54 3
        $this->definitionPrefix = $dependencyPrefix;
55 3
    }
56
57
    /**
58
     * Returns the DI container instance.
59
     * @return \Brickoo\Component\IoC\DIContainer
60
     */
61 1
    public function getDiContainer() {
62 1
        return $this->diContainer;
63
    }
64
65
    /**
66
     * Resolves a dependency definition.
67
     * @param \Brickoo\Component\IoC\Definition\DependencyDefinition
68
     * @throws \Brickoo\Component\IoC\Exception
69
     * @return mixed the resolved definition result
70
     */
71
    abstract public function resolve(DependencyDefinition $dependencyDefinition);
72
73
    /**
74
     * Collects the arguments from an argument definition.
75
     * @param \Brickoo\Component\IoC\Definition\Container\ArgumentDefinitionContainer $argumentsContainer
76
     * @return array the collected arguments
77
     */
78 2
    protected function collectArguments(ArgumentDefinitionContainer $argumentsContainer) {
79 2
        if ($argumentsContainer->isEmpty()) {
80 1
            return [];
81
        }
82
83 1
        $collectedArguments = [];
84 1
        $arguments = $argumentsContainer->getAll();
85 1
        foreach ($arguments as $index => $argument) {
86 1
            $argumentIndex = $this->getArgumentIndex($argument, $index);
87 1
            $collectedArguments[$argumentIndex] = $this->getArgumentValue($argument);
88 1
        }
89 1
        return $collectedArguments;
90
    }
91
92
    /**
93
     * Returns the argument index.
94
     * @param \Brickoo\Component\IoC\Definition\ArgumentDefinition $argument
95
     * @param integer $currentIndex
96
     * @return string|integer the argument index
97
     */
98 1
    private function getArgumentIndex(ArgumentDefinition $argument, $currentIndex) {
99 1
        return $argument->hasName() ? $argument->getName() : $currentIndex;
100
    }
101
102
    /**
103
     * Returns the argument definition resolved value.
104
     * @param \Brickoo\Component\IoC\Definition\ArgumentDefinition $argument
105
     * @return mixed the argument value
106
     */
107 1
    private function getArgumentValue(ArgumentDefinition $argument) {
108 1
        $argumentValue = $argument->getValue();
109
110 1
        if (is_callable($argumentValue)) {
111 1
            return call_user_func($argumentValue, $this->getDiContainer());
112
        }
113
114 1
        if (is_string($argumentValue)
115 1
            && strpos($argumentValue, $this->definitionPrefix) === 0) {
116 1
                return $this->getDiContainer()->retrieve(
117 1
                    substr($argumentValue, strlen($this->definitionPrefix))
118 1
                );
119
        }
120
121 1
        return $argumentValue;
122
    }
123
124
    /**
125
     * Injects the target object dependencies.
126
     * @param object $targetObject
127
     * @param \Brickoo\Component\IoC\Definition\DependencyDefinition $dependencyDefinition
128
     * @return \Brickoo\Component\IoC\Resolver\DependencyResolver
129
     */
130 2
    protected function injectDependencies($targetObject, DependencyDefinition $dependencyDefinition) {
131 2
        $injectionsContainer = $dependencyDefinition->getInjectionsContainer();
132 2
        if ($injectionsContainer->isEmpty()) {
133 1
            return $targetObject;
134
        }
135
136 1
        if (($injectionDefinitions = $injectionsContainer->getByTarget(InjectionDefinition::TARGET_METHOD))) {
137 1
            $this->injectDependenciesToMethods($targetObject, $injectionDefinitions);
138 1
        }
139
140 1
        if (($injectionDefinitions = $injectionsContainer->getByTarget(InjectionDefinition::TARGET_PROPERTY))) {
141 1
            $this->injectDependenciesToProperties($targetObject, $injectionDefinitions);
142 1
        }
143
144 1
        return $this;
145
    }
146
147
    /**
148
     * Injects the dependencies to the corresponding properties.
149
     * @param object $targetObject
150
     * @param array $injectionDefinitions
151
     * @return void
152
     */
153 1
    private function injectDependenciesToProperties($targetObject, array $injectionDefinitions) {
154 1
        $injectionDefinition = $injectionDefinitions[0];
155 1
        $targetProperty = $injectionDefinition->getTargetName();
156 1
        if (property_exists($targetObject, $targetProperty)) {
157 1
            $arguments = $this->collectArguments($injectionDefinition->getArgumentsContainer());
158 1
            $targetObject->{$targetProperty} = array_shift($arguments);
159 1
        }
160 1
    }
161
162
    /**
163
     * Injects the dependencies to the corresponding methods.
164
     * @param object $targetObject
165
     * @param array $injectionDefinitions
166
     * @return void
167
     */
168 1
    private function injectDependenciesToMethods($targetObject, array $injectionDefinitions) {
169 1
        foreach ($injectionDefinitions as $injectionDefinition) {
170 1
            $targetMethod = $injectionDefinition->getTargetName();
171 1
            if (method_exists($targetObject, $targetMethod)) {
172 1
                call_user_func_array([$targetObject, $targetMethod], $this->collectArguments($injectionDefinition->getArgumentsContainer()));
173 1
            }
174 1
        }
175 1
    }
176
177
}
178