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 (#4)
by Felix
01:39
created

Container::resolveParameters()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
dl 0
loc 22
ccs 0
cts 9
cp 0
rs 9.568
c 0
b 0
f 0
cc 4
nc 4
nop 1
crap 20
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
    public function unset(string $key): void
57
    {
58
        unset(
59
            $this->dicValues[$key],
60
            $this->dicObjects[$key]
61
        );
62
    }
63
64 21
    public function alias(string $alias, string $key): self
65
    {
66 21
        $this->aliases[$alias] = $key;
67
68 21
        return $this;
69
    }
70
71
    public function unalias(string $alias): void
72
    {
73
        unset($this->aliases[$alias]);
74
    }
75
76
    /**
77
     * Check if a DIC value/object exists.
78
     *
79
     * @param string $key
80
     * @return bool
81
     */
82 1
    public function has($key): bool
83
    {
84 1
        if (isset($this->aliases[$key])) {
85
            $key = $this->aliases[$key];
86
        }
87
88 1
        return isset($this->dicValues[$key]);
89
    }
90
91
    /**
92
     * @param string $key
93
     * @return bool
94
     */
95 2 View Code Duplication
    public function hasInstance($key): bool
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
96
    {
97 2
        if (isset($this->aliases[$key])) {
98
            $key = $this->aliases[$key];
99
        }
100
101 2
        return isset($this->dicObjects[$key]);
102
    }
103
104
    /**
105
     * Get the shared instance of a DIC object
106
     *
107
     * @param string $key
108
     * @return mixed
109
     */
110 21
    public function get($key)
111
    {
112 21
        if (isset($this->aliases[$key])) {
113
            $key = $this->aliases[$key];
114
        }
115
116
        // Get already instantiated object if it exist
117 21
        if (isset($this->dicObjects[$key])) {
118 2
            return $this->dicObjects[$key];
119
        }
120
121
        try {
122 21
            if (isset($this->dicValues[$key])) {
123 21
                $instance = $this->getValueInstance($key);
124
            } else {
125 21
                $instance = $this->resolveInstance($key);
126
            }
127 1
        } catch (\ReflectionException $e) {
128 1
            throw new NotFoundException(sprintf('Key "%s" could not be resolved. ', $key));
129
        }
130
131 21
        $this->dicObjects[$key] = $instance;
132
133 21
        return $this->dicObjects[$key];
134
    }
135
136
    /**
137
     * Get a new instance of a DIC object
138
     *
139
     * @param string $key
140
     * @return mixed
141
     */
142 3
    public function getNew(string $key)
143
    {
144 3
        if (isset($this->aliases[$key])) {
145
            $key = $this->aliases[$key];
146
        }
147
148
        try {
149 3
            if (isset($this->dicValues[$key])) {
150 2
                return $this->getValueInstance($key);
151
            }
152 1
            return $this->resolveInstance($key);
153 2
        } catch (\ReflectionException $e) {
154 2
            throw new NotFoundException(sprintf('Key "%s" could not be resolved.', $key));
155
        }
156
    }
157
158 21
    private function getValueInstance(string $key)
159
    {
160 21
        $value = $this->dicValues[$key];
161 21
        if (is_object($value)) {
162
            // Is it an invokable? (closure/anonymous function)
163 21
            if (method_exists($value, '__invoke')) {
164 21
                return $value($this);
165
            }
166 6
            return $value;
167
        }
168 1
        return $this->resolveInstance($value);
169
    }
170
171
    /**
172
     * Destroy a DIC object instance.
173
     *
174
     * Will force a new object to be created on next call.
175
     *
176
     * @param string $key
177
     */
178 1 View Code Duplication
    public function destroyInstance($key): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
179
    {
180 1
        if (isset($this->aliases[$key])) {
181
            $key = $this->aliases[$key];
182
        }
183
184 1
        unset($this->dicObjects[$key]);
185 1
    }
186
187
    /**
188
     * Destroy all DIC object instances.
189
     *
190
     * Will force new objects to be created on next call.
191
     */
192 1
    public function destroyAllInstances(): void
193
    {
194 1
        $this->dicObjects = [];
195
196
        // To make sure objects (like database connections) are destructed properly. PHP might not destruct objects
197
        // until the end of execution otherwise.
198 1
        gc_collect_cycles();
199 1
    }
200
201
    /**
202
     * Magic method to get or set DIC values.
203
     *
204
     * @param string $name
205
     * @param array  $arguments
206
     * @return mixed
207
     */
208 3
    public function __call($name, $arguments)
209
    {
210
        // getNew followed by an upper letter like getNewApple()
211 3
        if (preg_match('/^getNew([A-Z].*)/', $name, $matches)) {
212
            $key = lcfirst($matches[1]);
213
214
            return $this->getNew($key);
215 3
        } elseif (strpos($name, 'get') === 0) {
216 1
            $key = lcfirst(substr($name, 3));
217
218 1
            return $this->get($key);
219 3
        } elseif (strpos($name, 'set') === 0) {
220 2
            $argumentCount = count($arguments);
221 2
            if ($argumentCount !== 1) {
222 1
                throw new \BadMethodCallException("Invalid argument count[{$argumentCount}] for application {$name}()");
223
            }
224
225 1
            $key = lcfirst(substr($name, 3));
226
227 1
            return $this->set($key, $arguments[0]);
228
        } else {
229 1
            throw new \BadMethodCallException("No application method named {$name}()");
230
        }
231
    }
232
233
    /**
234
     * Instantiate an object of named class, recursively resolving dependencies
235
     *
236
     * @param string $className Fully qualified class name
237
     * @return mixed
238
     * @throws \ReflectionException
239
     */
240 3
    public function resolveInstance(string $className)
241
    {
242 3
        $class = new \ReflectionClass($className);
243
244
        if (!$class->isInstantiable()) {
245
            throw new \ReflectionException(sprintf('Class %s cannot be instantiated', $className));
246
        }
247
248
        $parameterValues = [];
249
        if (($constructor = $class->getConstructor())) {
250
            $parameterValues = $this->resolveParameters(
251
                $constructor->getParameters()
252
            );
253
        }
254
255
        return $class->newInstanceArgs($parameterValues);
256
    }
257
258
    /**
259
     * Recursively resolve function parameters using type hints
260
     *
261
     * @param \ReflectionParameter[]
262
     * @return mixed
263
     */
264
    private function resolveParameters(array $parameters): array
265
    {
266
        $values = [];
267
268
        /**
269
         * @var \ReflectionParameter $parameter
270
         */
271
        foreach ($parameters as $parameter) {
272
            if (($parameterClass = $parameter->getClass())) {
273
                try {
274
                    $values[] = $this->get($parameterClass->getName());
275
                }
276
                catch (NotFoundException $e) { // We're probably dealing with an unmapped interface here
277
                    $values[] = $parameter->getDefaultValue();
278
                }
279
            } else {
280
                $values[] = $parameter->getDefaultValue();
281
            }
282
        }
283
284
        return $values;
285
    }
286
}
287