Test Failed
Push — master ( 1ac121...ab0d76 )
by Alex
01:56
created
src/ContainerAwareInterface.php 1 patch
Indentation   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -19,18 +19,18 @@
 block discarded – undo
19 19
 interface ContainerAwareInterface
20 20
 {
21 21
 
22
-    /**
23
-     * Inject the container instance into the class.
24
-     *
25
-     * @param \Codeburner\Container\Container $container
26
-     */
27
-    public function setContainer(Container $container);
22
+	/**
23
+	 * Inject the container instance into the class.
24
+	 *
25
+	 * @param \Codeburner\Container\Container $container
26
+	 */
27
+	public function setContainer(Container $container);
28 28
 
29
-    /**
30
-     * get the container instance.
31
-     *
32
-     * @return \Codeburner\Container\Container $container
33
-     */
34
-    public function getContainer();
29
+	/**
30
+	 * get the container instance.
31
+	 *
32
+	 * @return \Codeburner\Container\Container $container
33
+	 */
34
+	public function getContainer();
35 35
 
36 36
 }
Please login to merge, or discard this patch.
src/ContainerAwareTrait.php 1 patch
Indentation   +29 added lines, -29 removed lines patch added patch discarded remove patch
@@ -19,34 +19,34 @@
 block discarded – undo
19 19
 trait ContainerAwareTrait
20 20
 {
21 21
 
22
-    /**
23
-     * The instance of container.
24
-     *
25
-     * @var \Codeburner\Container\Container
26
-     */
27
-    protected $container;
28
-
29
-    /**
30
-     * Set a container.
31
-     *
32
-     * @param \Codeburner\Container\Container $container
33
-     * @return mixed
34
-     */
35
-    public function setContainer(Container $container)
36
-    {
37
-        $this->container = $container;
38
-
39
-        return $this;
40
-    }
41
-
42
-    /**
43
-     * Get the container.
44
-     *
45
-     * @return \Codeburner\Container\Container
46
-     */
47
-    public function getContainer()
48
-    {
49
-        return $this->container;
50
-    }
22
+	/**
23
+	 * The instance of container.
24
+	 *
25
+	 * @var \Codeburner\Container\Container
26
+	 */
27
+	protected $container;
28
+
29
+	/**
30
+	 * Set a container.
31
+	 *
32
+	 * @param \Codeburner\Container\Container $container
33
+	 * @return mixed
34
+	 */
35
+	public function setContainer(Container $container)
36
+	{
37
+		$this->container = $container;
38
+
39
+		return $this;
40
+	}
41
+
42
+	/**
43
+	 * Get the container.
44
+	 *
45
+	 * @return \Codeburner\Container\Container
46
+	 */
47
+	public function getContainer()
48
+	{
49
+		return $this->container;
50
+	}
51 51
 
52 52
 }
Please login to merge, or discard this patch.
src/Container.php 4 patches
Unused Use Statements   +6 added lines, -1 removed lines patch added patch discarded remove patch
@@ -10,8 +10,13 @@
 block discarded – undo
10 10
 
11 11
 namespace Codeburner\Container;
12 12
 
13
-use Closure, Exception, ReflectionClass, ReflectionException, ReflectionFunction, ReflectionParameter;
13
+use Closure;
14
+use Exception;
14 15
 use Psr\Container\ContainerInterface;
16
+use ReflectionClass;
17
+use ReflectionException;
18
+use ReflectionFunction;
19
+use ReflectionParameter;
15 20
 use Codeburner\Container\Exceptions\{ContainerException, NotFoundException};
16 21
 
17 22
 /**
Please login to merge, or discard this patch.
Doc Comments   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -146,7 +146,7 @@  discard block
 block discarded – undo
146 146
      * @param array  $dependencies Array of ReflectionParameter
147 147
      *
148 148
      * @throws ContainerException When a dependency cannot be solved.
149
-     * @return array
149
+     * @return callable|null
150 150
      */
151 151
 
152 152
     protected function process(string $abstract, array $parameters, array $dependencies) : array
@@ -430,7 +430,7 @@  discard block
 block discarded – undo
430 430
      * Modify an element with a given function that receive the old element as argument.
431 431
      *
432 432
      * @param string  $abstract  The alias name that will be used to call the element.
433
-     * @param closure $extension The function that receives the old element and return a new or modified one.
433
+     * @param Closure $extension The function that receives the old element and return a new or modified one.
434 434
      *
435 435
      * @throws NotFoundException  When no element was found with $abstract key.
436 436
      * @return self
Please login to merge, or discard this patch.
Indentation   +448 added lines, -448 removed lines patch added patch discarded remove patch
@@ -32,453 +32,453 @@
 block discarded – undo
32 32
 class Container implements ContainerInterface
