Completed
Push — master ( 56e75a...611edb )
by Mikael
01:56
created

DI   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 168
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 16
lcom 1
cbo 2
dl 0
loc 168
ccs 43
cts 43
cp 1
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A has() 0 4 1
A set() 0 5 1
A setShared() 0 5 1
A getServices() 0 4 1
A get() 0 13 4
B load() 0 36 7
A getActiveServices() 0 4 1
1
<?php
2
3
namespace Anax\DI;
4
5
use Anax\DI\Exception\Exception;
6
use Anax\DI\Exception\NotFoundException;
7
use Psr\Container\ContainerInterface;
8
9
/**
10
 * A dependency/service container implementing the interface FIG PSR-11.
11
 * It can contain any of the fraework services, using lazy loading.
12
 */
13
class DI implements ContainerInterface
14
{
15
    /**
16
     * @var array $loaded  Store all lazy loaded services, ready to be
17
     *                     instantiated.
18
     * @var array $active  A service is instantiated into this array,
19
     *                     once its accessed.
20
     */
21
    protected $loaded = [];
22
    protected $active = [];
23
24
25
26
    /**
27
     * Finds an entry in the container by its identifier and returns it.
28
     * If the service is active/singelton then that instance is returned,
29
     * else the service is loaded and a new instance is returned.
30
     *
31
     * @param string $service     Identifier of the entry to look for.
32
     *
33
     * @throws NotFoundException  No entry was found for this identifier.
34
     * @throws Exception          Error while retrieving the entry.
35
     *
36
     * @return mixed Entry.
37
     */
38 13
    public function get($service)
39
    {
40 13
        if (!$this->has($service)) {
41 1
            throw new NotFoundException("The service '$service' is not loaded in the DI-container.");
42
        }
43
44 12
        if (isset($this->active[$service])
45 12
            && $this->loaded[$service]['singleton']) {
46 1
            return $this->active[$service];
47
        }
48
49 12
        return $this->load($service);
50
    }
51
52
53
54
    /**
55
     * Load a prepared service object and create an instance of it.
56
     *
57
     * @param string $service as a service label, naming this service.
58
     *
59
     * @throws Exception when service could not be loaded.
60
     *
61
     * @return object as instance of the service object.
62
     */
63 12
    protected function load($service)
64
    {
65 12
        $sol = isset($this->loaded[$service]['loader'])
66 11
            ? $this->loaded[$service]['loader']
67 12
            : null;
68
69 12
        if (is_callable($sol)) {
70
            // Load by calling a function
71
            try {
72 8
                $this->active[$service] = $sol();
73 1
            } catch (\Exception $e) {
74 1
                throw new Exception(
75 1
                    "Could not load service '$service'."
76 1
                    . "Failed in the callback that instantiates the service. "
77 8
                    . $e->getMessage()
78
                );
79
            }
80 5
        } elseif (is_object($sol)) {
81
            // Load by pre-instantiated object
82 1
            $this->active[$service] = $sol;
83 4
        } elseif (is_string($sol)) {
84
            // Load by creating a new object from class-string
85 3
            if (!class_exists($sol)) {
86 1
                throw new Exception(
87 1
                    "Could not load service '$service'."
88 1
                    . "Class '$sol' does not exists."
89
                );
90
            }
91 2
            $this->active[$service] = new $sol();
92
        } else {
93 1
            throw new Exception("The service '$service' has no init mechanism.");
94
        }
95
96 9
        $this->$service = $this->active[$service];
97 9
        return $this->active[$service];
98
    }
99
100
101
102
    /**
103
     * Returns true if the container can return an entry for the given
104
     * identifier, otherwise false
105
     *
106
     * @param string $service Identifier of the entry to look for.
107
     *
108
     * @return boolean
109
     */
110 13
    public function has($service)
111
    {
112 13
        return isset($this->loaded[$service]);
113
    }
114
115
116
117
    /**
118
     * Set a service and connect it to a task which creates the object
119
     * (lazy loading).
120
     *
121
     * @param string  $service   as a service label, naming this service.
122
     * @param mixed   $loader    contains a pre-defined object, a string with
123
     *                           class name or an callable which returns an
124
     *                           instance of the service object. Its the way
125
     *                           to actually load, insantiate, the service
126
     *                           object.
127
     *
128
     * @return void
129
     */
130 13
    public function set($service, $loader)
131
    {
132 13
        $this->loaded[$service]['loader'] = $loader;
133 13
        $this->loaded[$service]['singleton'] = false;
134 13
    }
135
136
137
138
    /**
139
     * Set a singleton service and connect it to a task which creates the
140
     * object (lazy loading).
141
     *
142
     * @param string $service as a service label, naming this service.
143
     * @param mixed   $loader    contains a pre-defined object, a string with
144
     *                           class name or an callable which returns an
145
     *                           instance of the service object. Its the way
146
     *                           to actually load, insantiate, the service
147
     *                           object.
148
     *
149
     * @return void
150
     */
151 4
    public function setShared($service, $loader)
152
    {
153 4
        $this->loaded[$service]['loader'] = $loader;
154 4
        $this->loaded[$service]['singleton'] = true;
155 4
    }
156
157
158
159
    /**
160
     * Return an arry with all loaded services names.
161
     *
162
     * @return void
163
     */
164 4
    public function getServices()
165
    {
166 4
        return array_keys($this->loaded);
167
    }
168
169
170
171
    /**
172
     * Return an arry with all active services names.
173
     *
174
     * @return void
175
     */
176 1
    public function getActiveServices()
177
    {
178 1
        return array_keys($this->active);
179
    }
180
}
181