Completed
Push — master ( 812eb8...a76adc )
by Timur
03:36
created

ExtraFieldsDetector::getFirstExtraField()   B

Complexity

Conditions 8
Paths 2

Size

Total Lines 32
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 8
eloc 17
nc 2
nop 2
dl 0
loc 32
rs 8.4444
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Laravel\ExtraFieldsValidator;
6
7
use Illuminate\Support\Arr;
8
use Illuminate\Support\Collection;
9
10
class ExtraFieldsDetector
11
{
12
    public function getFirstExtraField(array $data, array $rules): ?string
13
    {
14
        $original = Arr::dot($data);
15
        $rules = Collection::make($rules);
16
        $keys = $rules->keys();
17
        $filtered = [];
18
19
        $rules->each(function ($rules, $key) use ($original, $keys, &$filtered) {
20
            if (is_string($rules)) {
21
                $rules = explode('|', $rules);
22
            }
23
24
            $nestedRules = $keys->filter(fn ($otherKey) => strpos($otherKey, $key.'.') === 0);
25
26
            if (in_array('array', $rules) && $nestedRules->isEmpty()) {
27
                $key .= '.*';
28
            }
29
30
            foreach ($original as $dotIndex => $element) {
31
                if (fnmatch($key, $dotIndex)) {
32
                    Arr::set($filtered, $dotIndex, $element);
33
                }
34
            }
35
        });
36
37
        $dottedFiltered = Arr::dot($filtered);
38
39
        if (empty($dottedFiltered) && !empty($original)) {
40
            return array_key_first($original);
41
        }
42
43
        return $this->getFirstMissingField($original, $dottedFiltered);
44
    }
45
46
    private function getFirstMissingField(array $original, array $filtered): ?string
47
    {
48
        foreach ($original as $field => $value) {
49
            if (!empty($value) && !array_key_exists($field, $filtered)) {
50
                return $field;
51
            }
52
        }
53
54
        return null;
55
    }
56
}
57