33 33
 {
34 34
 
35
-    /**
36
-     * Holds all resolved or resolvable instances into the container.
37
-     *
38
-     * @var array
39
-     */
40
-
41
-    protected $collection;
42
-
43
-    /**
44
-     * Class specific defined dependencies.
45
-     *
46
-     * @var array
47
-     */
48
-
49
-    protected $dependencies;
50
-
51
-    /**
52
-     * Cache of classes inspector and resolver.
53
-     *
54
-     * @var array
55
-     */
56
-
57
-    protected $resolving;
58
-
59
-    /**
60
-     * Cache of classes dependencies in callbacks ready for resolution.
61
-     *
62
-     * @var array
63
-     */
64
-
65
-    protected $resolved;
66
-
67
-    /**
68
-     * Call a user function injecting the dependencies.
69
-     *
70
-     * @param string|Closure $function   The function or the user function name.
71
-     * @param array          $parameters The predefined dependencies.
72
-     *
73
-     * @return mixed
74
-     */
75
-
76
-    public function call($function, array $parameters = [])
77
-    {
78
-        $inspector = new ReflectionFunction($function);
79
-
80
-        $dependencies = $inspector->getParameters();
81
-        $dependencies = $this->process('', $parameters, $dependencies);
82
-
83
-        return call_user_func_array($function, $dependencies);
84
-    }
85
-
86
-    /**
87
-     * Makes an element or class injecting automatically all the dependencies.
88
-     *
89
-     * @param string $abstract   The class name or container element name to make.
90
-     * @param array  $parameters Specific parameters definition.
91
-     *
92
-     * @throws ContainerException
93
-     * @return object|null
94
-     */
95
-
96
-    public function make(string $abstract, array $parameters = [])
97
-    {
98
-        if (isset($this->resolving[$abstract])) {
99
-            return $this->resolving[$abstract]($abstract, $parameters);
100
-        }
101
-
102
-        try {
103
-            $this->resolving[$abstract] = $this->construct($abstract);
104
-            return $this->resolving[$abstract]($abstract, $parameters);
105
-        } catch (ReflectionException $e) {
106
-            throw new ContainerException("Fail while attempt to make '$abstract'", 0, $e);
107
-        }
108
-    }
109
-
110
-    /**
111
-     * Construct a class and all the dependencies using the reflection library of PHP.
112
-     *
113
-     * @param string $abstract The class name or container element name to make.
114
-     *
115
-     * @throws ReflectionException
116
-     * @return Closure
117
-     */
118
-
119
-    protected function construct(string $abstract) : Closure
120
-    {
121
-        $inspector = new ReflectionClass($abstract);
122
-
123
-        if (($constructor = $inspector->getConstructor()) && ($dependencies = $constructor->getParameters())) {
124
-
125
-            // if, and only if, a class has a constructor with parameters, we try to solve then
126
-            // creating a resolving callback that in every call will recalculate all dependencies
127
-            // for the given class, and offcourse, using a cached resolving callback if exists.
128
-
129
-            return function (string $abstract, array $parameters) use ($inspector, $dependencies) {
130
-                return $inspector->newInstanceArgs(
131
-                    $this->process($abstract, $parameters, $dependencies)
132
-                );
133
-            };
134
-        }
135
-
136
-        return function (string $abstract) {
137
-            return new $abstract;
138
-        };
139
-    }
140
-
141
-    /**
142
-     * Process all dependencies
143
-     *
144
-     * @param string $abstract     The class name or container element name to make
145
-     * @param array  $parameters   User defined parameters that must be used instead of resolved ones
146
-     * @param array  $dependencies Array of ReflectionParameter
147
-     *
148
-     * @throws ContainerException When a dependency cannot be solved.
149
-     * @return array
150
-     */
151
-
152
-    protected function process(string $abstract, array $parameters, array $dependencies) : array
153
-    {
154
-        foreach ($dependencies as &$dependency) {
155
-            if (isset($parameters[$dependency->name])) {
156
-                   $dependency = $parameters[$dependency->name];
157
-            } else $dependency = $this->resolve($abstract, $dependency);
158
-        }
159
-
160
-        return $dependencies;
161
-    }
162
-
163
-    /**
164
-     * Resolve all the given class reflected dependencies.
165
-     *
166
-     * @param string               $abstract   The class name or container element name to resolve dependencies.
167
-     * @param ReflectionParameter  $dependency The class dependency to be resolved.
168
-     *
169
-     * @throws ContainerException When a dependency cannot be solved.
170
-     * @return Object
171
-     */
172
-
173
-    protected function resolve(string $abstract, ReflectionParameter $dependency)
174
-    {
175
-        $key = $abstract.$dependency->name;
176
-
177
-        if (! isset($this->resolved[$key])) {
178
-            $this->resolved[$key] = $this->generate($abstract, $dependency);
179
-        }
180
-
181
-        return $this->resolved[$key]($this);
182
-    }
183
-
184
-    /**
185
-     * Generate the dependencies callbacks to jump some conditions in every dependency creation.
186
-     *
187
-     * @param string               $abstract   The class name or container element name to resolve dependencies.
188
-     * @param ReflectionParameter  $dependency The class dependency to be resolved.
189
-     *
190
-     * @throws ContainerException When a dependency cannot be solved.
191
-     * @return Closure
192
-     */
193
-
194
-    protected function generate(string $abstract, ReflectionParameter $dependency) : Closure
195
-    {
196
-        if ($class = $dependency->getClass()) {
197
-            return $this->build($class->name, "{$abstract}{$class->name}");
198
-        }
199
-
200
-        try {
201
-            $value = $dependency->getDefaultValue();
202
-
203
-            return function () use ($value) {
204
-                return $value;
205
-            };
206
-        } catch (ReflectionException $e) {
207
-            throw new ContainerException("Cannot resolve '$dependency->name' of '$abstract'", 0, $e);
208
-        }
209
-    }
210
-
211
-    /**
212
-     * Create a build closure for a given class
213
-     *
214
-     * @param string $classname The class that need to be build
215
-     * @param string $entry     Cache entry to search
216
-     *
217
-     * @return Closure
218
-     */
219
-
220
-    protected function build(string $classname, string $entry) : Closure
221
-    {
222
-        if (isset($this->dependencies[$entry])) {
223
-            return $this->dependencies[$entry];
224
-        }
225
-
226
-        return function () use ($classname) {
227
-            return $this->make($classname);
228
-        };
229
-    }
230
-
231
-    /**
232
-     * Reset the container, removing all the elements, cache and options.
233
-     *
234
-     * @return self
235
-     */
236
-
237
-    public function flush() : self
238
-    {
239
-        $this->collection = [];
240
-        $this->dependencies = [];
241
-        $this->resolving = [];
242
-        $this->resolved = [];
243
-
244
-        return $this;
245
-    }
246
-
247
-    /**
248
-     * Finds an entry of the container by its identifier and returns it.
249
-     *
250
-     * @param string $abstract Identifier of the entry to look for.
251
-     *
252
-     * @throws NotFoundException  No entry was found for this identifier.
253
-     * @throws ContainerException Error while retrieving the entry.
254
-     *
255
-     * @return mixed Entry.
256
-     */
257
-    public function get($abstract)
258
-    {
259
-        if (! isset($this->collection[$abstract])) {
260
-            throw new NotFoundException("Element '$abstract' not found");
261
-        }
262
-
263
-        if ($this->collection[$abstract] instanceof Closure) {
264
-            try {
265
-                return $this->collection[$abstract]($this);
266
-            } catch (Exception $e) {
267
-                throw new ContainerException("An exception was thrown while attempt to make $abstract", 0, $e);
268
-            }
269
-        }
270
-
271
-        return $this->collection[$abstract];
272
-    }
273
-
274
-    /**
275
-     * Returns true if the container can return an entry for the given identifier.
276
-     * Returns false otherwise.
277
-     *
278
-     * `has($abstract)` returning true does not mean that `get($abstract)` will not throw an exception.
279
-     * It does however mean that `get($abstract)` will not throw a `NotFoundException`.
280
-     *
281
-     * @param string $abstract Identifier of the entry to look for.
282
-     *
283
-     * @return boolean
284
-     */
285
-
286
-    public function has($abstract)
287
-    {
288
-        return isset($this->collection[$abstract]);
289
-    }
290
-
291
-    /**
292
-     * Verify if an element has a singleton instance.
293
-     *
294
-     * @param  string The class name or container element name to resolve dependencies.
295
-     * @return bool
296
-     */
297
-
298
-    public function isSingleton(string $abstract) : bool
299
-    {
300
-        return isset($this->collection[$abstract]) && $this->collection[$abstract] instanceof Closure === false;
301
-    }
302
-
303
-    /**
304
-     * Verify if an element is a instance of something.
305
-     *
306
-     * @param  string The class name or container element name to resolve dependencies.
307
-     * @return bool
308
-     */
309
-    public function isInstance(string $abstract) : bool
310
-    {
311
-        return isset($this->collection[$abstract]) && is_object($this->collection[$abstract]);
312
-    }
313
-
314
-    /**
315
-     * Bind a new element to the container.
316
-     *
317
-     * @param string                $abstract The alias name that will be used to call the element.
318
-     * @param string|closure|object $concrete The element class name, or an closure that makes the element, or the object itself.
319
-     * @param bool                  $shared   Define if the element will be a singleton instance.
320
-     *
321
-     * @return self
322
-     */
323
-
324
-    public function set(string $abstract, $concrete, bool $shared = false) : self
325
-    {
326
-        if (is_object($concrete)) {
327
-            return $this->instance($abstract, $concrete);
328
-        }
329
-
330
-        if ($concrete instanceof Closure === false) {
331
-            $concrete = function (Container $container) use ($concrete) {
332
-                return $container->make($concrete);
333
-            };
334
-        }
335
-
336
-        if ($shared === true) {
337
-               $this->collection[$abstract] = $concrete($this);
338
-        } else $this->collection[$abstract] = $concrete;
339
-
340
-        return $this;
341
-    }
342
-
343
-    /**
344
-     * Bind a new element to the container IF the element name not exists in the container.
345
-     *
346
-     * @param string         $abstract The alias name that will be used to call the element.
347
-     * @param string|closure $concrete The element class name, or an closure that makes the element.
348
-     * @param bool           $shared   Define if the element will be a singleton instance.
349
-     *
350
-     * @return self
351
-     */
352
-
353
-    public function setIf(string $abstract, $concrete, bool $shared = false) : self
354
-    {
355
-        if (! isset($this->collection[$abstract])) {
356
-            $this->set($abstract, $concrete, $shared);
357
-        }
358
-
359
-        return $this;
360
-    }
361
-
362
-    /**
363
-     * Bind an specific instance to a class dependency.
364
-     *
365
-     * @param string         $class          The class full name.
366
-     * @param string         $dependencyName The dependency full name.
367
-     * @param string|closure $dependency     The specific object class name or a classure that makes the element.
368
-     *
369
-     * @return self
370
-     */
371
-
372
-    public function setTo(string $class, string $dependencyName, $dependency) : self
373
-    {
374
-        if ($dependency instanceof Closure === false) {
375
-            if (is_object($dependency)) {
376
-                $dependency = function () use ($dependency) {
377
-                    return $dependency;
378
-                };
379
-            } else {
380
-                $dependency = function () use ($dependency) {
381
-                    return $this->get($dependency);
382
-                };
383
-            }
384
-        }
385
-
386
-        $this->dependencies[$class.$dependencyName] = $dependency;
387
-
388
-        return $this;
389
-    }
390
-
391
-    /**
392
-     * Bind an element that will be construct only one time, and every call for the element,
393
-     * the same instance will be given.
394
-     *
395
-     * @param string         $abstract The alias name that will be used to call the element.
396
-     * @param string|closure $concrete The element class name, or an closure that makes the element.
397
-     *
398
-     * @return self
399
-     */
400
-
401
-    public function singleton(string $abstract, $concrete) : self
402
-    {
403
-        $this->set($abstract, $concrete, true);
404
-
405
-        return $this;
406
-    }
407
-
408
-    /**
409
-     * Bind an object to the container.
410
-     *
411
-     * @param string $abstract The alias name that will be used to call the object.
412
-     * @param object $instance The object that will be inserted.
413
-     *
414
-     * @throws ContainerException When $instance is not an object.
415
-     * @return self
416
-     */
417
-
418
-    public function instance(string $abstract, $instance) : self
419
-    {
420
-        if (! is_object($instance)) {
421
-            throw new ContainerException('Trying to store ' . gettype($type) . ' as object.');
422
-        }
423
-
424
-        $this->collection[$abstract] = $instance;
425
-
426
-        return $this;
427
-    }
428
-
429
-    /**
430
-     * Modify an element with a given function that receive the old element as argument.
431
-     *
432
-     * @param string  $abstract  The alias name that will be used to call the element.
433
-     * @param closure $extension The function that receives the old element and return a new or modified one.
434
-     *
435
-     * @throws NotFoundException  When no element was found with $abstract key.
436
-     * @return self
437
-     */
438
-
439
-    public function extend(string $abstract, closure $extension) : self
440
-    {
441
-        if (! isset($this->collection[$abstract])) {
442
-            throw new NotFoundException($abstract);
443
-        }
444
-
445
-        $object = $this->collection[$abstract];
446
-
447
-        if ($object instanceof Closure) {
448
-            $this->collection[$abstract] = function () use ($object, $extension) {
449
-                return $extension($object($this), $this);
450
-            };
451
-        } else {
452
-            $this->collection[$abstract] = $extension($object, $this);
453
-        }
454
-
455
-        return $this;
456
-    }
457
-
458
-    /**
459
-     * Makes an resolvable element an singleton.
460
-     *
461
-     * @param  string $abstract The alias name that will be used to call the element.
462
-     *
463
-     * @throws NotFoundException  When no element was found with $abstract key.
464
-     * @throws ContainerException When the element on $abstract key is not resolvable.
465
-     *
466
-     * @return self
467
-     */
468
-
469
-    public function share(string $abstract) : self
470
-    {
471
-        if (! isset($this->collection[$abstract])) {
472
-            throw new NotFoundException("Element '$abstract' not found");
473
-        }
474
-
475
-        if (! $this->collection[$abstract] instanceof Closure) {
476
-            throw new ContainerException("'$abstract' must be a resolvable element");
477
-        }
478
-
479
-        $this->collection[$abstract] = $this->collection[$abstract]($this);
480
-
481
-        return $this;
482
-    }
35
+	/**
36
+	 * Holds all resolved or resolvable instances into the container.
37
+	 *
38
+	 * @var array
39
+	 */
40
+
41
+	protected $collection;
42
+
43
+	/**
44
+	 * Class specific defined dependencies.
45
+	 *
46
+	 * @var array
47
+	 */
48
+
49
+	protected $dependencies;
50
+
51
+	/**
52
+	 * Cache of classes inspector and resolver.
53
+	 *
54
+	 * @var array
55
+	 */
56
+
57
+	protected $resolving;
58
+
59
+	/**
60
+	 * Cache of classes dependencies in callbacks ready for resolution.
61
+	 *
62
+	 * @var array
63
+	 */
64
+
65
+	protected $resolved;
66
+
67
+	/**
68
+	 * Call a user function injecting the dependencies.
69
+	 *
70
+	 * @param string|Closure $function   The function or the user function name.
71
+	 * @param array          $parameters The predefined dependencies.
72
+	 *
73
+	 * @return mixed
74
+	 */
75
+
76
+	public function call($function, array $parameters = [])
77
+	{
78
+		$inspector = new ReflectionFunction($function);
79
+
80
+		$dependencies = $inspector->getParameters();
81
+		$dependencies = $this->process('', $parameters, $dependencies);
82
+
83
+		return call_user_func_array($function, $dependencies);
84
+	}
85
+
86
+	/**
87
+	 * Makes an element or class injecting automatically all the dependencies.
88
+	 *
89
+	 * @param string $abstract   The class name or container element name to make.
90
+	 * @param array  $parameters Specific parameters definition.
91
+	 *
92
+	 * @throws ContainerException
93
+	 * @return object|null
94
+	 */
95
+
96
+	public function make(string $abstract, array $parameters = [])
97
+	{
98
+		if (isset($this->resolving[$abstract])) {
99
+			return $this->resolving[$abstract]($abstract, $parameters);
100
+		}
101
+
102
+		try {
103
+			$this->resolving[$abstract] = $this->construct($abstract);
104
+			return $this->resolving[$abstract]($abstract, $parameters);
105
+		} catch (ReflectionException $e) {
106
+			throw new ContainerException("Fail while attempt to make '$abstract'", 0, $e);
107
+		}
108
+	}
109
+
110
+	/**
111
+	 * Construct a class and all the dependencies using the reflection library of PHP.
112
+	 *
113
+	 * @param string $abstract The class name or container element name to make.
114
+	 *
115
+	 * @throws ReflectionException
116
+	 * @return Closure
117
+	 */
118
+
119
+	protected function construct(string $abstract) : Closure
120
+	{
121
+		$inspector = new ReflectionClass($abstract);
122
+
123
+		if (($constructor = $inspector->getConstructor()) && ($dependencies = $constructor->getParameters())) {
124
+
125
+			// if, and only if, a class has a constructor with parameters, we try to solve then
126
+			// creating a resolving callback that in every call will recalculate all dependencies
127
+			// for the given class, and offcourse, using a cached resolving callback if exists.
128
+
129
+			return function (string $abstract, array $parameters) use ($inspector, $dependencies) {
130
+				return $inspector->newInstanceArgs(
131
+					$this->process($abstract, $parameters, $dependencies)
132
+				);
133
+			};
134
+		}
135
+
136
+		return function (string $abstract) {
137
+			return new $abstract;
138
+		};
139
+	}
140
+
141
+	/**
142
+	 * Process all dependencies
143
+	 *
144
+	 * @param string $abstract     The class name or container element name to make
145
+	 * @param array  $parameters   User defined parameters that must be used instead of resolved ones
146
+	 * @param array  $dependencies Array of ReflectionParameter
147
+	 *
148
+	 * @throws ContainerException When a dependency cannot be solved.
149
+	 * @return array
150
+	 */
151
+
152
+	protected function process(string $abstract, array $parameters, array $dependencies) : array
153
+	{
154
+		foreach ($dependencies as &$dependency) {
155
+			if (isset($parameters[$dependency->name])) {
156
+				   $dependency = $parameters[$dependency->name];
157
+			} else $dependency = $this->resolve($abstract, $dependency);
158
+		}
159
+
160
+		return $dependencies;
161
+	}
162
+
163
+	/**
164
+	 * Resolve all the given class reflected dependencies.
165
+	 *
166
+	 * @param string               $abstract   The class name or container element name to resolve dependencies.
167
+	 * @param ReflectionParameter  $dependency The class dependency to be resolved.
168
+	 *
169
+	 * @throws ContainerException When a dependency cannot be solved.
170
+	 * @return Object
171
+	 */
172
+
173
+	protected function resolve(string $abstract, ReflectionParameter $dependency)
174
+	{
175
+		$key = $abstract.$dependency->name;
176
+
177
+		if (! isset($this->resolved[$key])) {
178
+			$this->resolved[$key] = $this->generate($abstract, $dependency);
179
+		}
180
+
181
+		return $this->resolved[$key]($this);
182
+	}
183
+
184
+	/**
185
+	 * Generate the dependencies callbacks to jump some conditions in every dependency creation.
186
+	 *
187
+	 * @param string               $abstract   The class name or container element name to resolve dependencies.
188
+	 * @param ReflectionParameter  $dependency The class dependency to be resolved.
189
+	 *
190
+	 * @throws ContainerException When a dependency cannot be solved.
191
+	 * @return Closure
192
+	 */
193
+
194
+	protected function generate(string $abstract, ReflectionParameter $dependency) : Closure
195
+	{
196
+		if ($class = $dependency->getClass()) {
197
+			return $this->build($class->name, "{$abstract}{$class->name}");
198
+		}
199
+
200
+		try {
201
+			$value = $dependency->getDefaultValue();
202
+
203
+			return function () use ($value) {
204
+				return $value;
205
+			};
206
+		} catch (ReflectionException $e) {
207
+			throw new ContainerException("Cannot resolve '$dependency->name' of '$abstract'", 0, $e);
208
+		}
209
+	}
210
+
211
+	/**
212
+	 * Create a build closure for a given class
213
+	 *
214
+	 * @param string $classname The class that need to be build
215
+	 * @param string $entry     Cache entry to search
216
+	 *
217
+	 * @return Closure
218
+	 */
219
+
220
+	protected function build(string $classname, string $entry) : Closure
221
+	{
222
+		if (isset($this->dependencies[$entry])) {
223
+			return $this->dependencies[$entry];
224
+		}
225
+
226
+		return function () use ($classname) {
227
+			return $this->make($classname);
228
+		};
229
+	}
230
+
231
+	/**
232
+	 * Reset the container, removing all the elements, cache and options.
233
+	 *
234
+	 * @return self
235
+	 */
236
+
237
+	public function flush() : self
238
+	{
239
+		$this->collection = [];
240
+		$this->dependencies = [];
241
+		$this->resolving = [];
242
+		$this->resolved = [];
243
+
244
+		return $this;
245
+	}
246
+
247
+	/**
248
+	 * Finds an entry of the container by its identifier and returns it.
249
+	 *
250
+	 * @param string $abstract Identifier of the entry to look for.
251
+	 *
252
+	 * @throws NotFoundException  No entry was found for this identifier.
253
+	 * @throws ContainerException Error while retrieving the entry.
254
+	 *
255
+	 * @return mixed Entry.
256
+	 */
257
+	public function get($abstract)
258
+	{
259
+		if (! isset($this->collection[$abstract])) {
260
+			throw new NotFoundException("Element '$abstract' not found");
261
+		}
262
+
263
+		if ($this->collection[$abstract] instanceof Closure) {
264
+			try {
265
+				return $this->collection[$abstract]($this);
266
+			} catch (Exception $e) {
267
+				throw new ContainerException("An exception was thrown while attempt to make $abstract", 0, $e);
268
+			}
269
+		}
270
+
271
+		return $this->collection[$abstract];
272
+	}
273
+
274
+	/**
275
+	 * Returns true if the container can return an entry for the given identifier.
276
+	 * Returns false otherwise.
277
+	 *
278
+	 * `has($abstract)` returning true does not mean that `get($abstract)` will not throw an exception.
279
+	 * It does however mean that `get($abstract)` will not throw a `NotFoundException`.
280
+	 *
281
+	 * @param string $abstract Identifier of the entry to look for.
282
+	 *
283
+	 * @return boolean
284
+	 */
285
+
286
+	public function has($abstract)
287
+	{
288
+		return isset($this->collection[$abstract]);
289
+	}
290
+
291
+	/**
292
+	 * Verify if an element has a singleton instance.
293
+	 *
294
+	 * @param  string The class name or container element name to resolve dependencies.
295
+	 * @return bool
296
+	 */
297
+
298
+	public function isSingleton(string $abstract) : bool
299
+	{
300
+		return isset($this->collection[$abstract]) && $this->collection[$abstract] instanceof Closure === false;
301
+	}
302
+
303
+	/**
304
+	 * Verify if an element is a instance of something.
305
+	 *
306
+	 * @param  string The class name or container element name to resolve dependencies.
307
+	 * @return bool
308
+	 */
309
+	public function isInstance(string $abstract) : bool
310
+	{
311
+		return isset($this->collection[$abstract]) && is_object($this->collection[$abstract]);
312
+	}
313
+
314
+	/**
315
+	 * Bind a new element to the container.
316
+	 *
317
+	 * @param string                $abstract The alias name that will be used to call the element.
318
+	 * @param string|closure|object $concrete The element class name, or an closure that makes the element, or the object itself.
319
+	 * @param bool                  $shared   Define if the element will be a singleton instance.
320
+	 *
321
+	 * @return self
322
+	 */
323
+
324
+	public function set(string $abstract, $concrete, bool $shared = false) : self
325
+	{
326
+		if (is_object($concrete)) {
327
+			return $this->instance($abstract, $concrete);
328
+		}
329
+
330
+		if ($concrete instanceof Closure === false) {
331
+			$concrete = function (Container $container) use ($concrete) {
332
+				return $container->make($concrete);
333
+			};
334
+		}
335
+
336
+		if ($shared === true) {
337
+			   $this->collection[$abstract] = $concrete($this);
338
+		} else $this->collection[$abstract] = $concrete;
339
+
340
+		return $this;
341
+	}
342
+
343
+	/**
344
+	 * Bind a new element to the container IF the element name not exists in the container.
345
+	 *
346
+	 * @param string         $abstract The alias name that will be used to call the element.
347
+	 * @param string|closure $concrete The element class name, or an closure that makes the element.
348
+	 * @param bool           $shared   Define if the element will be a singleton instance.
349
+	 *
350
+	 * @return self
351
+	 */
352
+
353
+	public function setIf(string $abstract, $concrete, bool $shared = false) : self
354
+	{
355
+		if (! isset($this->collection[$abstract])) {
356
+			$this->set($abstract, $concrete, $shared);
357
+		}
358
+
359
+		return $this;
360
+	}
361
+
362
+	/**
363
+	 * Bind an specific instance to a class dependency.
364
+	 *
365
+	 * @param string         $class          The class full name.
366
+	 * @param string         $dependencyName The dependency full name.
367
+	 * @param string|closure $dependency     The specific object class name or a classure that makes the element.
368
+	 *
369
+	 * @return self
370
+	 */
371
+
372
+	public function setTo(string $class, string $dependencyName, $dependency) : self
373
+	{
374
+		if ($dependency instanceof Closure === false) {
375
+			if (is_object($dependency)) {
376
+				$dependency = function () use ($dependency) {
377
+					return $dependency;
378
+				};
379
+			} else {
380
+				$dependency = function () use ($dependency) {
381
+					return $this->get($dependency);
382
+				};
383
+			}
384
+		}
385
+
386
+		$this->dependencies[$class.$dependencyName] = $dependency;
387
+
388
+		return $this;
389
+	}
390
+
391
+	/**
392
+	 * Bind an element that will be construct only one time, and every call for the element,
393
+	 * the same instance will be given.
394
+	 *
395
+	 * @param string         $abstract The alias name that will be used to call the element.
396
+	 * @param string|closure $concrete The element class name, or an closure that makes the element.
397
+	 *
398
+	 * @return self
399
+	 */
400
+
401
+	public function singleton(string $abstract, $concrete) : self
402
+	{
403
+		$this->set($abstract, $concrete, true);
404
+
405
+		return $this;
406
+	}
407
+
408
+	/**
409
+	 * Bind an object to the container.
410
+	 *
411
+	 * @param string $abstract The alias name that will be used to call the object.
412
+	 * @param object $instance The object that will be inserted.
413
+	 *
414
+	 * @throws ContainerException When $instance is not an object.
415
+	 * @return self
416
+	 */
417
+
418
+	public function instance(string $abstract, $instance) : self
419
+	{
420
+		if (! is_object($instance)) {
421
+			throw new ContainerException('Trying to store ' . gettype($type) . ' as object.');
422
+		}
423
+
424
+		$this->collection[$abstract] = $instance;
425
+
426
+		return $this;
427
+	}
428
+
429
+	/**
430
+	 * Modify an element with a given function that receive the old element as argument.
431
+	 *
432
+	 * @param string  $abstract  The alias name that will be used to call the element.
433
+	 * @param closure $extension The function that receives the old element and return a new or modified one.
434
+	 *
435
+	 * @throws NotFoundException  When no element was found with $abstract key.
436
+	 * @return self
437
+	 */
438
+
439
+	public function extend(string $abstract, closure $extension) : self
440
+	{
441
+		if (! isset($this->collection[$abstract])) {
442
+			throw new NotFoundException($abstract);
443
+		}
444
+
445
+		$object = $this->collection[$abstract];
446
+
447
+		if ($object instanceof Closure) {
448
+			$this->collection[$abstract] = function () use ($object, $extension) {
449
+				return $extension($object($this), $this);
450
+			};
451
+		} else {
452
+			$this->collection[$abstract] = $extension($object, $this);
453
+		}
454
+
455
+		return $this;
456
+	}
457
+
458
+	/**
459
+	 * Makes an resolvable element an singleton.
460
+	 *
461
+	 * @param  string $abstract The alias name that will be used to call the element.
462
+	 *
463
+	 * @throws NotFoundException  When no element was found with $abstract key.
464
+	 * @throws ContainerException When the element on $abstract key is not resolvable.
465
+	 *
466
+	 * @return self
467
+	 */
468
+
469
+	public function share(string $abstract) : self
470
+	{
471
+		if (! isset($this->collection[$abstract])) {
472
+			throw new NotFoundException("Element '$abstract' not found");
473
+		}
474
+
475
+		if (! $this->collection[$abstract] instanceof Closure) {
476
+			throw new ContainerException("'$abstract' must be a resolvable element");
477
+		}
478
+
479
+		$this->collection[$abstract] = $this->collection[$abstract]($this);
480
+
481
+		return $this;
482
+	}
483 483
 
484 484
 }
