Test Failed
Push — master ( c31371...2e53c5 )
by Mike
01:43
created

ValidatorProvider::array_key_last()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2.0625

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 7
ccs 3
cts 4
cp 0.75
crap 2.0625
rs 10
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace Xervice\Validator\Business\Model;
5
6
7
use Xervice\Validator\Business\Dependency\ValidatorConfigurationProviderPluginInterface;
8
use Xervice\Validator\Business\Exception\ValidationException;
9
10
class ValidatorProvider implements ValidatorProviderInterface
11
{
12
    /**
13
     * @var \Xervice\Validator\Business\Dependency\ValidatorConfigurationProviderPluginInterface[]
14
     */
15
    private $configurationPlugins;
16
17
    /**
18
     * @var \Xervice\Validator\Business\Dependency\ValidatorTypePluginInterface[]
19
     */
20
    protected $validatorTypes;
21
22
    /**
23
     * Validator constructor.
24
     *
25
     * @param \Xervice\Validator\Business\Dependency\ValidatorConfigurationProviderPluginInterface[] $configurationPlugins
26
     * @param \Xervice\Validator\Business\Dependency\ValidatorTypePluginInterface[] $validatorTypes
27
     */
28 5
    public function __construct(array $configurationPlugins, array $validatorTypes)
29
    {
30 5
        $this->configurationPlugins = $configurationPlugins;
31 5
        $this->validatorTypes = $validatorTypes;
32 5
    }
33
34
35
    /**
36
     * @param array $data
37
     *
38
     * @throws \Xervice\Validator\Business\Exception\ValidationException
39
     */
40 5
    public function validate(array $data): void
41
    {
42
        try {
43 5
            foreach ($this->configurationPlugins as $configurationPlugin) {
44 5
                $this->validateByPlugin($data, $configurationPlugin);
45
            }
46
        }
47 5
        catch (ValidationException $exception) {
48 3
            throw new ValidationException(
49 3
                sprintf(
50 3
                    'Data not valid. %s',
51 3
                    $exception->getMessage()
52
                )
53
            );
54
        }
55
    }
56
57
    /**
58
     * @param array $data
59
     * @param \Xervice\Validator\Business\Dependency\ValidatorConfigurationProviderPluginInterface $configurationProviderPlugin
60
     */
61 5
    protected function validateByPlugin(array $data, ValidatorConfigurationProviderPluginInterface $configurationProviderPlugin): void
62
    {
63 5
        foreach ($configurationProviderPlugin->getValidatorConfiguration() as $fieldConfig) {
64 5
            if (is_string($fieldConfig)) {
65 5
                $this->validateField($data, $fieldConfig, $fieldConfig);
66
            }
67
            else {
68 5
                $this->validateNested($data, $fieldConfig);
69
            }
70
        }
71
    }
72
73
    /**
74
     * @param array $data
75
     * @param array $configs
76
     */
77 4
    protected function validateNested(array $data, array $configs): void
78
    {
79 4
        foreach ($configs as $key => $fieldConfig) {
80 4
            $this->validateByType($data, $key, $fieldConfig);
81
        }
82 4
    }
83
84
    /**
85
     * @param array $data
86
     * @param string $fieldName
87
     * @param $config
88
     */
89 5
    protected function validateField(array $data, string $fieldName, $config)
90
    {
91 5
        if (is_callable($config)) {
92 3
            echo '1';
93
        }
94
95 5
        foreach ($this->validatorTypes as $validatorType) {
96 5
            if ($validatorType->isResponsible($config)) {
97 5
                $validatorType->validate($data, $fieldName, $config);
98
            }
99
        }
100 5
    }
101
102
    /**
103
     * @param array $data
104
     * @param $key
105
     * @param mixed $fieldConfig
106
     */
107 2
    protected function validateArrayKey(array $data, $key, $fieldConfig): void
108
    {
109 2
        $context = explode('.', $key);
110 2
        $subdata = $data;
111 2
        $lastKey = $this->array_key_last($context);
112 2
        $lastChain = $context[$lastKey];
113 2
        foreach ($context as $subkey => $chain) {
114 2
            if ($subkey !== $lastKey) {
115 2
                $subdata = $subdata[$chain];
116
            }
117
        }
118 2
        $this->validateField($subdata, $lastChain, $fieldConfig);
119 2
    }
120
121
    /**
122
     * @param array $data
123
     * @param $key
124
     * @param $fieldConfig
125
     */
126 4
    protected function validateByType(array $data, $key, $fieldConfig): void
127
    {
128 4
        if (is_string($fieldConfig)) {
129 2
            $key = $fieldConfig;
130
        }
131
132 4
        if (strpos($key, '.*') !== false) {
133 2
            $this->validateAllArrayFields($data, $key, $fieldConfig);
134
        }
135 4
        elseif (strpos($key, '.') !== false) {
136 2
            $this->validateArrayKey($data, $key, $fieldConfig);
137
        }
138
        else {
139 4
            $this->validateField($data, $key, $fieldConfig);
140
        }
141 4
    }
142
143
    /**
144
     * @param array $data
145
     * @param $key
146
     * @param $fieldConfig
147
     */
148 2
    protected function validateAllArrayFields(array $data, $key, $fieldConfig): void
149
    {
150 2
        $context = explode('.', $key);
151 2
        $subdata = $data;
152 2
        $lastKey = array_key_last($context);
153
        foreach ($context as $subkey => $chain) {
154
            if ($subkey !== $lastKey) {
155
                $subdata = $subdata[$chain];
156
            }
157
        }
158
159
        foreach ($subdata as $childkey => $childdata) {
160
            $this->validateField($subdata, $childkey, $fieldConfig);
161
        }
162
    }
163
164
    /**
165
     * @param array $array
166
     *
167
     * @return mixed
168
     */
169 2
    private function array_key_last(array $array)
170
    {
171 2
        if (!function_exists("array_key_last")) {
172 2
            return array_keys($array)[count($array) - 1];
173
        }
174
175
        return array_key_last($array);
176
    }
177
}