Completed
Push — master ( 68c148...72ce2d )
by Phil
13:10
created

Definition::setConcrete()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php declare(strict_types=1);
2
3
namespace League\Container\Definition;
4
5
use League\Container\Argument\{
6
    ArgumentResolverInterface, ArgumentResolverTrait, ClassNameInterface, RawArgumentInterface
7
};
8
use League\Container\ContainerAwareTrait;
9
use ReflectionClass;
10
11
class Definition implements ArgumentResolverInterface, DefinitionInterface
12
{
13
    use ArgumentResolverTrait;
14
    use ContainerAwareTrait;
15
16
    /**
17
     * @var string
18
     */
19
    protected $alias;
20
21
    /**
22
     * @var mixed
23
     */
24
    protected $concrete;
25
26
    /**
27
     * @var boolean
28
     */
29
    protected $shared = false;
30
31
    /**
32
     * @var array
33
     */
34
    protected $tags = [];
35
36
    /**
37
     * @var array
38
     */
39
    protected $arguments = [];
40
41
    /**
42
     * @var array
43
     */
44
    protected $methods = [];
45
46
    /**
47
     * @var mixed
48
     */
49
    protected $resolved;
50
51
    /**
52
     * Constructor.
53
     *
54
     * @param string $id
55
     * @param mixed  $concrete
56
     */
57 60
    public function __construct(string $id, $concrete = null)
58
    {
59 60
        $concrete = $concrete ?? $id;
60
61 60
        $this->alias    = $id;
62 60
        $this->concrete = $concrete;
63 60
    }
64
65
    /**
66
     * {@inheritdoc}
67
     */
68 6
    public function addTag(string $tag) : DefinitionInterface
69
    {
70 6
        $this->tags[] = $tag;
71
72 6
        return $this;
73
    }
74
75
    /**
76
     * {@inheritdoc}
77
     */
78 6
    public function hasTag(string $tag) : bool
79
    {
80 6
        return in_array($tag, $this->tags);
81
    }
82
83
    /**
84
     * {@inheritdoc}
85
     */
86 33
    public function setAlias(string $id) : DefinitionInterface
87
    {
88 33
        $this->alias = $id;
89
90 33
        return $this;
91
    }
92
93
    /**
94
     * {@inheritdoc}
95
     */
96 30
    public function getAlias() : string
97
    {
98 30
        return $this->alias;
99
    }
100
101
    /**
102
     * {@inheritdoc}
103
     */
104 36
    public function setShared(bool $shared = true) : DefinitionInterface
105
    {
106 36
        $this->shared = $shared;
107
108 36
        return $this;
109
    }
110
111
    /**
112
     * {@inheritdoc}
113
     */
114 42
    public function isShared() : bool
115
    {
116 42
        return $this->shared;
117
    }
118
119
    /**
120
     * {@inheritdoc}
121
     */
122 15
    public function getConcrete()
123
    {
124 15
        return $this->concrete;
125
    }
126 15
127
    /**
128
     * {@inheritdoc}
129
     */
130
    public function setConcrete($concrete): DefinitionInterface
131
    {
132 3
        $this->concrete = $concrete;
133
134 3
        return $this;
135 3
    }
136
137
    /**
138 3
     * {@inheritdoc}
139
     */
140
    public function addArgument($arg) : DefinitionInterface
141
    {
142
        $this->arguments[] = $arg;
143
144 3
        return $this;
145
    }
146 3
147 3
    /**
148 3
     * {@inheritdoc}
149
     */
150
    public function addArguments(array $args) : DefinitionInterface
151 3
    {
152
        foreach ($args as $arg) {
153
            $this->addArgument($arg);
154
        }
155
156
        return $this;
157 3
    }
158
159 3
    /**
160 3
     * {@inheritdoc}
161
     */
162
    public function addMethodCall(string $method, array $args = []) : DefinitionInterface
163 3
    {
164
        $this->methods[] = [
165
            'method'    => $method,
166
            'arguments' => $args
167
        ];
168
169 42
        return $this;
170
    }
171 42
172
    /**
173 42
     * {@inheritdoc}
174 9
     */
175
    public function addMethodCalls(array $methods = []) : DefinitionInterface
176
    {
177 42
        foreach ($methods as $method => $args) {
178 12
            $this->addMethodCall($method, $args);
179
        }
180
181 42
        return $this;
182 3
    }
183
184 3
    /**
185
     * {@inheritdoc}
186
     */
187 39
    public function resolve(bool $new = false)
188 6
    {
189
        $concrete = $this->concrete;
190
191 39
        if ($this->isShared() && ! is_null($this->resolved) && $new === false) {
192 30
            return $this->resolved;
193
        }
194
195 39
        if (is_callable($concrete)) {
196 36
            $concrete = $this->resolveCallable($concrete);
197
        }
198
199 39
        if ($concrete instanceof RawArgumentInterface) {
200
            $this->resolved = $concrete->getValue();
201 39
202
            return $concrete->getValue();
203
        }
204
205
        if ($concrete instanceof ClassNameInterface) {
206
            $concrete = $concrete->getValue();
207
        }
208
209
        if (is_string($concrete) && class_exists($concrete)) {
210
            $concrete = $this->resolveClass($concrete);
211 12
        }
212
213 12
        if (is_object($concrete)) {
214
            $concrete = $this->invokeMethods($concrete);
215 12
        }
216
217
        $this->resolved = $concrete;
218
219
        return $concrete;
220
    }
221
222
    /**
223
     * Resolve a callable.
224
     *
225 30
     * @param callable $concrete
226
     *
227 30
     * @return mixed
228 30
     */
229
    protected function resolveCallable(callable $concrete)
230 30
    {
231
        $resolved = $this->resolveArguments($this->arguments);
232
233
        return call_user_func_array($concrete, $resolved);
234
    }
235
236
    /**
237
     * Resolve a class.
238
     *
239
     * @param string $concrete
240 36
     *
241
     * @return object
242 36
     */
243 3
    protected function resolveClass(string $concrete)
244 3
    {
245
        $resolved   = $this->resolveArguments($this->arguments);
246
        $reflection = new ReflectionClass($concrete);
247 36
248
        return $reflection->newInstanceArgs($resolved);
249
    }
250
251
    /**
252
     * Invoke methods on resolved instance.
253
     *
254
     * @param object $instance
255
     *
256
     * @return object
257
     */
258
    protected function invokeMethods($instance)
259
    {
260
        foreach ($this->methods as $method) {
261
            $args = $this->resolveArguments($method['arguments']);
262
            call_user_func_array([$instance, $method['method']], $args);
263
        }
264
265
        return $instance;
266
    }
267
}
268