Completed
Push — master ( dd013b...f97877 )
by Maxim
02:18
created

ValidationData::splitKey()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
namespace Weew\Validator;
4
5
use Traversable;
6
use Weew\Contracts\IArrayable;
7
8
class ValidationData implements IValidationData {
9
    /**
10
     * @var IPropertyReader
11
     */
12
    protected $propertyReader;
13
14
    /**
15
     * @var mixed
16
     */
17
    protected $data;
18
19
    /**
20
     * ValidationData constructor.
21
     *
22
     * @param $data
23
     * @param IPropertyReader $propertyReader
24
     */
25
    public function __construct($data, IPropertyReader $propertyReader = null) {
26
        if ( ! $propertyReader instanceof IPropertyReader) {
27
            $propertyReader = $this->createPropertyReader();
28
        }
29
30
        $this->data = $data;
31
        $this->propertyReader = $propertyReader;
32
    }
33
34
    /**
35
     * @param string $key
36
     *
37
     * @return array
38
     */
39
    public function get($key) {
40
        return $this->getValues(
41
            $this->data, $this->splitKey($key)
42
        );
43
    }
44
45
    /**
46
     * @param mixed $data
47
     * @param array $keys
48
     *
49
     * @return array
50
     */
51
    protected function getValues($data, array $keys) {
52
        $key = array_shift($keys);
53
54
        if (array_contains(['', null], $key)) {
55
            return [];
56
        }
57
58
        if ($key === '*') {
59
            $values = $this->getValuesForWildcardKey($data, $keys);
60
        } else {
61
            $values = $this->getValuesForRegularKey($data, $key, $keys);
62
        }
63
64
        return $values;
65
    }
66
67
    /**
68
     * @param mixed $data
69
     * @param array $keys
70
     *
71
     * @return array
72
     */
73
    protected function getValuesForWildcardKey($data, array $keys) {
74
        $values = [];
75
76
        if ( ! is_array($data) && ! $data instanceof Traversable) {
77
            if ($data instanceof IArrayable) {
78
                $data = $data->toArray();
79
            }
80
81
            if ( ! is_array($data)) {
82
                $data = [];
83
            }
84
        }
85
86
        if (count($keys) === 0) {
87
            foreach ($data as $itemKey => $itemValue) {
88
                $values[$itemKey] = $itemValue;
89
            }
90
        }
91
92
        if (count($keys) > 0) {
93
            foreach ($data as $itemKey => $itemValue) {
94
                $nestedValues = $this->getValues($itemValue, $keys);
95
                $isLastWildcard = ! array_contains($keys, '*');
96
97
                foreach ($nestedValues as $nestedKey => $nestedValue) {
98
                    // do no collect null values unless it is the last wildcard node
99
                    if ($nestedValue !== null || $isLastWildcard) {
100
                        $values[$this->buildKey($itemKey, $nestedKey)] = $nestedValue;
101
                    }
102
                }
103
            }
104
        }
105
106
        return $values;
107
    }
108
109
    /**
110
     * @param mixed $data
111
     * @param string $key
112
     * @param array $keys
113
     *
114
     * @return array
115
     */
116
    protected function getValuesForRegularKey($data, $key, array $keys) {
117
        $values = [];
118
119
        if (count($keys) === 0) {
120
            $values[$key] = $this->propertyReader->getProperty($data, $key);
121
        }
122
123
        if (count($keys) > 0) {
124
            $value = $this->propertyReader->getProperty($data, $key);
125
            $nestedValues = $this->getValues($value, $keys);
126
127
            foreach ($nestedValues as $nestedKey => $nestedValue) {
128
                $values[$this->buildKey($key, $nestedKey)] = $nestedValue;
129
            }
130
        }
131
132
        return $values;
133
    }
134
135
    /**
136
     * @param string $key
137
     *
138
     * @return array
139
     */
140
    protected function splitKey($key) {
141
        return explode('.', $key);
142
    }
143
144
    /**
145
     * @param array ...$keys
146
     *
147
     * @return string
148
     */
149
    protected function buildKey($keys) {
0 ignored issues
show
Unused Code introduced by
The parameter $keys is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
150
        return implode('.', func_get_args());
151
    }
152
153
    /**
154
     * @return IPropertyReader
155
     */
156
    protected function createPropertyReader() {
157
        return new PropertyReader();
158
    }
159
}
160