Passed
Push — master ( 1c0d04...a65817 )
by Mike
01:40
created

ValidatorProvider   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 162
Duplicated Lines 0 %

Test Coverage

Coverage 98.36%

Importance

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

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A validateByPlugin() 0 8 3
A validate() 0 12 3
A validateNested() 0 4 2
A validateByType() 0 14 4
A validateAllArrayFields() 0 13 4
A validateField() 0 5 3
A validateArrayKey() 0 12 3
A array_key_last() 0 7 2
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 4
        catch (ValidationException $exception) {
48 4
            throw new ValidationException(
49 4
                sprintf(
50 4
                    'Data not valid. %s',
51 4
                    $exception->getMessage()
52
                )
53
            );
54
        }
55 1
    }
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 2
    }
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 mixed $config
88
     */
89 5
    protected function validateField(array $data, string $fieldName, $config): void
90
    {
91 5
        foreach ($this->validatorTypes as $validatorType) {
92 5
            if ($validatorType->isResponsible($config)) {
93 5
                $validatorType->validate($data, $fieldName, $config);
94
            }
95
        }
96 5
    }
97
98
    /**
99
     * @param array $data
100
     * @param string $key
101
     * @param mixed $fieldConfig
102
     */
103 2
    protected function validateArrayKey(array $data, string $key, $fieldConfig): void
104
    {
105 2
        $context = explode('.', $key);
106 2
        $subdata = $data;
107 2
        $lastKey = $this->array_key_last($context);
108 2
        $lastChain = $context[$lastKey];
109 2
        foreach ($context as $subkey => $chain) {
110 2
            if ($subkey !== $lastKey) {
111 2
                $subdata = $subdata[$chain];
112
            }
113
        }
114 2
        $this->validateField($subdata, $lastChain, $fieldConfig);
115 2
    }
116
117
    /**
118
     * @param array $data
119
     * @param mixed $key
120
     * @param mixed $fieldConfig
121
     */
122 4
    protected function validateByType(array $data, $key, $fieldConfig): void
123
    {
124 4
        if (is_string($fieldConfig)) {
125 2
            $key = $fieldConfig;
126
        }
127
128 4
        if (strpos($key, '.*') !== false) {
129 2
            $this->validateAllArrayFields($data, $key, $fieldConfig);
130
        }
131 4
        elseif (strpos($key, '.') !== false) {
132 2
            $this->validateArrayKey($data, $key, $fieldConfig);
133
        }
134
        else {
135 4
            $this->validateField($data, $key, $fieldConfig);
136
        }
137 4
    }
138
139
    /**
140
     * @param array $data
141
     * @param string $key
142
     * @param mixed $fieldConfig
143
     */
144 2
    protected function validateAllArrayFields(array $data, string $key, $fieldConfig): void
145
    {
146 2
        $context = explode('.', $key);
147 2
        $subdata = $data;
148 2
        $lastKey = $this->array_key_last($context);
149 2
        foreach ($context as $subkey => $chain) {
150 2
            if ($subkey !== $lastKey) {
151 2
                $subdata = $subdata[$chain];
152
            }
153
        }
154
155 2
        foreach ($subdata as $childkey => $childdata) {
156 2
            $this->validateField($subdata, $childkey, $fieldConfig);
157
        }
158 2
    }
159
160
    /**
161
     * @param array $array
162
     *
163
     * @return mixed
164
     */
165 2
    private function array_key_last(array $array)
166
    {
167 2
        if (!function_exists("array_key_last")) {
168 2
            return array_keys($array)[count($array) - 1];
169
        }
170
171
        return array_key_last($array);
172
    }
173
}