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

Container::unset()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

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