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:40
created

Container::resolveInstance()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 3.4578

Importance

Changes 0
Metric Value
dl 0
loc 15
ccs 2
cts 7
cp 0.2857
rs 9.7666
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 3.4578
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 21
        $this->aliases[$alias] = $key;
58
59 21
        return $this;
60
    }
61
62
    /**
63
     * Check if a DIC value/object exists.
64
     *
65
     * @param string $key
66
     * @return bool
67
     */
68 2
    public function has($key): bool
69
    {
70 2
        if (array_key_exists($key, $this->aliases)) {
71
            $key = $this->aliases[$key];
72
        }
73
74 2
        return array_key_exists($key, $this->dicValues);
75
    }
76
77
    /**
78
     * @param string $key
79
     * @return bool
80
     */
81 2
    public function hasInstance($key): bool
82
    {
83 2
        if (array_key_exists($key, $this->aliases)) {
84 1
            $key = $this->aliases[$key];
85
        }
86
87 2
        return isset($this->dicObjects[$key]);
88
    }
89
90
    /**
91
     * Get the shared instance of a DIC object
92
     *
93
     * @param string $key
94
     * @return mixed
95
     */
96 21
    public function get($key)
97
    {
98 21
        if (array_key_exists($key, $this->aliases)) {
99
            $key = $this->aliases[$key];
100
        }
101
102
        // Get already instantiated object if it exist
103 21
        if (isset($this->dicObjects[$key])) {
104 2
            return $this->dicObjects[$key];
105
        }
106
107
        try {
108 21
            if (array_key_exists($key, $this->dicValues)) {
109 21
                if (\is_object($this->dicValues[$key])) {
110
                    // Is it an invokable? (closure/anonymous function)
111 21
                    if (method_exists($this->dicValues[$key], '__invoke')) {
112 21
                        $instance = $this->dicValues[$key]($this);
113
                    } else {
114 21
                        $instance =  $this->dicValues[$key];
115
                    }
116
                } else {
117 21
                    $instance = $this->resolveInstance($this->dicValues[$key]);
118
                }
119
            } else {
120 21
                $instance =  $this->resolveInstance($key);
121
            }
122 1
        } catch (\ReflectionException $e) {
123 1
            throw new NotFoundException(sprintf('Key "%s" could not be resolved. ', $key));
124
        }
125
126 21
        $this->dicObjects[$key] = $instance;
127
128 21
        return $this->dicObjects[$key];
129
    }
130
131
    /**
132
     * Get a new instance of a DIC object
133
     *
134
     * @param string $key
135
     * @return mixed
136
     */
137 3
    public function getNew(string $key)
138
    {
139 3
        if (array_key_exists($key, $this->aliases)) {
140
            $key = $this->aliases[$key];
141
        }
142
143
        try {
144 3
            if (array_key_exists($key, $this->dicValues)) {
145 2
                if (\is_object($this->dicValues[$key])) {
146
                    // Is it an invokable? (closure/anonymous function)
147 1
                    if (method_exists($this->dicValues[$key], '__invoke')) {
148 1
                        return $this->dicValues[$key]($this);
149
                    }
150
                    throw new \LogicException('The value for the specified key is a pre-made instance');
151
                }
152 1
                return $this->resolveInstance($this->dicValues[$key]);
153
            }
154 1
            return $this->resolveInstance($key);
155 2
        } catch (\ReflectionException $e) {
156 2
            throw new NotFoundException(sprintf('Key "%s" could not be resolved.', $key));
157
        }
158
    }
159
160
    /**
161
     * Destroy a DIC object instance.
162
     *
163
     * Will force a new object to be created on next call.
164
     *
165
     * @param string $key
166
     */
167 1
    public function destroyInstance($key): void
168
    {
169 1
        unset($this->dicObjects[$key]);
170 1
    }
171
172
    /**
173
     * Destroy all DIC object instances.
174
     *
175
     * Will force new objects to be created on next call.
176
     */
177 1
    public function destroyAllInstances(): void
178
    {
179 1
        $this->dicObjects = [];
180
181
        // To make sure objects (like database connections) are destructed properly. PHP might not destruct objects
182
        // until the end of execution otherwise.
183 1
        gc_collect_cycles();
184 1
    }
185
186
    /**
187
     * Magic method to get or set DIC values.
188
     *
189
     * @param string $name
190
     * @param array  $arguments
191
     * @return mixed
192
     */
193 3
    public function __call($name, $arguments)
194
    {
195
        // getNew followed by an upper letter like getNewApple()
196 3
        if (preg_match('/^getNew([A-Z].*)/', $name, $matches)) {
197
            $key = lcfirst($matches[1]);
198
199
            return $this->getNew($key);
200 3
        } elseif (strpos($name, 'get') === 0) {
201 1
            $key = lcfirst(substr($name, 3));
202
203 1
            return $this->get($key);
204 3
        } elseif (strpos($name, 'set') === 0) {
205 2
            $argumentCount = \count($arguments);
206 2
            if ($argumentCount !== 1) {
207 1
                throw new \BadMethodCallException("Invalid argument count[{$argumentCount}] for application {$name}()");
208
            }
209
210 1
            $key = lcfirst(substr($name, 3));
211
212 1
            return $this->set($key, $arguments[0]);
213
        } else {
214 1
            throw new \BadMethodCallException("No application method named {$name}()");
215
        }
216
    }
217
218
    /**
219
     * Instantiate an object of named class, recursively resolving dependencies
220
     *
221
     * @param string $className Fully qualified class name
222
     * @return mixed
223
     * @throws \ReflectionException
224
     */
225 3
    protected function resolveInstance(string $className)
226
    {
227 3
        $class = new \ReflectionClass($className);
228
229
        if (!$class->isInstantiable()) {
230
            throw new \ReflectionException(sprintf('Class %s cannot be instantiated', $className));
231
        }
232
233
234
        $parameterValues = $this->resolveParameters(
235
            $class->getConstructor()->getParameters()
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
    protected 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()) && $this->has($parameterClass->getName())) {
256
                $values[] = $this->get($parameterClass->getName());
257
            } else {
258
                $values[] = $parameter->getDefaultValue();
259
            }
260
        }
261
262
        return $values;
263
    }
264
}
265