Completed
Push — master ( c00970...bb21c4 )
by Eric
7s
created

CallbackResolver::resolveArgumentsForClosure()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 20
rs 8.8571
c 0
b 0
f 0
cc 5
eloc 11
nc 6
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Jarvis\Skill\Core;
6
7
use Jarvis\Jarvis;
8
use Jarvis\Skill\DependencyInjection\Reference;
9
10
/**
11
 * @author Eric Chau <[email protected]>
12
 */
13
class CallbackResolver
14
{
15
    /**
16
     * @var Jarvis
17
     */
18
    private $app;
19
20
    public function __construct(Jarvis $app)
21
    {
22
        $this->app = $app;
23
    }
24
25
    /**
26
     * Resolves and replaces placeholders references by the parameter from Jarvis's
27
     * dependency injection container.
28
     *
29
     * @param  mixed $callback
30
     * @return \Closure
31
     */
32
    public function resolve($callback): \Closure
33
    {
34
        if (is_array($callback) && $callback[0] instanceof Reference) {
35
            $callback[0] = $this->app[(string) $callback[0]] ?? $callback[0];
36
        }
37
38
        return \Closure::fromCallable($callback);
39
    }
40
41
    /**
42
     * Resolves and returns an array of arguments according to the given closure.
43
     * This method can also smartly type hint and find the right object to match
44
     * callback requested arguments.
45
     *
46
     * @param  \Closure $callback
47
     * @param  array    $rawArgs
48
     * @return array
49
     */
50
    public function resolveArgumentsForClosure(\Closure $callback, array $rawArgs): array
51
    {
52
        $result = [];
53
        $refMethod = new \ReflectionMethod($callback, '__invoke');
54
        foreach ($refMethod->getParameters() as $refParam) {
55
            if (null !== $refClass = $refParam->getClass()) {
56
                if (isset($this->app[$refClass->name])) {
57
                    $result[$refParam->getPosition()] = $this->app[$refClass->name];
58
59
                    continue;
60
                }
61
            }
62
63
            if (in_array($refParam->name, array_keys($rawArgs))) {
64
                $result[$refParam->getPosition()] = $rawArgs[$refParam->name];
65
            }
66
        }
67
68
        return $result;
69
    }
70
}
71