Please login to merge, or discard this patch.
Spacing   +17 added lines, -17 removed lines patch added patch discarded remove patch
@@ -19,7 +19,7 @@  discard block
 block discarded – undo
19 19
  * because it is aways needed.
20 20
  */
21 21
 
22
-require_once __DIR__ . '/ContainerInterface.php';
22
+require_once __DIR__.'/ContainerInterface.php';
23 23
 
24 24
 /**
25 25
  * The container class is reponsable to construct all objects
@@ -126,14 +126,14 @@  discard block
 block discarded – undo
126 126
             // creating a resolving callback that in every call will recalculate all dependencies
127 127
             // for the given class, and offcourse, using a cached resolving callback if exists.
128 128
 
129
-            return function (string $abstract, array $parameters) use ($inspector, $dependencies) {
129
+            return function(string $abstract, array $parameters) use ($inspector, $dependencies) {
130 130
                 return $inspector->newInstanceArgs(
131 131
                     $this->process($abstract, $parameters, $dependencies)
132 132
                 );
133 133
             };
134 134
         }
135 135
 
136
-        return function (string $abstract) {
136
+        return function(string $abstract) {
137 137
             return new $abstract;
138 138
         };
139 139
     }
@@ -174,7 +174,7 @@  discard block
 block discarded – undo
174 174
     {
175 175
         $key = $abstract.$dependency->name;
176 176
 
177
-        if (! isset($this->resolved[$key])) {
177
+        if (!isset($this->resolved[$key])) {
178 178
             $this->resolved[$key] = $this->generate($abstract, $dependency);
179 179
         }
180 180
 
@@ -200,7 +200,7 @@  discard block
 block discarded – undo
200 200
         try {
201 201
             $value = $dependency->getDefaultValue();
202 202
 
203
-            return function () use ($value) {
203
+            return function() use ($value) {
204 204
                 return $value;
205 205
             };
206 206
         } catch (ReflectionException $e) {
@@ -223,7 +223,7 @@  discard block
 block discarded – undo
223 223
             return $this->dependencies[$entry];
224 224
         }
225 225
 
226
-        return function () use ($classname) {
226
+        return function() use ($classname) {
227 227
             return $this->make($classname);
228 228
         };
229 229
     }
@@ -256,7 +256,7 @@  discard block
 block discarded – undo
256 256
      */
