GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Pull Request — master (#3)
by
unknown
01:59
created

Container::getValueInstance()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 7
cts 7
cp 1
rs 9.8666
c 0
b 0
f 0
cc 3
nc 3
nop 1
crap 3
1
<?php
2
/**
3
 * Starlit App.
4
 *
5
 * @copyright Copyright (c) 2016 Starweb AB
6
 * @license   BSD 3-Clause
7
 */
8
9
namespace Starlit\App\Container;
10
11
use Psr\Container\ContainerInterface;
12
13
/**
14
 * Dependency injection container.
15
 *
16
 * @author Andreas Nilsson <http://github.com/jandreasn>
17
 */
18
class Container implements ContainerInterface
19
{
20
    /**
21
     * @var array
22
     */
23
    private $dicValues = [];
24
25
    /**
26
     * @var array
27
     */
28
    private $aliases = [];
29
30
    /**
31
     * @var array
32
     */
33
    private $dicObjects = [];
34
35
    /**
36
     * Set a DIC value.
37
     *
38
     * Wrap objects provided in a closure for lazy loading.
39
     *
40
     * @param string $key
41
     * @param mixed  $value
42
     * @return Container
43
     */
44 21
    public function set(string $key, $value): self
45
    {
46 21
        if (!(\is_string($value) || \is_object($value))) {
47
            throw new \InvalidArgumentException('Value must be a class name, an object instance, or a callable');
48
        }
49
50 21
        $this->dicValues[$key] = $value;
51 21
        unset($this->dicObjects[$key]); // In case an object instance was stored for sharing
52
53 21
        return $this;
54
    }
55
56 21
    public function alias(string $alias, string $key): self
57
    {
58 21
        $this->aliases[$alias] = $key;
59
60 21
        return $this;
61
    }
62
63
    /**
64
     * Check if a DIC value/object exists.
65
     *
66
     * @param string $key
67
     * @return bool
68
     */
69 2
    public function has($key): bool
70
    {
71 2
        if (isset($this->aliases[$key])) {
72
            $key = $this->aliases[$key];
73
        }
74
75 2
        return isset($this->dicValues[$key]);
76
    }
77
78
    /**
79
     * @param string $key
80
     * @return bool
81
     */
82 2
    public function hasInstance($key): bool
83
    {
84 2
        if (isset($this->aliases[$key])) {
85 1
            $key = $this->aliases[$key];
86
        }
87
88 2
        return isset($this->dicObjects[$key]);
89
    }
90
91
    /**
92
     * Get the shared instance of a DIC object
93
     *
94
     * @param string $key
95
     * @return mixed
96
     */
97 21
    public function get($key)
98
    {
99 21
        if (isset($this->aliases[$key])) {
100
            $key = $this->aliases[$key];
101
        }
102
103
        // Get already instantiated object if it exist
104 21
        if (isset($this->dicObjects[$key])) {
105 2
            return $this->dicObjects[$key];
106
        }
107
108
        try {
109 21
            if (isset($this->dicValues[$key])) {
110 21
                $instance = $this->getValueInstance($key);
111
            } else {
112 21
                $instance = $this->resolveInstance($key);
113
            }
114 1
        } catch (\ReflectionException $e) {
115 1
            throw new NotFoundException(sprintf('Key "%s" could not be resolved. ', $key));
116
        }
117
118 21
        $this->dicObjects[$key] = $instance;
119
120 21
        return $this->dicObjects[$key];
121
    }
122
123
    /**
124
     * Get a new instance of a DIC object
125
     *
126
     * @param string $key
127
     * @return mixed
128
     */
129 3
    public function getNew(string $key)
130
    {
131 3
        if (isset($this->aliases[$key])) {
132
            $key = $this->aliases[$key];
133
        }
134
135
        try {
136 3
            if (isset($this->dicValues[$key])) {
137 2
                return $this->getValueInstance($key);
138
            }
139 1
            return $this->resolveInstance($key);
140 2
        } catch (\ReflectionException $e) {
141 2
            throw new NotFoundException(sprintf('Key "%s" could not be resolved.', $key));
142
        }
143
    }
144
145 21
    private function getValueInstance(string $key)
146
    {
147 21
        $value = $this->dicValues[$key];
148 21
        if (\is_object($value)) {
149
            // Is it an invokable? (closure/anonymous function)
150 21
            if (method_exists($value, '__invoke')) {
151 21
                return $value($this);
152
            }
153 7
            return $value;
154
        }
155 1
        return $this->resolveInstance($value);
156
    }
157
158
    /**
159
     * Destroy a DIC object instance.
160
     *
161
     * Will force a new object to be created on next call.
162
     *
163
     * @param string $key
164
     */
165 1
    public function destroyInstance($key): void
166
    {
167 1
        unset($this->dicObjects[$key]);
168 1
    }
169
170
    /**
171
     * Destroy all DIC object instances.
172
     *
173
     * Will force new objects to be created on next call.
174
     */
175 1
    public function destroyAllInstances(): void
176
    {
177 1
        $this->dicObjects = [];
178
179
        // To make sure objects (like database connections) are destructed properly. PHP might not destruct objects
180
        // until the end of execution otherwise.
181 1
        gc_collect_cycles();
182 1
    }
183
184
    /**
185
     * Magic method to get or set DIC values.
186
     *
187
     * @param string $name
188
     * @param array  $arguments
189
     * @return mixed
190
     */
191 3
    public function __call($name, $arguments)
192
    {
193
        // getNew followed by an upper letter like getNewApple()
194 3
        if (preg_match('/^getNew([A-Z].*)/', $name, $matches)) {
195
            $key = lcfirst($matches[1]);
196
197
            return $this->getNew($key);
198 3
        } elseif (strpos($name, 'get') === 0) {
199 1
            $key = lcfirst(substr($name, 3));
200
201 1
            return $this->get($key);
202 3
        } elseif (strpos($name, 'set') === 0) {
203 2
            $argumentCount = \count($arguments);
204 2
            if ($argumentCount !== 1) {
205 1
                throw new \BadMethodCallException("Invalid argument count[{$argumentCount}] for application {$name}()");
206
            }
207
208 1
            $key = lcfirst(substr($name, 3));
209
210 1
            return $this->set($key, $arguments[0]);
211
        } else {
212 1
            throw new \BadMethodCallException("No application method named {$name}()");
213
        }
214
    }
215
216
    /**
217
     * Instantiate an object of named class, recursively resolving dependencies
218
     *
219
     * @param string $className Fully qualified class name
220
     * @return mixed
221
     * @throws \ReflectionException
222
     */
223 3
    private function resolveInstance(string $className)
224
    {
225 3
        $class = new \ReflectionClass($className);
226
227
        if (!$class->isInstantiable()) {
228
            throw new \ReflectionException(sprintf('Class %s cannot be instantiated', $className));
229
        }
230
231
        $parameterValues = [];
232
        if (($constructor = $class->getConstructor())) {
233
            $parameterValues = $this->resolveParameters(
234
                $constructor->getParameters()
235
            );
236
        }
237
238
        return $class->newInstanceArgs($parameterValues);
239
    }
240
241
    /**
242
     * Recursively resolve function parameters using type hints
243
     *
244
     * @param \ReflectionParameter[]
245
     * @return mixed
246
     */
247
    private function resolveParameters(array $parameters): array
248
    {
249
        $values = [];
250
251
        /**
252
         * @var \ReflectionParameter $parameter
253
         */
254
        foreach ($parameters as $parameter) {
255
            if (($parameterClass = $parameter->getClass())) {
256
                try {
257
                    $values[] = $this->get($parameterClass->getName());
258
                }
259
                catch (NotFoundException $e) { // We're probably dealing with an unmapped interface here
260
                    $values[] = $parameter->getDefaultValue();
261
                }
262
            } else {
263
                $values[] = $parameter->getDefaultValue();
264
            }
265
        }
266
267
        return $values;
268
    }
269
}
270