Completed
Push — master ( f32a6f...d8f6dd )
by Vitaly
02:49
created

AbstractContainer::generateConditions()   B

Complexity

Conditions 6
Paths 15

Size

Total Lines 32
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 3
Bugs 0 Features 1
Metric Value
c 3
b 0
f 1
dl 0
loc 32
ccs 0
cts 15
cp 0
rs 8.439
cc 6
eloc 14
nc 15
nop 2
crap 42
1
<?php
2
/**
3
 * Created by Vitaly Iegorov <[email protected]>.
4
 * on 22.01.16 at 23:53
5
 */
6
namespace samsonframework\di;
7
8
use Interop\Container\ContainerInterface;
9
use samsonframework\di\exception\ClassNotFoundException;
10
use samsonframework\di\exception\ContainerException;
11
12
/**
13
 * Abstract dependency injection container.
14
 *
15
 * @author Vitaly Iegorov <[email protected]>
16
 */
17
abstract class AbstractContainer implements ContainerInterface
18
{
19
    /** @var array[string] Collection of alias => class name for alias resolving */
20
    protected $aliases = array();
21
22
    /** @var array[string] Collection of class name dependencies trees */
23
    protected $dependencies = array();
24
25
    /** @var ContainerInterface[] Collection of delegated containers */
26
    protected $delegates = array();
27
28
    /** @var callable Dependency resolving function callable */
29
    protected $logicCallable;
30
31
32
    /**
33
     * Wrapper for calling dependency resolving function.
34
     *
35
     * @param string $dependency Dependency name
36
     *
37
     * @return mixed Created instance or null
38
     * @throws ContainerException
39
     */
40
    protected function logic($dependency)
41
    {
42
        if (!function_exists($this->logicCallable)) {
43
            throw new ContainerException('Logic function does not exists');
44
        }
45
46
        return call_user_func($this->logicCallable, $dependency);
47
    }
48
49
    /**
50
     * {@inheritdoc}
51
     */
52
    public function get($dependency)
53
    {
54
        // Get pointer from logic
55
        $module = $this->logic($dependency);
56
57
        // Try delegate lookup
58
        if (null === $module) {
59
            foreach ($this->delegates as $delegate) {
60
                try {
61
                    $module = $delegate->get($dependency);
62
                } catch (ContainerException $e) {
63
                    // Catch all delegated exceptions
64
                } catch (ClassNotFoundException $e) {
65
                    // Catch all delegated exceptions
66
                }
67
            }
68
        }
69
70
        if (null === $module) {
71
            throw new ClassNotFoundException($dependency);
72
        } else {
73
            return $module;
74
        }
75
    }
76
77
    /**
78
     * Implementing delegate lookup feature.
79
     * If current container cannot resolve entity dependency
80
     * resolving process is passed to delegated container.
81
     *
82
     * @param ContainerInterface $container Container for delegate lookup
83
     */
84
    public function delegate(ContainerInterface $container)
85
    {
86
        $this->delegates[] = $container;
87
    }
88
89
    /**
90
     * {@inheritdoc}
91
     */
92
    public function has($dependency)
93
    {
94
        $found = array_key_exists($dependency, $this->dependencies)
95
            || in_array($dependency, $this->aliases, true);
96
97
        if (!$found) {
98
            foreach ($this->delegates as $delegate) {
99
                if ($delegate->has($dependency)) {
100
                    return true;
101
                }
102
            }
103
        }
104
105
        return $found;
106
    }
107
108
    /**
109
     * Set container dependency.
110
     *
111
     * @param mixed       $entity     Entity
112
     * @param string|null $alias      Entity alias for simplier finding
113
     * @param array       $parameters Collection of additional parameters
114
     *
115
     * @return self Chaining
116
     */
117
    abstract public function set($entity, $alias = null, array $parameters = array());
118
}
119