Completed
Push — master ( 5b603d...f09253 )
by David
12s
created

BasicAutoWiringContainer::has()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 8
dl 0
loc 14
rs 9.6111
c 0
b 0
f 0
cc 5
nc 5
nop 1
1
<?php
2
3
4
namespace TheCodingMachine\GraphQL\Controllers\Containers;
5
6
use function class_exists;
7
use Psr\Container\ContainerExceptionInterface;
8
use Psr\Container\ContainerInterface;
9
use Psr\Container\NotFoundExceptionInterface;
10
use GraphQL\Type\Definition\ObjectType;
11
12
/**
13
 * The BasicAutoWiringContainer is a container wrapper that will automatically instantiate classes that have
14
 * no constructor arguments.
15
 */
16
class BasicAutoWiringContainer implements ContainerInterface
17
{
18
    /**
19
     * @var ContainerInterface
20
     */
21
    private $container;
22
    /**
23
     * @var ObjectType[]
24
     */
25
    private $values = [];
26
27
    /**
28
     * @param ContainerInterface $container The proxied container.
29
     */
30
    public function __construct(ContainerInterface $container)
31
    {
32
        $this->container = $container;
33
    }
34
35
    /**
36
     * Finds an entry of the container by its identifier and returns it.
37
     *
38
     * @param string $id Identifier of the entry to look for.
39
     *
40
     * @throws NotFoundExceptionInterface  No entry was found for **this** identifier.
41
     * @throws ContainerExceptionInterface Error while retrieving the entry.
42
     *
43
     * @return mixed Entry.
44
     */
45
    public function get($id)
46
    {
47
        if (isset($this->values[$id])) {
48
            return $this->values[$id];
49
        }
50
        if ($this->container->has($id)) {
51
            return $this->container->get($id);
52
        }
53
54
        // The container will try to instantiate the type if the class exists and has an annotation.
55
        if (class_exists($id)) {
56
            $refTypeClass = new \ReflectionClass($id);
57
            if ($refTypeClass->hasMethod('__construct') && $refTypeClass->getMethod('__construct')->getNumberOfRequiredParameters() > 0) {
58
                throw NotFoundException::notFoundInContainer($id);
59
            }
60
            $this->values[$id] = new $id();
61
            return $this->values[$id];
62
        }
63
64
        throw NotFoundException::notFound($id);
65
    }
66
67
    /**
68
     * Returns true if the container can return an entry for the given identifier.
69
     * Returns false otherwise.
70
     *
71
     * `has($id)` returning true does not mean that `get($id)` will not throw an exception.
72
     * It does however mean that `get($id)` will not throw a `NotFoundExceptionInterface`.
73
     *
74
     * @param string $id Identifier of the entry to look for.
75
     *
76
     * @return bool
77
     */
78
    public function has($id)
79
    {
80
        if (isset($this->values[$id])) {
81
            return true;
82
        }
83
        if ($this->container->has($id)) {
84
            return true;
85
        }
86
87
        if (class_exists($id)) {
88
            $refTypeClass = new \ReflectionClass($id);
89
            return !($refTypeClass->hasMethod('__construct') && $refTypeClass->getMethod('__construct')->getNumberOfRequiredParameters() > 0);
90
        }
91
        return false;
92
    }
93
}
94