DependencyInjectionManager::getFrameworkInstance()   B
last analyzed

Complexity

Conditions 5
Paths 5

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
dl 0
loc 18
ccs 0
cts 10
cp 0
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 9
nc 5
nop 1
crap 30
1
<?php
2
/*
3
 * The MIT License (MIT)
4
 *
5
 * Copyright (c) 2015 zepi
6
 *
7
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8
 * of this software and associated documentation files (the "Software"), to deal
9
 * in the Software without restriction, including without limitation the rights
10
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
 * copies of the Software, and to permit persons to whom the Software is
12
 * furnished to do so, subject to the following conditions:
13
 *
14
 * The above copyright notice and this permission notice shall be included in
15
 * all copies or substantial portions of the Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
 * THE SOFTWARE.
24
 *
25
 */
26
27
/**
28
 * The DependenyInjectionManager manages the initiation of new
29
 * objects. The manager will analyze the construct method of the
30
 * given class name and loads the needed objects for the construction.
31
 * 
32
 * @package Zepi\Turbo\Manager
33
 * @author Matthias Zobrist <[email protected]>
34
 * @copyright Copyright (c) 2016 zepi
35
 */
36
37
namespace Zepi\Turbo\Manager;
38
39
use \Zepi\Turbo\Framework;
40
use \Zepi\Turbo\Exception;
41
use \ReflectionClass;
42
use \ReflectionMethod;
43
44
/**
45
 * The DependenyInjectionManager manages the initiation of new
46
 * objects. The manager will analyze the construct method of the
47
 * given class name and loads the needed objects for the construction.
48
 * 
49
 * @author Matthias Zobrist <[email protected]>
50
 * @copyright Copyright (c) 2016 zepi
51
 */
52
class DependencyInjectionManager
53
{
54
    /**
55
     * @access protected
56
     * @var Framework
57
     */
58
    protected $framework;
59
    
60
    /**
61
     * @var array
62
     */
63
    protected $sharedInstances = array();
64
    
65
    /**
66
     * Constructs the object
67
     * 
68
     * @access public
69
     * @param \Zepi\Turbo\Framework $framework
70
     */
71 17
    public function __construct(Framework $framework)
72
    {
73 17
        $this->framework = $framework;
74 17
    }
75
    
76
    /**
77
     * Initiates the given class name
78
     *
79
     * @param string $className
80
     * @param array $additionalParameters
81
     * @param boolean $shared
82
     * @return object
83
     */
84
    public function initiateObject($className, $additionalParameters = array(), $shared = false)
85
    {
86
        if (isset($this->sharedInstances[$className])) {
87
            return $this->sharedInstances[$className];
88
        }
89
        
90
        $reflection = new ReflectionClass($className);
91
        
92
        if ($reflection->hasMethod('__construct')) {
93
            $constructor = $reflection->getConstructor();
94
            $parameters = $this->prepareParameters($constructor, $additionalParameters);
95
            
96
            $instance = $reflection->newInstanceArgs($parameters);
97
        } else {
98
            $instance = new $className();
99
        }
100
        
101
        if ($shared) {
102
            $this->sharedInstances[$className] = $instance;
103
        }
104
        
105
        return $instance;
106
    }
107
    
108
    /**
109
     * Prepares the parameters for the given constructor
110
     * 
111
     * @param \ReflectionMethod $constructor
112
     * @param array $additionalParameters
113
     * @return array
114
     * 
115
     * @throws \Zepi\Turbo\Exception Cannot find correct value for parameter "{parameterName}" in class "{className}". 
116
     */
117
    protected function prepareParameters(ReflectionMethod $constructor, $additionalParameters)
118
    {
119
        $parameters = array();
120
        foreach ($constructor->getParameters() as $parameter) {
121
            $parameterValue = null;
122
        
123
            if (isset($additionalParameters[$parameter->name])) {
124
                $parameterValue = $additionalParameters[$parameter->name];
125
            } else if ($parameter->getClass() !== null) {
126
                $parameterValue = $this->getInstance($parameter->getClass());
127
            }
128
        
129
            if ($parameterValue === null) {
130
                throw new Exception('Cannot find correct value for parameter "' . $parameter->name . '" in class "' . $constructor->class . '".');
131
            }
132
        
133
            $parameters[] = $parameterValue;
134
        }
135
        
136
        return $parameters;
137
    }
138
    
139
    /**
140
     * Returns the instance for the given class
141
     * 
142
     * @param \ReflectionClass $parameterClass
143
     * @return null|object
144
     */
145
    protected function getInstance(ReflectionClass $parameterClass)
146
    {
147
        if (!class_exists($parameterClass->name, true)) {
148
            return null;
149
        }
150
        
151
        if (strpos($parameterClass->name, 'Zepi\\Turbo\\') === 0) {
152
            return $this->getFrameworkInstance($parameterClass);
153
        }
154
        
155
        if ($parameterClass->isInstantiable()) {
156
            return $this->framework->getInstance($parameterClass->name);
157
        }
158
    }
159
    
160
    /**
161
     * Returns the instance for the given class if the class path
162
     * starts with Zepi\Turbo.
163
     * 
164
     * @param \ReflectionClass $parameterClass
165
     * @return object
166
     */
167
    protected function getFrameworkInstance(ReflectionClass $parameterClass)
168
    {
169
        if ($parameterClass->name == 'Zepi\\Turbo\\Framework') {
170
            return $this->framework;
171
        }
172
        
173
        if ($parameterClass->name == 'Zepi\\Turbo\\Request\\RequestAbstract') {
174
            return $this->framework->getRequest();
175
        }
176
        
177
        if ($parameterClass->name == 'Zepi\\Turbo\\Response\\Response') {
178
            return $this->framework->getResponse();
179
        }
180
        
181
        if ($parameterClass->getNamespaceName() === 'Zepi\\Turbo\\Manager') {
182
            return $this->getFrameworkManager($parameterClass->name);
183
        }
184
    }
185
    
186
    /**
187
     * Returns the framework manager for the given class name
188
     * 
189
     * @param string $className
190
     * @return object
191
     * 
192
     * @throws \Zepi\Turbo\Exception Cannot find framework manager "{className}".
193
     */
194
    protected function getFrameworkManager($className)
195
    {
196
        switch ($className) {
197
            case 'Zepi\\Turbo\\Manager\\DataSourceManager':
198
                return $this->framework->getDataSourceManager();
199
            break;
200
            
201
            case 'Zepi\\Turbo\\Manager\\DependencyInjectionManager':
202
                return $this->framework->getDependencyInjectionManager();
203
            break;
204
                
205
            case 'Zepi\\Turbo\\Manager\\ModuleManager':
206
                return $this->framework->getModuleManager();
207
            break;
208
                
209
            case 'Zepi\\Turbo\\Manager\\RequestManager':
210
                return $this->framework->getRequestManager();
211
            break;
212
                
213
            case 'Zepi\\Turbo\\Manager\\RouteManager':
214
                return $this->framework->getRouteManager();
215
            break;
216
            
217
            case 'Zepi\\Turbo\\Manager\\RuntimeManager':
218
                return $this->framework->getRuntimeManager();
219
            break;
220
            
221
            default:
222
                throw new Exception('Cannot find framework manager "' . $className . '".');
223
            break;
224
        }
225
    }
226
}
227