Passed
Push — master ( 3266fb...94512e )
by Thomas
03:56 queued 01:13
created

ServiceContainer::instantiate()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 18
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3.009

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 9
nc 3
nop 1
dl 0
loc 18
ccs 9
cts 10
cp 0.9
crap 3.009
rs 9.9666
c 1
b 0
f 0
1
<?php
2
3
namespace MadWizard\WebAuthn\Builder;
4
5
use ArrayAccess;
6
use MadWizard\WebAuthn\Exception\WebAuthnException;
7
use Psr\Log\LoggerAwareInterface;
8
use Psr\Log\LoggerInterface;
9
use RuntimeException;
10
11
/**
12
 * @implements ArrayAccess<string, object>
13
 */
14
class ServiceContainer implements ArrayAccess
15
{
16
    /**
17
     * @phpstan-var array<class-string, object>
18
     *
19
     * @var object[]
20
     */
21
    private $serviceMap = [];
22
23
    /**
24
     * @phpstan-var array<class-string, callable(self): object>
25
     *
26
     * @var callable[]
27
     */
28
    private $instantiators = [];
29
30
    /**
31
     * @param string $offset
32
     * @param string $offset
33
     * @phpstan-param class-string $offset
34
     *
35
     * @return bool
36
     */
37
    public function offsetExists($offset): bool
38
    {
39
        return isset($this->serviceMap[$offset]) || isset($this->instantiators[$offset]);
40
    }
41
42
    /**
43
     * @template T of object
44
     *
45
     * @param string $service
46
     * @phpstan-param class-string<T> $service
47
     * @phpstan-return T
48
     */
49 18
    public function offsetGet($service): object
50
    {
51
        /**
52
         * @phpstan-var T
53
         */
54 18
        $service = ($this->serviceMap[$service] ?? $this->instantiate($service));
55 18
        return $service;
56
    }
57
58
    /**
59
     * @param string $offset
60
     */
61
    #[\ReturnTypeWillChange]
62
    public function offsetUnset($offset)
63
    {
64
        throw new RuntimeException('Unset operation is not supported.');
65
    }
66
67
    /**
68
     * @param string   $offset
69
     * @param callable $value
70
     * @phpstan-param class-string $offset
71
     * @phpstan-param callable(self): object $value
72
     */
73 18
    public function offsetSet($offset, $value): void
74
    {
75 18
        $this->instantiators[$offset] = $value;
76 18
    }
77
78
    /**
79
     * @template T of object
80
     * @phpstan-param class-string<T> $offset
81
     * @phpstan-return T of object
82
     */
83 18
    private function instantiate(string $offset): object
84
    {
85 18
        $instantiator = $this->instantiators[$offset] ?? null;
86 18
        if ($instantiator === null) {
87
            throw new WebAuthnException(sprintf('Missing service %s.', $offset));
88
        }
89
        /**
90
         * @phpstan-var T
91
         */
92 18
        $service = $instantiator($this);
93 18
        $this->serviceMap[$offset] = $service;
94
95 18
        if ($service instanceof LoggerAwareInterface) {
96 18
            $service->setLogger($this[LoggerInterface::class]);
97
        }
98
        // Free instantatior resources:
99 18
        unset($this->instantiators[$offset]);
100 18
        return $service;
101
    }
102
}
103