Passed
Push — master ( 42dea4...54c542 )
by Mikael
01:37
created

DI::has()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 0
cts 4
cp 0
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 1
crap 6
1
<?php
2
3
namespace Anax\DI;
4
5
/**
6
 * Anax base class implementing Dependency Injection / Service Locator of
7
 * the services used by the framework, using lazy loading.
8
 */
9
class DI implements DIInterface
10
{
11
    /**
12
     * Properties
13
     *
14
     */
15
    public $loaded = [];  // Store all lazy loaded services, ready to be instantiated
16
    public $active = [];  // A service is instantiated into this array, once its accessed
17
18
19
20
    /**
21
     * Finds an entry of the container by its identifier and returns it.
22
     *
23
     * @param string $service     Identifier of the entry to look for.
24
     *
25
     * @throws NotFoundException  No entry was found for this identifier.
26
     * @throws Exception          Error while retrieving the entry.
27
     *
28
     * @return mixed Entry.
29
     */
30 2
    public function get($service)
31
    {
32
        // Is the service active?
33 2
        if (isset($this->active[$service])) {
34
            if ($this->loaded[$service]['singleton']) {
35
                return $this->active[$service];
36
            } else {
37
                return $this->load($service);
38
            }
39 2
        } elseif (isset($this->loaded[$service])) {
40
            // Is the service loaded?
41 2
            return $this->load($service);
42
        }
43
44
        $message  = "DI the service accessed '$service' is not loaded in the DI-container.";
45
        $services = $this->getServices();
46
        natcasesort($services);
47
        $services = implode("\n", $services);
48
        $message .= " Loaded services are: <pre>$services</pre>";
49
        
50
        throw new NotFoundException($message);
51
    }
52
53
54
55
    /**
56
     * Returns true if the container can return an entry for the given
57
     * identifier, otherwise false
58
     *
59
     * @param string $service Identifier of the entry to look for.
60
     *
61
     * @return boolean
62
     */
63
    public function has($service)
64
    {
65
        return isset($this->loaded[$service])
66
            ? true
67
            : false;
68
    }
69
70
71
72
    /**
73
     * Set a service and connect it to a task which creates the object (lazy loading).
74
     *
75
     * @param string  $service   as a service label, naming this service.
76
     * @param mixed   $loader    contains a pre-defined object, a string with classname or an
77
     *      callable which returns an instance of the service object. Its the way to
78
     *      actually load, insantiate, the serviceobject.
79
     * @param boolean $singleton set if service is to act as singleton or not, default is false.
80
     *
81
     * @return nothing.
0 ignored issues
show
Documentation introduced by
The doc-type nothing. could not be parsed: Unknown type name "nothing." at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
82
     */
83 2
    public function set($service, $loader, $singleton = false)
84
    {
85 2
        $this->loaded[$service]['loader'] = $loader;
86 2
        $this->loaded[$service]['singleton'] = $singleton;
87 2
    }
88
89
90
91
    /**
92
     * Return an arry with all loaded services names.
93
     *
94
     * @return void
95
     */
96
    public function getServices()
97
    {
98
        return array_keys($this->loaded);
99
    }
100
101
102
103
    /**
104
     * Return an array with all loaded services that are controllers.
105
     *
106
     * @return void
107
     */
108
    public function getControllers()
109
    {
110
        return array_filter(
111
            array_keys($this->loaded),
112
            function ($val) {
113
                return strpos($val, "Controller") !== false;
114
            }
115
        );
116
    }
117
118
119
120
    /**
121
     * Return an arry with all active services names.
122
     *
123
     * @return void
124
     */
125
    public function getActiveServices()
126
    {
127
        return array_keys($this->active);
128
    }
129
130
131
132
    /**
133
     * Set a singleton service and connect it to a task which creates the object (lazy loading).
134
     *
135
     * @param string $service as a service label, naming this service.
136
     * @param mixed  $loader  contains a pre-defined object, a string with
137
     *                        classname or an callable which returns an
138
     *                        instance of the service object. Its the way
139
     *                        to actually load, insantiate, the serviceobject.
140
     *
141
     * @return nothing.
0 ignored issues
show
Documentation introduced by
The doc-type nothing. could not be parsed: Unknown type name "nothing." at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
142
     */
143 1
    public function setShared($service, $loader)
144
    {
145 1
        $this->set($service, $loader, true);
146 1
    }
147
148
149
150
    /**
151
     * Magic method to get and create services.
152
     * When created it is also stored as a parameter of this object.
153
     *
154
     * @param string $service name of class property not existing.
155
     *
156
     * @return class as the service requested.
157
     */
158
    public function __get($service)
159
    {
160
        return $this->get($service);
161
    }
162
163
164
165
    /**
166
     * Magic method to get and create services.
167
     * When created it is also stored as a parameter of this object.
168
     *
169
     * @param string $service   name of class property not existing.
170
     * @param array  $arguments currently NOT USED.
171
     *
172
     * @return class as the service requested.
173
     */
174
    public function __call($service, $arguments = [])
175
    {
176
        return $this->get($service);
177
    }
178
179
180
181
    /**
182
     * Lazy load a service object and create an instance of it.
183
     *
184
     * @param string $service as a service label, naming this service.
185
     *
186
     * @return object as instance of the service object.
187
     * @throws Exception when service could not be loaded.
188
     */
189 2
    protected function load($service)
190
    {
191 2
        $sol = isset($this->loaded[$service]['loader'])
192 2
            ? $this->loaded[$service]['loader']
193 2
            : null;
194
195
        // Load by calling a function
196 2
        if (is_callable($sol)) {
197
            try {
198 2
                $this->active[$service] = $sol();
199 2
            } catch (\Exception $e) {
200 1
                throw new \Exception(
201 1
                    "CDI could not load service '$service'."
202
                    . "Failed in the callback that instantiates the service. "
203 1
                    . $e->getMessage()
204 1
                );
205
            }
206 1
        } elseif (is_object($sol)) {
207
            // Load by pre-instantiated object
208
            $this->active[$service] = $sol;
209
        } elseif (is_string($sol)) {
210
            // Load by creating a new object from class-string
211
            $this->active[$service] = new $sol();
212
        } else {
213
            throw new Exception("CDI could not load service '$service'. It is unknown how to load it.");
214
        }
215
216 1
        $this->$service = $this->active[$service];
217 1
        return $this->active[$service];
218
    }
219
}
220