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
02:02 queued 21s
created

Container::resolveInstance()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 7.2349

Importance

Changes 0
Metric Value
dl 0
loc 18
ccs 2
cts 9
cp 0.2222
rs 9.6666
c 0
b 0
f 0
cc 3
nc 3
nop 1
crap 7.2349
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 (array_key_exists($key, $this->aliases)) {
72
            $key = $this->aliases[$key];
73
        }
74
75 2
        return array_key_exists($key, $this->dicValues);
76
    }
77
78
    /**
79
     * @param string $key
80
     * @return bool
81
     */
82 2
    public function hasInstance($key): bool
83
    {
84 2
        if (array_key_exists($key, $this->aliases)) {
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 (array_key_exists($key, $this->aliases)) {
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 (array_key_exists($key, $this->dicValues)) {
110 21
                if (\is_object($this->dicValues[$key])) {
111
                    // Is it an invokable? (closure/anonymous function)
112 21
                    if (method_exists($this->dicValues[$key], '__invoke')) {
113 21
                        $instance = $this->dicValues[$key]($this);
114
                    } else {
115 21
                        $instance =  $this->dicValues[$key];
116
                    }
117
                } else {
118 21
                    $instance = $this->resolveInstance($this->dicValues[$key]);
119
                }
120
            } else {
121 21
                $instance =  $this->resolveInstance($key);
122
            }
123 1
        } catch (\ReflectionException $e) {
124 1
            throw new NotFoundException(sprintf('Key "%s" could not be resolved. ', $key));
125
        }
126
127 21
        $this->dicObjects[$key] = $instance;
128
129 21
        return $this->dicObjects[$key];
130
    }
131
132
    /**
133
     * Get a new instance of a DIC object
134
     *
135
     * @param string $key
136
     * @return mixed
137
     */
138 3
    public function getNew(string $key)
139
    {
140 3
        if (array_key_exists($key, $this->aliases)) {
141
            $key = $this->aliases[$key];
142
        }
143
144
        try {
145 3
            if (array_key_exists($key, $this->dicValues)) {
146 2
                if (\is_object($this->dicValues[$key])) {
147
                    // Is it an invokable? (closure/anonymous function)
148 1
                    if (method_exists($this->dicValues[$key], '__invoke')) {
149 1
                        return $this->dicValues[$key]($this);
150
                    }
151
                    throw new \LogicException('The value for the specified key is a pre-made instance');
152
                }
153 1
                return $this->resolveInstance($this->dicValues[$key]);
154
            }
155 1
            return $this->resolveInstance($key);
156 2
        } catch (\ReflectionException $e) {
157 2
            throw new NotFoundException(sprintf('Key "%s" could not be resolved.', $key));
158
        }
159
    }
160
161
    /**
162
     * Destroy a DIC object instance.
163
     *
164
     * Will force a new object to be created on next call.
165
     *
166
     * @param string $key
167
     */
168 1
    public function destroyInstance($key): void
169
    {
170 1
        unset($this->dicObjects[$key]);
171 1
    }
172
173
    /**
174
     * Destroy all DIC object instances.
175
     *
176
     * Will force new objects to be created on next call.
177
     */
178 1
    public function destroyAllInstances(): void
179
    {
180 1
        $this->dicObjects = [];
181
182
        // To make sure objects (like database connections) are destructed properly. PHP might not destruct objects
183
        // until the end of execution otherwise.
184 1
        gc_collect_cycles();
185 1
    }
186
187
    /**
188
     * Magic method to get or set DIC values.
189
     *
190
     * @param string $name
191
     * @param array  $arguments
192
     * @return mixed
193
     */
194 3
    public function __call($name, $arguments)
195
    {
196
        // getNew followed by an upper letter like getNewApple()
197 3
        if (preg_match('/^getNew([A-Z].*)/', $name, $matches)) {
198
            $key = lcfirst($matches[1]);
199
200
            return $this->getNew($key);
201 3
        } elseif (strpos($name, 'get') === 0) {
202 1
            $key = lcfirst(substr($name, 3));
203
204 1
            return $this->get($key);
205 3
        } elseif (strpos($name, 'set') === 0) {
206 2
            $argumentCount = \count($arguments);
207 2
            if ($argumentCount !== 1) {
208 1
                throw new \BadMethodCallException("Invalid argument count[{$argumentCount}] for application {$name}()");
209
            }
210
211 1
            $key = lcfirst(substr($name, 3));
212
213 1
            return $this->set($key, $arguments[0]);
214
        } else {
215 1
            throw new \BadMethodCallException("No application method named {$name}()");
216
        }
217
    }
218
219
    /**
220
     * Instantiate an object of named class, recursively resolving dependencies
221
     *
222
     * @param string $className Fully qualified class name
223
     * @return mixed
224
     * @throws \ReflectionException
225
     */
226 3
    protected function resolveInstance(string $className)
227
    {
228 3
        $class = new \ReflectionClass($className);
229
230
        if (!$class->isInstantiable()) {
231
            throw new \ReflectionException(sprintf('Class %s cannot be instantiated', $className));
232
        }
233
234
235
        $parameterValues = [];
236
        if (($constructor = $class->getConstructor())) {
237
            $parameterValues = $this->resolveParameters(
238
                $constructor->getParameters()
239
            );
240
        }
241
242
        return $class->newInstanceArgs($parameterValues);
243
    }
244
245
    /**
246
     * Recursively resolve function parameters using type hints
247
     *
248
     * @param \ReflectionParameter[]
249
     * @return mixed
250
     */
251
    protected function resolveParameters(array $parameters): array
252
    {
253
        $values = [];
254
255
        /**
256
         * @var \ReflectionParameter $parameter
257
         */
258
        foreach ($parameters as $parameter) {
259
            if (($parameterClass = $parameter->getClass())) {
260
                $values[] = $this->get($parameterClass->getName());
261
            } else {
262
                $values[] = $parameter->getDefaultValue();
263
            }
264
        }
265
266
        return $values;
267
    }
268
}
269