AbstractContainer::doGet()
last analyzed

Size

Total Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 1
ccs 0
cts 0
cp 0
c 0
b 0
f 0
nc 1
1
<?php
2
declare(strict_types=1);
3
/**
4
 * Caridea
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
7
 * use this file except in compliance with the License. You may obtain a copy of
8
 * the License at
9
 *
10
 * http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15
 * License for the specific language governing permissions and limitations under
16
 * the License.
17
 *
18
 * @copyright 2015-2018 LibreWorks contributors
19
 * @license   Apache-2.0
20
 */
21
namespace Caridea\Container;
22
23
/**
24
 * Abstract dependency injection container.
25
 *
26
 * @copyright 2015-2018 LibreWorks contributors
27
 * @license   Apache-2.0
28
 */
29
abstract class AbstractContainer implements Container
30
{
31
    /**
32
     * @var Container The parent container
33
     */
34
    protected $parent;
35
    /**
36
     * @var string[] with string keys
37
     */
38
    protected $types = [];
39
    /**
40
     * @var string[] the list of PHP native types
41
     */
42
    protected static $primitives = ['array', 'bool', 'float', 'int', 'resource', 'string'];
43
44
    /**
45
     * Creates a new AbstractContainer.
46
     *
47
     * @param string[] $types with string keys
48
     * @param \Caridea\Container\Container $parent The parent container
49
     */
50 5
    protected function __construct(array $types, Container $parent = null)
51
    {
52 5
        $this->types = $types;
53 5
        $this->parent = $parent;
54 5
    }
55
56
    /**
57
     * {@inheritDoc}
58
     */
59 1
    public function contains(string $name): bool
60
    {
61 1
        return $this->has($name);
62
    }
63
64
    /**
65
     * {@inheritDoc}
66
     */
67 1
    public function containsType(string $type): bool
68
    {
69 1
        $isObject = !in_array($type, self::$primitives, true);
70 1
        foreach ($this->types as $ctype) {
71 1
            if ($type === $ctype || ($isObject && is_a($ctype, $type, true))) {
72 1
                return true;
73
            }
74
        }
75 1
        return $this->parent ? $this->parent->containsType($type) : false;
76
    }
77
78
    /**
79
     * {@inheritDoc}
80
     */
81 5
    public function get($id)
82
    {
83 5
        $entry = isset($this->types[$id]) ? $this->doGet($id) :
84 3
            ($this->parent ? $this->parent->get($id) : null);
85 3
        if ($entry === null) {
86 1
            throw new Exception\Missing("No container entry found for key: $id");
87
        }
88 2
        return $entry;
89
    }
90
91
    /**
92
     * {@inheritDoc}
93
     */
94 1
    public function getByType(string $type): array
95
    {
96 1
        $components = $this->parent ? $this->parent->getByType($type) : [];
97 1
        $isObject = !in_array($type, self::$primitives, true);
98 1
        foreach ($this->types as $name => $ctype) {
99 1
            if ($type === $ctype || ($isObject && is_a($ctype, $type, true))) {
100 1
                $components[$name] = $this->doGet($name);
101
            }
102
        }
103 1
        return $components;
104
    }
105
106
    /**
107
     * {@inheritDoc}
108
     */
109 1
    public function getFirst(string $type)
110
    {
111 1
        $isObject = !in_array($type, self::$primitives, true);
112 1
        foreach ($this->types as $name => $ctype) {
113 1
            if ($type === $ctype || ($isObject && is_a($ctype, $type, true))) {
114 1
                return $this->doGet($name);
115
            }
116
        }
117 1
        return $this->parent ? $this->parent->getFirst($type) : null;
118
    }
119
120
    /**
121
     * {@inheritDoc}
122
     */
123 1
    public function has($name): bool
124
    {
125 1
        return isset($this->types[$name]) ||
126 1
            ($this->parent ? $this->parent->has($name) : false);
127
    }
128
129
    /**
130
     * Retrieves the value
131
     *
132
     * @param string $name The value name
133
     */
134
    abstract protected function doGet(string $name);
135
136
    /**
137
     * {@inheritDoc}
138
     */
139 1
    public function getNames(): array
140
    {
141 1
        return array_keys($this->types);
142
    }
143
144
    /**
145
     * {@inheritDoc}
146
     */
147 1
    public function getParent(): ?Container
148
    {
149 1
        return $this->parent;
150
    }
151
152
    /**
153
     * {@inheritDoc}
154
     */
155 1
    public function getType(string $name): ?string
156
    {
157 1
        return isset($this->types[$name]) ? $this->types[$name] :
158 1
            ($this->parent ? $this->parent->getType($name) : null);
159
    }
160
161
    /**
162
     * {@inheritDoc}
163
     */
164 4
    public function named(string $name, string $type)
165
    {
166 4
        if (isset($this->types[$name])) {
167 3
            $ctype = $this->types[$name];
168 3
            $isObject = !in_array($type, self::$primitives, true);
169 3
            if ($type !== $ctype && (!$isObject || !is_a($ctype, $type, true))) {
170 2
                throw new \UnexpectedValueException("A $type was requested, but a $ctype was found");
171
            }
172 1
            return $this->doGet($name);
173 3
        } elseif ($this->parent !== null) {
174 3
            return $this->parent->named($name, $type);
175
        }
176 1
        throw new \UnexpectedValueException("A $type was requested, but null was found");
177
    }
178
}
179