Passed
Push — master ( 3d5b3f...0c7e1d )
by Korotkov
01:42 queued 10s
created

Objects::new()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 7
c 1
b 0
f 0
nc 2
nop 2
dl 0
loc 12
rs 10
1
<?php
2
3
/**
4
 * @author    : Jagepard <[email protected]">
5
 * @license   https://mit-license.org/ MIT
6
 */
7
8
namespace Rudra\Container;
9
10
use Rudra\Container\Interfaces\ContainerInterface;
11
12
class Objects extends Container
13
{
14
    private ContainerInterface $binding;
15
16
    public function __construct(ContainerInterface $binding)
17
    {
18
        $this->binding = $binding;
19
    }
20
21
    public function set(array $data): void
22
    {
23
        list($key, $object) = $data;
24
25
        if (is_array($object) && array_key_exists(1, $object)) {
26
            ("raw" === $object[1]) ? $this->mergeData($key, $object[0]) : $this->iOc($key, $object[0], $object[1]);
27
            return;
28
        }
29
30
        $this->iOc($key, $object);
31
    }
32
33
    private function mergeData(string $key, $object)
34
    {
35
        $this->data = array_merge([$key => $object], $this->data);
36
    }
37
38
    private function iOc(string $key, $object, $params = null): void
39
    {
40
        $reflection = new \ReflectionClass($object);
41
        $constructor = $reflection->getConstructor();
42
43
        if ($constructor && $constructor->getNumberOfParameters()) {
44
            $paramsIoC = $this->getParamsIoC($constructor, $params);
45
            $this->mergeData($key, $reflection->newInstanceArgs($paramsIoC));
46
            return;
47
        }
48
49
        $this->mergeData($key, new $object());
50
    }
51
52
    private function getParamsIoC(\ReflectionMethod $constructor, $params): array
53
    {
54
        $i = 0;
55
        $paramsIoC = [];
56
57
        foreach ($constructor->getParameters() as $value) {
58
            /*
59
             | If in the constructor expects the implementation of interface,
60
             | so that the container automatically created the necessary object and substituted as an argument,
61
             | we need to bind the interface with the implementation.
62
             */
63
            if (isset($value->getClass()->name) && $this->binding->has($value->getClass()->name)) {
64
                $className = $this->binding->get($value->getClass()->name);
65
                $paramsIoC[] = (is_object($className)) ? $className : new $className;
66
                continue;
67
            }
68
69
            /*
70
             | If the class constructor contains arguments with default values,
71
             | then if no arguments are passed,
72
             | values will be added by default by container
73
             */
74
            if ($value->isDefaultValueAvailable() && !isset($params[$i])) {
75
                $paramsIoC[] = $value->getDefaultValue();
76
                continue;
77
            }
78
79
            $paramsIoC[] = $params[$i++];
80
        }
81
82
        return $paramsIoC;
83
    }
84
85
    /*
86
     | Creates an object without adding to the container
87
     */
88
    public function new($object, $params = null)
89
    {
90
        $reflection = new \ReflectionClass($object);
91
        $constructor = $reflection->getConstructor();
92
93
        if ($constructor && $constructor->getNumberOfParameters()) {
94
            $paramsIoC = $this->getParamsIoC($constructor, $params);
95
96
            return $reflection->newInstanceArgs($paramsIoC);
97
        }
98
99
        return new $object();
100
    }
101
}
102