Container::get()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 3
nop 1
dl 0
loc 15
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ApiSkeletons\Doctrine\ORM\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
/**
17
 * Used in many places to create a container of types and services
18
 */
19
abstract class Container implements ContainerInterface
20
{
21
    /** @var mixed[] */
22
    protected array $register = [];
23
24
    public function has(string $id): bool
25
    {
26
        return isset($this->register[strtolower($id)]);
27
    }
28
29
    /** @throws Error */
30
    public function get(string $id): mixed
31
    {
32
        $id = strtolower($id);
33
34
        if (! $this->has($id)) {
35
            throw new Error($id . ' is not registered');
36
        }
37
38
        if ($this->register[$id] instanceof Closure) {
39
            $closure = $this->register[$id];
40
41
            $this->register[$id] = $closure($this);
42
        }
43
44
        return $this->register[$id];
45
    }
46
47
    /**
48
     * This allows for a duplicate id to overwrite an existing registration
49
     */
50
    public function set(string $id, mixed $value): self
51
    {
52
        $id = strtolower($id);
53
54
        $this->register[$id] = $value;
55
56
        return $this;
57
    }
58
59
    /**
60
     * This function allows for buildable types.  The Type\Connection type is created this way
61
     * because it relies on the entity object type.  To create a custom buildable object type
62
     * it must implement the Buildable interface.
63
     *
64
     * @param class-string $className
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string.
Loading history...
65
     *
66
     * @throws Error
67
     * @throws ReflectionException
68
     */
69
    public function build(string $className, string $typeName, mixed ...$params): mixed
70
    {
71
        if ($this->has($typeName)) {
72
            return $this->get($typeName);
73
        }
74
75
        $reflectionClass = new ReflectionClass($className);
76
        assert($reflectionClass->implementsInterface(Buildable::class));
77
78
        return $this
79
            ->set($typeName, new $className($this, $typeName, $params))
80
            ->get($typeName);
81
    }
82
}
83