Passed
Push — master ( 60ec40...f0d439 )
by mcfog
01:27
created

Container::value()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Lit\Air\Psr;
6
7
use Lit\Air\Configurator;
8
use Lit\Air\Recipe\AbstractRecipe;
9
use Lit\Air\Recipe\AliasRecipe;
10
use Lit\Air\Recipe\AutowireRecipe;
11
use Lit\Air\Recipe\BuilderRecipe;
12
use Lit\Air\Recipe\FixedValueRecipe;
13
use Lit\Air\Recipe\InstanceRecipe;
14
use Lit\Air\Recipe\RecipeInterface;
15
use Psr\Container\ContainerInterface;
16
17
class Container implements ContainerInterface
18
{
19
    const CONFIGURATOR_CLASS = Configurator::class;
20
    /**
21
     * @var RecipeInterface[]
22
     */
23
    protected $recipe = [];
24
    protected $local = [];
25
26
    /**
27
     * @var ContainerInterface
28
     */
29
    protected $delegateContainer;
30
31 14
    public function __construct(?array $config = null)
32
    {
33 14
        if ($config) {
34
            $class = static::CONFIGURATOR_CLASS;
35
            /**
36
             * @see Configurator::config()
37
             * @var Configurator $class
38
             */
39
            $class::config($this, $config);
40
        }
41 14
        $this->set(static::class, $this);
42 14
        $this->set(ContainerInterface::class, $this);
43 14
    }
44
45 1
    public static function alias(string $alias): AbstractRecipe
46
    {
47 1
        return new AliasRecipe($alias);
48
    }
49
50 2
    public static function autowire(?string $className = null, array $extra = []): AbstractRecipe
51
    {
52 2
        return new AutowireRecipe($className, $extra);
53
    }
54
55 1
    public static function instance(?string $className = null, array $extra = []): AbstractRecipe
56
    {
57 1
        return new InstanceRecipe($className, $extra);
58
    }
59
60 2
    public static function builder(callable $builder, array $extra = []): AbstractRecipe
61
    {
62 2
        return new BuilderRecipe($builder, $extra);
63
    }
64
65 6
    public static function value($value): AbstractRecipe
66
    {
67 6
        return new FixedValueRecipe($value);
68
    }
69
70 1
    public static function wrap(ContainerInterface $container): self
71
    {
72 1
        return (new static())->setDelegateContainer($container);
73
    }
74
75
    /**
76
     * @param string $id
77
     * @return mixed
78
     * @throws \Psr\Container\ContainerExceptionInterface
79
     */
80 12
    public function get($id)
81
    {
82 12
        if (array_key_exists($id, $this->local)) {
83 11
            return $this->local[$id];
84
        }
85
86 10
        if (array_key_exists($id, $this->recipe)) {
87 8
            return $this->recipe[$id]->resolve($this, $id);
88
        }
89
90 2
        if ($this->delegateContainer && $this->delegateContainer->has($id)) {
91 1
            return $this->delegateContainer->get($id);
92
        }
93
94 1
        throw new NotFoundException($id);
95
    }
96
97 11
    public function has($id)
98
    {
99 11
        return array_key_exists($id, $this->local)
100 11
            || array_key_exists($id, $this->recipe)
101 11
            || ($this->delegateContainer && $this->delegateContainer->has($id));
102
    }
103
104 9
    public function define(string $id, RecipeInterface $recipe): self
105
    {
106 9
        $this->recipe[$id] = $recipe;
107 9
        return $this;
108
    }
109
110 1
    public function getRecipe(string $id): ?RecipeInterface
111
    {
112 1
        if (array_key_exists($id, $this->recipe)) {
113
            return $this->recipe[$id];
114
        }
115
116 1
        return null;
117
    }
118
119 1
    public function extendRecipe(string $id, callable $wrapper): self
120
    {
121 1
        if (!array_key_exists($id, $this->recipe)) {
122
            throw new \InvalidArgumentException("recipe [$id] unexists");
123
        }
124
125 1
        $recipe = static::applyRecipeWrapper($wrapper, $this->recipe[$id]);
126
127 1
        $this->recipe[$id] = $recipe;
128
129 1
        return $this;
130
    }
131
132 5
    public function hasLocalEntry(string $id): bool
133
    {
134 5
        return array_key_exists($id, $this->local);
135
    }
136
137 4
    public function flush(string $id): self
138
    {
139 4
        unset($this->local[$id]);
140 4
        return $this;
141
    }
142
143 4
    public function resolveRecipe($value)
144
    {
145 4
        $class = static::CONFIGURATOR_CLASS;
146
        /**
147
         * @see Configurator::convertArray()
148
         * @var Configurator $class
149
         */
150 4
        return $class::convertToRecipe($value)->resolve($this);
151
    }
152
153 14
    public function set($id, $value): self
154
    {
155 14
        $this->local[$id] = $value;
156 14
        return $this;
157
    }
158
159
    /**
160
     * @param ContainerInterface $delegateContainer
161
     * @return $this
162
     */
163 1
    public function setDelegateContainer(ContainerInterface $delegateContainer): self
164
    {
165 1
        $this->delegateContainer = $delegateContainer;
166
167 1
        return $this;
168
    }
169
170
    /**
171
     * @param callable $wrapper
172
     * @param RecipeInterface $recipe
173
     * @return RecipeInterface
174
     */
175 1
    protected static function applyRecipeWrapper(callable $wrapper, RecipeInterface $recipe): RecipeInterface
176
    {
177 1
        $recipe = $wrapper($recipe);
178
179 1
        return $recipe;
180
    }
181
}
182