Services::getCurrent()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 8
rs 9.4286
cc 2
eloc 4
nc 2
nop 0
1
<?php
2
/**
3
 * Scabbia2 Services Component
4
 * https://github.com/eserozvataf/scabbia2
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 *
9
 * @link        https://github.com/eserozvataf/scabbia2-services for the canonical source repository
10
 * @copyright   2010-2016 Eser Ozvataf. (http://eser.ozvataf.com/)
11
 * @license     http://www.apache.org/licenses/LICENSE-2.0 - Apache License, Version 2.0
12
 */
13
14
namespace Scabbia\Services;
15
16
use ArrayAccess;
17
use InvalidArgumentException;
18
19
/**
20
 * Service container and registry
21
 *
22
 * @package     Scabbia\Services
23
 * @author      Eser Ozvataf <[email protected]>
24
 * @since       2.0.0
25
 */
26
class Services implements ArrayAccess
27
{
28
    /** @type Services    $default   default service container */
29
    public static $default = null;
30
31
    /** @type array       $services  shared service objects */
32
    protected $services = [];
33
34
35
    /**
36
     * Returns the instance of default service container
37
     *
38
     * @return Services default service container
39
     */
40
    public static function getCurrent()
41
    {
42
        if (static::$default === null) {
43
            static::$default = new Services();
44
        }
45
46
        return static::$default;
47
    }
48
49
    /**
50
     * Sets a service definition
51
     *
52
     * @param string    $uId               name of the service
53
     * @param mixed     $uValue            any value
54
     *
55
     * @return void
56
     */
57
    public function offsetSet($uId, $uValue)
58
    {
59
        $this->services[$uId] = [$uValue, true];
60
    }
61
62
    /**
63
     * Sets a factory function in order to generate service instances
64
     *
65
     * @param string    $uName             name of the service
66
     * @param callable  $uCallback         callback generates service instances
67
     *
68
     * @return void
69
     */
70
    public function setFactory($uName, $uCallback)
71
    {
72
        $this->services[$uName] = [$uCallback, false];
73
    }
74
75
    /**
76
     * Sets a factory function in order to generate service instances
77
     *
78
     * @param string    $uName             name of the service
79
     * @param callable  $uCallback         callback generates service instances
80
     *
81
     * @throws InvalidArgumentException if the service is not defined
82
     * @return void
83
     */
84
    public function decorate($uName, $uCallback)
85
    {
86
        if (!isset($this->services[$uName])) {
87
            throw new InvalidArgumentException(sprintf("Service '%s' is not defined.", $uName));
88
        }
89
90
        $tService = $this->services[$uName];
91
        $tClosure = function () use ($tService, $uCallback) {
92
            // it's a shared instance, not a factory.
93
            if ($tService[1] === true) {
94
                $tValue = $tService[0];
95
            } else {
96
                $tValue = call_user_func($tService[0]);
97
            }
98
99
            return call_user_func($uCallback, $tValue);
100
        };
101
102
        $this->services[$uName] = [$tClosure, false];
103
    }
104
105
    /**
106
     * Gets the service instance or invokes factory callback if the service is defined
107
     *
108
     * @param string    $uId               name of the service
109
     *
110
     * @throws InvalidArgumentException if the service is not defined
111
     * @return mixed the service instance
112
     */
113
    public function offsetGet($uId)
114
    {
115
        if (!isset($this->services[$uId])) {
116
            throw new InvalidArgumentException(sprintf("Service '%s' is not defined.", $uId));
117
        }
118
119
        $tService = $this->services[$uId];
120
121
        // it's a shared instance, not a factory.
122
        if ($tService[1] === true) {
123
            return $tService[0];
124
        }
125
126
        return call_user_func($tService[0]);
127
    }
128
129
    /**
130
     * Checks if service is defined
131
     *
132
     * @param string    $uId               name of the service
133
     *
134
     * @return bool
135
     */
136
    public function offsetExists($uId)
137
    {
138
        return isset($this->services[$uId]);
139
    }
140
141
    /**
142
     * Unsets a service
143
     *
144
     * @param string    $uId               name of the service
145
     *
146
     * @return void
147
     */
148
    public function offsetUnset($uId)
149
    {
150
        unset($this->services[$uId]);
151
    }
152
}
153