Passed
Push — master ( 6871b5...2179ad )
by Mike
05:46 queued 02:24
created

ArrayHandler   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 184
Duplicated Lines 0 %

Test Coverage

Coverage 98.36%

Importance

Changes 0
Metric Value
wmc 25
eloc 54
dl 0
loc 184
ccs 60
cts 61
cp 0.9836
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A validateByType() 0 15 4
A validateNested() 0 7 2
A validateField() 0 11 4
A handleArray() 0 15 5
A validateArrayKey() 0 9 1
A setElementWithKey() 0 10 2
A getElementWithKey() 0 8 2
A getLastArrayKey() 0 7 2
A validateAllArrayFields() 0 11 2
1
<?php
2
declare(strict_types=1);
3
4
namespace Xervice\ArrayHandler\Business\Model;
5
6
7
use Xervice\ArrayHandler\Dependency\FieldHandlerPluginInterface;
8
9
class ArrayHandler implements ArrayHandlerInterface
10
{
11
    /**
12
     * @var \Xervice\ArrayHandler\Dependency\FieldHandlerPluginInterface
13
     */
14
    private $fieldHandler;
15
16
    /**
17
     * ArrayHandler constructor.
18
     *
19
     * @param \Xervice\ArrayHandler\Dependency\FieldHandlerPluginInterface $fieldHandler
20
     */
21 1
    public function __construct(FieldHandlerPluginInterface $fieldHandler)
22
    {
23 1
        $this->fieldHandler = $fieldHandler;
24 1
    }
25
26
    /**
27
     * @param array $payload
28
     * @param array $config
29
     *
30
     * @return array
31
     */
32 1
    public function handleArray(array $payload, array $config): array
33
    {
34 1
        foreach ($config as $key => $configItem) {
35 1
            if (is_string($configItem)) {
36 1
                $payload = $this->validateField($payload, $configItem, $configItem);
37 1
            } elseif ($key === '*') {
38 1
                foreach ($payload as $dataKey => $subdata) {
39 1
                    $payload[$dataKey] = $this->handleArray($subdata, $configItem);
40
                }
41
            } else {
42 1
                $payload = $this->validateNested($payload, $configItem);
43
            }
44
        }
45
46 1
        return $payload;
47
    }
48
49
    /**
50
     * @param array $data
51
     * @param string $fieldName
52
     * @param mixed $config
53
     *
54
     * @return array
55
     */
56 1
    protected function validateField(array $data, string $fieldName, $config): array
57
    {
58 1
        if (is_string($config)) {
59 1
            $data = $this->fieldHandler->handleSimpleConfig($data, $fieldName, $config);
60 1
        } elseif (is_array($config)) {
61 1
            $data = $this->fieldHandler->handleNestedConfig($data, $fieldName, $config);
62 1
        } elseif (is_callable($config)) {
63 1
            $data = $this->fieldHandler->handleCallableConfig($data, $fieldName, $config);
64
        }
65
66 1
        return $data;
67
    }
68
69
    /**
70
     * @param array $data
71
     * @param array $configs
72
     *
73
     * @return array
74
     */
75 1
    protected function validateNested(array $data, array $configs): array
76
    {
77 1
        foreach ($configs as $key => $fieldConfig) {
78 1
            $data = $this->validateByType($data, $key, $fieldConfig);
79
        }
80
81 1
        return $data;
82
    }
83
84
    /**
85
     * @param array $data
86
     * @param mixed $key
87
     * @param mixed $fieldConfig
88
     *
89
     * @return array
90
     */
91 1
    protected function validateByType(array $data, $key, $fieldConfig): array
92
    {
93 1
        if (is_string($fieldConfig)) {
94 1
            $key = $fieldConfig;
95
        }
96
97 1
        if (strpos($key, '.*') !== false) {
98 1
            $data = $this->validateAllArrayFields($data, $key, $fieldConfig);
99 1
        } elseif (strpos($key, '.') !== false) {
100 1
            $data = $this->validateArrayKey($data, $key, $fieldConfig);
101
        } else {
102 1
            $data = $this->validateField($data, $key, $fieldConfig);
103
        }
104
105 1
        return $data;
106
    }
107
108
    /**
109
     * @param array $data
110
     * @param string $key
111
     * @param mixed $fieldConfig
112
     *
113
     * @return array
114
     */
115 1
    protected function validateArrayKey(array $data, string $key, $fieldConfig): array
116
    {
117 1
        $keychain = explode('.', $key);
118 1
        $lastKey = $this->getLastArrayKey($keychain);
119
120 1
        $subdata = $this->getElementWithKey($data, $keychain);
121 1
        $subdata = $this->validateField($subdata, $keychain[$lastKey], $fieldConfig);
122
123 1
        return $this->setElementWithKey($data, $keychain, $subdata);
124
    }
125
126
    /**
127
     * @param array $data
128
     * @param string $key
129
     * @param mixed $fieldConfig
130
     *
131
     * @return array
132
     */
133 1
    protected function validateAllArrayFields(array $data, string $key, $fieldConfig): array
134
    {
135 1
        $keychain = explode('.', $key);
136 1
        $lastKey = $this->getLastArrayKey($keychain);
0 ignored issues
show
Unused Code introduced by
The assignment to $lastKey is dead and can be removed.
Loading history...
137
138 1
        $subdata = $this->getElementWithKey($data, $keychain);
139 1
        foreach ($subdata as $childkey => $childdata) {
140 1
            $subdata = $this->validateField($subdata, (string) $childkey, $fieldConfig);
141
        }
142
143 1
        return $this->setElementWithKey($data, $keychain, $subdata);
144
    }
145
146
    /**
147
     * @param array $data
148
     * @param array $keychain
149
     * @param $value
150
     *
151
     * @return array
152
     */
153 1
    private function setElementWithKey(array $data, array $keychain, $value): array
154
    {
155 1
        if (count($keychain) === 1) {
156 1
            return $value;
157
        }
158
159 1
        $key = array_shift($keychain);
160 1
        $data[$key] = $this->setElementWithKey($data[$key], $keychain, $value);
161
162 1
        return $data;
163
    }
164
165
    /**
166
     * @param array $data
167
     * @param array $keychain
168
     *
169
     * @return mixed
170
     */
171 1
    private function getElementWithKey(array $data, array $keychain)
172
    {
173 1
        if (count($keychain) === 1) {
174 1
            return $data;
175
        }
176
177 1
        $key = array_shift($keychain);
178 1
        return $this->getElementWithKey($data[$key], $keychain);
179
    }
180
181
    /**
182
     * @param array $array
183
     *
184
     * @return mixed
185
     */
186 1
    private function getLastArrayKey(array $array)
187
    {
188 1
        if (!function_exists("array_key_last")) {
189 1
            return array_keys($array)[count($array) - 1];
190
        }
191
192
        return array_key_last($array);
193
    }
194
}