PluginProbe
Defender Security – Malware Scanner, Login Security & Firewall / 3.0.1
Defender Security – Malware Scanner, Login Security & Firewall v3.0.1
6.3.0 6.2.3 6.2.4 6.2.0 6.2.1 6.2.2 6.1.0 5.3.1 5.4.0 5.4.1 5.5.0 5.5.1 5.6.0 5.6.1 5.6.2 5.7.0 5.7.1 5.7.2 5.8.0 5.8.1 5.9.0 6.0.0 6.0.1 3.0.1 3.1.0 All 141 releases
defender-security / vendor / php-di / php-di / src / DI / Definition / ObjectDefinition.php

ObjectDefinition.php in Defender Security – Malware Scanner, Login Security & Firewall 3.0.1, at vendor/php-di/php-di/src/DI/Definition/ObjectDefinition.php

337 lines 7.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace DI\Definition;
4
5 use DI\Definition\Dumper\ObjectDefinitionDumper;
6 use DI\Definition\ObjectDefinition\MethodInjection;
7 use DI\Definition\ObjectDefinition\PropertyInjection;
8 use DI\Scope;
9 use ReflectionClass;
10
11 /**
12 * Defines how an object can be instantiated.
13 *
14 * @author Matthieu Napoli <[email protected]>
15 */
16 class ObjectDefinition implements Definition, CacheableDefinition, HasSubDefinition
17 {
18 /**
19 * Entry name (most of the time, same as $classname).
20 * @var string
21 */
22 private $name;
23
24 /**
25 * Class name (if null, then the class name is $name).
26 * @var string|null
27 */
28 private $className;
29
30 /**
31 * Constructor parameter injection.
32 * @var MethodInjection|null
33 */
34 private $constructorInjection;
35
36 /**
37 * Property injections.
38 * @var PropertyInjection[]
39 */
40 private $propertyInjections = [];
41
42 /**
43 * Method calls.
44 * @var MethodInjection[][]
45 */
46 private $methodInjections = [];
47
48 /**
49 * @var string|null
50 */
51 private $scope;
52
53 /**
54 * @var bool|null
55 */
56 private $lazy;
57
58 /**
59 * Store if the class exists. Storing it (in cache) avoids recomputing this.
60 *
61 * @var bool
62 */
63 private $classExists;
64
65 /**
66 * Store if the class is instantiable. Storing it (in cache) avoids recomputing this.
67 *
68 * @var bool
69 */
70 private $isInstantiable;
71
72 /**
73 * @param string $name Class name
74 * @param string $className
75 */
76 public function __construct($name, $className = null)
77 {
78 $this->name = (string) $name;
79 $this->setClassName($className);
80 }
81
82 /**
83 * @return string Entry name
84 */
85 public function getName()
86 {
87 return $this->name;
88 }
89
90 /**
91 * @param string|null $className
92 */
93 public function setClassName($className)
94 {
95 $this->className = $className;
96
97 $this->updateCache();
98 }
99
100 /**
101 * @return string Class name
102 */
103 public function getClassName()
104 {
105 if ($this->className !== null) {
106 return $this->className;
107 }
108
109 return $this->name;
110 }
111
112 /**
113 * @return MethodInjection|null
114 */
115 public function getConstructorInjection()
116 {
117 return $this->constructorInjection;
118 }
119
120 /**
121 * @param MethodInjection $constructorInjection
122 */
123 public function setConstructorInjection(MethodInjection $constructorInjection)
124 {
125 $this->constructorInjection = $constructorInjection;
126 }
127
128 /**
129 * @return PropertyInjection[] Property injections
130 */
131 public function getPropertyInjections()
132 {
133 return $this->propertyInjections;
134 }
135
136 public function addPropertyInjection(PropertyInjection $propertyInjection)
137 {
138 $className = $propertyInjection->getClassName();
139 if ($className) {
140 // Index with the class name to avoid collisions between parent and
141 // child private properties with the same name
142 $key = $className . '::' . $propertyInjection->getPropertyName();
143 } else {
144 $key = $propertyInjection->getPropertyName();
145 }
146
147 $this->propertyInjections[$key] = $propertyInjection;
148 }
149
150 /**
151 * @return MethodInjection[] Method injections
152 */
153 public function getMethodInjections()
154 {
155 // Return array leafs
156 $injections = [];
157 array_walk_recursive($this->methodInjections, function ($injection) use (&$injections) {
158 $injections[] = $injection;
159 });
160
161 return $injections;
162 }
163
164 /**
165 * @param MethodInjection $methodInjection
166 */
167 public function addMethodInjection(MethodInjection $methodInjection)
168 {
169 $method = $methodInjection->getMethodName();
170 if (! isset($this->methodInjections[$method])) {
171 $this->methodInjections[$method] = [];
172 }
173 $this->methodInjections[$method][] = $methodInjection;
174 }
175
176 /**
177 * @param string $scope
178 */
179 public function setScope($scope)
180 {
181 $this->scope = $scope;
182 }
183
184 /**
185 * {@inheritdoc}
186 */
187 public function getScope()
188 {
189 return $this->scope ?: Scope::SINGLETON;
190 }
191
192 /**
193 * @param bool|null $lazy
194 */
195 public function setLazy($lazy)
196 {
197 $this->lazy = $lazy;
198 }
199
200 /**
201 * @return bool
202 */
203 public function isLazy()
204 {
205 if ($this->lazy !== null) {
206 return $this->lazy;
207 } else {
208 // Default value
209 return false;
210 }
211 }
212
213 /**
214 * @return bool
215 */
216 public function classExists()
217 {
218 return $this->classExists;
219 }
220
221 /**
222 * @return bool
223 */
224 public function isInstantiable()
225 {
226 return $this->isInstantiable;
227 }
228
229 /**
230 * {@inheritdoc}
231 */
232 public function getSubDefinitionName()
233 {
234 return $this->getClassName();
235 }
236
237 /**
238 * {@inheritdoc}
239 */
240 public function setSubDefinition(Definition $definition)
241 {
242 if (! $definition instanceof self) {
243 return;
244 }
245
246 // The current prevails
247 if ($this->className === null) {
248 $this->setClassName($definition->className);
249 }
250 if ($this->scope === null) {
251 $this->scope = $definition->scope;
252 }
253 if ($this->lazy === null) {
254 $this->lazy = $definition->lazy;
255 }
256
257 // Merge constructor injection
258 $this->mergeConstructorInjection($definition);
259
260 // Merge property injections
261 $this->mergePropertyInjections($definition);
262
263 // Merge method injections
264 $this->mergeMethodInjections($definition);
265 }
266
267 public function __toString()
268 {
269 return (new ObjectDefinitionDumper)->dump($this);
270 }
271
272 private function mergeConstructorInjection(ObjectDefinition $definition)
273 {
274 if ($definition->getConstructorInjection() !== null) {
275 if ($this->constructorInjection !== null) {
276 // Merge
277 $this->constructorInjection->merge($definition->getConstructorInjection());
278 } else {
279 // Set
280 $this->constructorInjection = $definition->getConstructorInjection();
281 }
282 }
283 }
284
285 private function mergePropertyInjections(ObjectDefinition $definition)
286 {
287 foreach ($definition->propertyInjections as $propertyName => $propertyInjection) {
288 if (! isset($this->propertyInjections[$propertyName])) {
289 // Add
290 $this->propertyInjections[$propertyName] = $propertyInjection;
291 }
292 }
293 }
294
295 private function mergeMethodInjections(ObjectDefinition $definition)
296 {
297 foreach ($definition->methodInjections as $methodName => $calls) {
298 if (array_key_exists($methodName, $this->methodInjections)) {
299 $this->mergeMethodCalls($calls, $methodName);
300 } else {
301 // Add
302 $this->methodInjections[$methodName] = $calls;
303 }
304 }
305 }
306
307 private function mergeMethodCalls(array $calls, $methodName)
308 {
309 foreach ($calls as $index => $methodInjection) {
310 // Merge
311 if (array_key_exists($index, $this->methodInjections[$methodName])) {
312 // Merge
313 $this->methodInjections[$methodName][$index]->merge($methodInjection);
314 } else {
315 // Add
316 $this->methodInjections[$methodName][$index] = $methodInjection;
317 }
318 }
319 }
320
321 private function updateCache()
322 {
323 $className = $this->getClassName();
324
325 $this->classExists = class_exists($className) || interface_exists($className);
326
327 if (! $this->classExists) {
328 $this->isInstantiable = false;
329
330 return;
331 }
332
333 $class = new ReflectionClass($className);
334 $this->isInstantiable = $class->isInstantiable();
335 }
336 }
337