Passed
Push — master ( 3f0f4d...875c9b )
by Mauro
01:59
created

DIC::getFromEnvOrDICParams()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 5
nc 5
nop 1
dl 0
loc 11
rs 9.6111
c 0
b 0
f 0
1
<?php
2
3
namespace SimpleDIC;
4
5
use Pimple\Container;
6
use SimpleDIC\Parser\Parser;
7
8
class DIC
9
{
10
    /**
11
     * @var Container
12
     */
13
    private static $container;
14
15
    /**
16
     * DIC constructor.
17
     *
18
     * @param array $config
19
     */
20
    private function __construct(array $config = [])
21
    {
22
        self::$container = new Container();
23
24
        $this->resolveDependencies($config);
25
    }
26
27
    /**
28
     * @return int
29
     */
30
    public static function count()
31
    {
32
        return count(self::keys());
33
    }
34
35
    /**
36
     * Initialise the DIC
37
     *
38
     * @param array $config
39
     *
40
     * @return DIC
41
     */
42
    public static function init(array $config = [])
43
    {
44
        return new self($config);
45
    }
46
47
    /**
48
     * @param string $filename
49
     *
50
     * @return DIC
51
     * @throws \Exception
52
     */
53
    public static function initFromFile($filename)
54
    {
55
        return new self(Parser::parse($filename));
56
    }
57
58
    /**
59
     * @return array
60
     */
61
    public static function keys()
62
    {
63
        return self::$container->keys();
64
    }
65
66
    /**
67
     * Resolve the dependencies and register into the DIC
68
     *
69
     * @param array $config
70
     */
71
    private function resolveDependencies(array $config = [])
72
    {
73
        foreach ($config as $key => $content) {
74
            self::set($key, $content);
75
        }
76
    }
77
78
    /**
79
     *
80
     * Check for an entry existence within the container
81
     *
82
     * @param string $dependency
83
     *
84
     * @return bool
85
     */
86
    public static function has($dependency)
87
    {
88
        return isset(self::$container[$dependency]);
89
    }
90
91
    /**
92
     * Get an entry from the container.
93
     *
94
     * The method returns:
95
     * - false if the entry has a wrong configuration
96
     * - NULL if the entry does not exists
97
     *
98
     * @param string $dependency
99
     *
100
     * @return mixed
101
     */
102
    public static function get($dependency)
103
    {
104
        if (self::has($dependency)) {
105
            return self::$container[$dependency];
106
        }
107
    }
108
109
    /**
110
     * Set an entry in the container.
111
     *
112
     * @param string $key
113
     * @param array|mixed $content
114
     *
115
     * @return mixed|bool|null
116
     */
117
    public static function set($key, $content)
118
    {
119
        if (false === self::has($key)) {
120
            self::$container[$key] = function ($c) use ($content) {
121
122
                // if is not a class set the entry value in DIC
123
                if (false === isset($content['class'])) {
124
                    return self::getFromEnvOrDICParams($content);
125
                }
126
127
                // otherwise it's a class, so extract variables
128
                $class           = isset($content['class']) ? $content['class'] : null;
129
                $classArguments  = isset($content['arguments']) ? $content['arguments'] : null;
130
                $method          = isset($content['method']) ? $content['method'] : null;
131
                $methodArguments = isset($content['method_arguments']) ? $content['method_arguments'] : null;
132
133
                // if specified, call a method
134
                if ($method) {
135
136
                    // if specified, call the method with provided arguments
137
                    if ($methodArguments) {
138
                        try {
139
                            return call_user_func_array([$class, $method], self::getArgumentsToInject($c, $methodArguments));
140
                        } catch (\Error $error) {
141
                            return false;
142
                        } catch (\Exception $exception) {
143
                            return false;
144
                        }
145
                    }
146
147
                    // if not, call the method with no arguments
148
                    try {
149
                        return call_user_func([$class, $method]);
150
                    } catch (\Error $error) {
151
                        return false;
152
                    } catch (\Exception $exception) {
153
                        return false;
154
                    }
155
                }
156
157
                if (false === class_exists($class)) {
158
                    return false;
159
                }
160
161
                // if the method is not specified, call the constructor
162
                try {
163
                    return new $class(...self::getArgumentsToInject($c, $classArguments));
164
                } catch (\Error $error) {
165
                    return false;
166
                } catch (\Exception $exception) {
167
                    return false;
168
                }
169
            };
170
171
            return null;
172
        }
173
    }
174
175
    /**
176
     * Get the arguments to inject into the class to instantiate within DIC.
177
     *
178
     * @param Container $c
179
     * @param null      $providedArguments
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $providedArguments is correct as it would always require null to be passed?
Loading history...
180
     *
181
     * @return array
182
     */
183
    private static function getArgumentsToInject(Container $c, $providedArguments = null)
184
    {
185
        $returnArguments = [];
186
187
        if (null != $providedArguments) {
0 ignored issues
show
introduced by
The condition null != $providedArguments is always false.
Loading history...
188
            foreach ($providedArguments as $argument) {
189
                $returnArguments[] = self::getArgumentToInject($argument, $c);
190
            }
191
        }
192
193
        return $returnArguments;
194
    }
195
196
    /**
197
     * @param   string        $argument
198
     * @param Container $c
199
     *
200
     * @return mixed|string|null
201
     */
202
    private static function getArgumentToInject($argument, Container $c)
203
    {
204
        if (isset($c[ltrim($argument, '@')])) {
205
            return $c[ltrim($argument, '@')];
206
        }
207
208
        return self::getFromEnvOrDICParams($argument);
209
    }
210
211
    /**
212
     * @param string $parameter
213
     *
214
     * @return mixed|string|null
215
     */
216
    private static function getFromEnvOrDICParams($parameter)
217
    {
218
        if (is_string($parameter)) {
0 ignored issues
show
introduced by
The condition is_string($parameter) is always true.
Loading history...
219
            if (null !== self::getEnvKey($parameter)) {
220
                return (getenv(self::getEnvKey($parameter))) ? getenv(self::getEnvKey($parameter)) : $parameter;
221
            }
222
223
            return (DICParams::has(self::getParamKey($parameter))) ? DICParams::get(self::getParamKey($parameter)) : $parameter;
224
        }
225
226
        return $parameter;
227
    }
228
229
    /**
230
     * Extract from a string like %env(FOO)%
231
     *
232
     * @param string $string
233
     *
234
     * @return mixed|null
235
     */
236
    private static function getEnvKey($string)
237
    {
238
        preg_match('~%env\((.*?)\)%~', $string, $matches);
239
240
        return (count($matches) > 0) ? $matches[1] : null;
241
    }
242
243
    /**
244
     * @param string $string
245
     *
246
     * @return string
247
     */
248
    private static function getParamKey($string)
249
    {
250
        return trim($string, '%');
251
    }
252
}
253