Handler::createInstance()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 4
rs 10
1
<?php
2
3
namespace Tleckie\Di\Definition\Handler;
4
5
use ReflectionClass;
6
use ReflectionException;
7
use Tleckie\Di\DiInterface;
8
use function call_user_func_array;
9
10
/**
11
 * Class Handler
12
 *
13
 * @package Tleckie\Di\Handler\Handler
14
 * @author  Teodoro Leckie Westberg <[email protected]>
15
 */
16
class Handler implements HandlerInterface
17
{
18
    /** @var HandlerInterface|null */
19
    protected HandlerInterface|null $next = null;
20
21
    /** @var DiInterface */
22
    protected DiInterface $di;
23
24
    /**
25
     * Handler constructor.
26
     *
27
     * @param DiInterface $di
28
     */
29
    public function __construct(DiInterface $di)
30
    {
31
        $this->di = $di;
32
    }
33
34
    /**
35
     * @param HandlerInterface $definition
36
     * @return HandlerInterface
37
     */
38
    public function next(HandlerInterface $definition): HandlerInterface
39
    {
40
        $this->next = $definition;
41
42
        return $definition;
43
    }
44
45
    /**
46
     * @param $value
47
     * @return mixed
48
     */
49
    public function handle($value): mixed
50
    {
51
        if ($this->next instanceof HandlerInterface) {
52
            return $this->next->handle($value);
53
        }
54
55
        return $value;
56
    }
57
58
    /**
59
     * @param string $className
60
     * @param array  $arguments
61
     * @return object
62
     * @throws ReflectionException
63
     */
64
    protected function createInstance(string $className, array $arguments): object
65
    {
66
        return (new ReflectionClass($className))
67
            ->newInstanceArgs($this->resolveParams($arguments));
68
    }
69
70
    /**
71
     * @param array $params
72
     * @return array
73
     */
74
    protected function resolveParams(array $params): array
75
    {
76
        $di = $this->di;
77
78
        return $this->recursiveArrayMap(static function ($param) use ($di) {
79
            if ($di->handler()) {
80
                return $di->handler()->handle($param);
81
            }
82
83
            return $param;
84
        }, $params);
85
    }
86
87
    /**
88
     * @param $callback
89
     * @param $input
90
     * @return array
91
     */
92
    private function recursiveArrayMap($callback, $input): array
93
    {
94
        $output = [];
95
        foreach ($input as $key => $data) {
96
            $output[$key] = (is_array($data)) ?
97
                $this->recursiveArrayMap($callback, $data) :
98
                $callback($data);
99
        }
100
101
        return $output;
102
    }
103
104
    /**
105
     * @param object $object
106
     * @param string $methodName
107
     * @param array  $arguments
108
     */
109
    protected function callMethod(object $object, string $methodName, array $arguments): void
110
    {
111
        call_user_func_array(
112
            [$object, $methodName],
113
            $this->resolveParams($arguments)
114
        );
115
    }
116
}
117