257 257
     public function get($abstract)
258 258
     {
259
-        if (! isset($this->collection[$abstract])) {
259
+        if (!isset($this->collection[$abstract])) {
260 260
             throw new NotFoundException("Element '$abstract' not found");
261 261
         }
262 262
 
@@ -328,7 +328,7 @@  discard block
 block discarded – undo
328 328
         }
329 329
 
330 330
         if ($concrete instanceof Closure === false) {
331
-            $concrete = function (Container $container) use ($concrete) {
331
+            $concrete = function(Container $container) use ($concrete) {
332 332
                 return $container->make($concrete);
333 333
             };
334 334
         }
@@ -352,7 +352,7 @@  discard block
 block discarded – undo
352 352
 
353 353
     public function setIf(string $abstract, $concrete, bool $shared = false) : self
354 354
     {
355
-        if (! isset($this->collection[$abstract])) {
355
+        if (!isset($this->collection[$abstract])) {
356 356
             $this->set($abstract, $concrete, $shared);
357 357
         }
358 358
 
@@ -373,11 +373,11 @@  discard block
 block discarded – undo
373 373
     {
374 374
         if ($dependency instanceof Closure === false) {
375 375
             if (is_object($dependency)) {
376
-                $dependency = function () use ($dependency) {
376
+                $dependency = function() use ($dependency) {
377 377
                     return $dependency;
378 378
                 };
379 379
             } else {
380
-                $dependency = function () use ($dependency) {
380
+                $dependency = function() use ($dependency) {
381 381
                     return $this->get($dependency);
382 382
                 };
383 383
             }
@@ -417,8 +417,8 @@  discard block
 block discarded – undo
417 417
 
418 418
     public function instance(string $abstract, $instance) : self
419 419
     {
420
-        if (! is_object($instance)) {
421
-            throw new ContainerException('Trying to store ' . gettype($type) . ' as object.');
420
+        if (!is_object($instance)) {
421
+            throw new ContainerException('Trying to store '.gettype($type).' as object.');
422 422
         }
423 423
 
424 424
         $this->collection[$abstract] = $instance;
@@ -438,14 +438,14 @@  discard block
 block discarded – undo
438 438
 
439 439
     public function extend(string $abstract, closure $extension) : self
440 440
     {
441
-        if (! isset($this->collection[$abstract])) {
441
+        if (!isset($this->collection[$abstract])) {
442 442
             throw new NotFoundException($abstract);
443 443
         }
444 444
 
445 445
         $object = $this->collection[$abstract];
446 446
 
447 447
         if ($object instanceof Closure) {
448
-            $this->collection[$abstract] = function () use ($object, $extension) {
448
+            $this->collection[$abstract] = function() use ($object, $extension) {
449 449
                 return $extension($object($this), $this);
450 450
             };
451 451
         } else {
@@ -468,11 +468,11 @@  discard block
 block discarded – undo
468 468
 
469 469
     public function share(string $abstract) : self
470 470
     {
471
-        if (! isset($this->collection[$abstract])) {
471
+        if (!isset($this->collection[$abstract])) {
472 472
             throw new NotFoundException("Element '$abstract' not found");
473 473
         }
474 474
 
475
-        if (! $this->collection[$abstract] instanceof Closure) {
475
+        if (!$this->collection[$abstract] instanceof Closure) {
476 476
             throw new ContainerException("'$abstract' must be a resolvable element");
477 477
         }
478 478
 
Please login to merge, or discard this patch.
src/ContainerInterface.php 1 patch
Indentation   +70 added lines, -70 removed lines patch added patch discarded remove patch
@@ -22,75 +22,75 @@
 block discarded – undo
22 22
 
23 23
 interface ContainerInterface extends PsrContainerInterface {
24 24
 
25
-    /**
26
-     * Call a user function injecting the dependencies.
27
-     *
28
-     * @param string|Closure $function   The function or the user function name.
29
-     * @param array          $parameters The predefined dependencies.
30
-     *
31
-     * @return mixed
32
-     */
33
-
34
-    public function call($function, array $parameters = []);
35
-
36
-    /**
37
-     * Makes an element or class injecting automatically all the dependencies.
38
-     *
39
-     * @param string $abstract   The class name or container element name to make.
40
-     * @param array  $parameters Specific parameters definition.
41
-     *
42
-     * @throws ContainerException
43
-     * @return object|null
44
-     */
45
-
46
-    public function make(string $abstract, array $parameters = []);
47
-
48
-    /**
49
-     * Bind a new element to the container.
50
-     *
51
-     * @param string                $abstract The alias name that will be used to call the element.
52
-     * @param string|closure|object $concrete The element class name, or an closure that makes the element, or the object itself.
53
-     * @param bool                  $shared   Define if the element will be a singleton instance.
54
-     *
55
-     * @return self
56
-     */
57
-
58
-    public function set(string $abstract, $concrete, bool $shared = false) : self;
59
-
60
-    /**
61
-     * Bind a new element to the container IF the element name not exists in the container.
62
-     *
63
-     * @param string         $abstract The alias name that will be used to call the element.
64
-     * @param string|closure $concrete The element class name, or an closure that makes the element.
65
-     * @param bool           $shared   Define if the element will be a singleton instance.
66
-     *
67
-     * @return self
68
-     */
69
-
70
-    public function setIf(string $abstract, $concrete, bool $shared = false) : self;
71
-
72
-    /**
73
-     * Bind an element that will be construct only one time, and every call for the element,
74
-     * the same instance will be given.
75
-     *
76
-     * @param string         $abstract The alias name that will be used to call the element.
77
-     * @param string|closure $concrete The element class name, or an closure that makes the element.
78
-     *
79
-     * @return self
80
-     */
81
-
82
-    public function singleton(string $abstract, $concrete) : self;
83
-
84
-    /**
85
-     * Bind an object to the container.
86
-     *
87
-     * @param string $abstract The alias name that will be used to call the object.
88
-     * @param object $instance The object that will be inserted.
89
-     *
90
-     * @throws ContainerException When $instance is not an object.
91
-     * @return self
92
-     */
93
-
94
-    public function instance(string $abstract, $instance) : self;
25
+	/**
26
+	 * Call a user function injecting the dependencies.
27
+	 *
28
+	 * @param string|Closure $function   The function or the user function name.
29
+	 * @param array          $parameters The predefined dependencies.
30
+	 *
31
+	 * @return mixed
32
+	 */
33
+
34
+	public function call($function, array $parameters = []);
35
+
36
+	/**
37
+	 * Makes an element or class injecting automatically all the dependencies.
38
+	 *
39
+	 * @param string $abstract   The class name or container element name to make.
40
+	 * @param array  $parameters Specific parameters definition.
41
+	 *
42
+	 * @throws ContainerException
43
+	 * @return object|null
44
+	 */
45
+
46
+	public function make(string $abstract, array $parameters = []);
47
+
48
+	/**
49
+	 * Bind a new element to the container.
50
+	 *
51
+	 * @param string                $abstract The alias name that will be used to call the element.
52
+	 * @param string|closure|object $concrete The element class name, or an closure that makes the element, or the object itself.
53
+	 * @param bool                  $shared   Define if the element will be a singleton instance.
54
+	 *
55
+	 * @return self
56
+	 */
57
+
58
+	public function set(string $abstract, $concrete, bool $shared = false) : self;
59
+
60
+	/**
61
+	 * Bind a new element to the container IF the element name not exists in the container.
62
+	 *
63
+	 * @param string         $abstract The alias name that will be used to call the element.
64
+	 * @param string|closure $concrete The element class name, or an closure that makes the element.
65
+	 * @param bool           $shared   Define if the element will be a singleton instance.
66
+	 *
67
+	 * @return self
68
+	 */
69
+
70
+	public function setIf(string $abstract, $concrete, bool $shared = false) : self;
71
+
72
+	/**
73
+	 * Bind an element that will be construct only one time, and every call for the element,
74
+	 * the same instance will be given.
75
+	 *
76
+	 * @param string         $abstract The alias name that will be used to call the element.
77
+	 * @param string|closure $concrete The element class name, or an closure that makes the element.
78
+	 *
79
+	 * @return self
80
+	 */
81
+
82
+	public function singleton(string $abstract, $concrete) : self;
83
+
84
+	/**
85
+	 * Bind an object to the container.
86
+	 *
87
+	 * @param string $abstract The alias name that will be used to call the object.
88
+	 * @param object $instance The object that will be inserted.
89
+	 *
90
+	 * @throws ContainerException When $instance is not an object.
91
+	 * @return self
92
+	 */
93
+
94
+	public function instance(string $abstract, $instance) : self;
95 95
 
96 96
 }
Please login to merge, or discard this patch.