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

Container::destroyInstance()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

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