1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* |
4
|
|
|
*/ |
5
|
|
|
|
6
|
|
|
namespace Mvc5\Resolver; |
7
|
|
|
|
8
|
|
|
use Closure; |
9
|
|
|
use Mvc5\Arg; |
10
|
|
|
use Mvc5\Event\Event; |
11
|
|
|
use Mvc5\Plugin\Gem\Args; |
12
|
|
|
use Mvc5\Plugin\Gem\Call; |
13
|
|
|
use Mvc5\Plugin\Gem\Calls; |
14
|
|
|
use Mvc5\Plugin\Gem\Child; |
15
|
|
|
use Mvc5\Plugin\Gem\Config; |
16
|
|
|
use Mvc5\Plugin\Gem\Dependency; |
17
|
|
|
use Mvc5\Plugin\Gem\Factory; |
18
|
|
|
use Mvc5\Plugin\Gem\Filter; |
19
|
|
|
use Mvc5\Plugin\Gem\Invokable; |
20
|
|
|
use Mvc5\Plugin\Gem\Invoke; |
21
|
|
|
use Mvc5\Plugin\Gem\Link; |
22
|
|
|
use Mvc5\Plugin\Gem\Param; |
23
|
|
|
use Mvc5\Plugin\Gem\Plug; |
24
|
|
|
use Mvc5\Plugin\Gem\Plugin; |
25
|
|
|
use Mvc5\Resolvable; |
26
|
|
|
use Mvc5\Service\Config as Container; |
27
|
|
|
use Mvc5\Service\Container as ServiceContainer; |
28
|
|
|
use Mvc5\Service\Manager as ServiceManager; |
29
|
|
|
use ReflectionClass; |
30
|
|
|
use RuntimeException; |
31
|
|
|
|
32
|
|
|
trait Resolver |
33
|
|
|
{ |
34
|
|
|
/** |
35
|
|
|
* |
36
|
|
|
*/ |
37
|
|
|
use Container; |
38
|
|
|
use Generator; |
39
|
|
|
use Initializer; |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* @param $args |
43
|
|
|
* @return array|callable|null|object|string |
44
|
|
|
*/ |
45
|
|
|
protected function args($args) |
46
|
|
|
{ |
47
|
|
|
if (!$args) { |
48
|
12 |
|
return $args; |
49
|
|
|
} |
50
|
12 |
|
|
51
|
6 |
|
if (!is_array($args)) { |
52
|
|
|
return $this->resolve($args); |
53
|
|
|
} |
54
|
11 |
|
|
55
|
8 |
|
foreach($args as $index => $value) { |
56
|
|
|
$value instanceof Resolvable && $args[$index] = $this->resolve($value); |
57
|
|
|
} |
58
|
6 |
|
|
59
|
6 |
|
return $args; |
60
|
|
|
} |
61
|
|
|
|
62
|
6 |
|
/** |
63
|
|
|
* @param array $config |
64
|
|
|
* @param array $args |
65
|
|
|
* @param callable $callback |
66
|
|
|
* @param bool $plugin |
67
|
|
|
* @return callable|object |
68
|
|
|
*/ |
69
|
|
|
protected function build(array $config, array $args = [], callable $callback = null, $plugin = false) |
70
|
|
|
{ |
71
|
4 |
|
return $this->combine(array_shift($config), $config, $args, $callback, $plugin); |
72
|
|
|
} |
73
|
4 |
|
|
74
|
|
|
/** |
75
|
|
|
* @param array|callable|object|string $config |
76
|
|
|
* @param array $args |
77
|
|
|
* @param callable $callback |
78
|
|
|
* @return callable|mixed|null|object |
79
|
|
|
* @throws \RuntimeException |
80
|
|
|
*/ |
81
|
|
|
public function call($config, array $args = [], callable $callback = null) |
82
|
|
|
{ |
83
|
11 |
|
if (is_string($config)) { |
84
|
|
|
return $this->transmit(explode(Arg::CALL_SEPARATOR, $config), $args, $callback); |
85
|
11 |
|
} |
86
|
2 |
|
|
87
|
2 |
|
if ($config instanceof Event) { |
88
|
|
|
return $this->event($config, $args, $callback); |
89
|
|
|
} |
90
|
9 |
|
|
91
|
9 |
|
return $this->invoke($config, $args, $callback); |
92
|
9 |
|
} |
93
|
|
|
|
94
|
|
|
/** |
95
|
3 |
|
* @param array|callable|object|string $config |
96
|
1 |
|
* @return callable|null |
97
|
3 |
|
*/ |
98
|
|
|
protected function callable($config) : callable |
99
|
9 |
|
{ |
100
|
|
|
if (is_string($config)) { |
101
|
9 |
|
return function($args = []) use($config) { return $this->call($config, $args); }; |
102
|
1 |
|
} |
103
|
|
|
|
104
|
|
|
if (is_array($config)) { |
105
|
8 |
|
return is_string($config[0]) ? $config : [$this->resolve($config[0]), $config[1]]; |
106
|
1 |
|
} |
107
|
|
|
|
108
|
|
|
return $config instanceof Closure ? $config : $this->listener($this->resolve($config)); |
|
|
|
|
109
|
8 |
|
} |
110
|
|
|
|
111
|
|
|
/** |
112
|
|
|
* @param $name |
113
|
|
|
* @param array $args |
114
|
|
|
* @param callable|null $callback |
115
|
|
|
* @return callable|object |
116
|
|
|
*/ |
117
|
1 |
|
protected function callback($name, array $args = [], callable $callback = null) |
118
|
|
|
{ |
119
|
1 |
|
return $callback && !class_exists($name) ? $callback($name) : $this->make($name, $args); |
120
|
|
|
} |
121
|
|
|
|
122
|
|
|
/** |
123
|
|
|
* @param Child $config |
124
|
|
|
* @param array $args |
125
|
|
|
* @return array|callable|object|string |
126
|
|
|
*/ |
127
|
|
|
protected function child(Child $config, array $args = []) |
128
|
|
|
{ |
129
|
5 |
|
return $this->provide($this->merge(clone $this->parent($config->parent()), $config), $args); |
130
|
|
|
} |
131
|
5 |
|
|
132
|
3 |
|
/** |
133
|
1 |
|
* @param $name |
134
|
3 |
|
* @param array $config |
135
|
|
|
* @param array $args |
136
|
|
|
* @param callable $callback |
137
|
|
|
* @param bool $plugin |
138
|
5 |
|
* @return callable|object |
139
|
|
|
*/ |
140
|
|
|
protected function combine($name, array $config, array $args = [], callable $callback = null, $plugin = false) |
141
|
|
|
{ |
142
|
|
|
return $this->compose( |
143
|
|
|
$this->create($name, $args, $callback, $plugin || $config), $config, $args, $callback |
|
|
|
|
144
|
|
|
); |
145
|
|
|
} |
146
|
|
|
|
147
|
6 |
|
/** |
148
|
|
|
* @param $plugin |
149
|
6 |
|
* @param array $config |
150
|
6 |
|
* @param array $args |
151
|
|
|
* @param callable $callback |
152
|
|
|
* @return callable|object |
153
|
|
|
*/ |
154
|
|
|
protected function compose($plugin, array $config = [], array $args = [], callable $callback = null) |
155
|
|
|
{ |
156
|
|
|
foreach($config as $name) { |
157
|
|
|
$plugin = $plugin instanceof ServiceManager ? $plugin->plugin($name, $args, $callback) : ( |
158
|
|
|
$plugin instanceof ServiceContainer ? $this->plugin($plugin[$name], $args, $callback) : |
159
|
1 |
|
$this->resolve($plugin[$name], $args) |
160
|
|
|
); |
161
|
1 |
|
} |
162
|
1 |
|
|
163
|
|
|
return $plugin; |
164
|
|
|
} |
165
|
1 |
|
|
166
|
|
|
/** |
167
|
|
|
* @param $name |
168
|
|
|
* @param array $args |
169
|
|
|
* @param callable $callback |
170
|
|
|
* @param bool $plugin |
171
|
|
|
* @return callable|object |
172
|
2 |
|
*/ |
173
|
|
|
protected function create($name, array $args = [], callable $callback = null, $plugin = true) |
174
|
2 |
|
{ |
175
|
|
|
return ($plugin ? $this->unique($name, $this->configured($name), $args, $callback) : null) ?? |
176
|
|
|
$this->callback($name, $args, $callback); |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
/** |
180
|
|
|
* @param array|callable|null|object|string $arg |
181
|
|
|
* @param array $filters |
182
|
11 |
|
* @return mixed |
183
|
|
|
*/ |
184
|
11 |
|
protected function filter($arg, array $filters) |
185
|
10 |
|
{ |
186
|
3 |
|
foreach($filters as $filter) { |
187
|
1 |
|
$arg = $filter($arg); |
188
|
1 |
|
} |
189
|
|
|
|
190
|
|
|
return $arg; |
191
|
2 |
|
} |
192
|
1 |
|
|
193
|
1 |
|
/** |
194
|
|
|
* @param string $name |
195
|
|
|
* @return mixed |
196
|
1 |
|
*/ |
197
|
1 |
|
public function get($name) |
198
|
|
|
{ |
199
|
|
|
return $this->shared($name) ?? $this->plugin($name); |
200
|
7 |
|
} |
201
|
6 |
|
|
202
|
6 |
|
/** |
203
|
|
|
* @param Plugin $config |
204
|
6 |
|
* @param object $service |
205
|
3 |
|
* @return object |
206
|
3 |
|
*/ |
207
|
|
|
protected function hydrate(Plugin $config, $service) |
208
|
|
|
{ |
209
|
6 |
|
foreach($config->calls() as $method => $args) { |
210
|
6 |
|
if (is_string($method)) { |
211
|
6 |
|
if (Arg::INDEX == $method[0]) { |
212
|
|
|
$service[substr($method, 1)] = $this->resolve($args); |
213
|
|
|
continue; |
214
|
6 |
|
} |
215
|
|
|
|
216
|
|
|
if (Arg::PROPERTY == $method[0]) { |
217
|
1 |
|
$service->{substr($method, 1)} = $this->resolve($args); |
218
|
|
|
continue; |
219
|
|
|
} |
220
|
11 |
|
|
221
|
|
|
$service->$method($this->resolve($args)); |
222
|
|
|
continue; |
223
|
|
|
} |
224
|
|
|
|
225
|
|
|
if (is_array($args)) { |
226
|
|
|
$method = array_shift($args); |
227
|
5 |
|
$param = $config->param(); |
228
|
|
|
|
229
|
5 |
|
if (is_string($method) && Arg::PROPERTY == $method[0]) { |
230
|
|
|
$param = substr($method, 1); |
231
|
|
|
$method = array_shift($args); |
232
|
|
|
} |
233
|
4 |
|
|
234
|
2 |
|
$this->invoke( |
235
|
|
|
is_string($method) ? [$service, $method] : $method, |
236
|
|
|
($param && (!$args || is_string(key($args))) ? [$param => $service] : []) + $this->args($args) |
|
|
|
|
237
|
2 |
|
); |
238
|
|
|
|
239
|
|
|
continue; |
240
|
|
|
} |
241
|
|
|
|
242
|
|
|
$this->resolve($args); |
243
|
|
|
} |
244
|
|
|
|
245
|
|
|
return $service; |
246
|
10 |
|
} |
247
|
|
|
|
248
|
10 |
|
/** |
249
|
|
|
* @param array|callable|object|string $name |
250
|
|
|
* @return callable|null |
251
|
|
|
*/ |
252
|
|
|
protected function invokable($name) |
253
|
|
|
{ |
254
|
|
|
return Arg::CALL === $name[0] ? substr($name, 1) : $this->listener($this->plugin($name, [], function($name) { |
|
|
|
|
255
|
2 |
|
return $this->create(Arg::EVENT_MODEL, [Arg::EVENT => $name]); |
256
|
|
|
})); |
257
|
2 |
|
} |
258
|
|
|
|
259
|
|
|
/** |
260
|
|
|
* @param array|callable|object|string $config |
261
|
|
|
* @param array $args |
262
|
|
|
* @param callable $callback |
263
|
|
|
* @return array|callable|object|string |
264
|
|
|
*/ |
265
|
|
|
protected function invoke($config, array $args = [], callable $callback = null) |
266
|
|
|
{ |
267
|
7 |
|
return $this->signal($config, $args, $callback ?? $this); |
268
|
|
|
} |
269
|
7 |
|
|
270
|
|
|
/** |
271
|
7 |
|
* @param string $name |
272
|
1 |
|
* @param array $args |
273
|
|
|
* @return callable|object |
274
|
|
|
*/ |
275
|
6 |
|
protected function make($name, array $args = []) |
276
|
1 |
|
{ |
277
|
|
|
$class = new ReflectionClass($name); |
278
|
|
|
|
279
|
5 |
|
if (!$class->hasMethod('__construct')) { |
280
|
5 |
|
return $class->newInstanceWithoutConstructor(); |
281
|
|
|
} |
282
|
5 |
|
|
283
|
4 |
|
if ($args && !is_string(key($args))) { |
|
|
|
|
284
|
3 |
|
return $class->newInstanceArgs($this->args($args)); |
285
|
3 |
|
} |
286
|
|
|
|
287
|
|
|
$matched = []; |
288
|
4 |
|
$params = $class->getConstructor()->getParameters(); |
289
|
3 |
|
|
290
|
3 |
|
foreach($params as $param) { |
291
|
3 |
|
if (isset($args[$param->name])) { |
292
|
|
|
$matched[] = $this->resolve($args[$param->name]); |
293
|
|
|
continue; |
294
|
3 |
|
} |
295
|
1 |
|
|
296
|
1 |
|
if ($param->isOptional()) { |
297
|
|
|
$param->isDefaultValueAvailable() && |
298
|
|
|
$matched[] = $param->getDefaultValue(); |
299
|
2 |
|
continue; |
300
|
1 |
|
} |
301
|
1 |
|
|
302
|
|
|
if (null !== ($hint = $param->getClass()) && null !== $match = $this($hint->name)) { |
303
|
|
|
$matched[] = $match; |
304
|
1 |
|
continue; |
305
|
|
|
} |
306
|
|
|
|
307
|
4 |
|
if (null !== $match = $this($param->name)) { |
308
|
|
|
$matched[] = $match; |
309
|
|
|
continue; |
310
|
|
|
} |
311
|
|
|
|
312
|
|
|
throw new RuntimeException('Missing required parameter $' . $param->name . ' for ' . $name); |
313
|
|
|
} |
314
|
|
|
|
315
|
3 |
|
return $class->newInstanceArgs($params ? $matched : $this->args($args)); |
316
|
|
|
} |
317
|
3 |
|
|
318
|
|
|
/** |
319
|
3 |
|
* @param Plugin $parent |
320
|
1 |
|
* @param Plugin $config |
321
|
1 |
|
* @return Plugin |
322
|
|
|
*/ |
323
|
|
|
protected function merge(Plugin $parent, Plugin $config) |
324
|
3 |
|
{ |
325
|
2 |
|
!$parent->name() && |
326
|
2 |
|
$parent[Arg::NAME] = $this->resolve($config->name()); |
327
|
|
|
|
328
|
|
|
$config->args() && |
329
|
3 |
|
$parent[Arg::ARGS] = is_string(key($config->args())) ? $config->args() + $parent->args() : $config->args(); |
330
|
|
|
|
331
|
3 |
|
$config->calls() && |
332
|
|
|
$parent[Arg::CALLS] = $config->merge() ? array_merge($parent->calls(), $config->calls()) : $config->calls(); |
333
|
|
|
|
334
|
|
|
$config->param() && |
335
|
|
|
$parent[Arg::PARAM] = $config->param(); |
336
|
|
|
|
337
|
|
|
return $parent; |
338
|
1 |
|
} |
339
|
|
|
|
340
|
1 |
|
/** |
341
|
1 |
|
* @param string $name |
342
|
|
|
* @return mixed |
343
|
1 |
|
*/ |
344
|
1 |
|
public function param($name) |
345
|
|
|
{ |
346
|
|
|
$name = explode(Arg::CALL_SEPARATOR, $name); |
347
|
1 |
|
$value = $this->config()[array_shift($name)]; |
348
|
|
|
|
349
|
|
|
foreach($name as $n) { |
350
|
|
|
$value = $value[$n]; |
351
|
|
|
} |
352
|
|
|
|
353
|
|
|
return $value; |
354
|
1 |
|
} |
355
|
|
|
|
356
|
1 |
|
/** |
357
|
|
|
* @param $config |
358
|
|
|
* @return array|callable|Plugin|null|object|string |
359
|
|
|
*/ |
360
|
|
|
protected function parent($config) |
361
|
|
|
{ |
362
|
|
|
return $this->configured($this->resolve($config)); |
|
|
|
|
363
|
|
|
} |
364
|
|
|
|
365
|
12 |
|
/** |
366
|
|
|
* @param string $config |
367
|
12 |
|
* @param array $args |
368
|
5 |
|
* @param callable|null $callback |
369
|
|
|
* @return array|callable|null|object|string |
370
|
|
|
*/ |
371
|
11 |
|
public function plugin($config, array $args = [], callable $callback = null) |
372
|
8 |
|
{ |
373
|
8 |
|
if (!$config) { |
374
|
|
|
return $config; |
375
|
|
|
} |
376
|
3 |
|
|
377
|
1 |
|
if (is_string($config)) { |
378
|
|
|
return $this->build(explode(Arg::SERVICE_SEPARATOR, $config), $args, $callback, true); |
379
|
|
|
} |
380
|
2 |
|
|
381
|
1 |
|
if (is_array($config)) { |
382
|
|
|
return $this->plugin(array_shift($config), $args + $config, $callback); |
383
|
|
|
} |
384
|
1 |
|
|
385
|
|
|
if ($config instanceof Closure) { |
386
|
|
|
return $this->invoke($config, $args, $callback); |
387
|
|
|
} |
388
|
|
|
|
389
|
|
|
return $this->resolve($config, $args); |
390
|
|
|
} |
391
|
|
|
|
392
|
3 |
|
/** |
393
|
|
|
* @param Plugin $config |
394
|
3 |
|
* @param array $args |
395
|
3 |
|
* @return callable|null|object |
396
|
|
|
*/ |
397
|
3 |
|
protected function provide(Plugin $config, array $args = []) |
398
|
|
|
{ |
399
|
3 |
|
$name = $this->solve($config->name()); |
400
|
|
|
$parent = $this->configured($name); |
401
|
3 |
|
|
402
|
2 |
|
$args && is_string(key($args)) && $config->args() && $args += $config->args(); |
|
|
|
|
403
|
|
|
|
404
|
|
|
!$args && $args = $config->args(); |
|
|
|
|
405
|
2 |
|
|
406
|
1 |
|
if (!$parent) { |
407
|
|
|
return $this->hydrate($config, $this->build(explode(Arg::SERVICE_SEPARATOR, $name), $args)); |
|
|
|
|
408
|
|
|
} |
409
|
1 |
|
|
410
|
|
|
if (!$parent instanceof Plugin) { |
411
|
|
|
return $this->hydrate( |
412
|
|
|
$config, $name === $parent ? $this->make($name, $args) : $this->plugin($this->solve($parent), $args) |
|
|
|
|
413
|
|
|
); |
414
|
|
|
} |
415
|
|
|
|
416
|
|
|
if ($name == $parent->name()) { |
417
|
24 |
|
return $this->hydrate($config, $this->make($name, $args)); |
418
|
|
|
} |
419
|
24 |
|
|
420
|
12 |
|
return $this->provide($this->merge(clone $parent, $config), $args); |
421
|
|
|
} |
422
|
|
|
|
423
|
16 |
|
/** |
424
|
1 |
|
* @param $plugin |
425
|
|
|
* @param array $config |
426
|
|
|
* @param array $args |
427
|
15 |
|
* @param callable|null $callback |
428
|
1 |
|
* @return array|callable|object|string |
429
|
|
|
*/ |
430
|
|
|
protected function relay($plugin, array $config = [], array $args = [], callable $callback = null) |
431
|
14 |
|
{ |
432
|
1 |
|
return !$config ? $this->invoke($plugin, $args, $callback) : |
433
|
|
|
$this->relay([$plugin, array_shift($config)], $config, $args, $callback); |
434
|
|
|
} |
435
|
13 |
|
|
436
|
1 |
|
/** |
437
|
|
|
* @param $config |
438
|
|
|
* @param array $args |
439
|
12 |
|
* @param callable $callback |
440
|
2 |
|
* @return array|callable|Plugin|null|object|Resolvable|string |
441
|
|
|
* @throws RuntimeException |
442
|
|
|
*/ |
443
|
10 |
|
protected function resolvable($config, array $args = [], callable $callback = null) |
444
|
1 |
|
{ |
445
|
|
|
if (!$config instanceof Resolvable) { |
446
|
|
|
return $config; |
447
|
9 |
|
} |
448
|
1 |
|
|
449
|
|
|
if ($config instanceof Factory) { |
450
|
|
|
return $this->invoke($this->child($config, $args)); |
|
|
|
|
451
|
8 |
|
} |
452
|
1 |
|
|
453
|
|
|
if ($config instanceof Calls) { |
454
|
|
|
return $this->hydrate($config, $this->resolve($config->name(), $args)); |
|
|
|
|
455
|
7 |
|
} |
456
|
1 |
|
|
457
|
|
|
if ($config instanceof Child) { |
458
|
|
|
return $this->child($config, $args); |
459
|
6 |
|
} |
460
|
1 |
|
|
461
|
|
|
if ($config instanceof Plugin) { |
462
|
|
|
return $this->provide($config, $args); |
463
|
5 |
|
} |
464
|
1 |
|
|
465
|
|
|
if ($config instanceof Dependency) { |
466
|
|
|
return $this->shared($config->name()) ?? $this->initialize($config->name(), $config->config()); |
467
|
4 |
|
} |
468
|
1 |
|
|
469
|
|
|
if ($config instanceof Param) { |
470
|
|
|
return $this->resolve($this->param($config->name()), $args); |
471
|
3 |
|
} |
472
|
|
|
|
473
|
1 |
|
if ($config instanceof Call) { |
474
|
1 |
|
return $this->call($config->config(), $args + $this->args($config->args())); |
475
|
|
|
} |
476
|
|
|
|
477
|
2 |
|
if ($config instanceof Args) { |
478
|
|
|
return $this->args($config->config()); |
479
|
1 |
|
} |
480
|
1 |
|
|
481
|
|
|
if ($config instanceof Config) { |
482
|
|
|
return $this->config(); |
483
|
1 |
|
} |
484
|
|
|
|
485
|
|
|
if ($config instanceof Link) { |
486
|
|
|
return $this; |
487
|
|
|
} |
488
|
|
|
|
489
|
|
|
if ($config instanceof Filter) { |
490
|
2 |
|
return $this->filter($this->resolve($config->config()), $config->filter()); |
|
|
|
|
491
|
|
|
} |
492
|
2 |
|
|
493
|
|
|
if ($config instanceof Plug) { |
494
|
|
|
return is_string($config->name()) ? $this->configured($config->name()) : $config->name(); |
495
|
|
|
} |
496
|
|
|
|
497
|
|
|
if ($config instanceof Invoke) { |
498
|
|
|
return function(array $args = []) use ($config) { |
499
|
|
|
return $this->call($this->solve($config->config()), $args + $this->args($config->args())); |
|
|
|
|
500
|
|
|
}; |
501
|
1 |
|
} |
502
|
|
|
|
503
|
1 |
|
if ($config instanceof Invokable) { |
504
|
1 |
|
return function(array $args = []) use ($config) { |
505
|
|
|
return $this->solve($this->resolve($config->config(), $args + $config->args())); |
506
|
|
|
}; |
507
|
|
|
} |
508
|
|
|
|
509
|
|
|
return $callback ? $callback($config) : $this->resolver($config); |
510
|
|
|
} |
511
|
|
|
|
512
|
|
|
/** |
513
|
|
|
* @param $config |
514
|
|
|
* @param array $args |
515
|
|
|
* @return array|callable|Plugin|null|object|Resolvable|string |
516
|
|
|
* @throws RuntimeException |
517
|
|
|
*/ |
518
|
|
|
protected function resolve($config, array $args = []) |
519
|
|
|
{ |
520
|
|
|
return $this->resolvable($config, $args); |
521
|
|
|
} |
522
|
|
|
|
523
|
|
|
/** |
524
|
|
|
* @param $config |
525
|
|
|
* @return callable|mixed|null|object |
526
|
|
|
*/ |
527
|
|
|
protected function resolver($config) |
528
|
|
|
{ |
529
|
|
|
return $this->call(Arg::SERVICE_RESOLVER, [Arg::PLUGIN => $config]); |
530
|
|
|
} |
531
|
|
|
|
532
|
|
|
/** |
533
|
|
|
* @param $config |
534
|
|
|
* @param int $c |
535
|
|
|
* @return mixed |
536
|
|
|
*/ |
537
|
|
|
protected function solve($config, $c = 0) |
538
|
|
|
{ |
539
|
|
|
return !$config instanceof Resolvable ? $config : ( |
540
|
|
|
$c < Arg::MAX_RECURSION ? |
541
|
|
|
$this->solve($this->resolve($config), ++$c) : $this->signal(new Exception, [Arg::PLUGIN => $config]) |
542
|
|
|
); |
543
|
|
|
} |
544
|
|
|
|
545
|
|
|
/** |
546
|
|
|
* @param array $config |
547
|
|
|
* @param array $args |
548
|
|
|
* @param callable|null $callback |
549
|
|
|
* @return array|callable|object|string |
550
|
|
|
*/ |
551
|
|
|
protected function transmit(array $config = [], array $args = [], callable $callback = null) |
552
|
|
|
{ |
553
|
|
|
return $this->relay($this->invokable(array_shift($config)), $config, $args, $callback); |
554
|
|
|
} |
555
|
|
|
|
556
|
|
|
/** |
557
|
|
|
* @param array|object|string|\Traversable $event |
558
|
|
|
* @param array $args |
559
|
|
|
* @param callable $callback |
560
|
|
|
* @return mixed|null |
561
|
|
|
*/ |
562
|
|
|
public function trigger($event, array $args = [], callable $callback = null) |
563
|
|
|
{ |
564
|
|
|
return $this->event($event instanceof Event ? $event : $this($event) ?? $event, $args, $callback); |
565
|
|
|
} |
566
|
|
|
|
567
|
|
|
/** |
568
|
|
|
* @param $name |
569
|
|
|
* @param $config |
570
|
|
|
* @param array $args |
571
|
|
|
* @param callable $callback |
572
|
|
|
* @return callable|object |
573
|
|
|
*/ |
574
|
|
|
protected function unique($name, $config, array $args = [], callable $callback = null) |
575
|
|
|
{ |
576
|
|
|
return $name === $config ? $this->callback($name, $args, $callback) : $this($config, $args); |
577
|
|
|
} |
578
|
|
|
|
579
|
|
|
/** |
580
|
|
|
* @param string $name |
581
|
|
|
* @param callable $callback |
582
|
|
|
* @param array $args |
583
|
|
|
* @return array|callable|null|object|string |
584
|
|
|
*/ |
585
|
|
|
public function __invoke($name, array $args = [], callable $callback = null) |
586
|
|
|
{ |
587
|
|
|
return $this->plugin($name, $args, $callback ?? function(){}); |
588
|
|
|
} |
589
|
|
|
} |
590
|
|
|
|
This check looks at variables that are passed out again to other methods.
If the outgoing method call has stricter type requirements than the method itself, an issue is raised.
An additional type check may prevent trouble.