Passed
Push — main ( 5c74ff...777132 )
by Tom
59s queued 15s
created

AbstractContainer   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 61
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 18
dl 0
loc 61
rs 10
c 2
b 0
f 0
wmc 7

4 Methods

Rating   Name   Duplication   Size   Complexity  
A get() 0 15 3
A build() 0 11 2
A set() 0 7 1
A has() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ApiSkeletons\Doctrine\GraphQL;
6
7
use Closure;
8
use GraphQL\Error\Error;
9
use Psr\Container\ContainerInterface;
10
use ReflectionClass;
11
use ReflectionException;
12
13
use function assert;
14
use function strtolower;
15
16
abstract class AbstractContainer implements ContainerInterface
17
{
18
    /** @var mixed[] */
19
    protected array $register = [];
20
21
    public function has(string $id): bool
22
    {
23
        return isset($this->register[strtolower($id)]);
24
    }
25
26
    /** @throws Error */
27
    public function get(string $id): mixed
28
    {
29
        $id = strtolower($id);
30
31
        if (! $this->has($id)) {
32
            throw new Error($id . ' is not registered');
33
        }
34
35
        if ($this->register[$id] instanceof Closure) {
36
            $closure = $this->register[$id];
37
38
            $this->register[$id] = $closure($this);
39
        }
40
41
        return $this->register[$id];
42
    }
43
44
    /**
45
     * This allows for a duplicate id to overwrite an existing registration
46
     */
47
    public function set(string $id, mixed $value): self
48
    {
49
        $id = strtolower($id);
50
51
        $this->register[$id] = $value;
52
53
        return $this;
54
    }
55
56
    /**
57
     * This function allows for buildable types.  The Type\Connection type is created this way
58
     * because it relies on the entity object type.  To create a custom buildable object type
59
     * it must implement the Buildable interface.
60
     *
61
     * @param mixed[] $params
62
     *
63
     * @throws Error
64
     * @throws ReflectionException
65
     */
66
    public function build(string $typeClassName, string $typeName, mixed ...$params): mixed
67
    {
68
        if ($this->has($typeName)) {
69
            return $this->get($typeName);
70
        }
71
72
        assert((new ReflectionClass($typeClassName))->implementsInterface(Buildable::class));
73
74
        return $this
75
            ->set($typeName, new $typeClassName($this, $typeName, $params))
76
            ->get($typeName);
77
    }
78
}
79