AbstractDataProvider::getCollectionData()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 4
c 1
b 0
f 0
nc 2
nop 4
dl 0
loc 11
ccs 5
cts 5
cp 1
crap 2
rs 10
1
<?php
2
declare(strict_types=1);
3
4
5
namespace Xervice\DataProvider\Business\Model\DataProvider;
6
7
abstract class AbstractDataProvider implements DataProviderInterface
8
{
9
    /**
10
     * @param array|null $data
11
     */
12 8
    function __construct(?array $data = NULL)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
13
    {
14 8
        if ($data !== NULL) {
15
            $this->fromArray($data);
16
        }
17 8
    }
18
19
    /**
20
     * @return array
21
     */
22 3
    public function toArray(): array
23
    {
24 3
        return $this->convertToArray($this);
25
    }
26
27
    /**
28
     * @param array $data
29
     */
30 4
    public function fromArray(array $data): void
31
    {
32 4
        foreach ($this->getElements() as $element) {
33 4
            $fieldname = $element['isCamelCase'] ? $this->convertUnderlines($element['name']) : $element['name'];
34 4
            if (isset($data[$fieldname])) {
35 4
                $this->setFieldFromArrayData($data, $element, $fieldname);
36
            }
37
        }
38 4
    }
39
40
    /**
41
     * @param \Xervice\DataProvider\Business\Model\DataProvider\AbstractDataProvider $provider
42
     *
43
     * @return array
44
     */
45 3
    private function convertToArray(AbstractDataProvider $provider): array
46
    {
47 3
        $data = [];
48 3
        foreach ($provider->getElements() as $element) {
49 3
            $fieldname = $element['isCamelCase'] ? $this->convertUnderlines($element['name']) : $element['name'];
50 3
            $hasMethod = 'has' . $fieldname;
51 3
            if ($provider->$hasMethod()) {
52 3
                $data = $this->getDataFromFields($provider, $fieldname, $element, $data);
53
            }
54
        }
55
56 3
        return $data;
57
    }
58
59
    /**
60
     * @param array $data
61
     * @param array $element
62
     * @param string $fieldname
63
     */
64 4
    private function setFieldFromArrayData(array $data, array $element, string $fieldname): void
65
    {
66 4
        if (strpos($element['type'], 'DataProviderInterface[]') !== false) {
67 1
            $this->setChildData($data, $element, $fieldname);
68
        }
69 4
        elseif (strpos($element['type'], 'DataProviderInterface') !== false) {
70 1
            $this->setAnyDataProviderValues($data, $element, $fieldname);
71
        }
72 4
        elseif ($element['is_dataprovider']) {
73 1
            $this->setOneDataProviderValue($data, $element, $fieldname);
74
        }
75 4
        elseif ($element['is_collection']) {
76 2
            $this->setCollectionValues($data, $element, $fieldname);
77
        }
78
        else {
79 4
            $this->{$element['name']} = $data[$fieldname];
80
        }
81 4
    }
82
83
    /**
84
     * @param \Xervice\DataProvider\Business\Model\DataProvider\DataProviderInterface $provider
85
     * @param string $fieldname
86
     * @param array $element
87
     * @param array $data
88
     *
89
     * @return mixed
90
     */
91 3
    private function getDataFromFields(DataProviderInterface $provider, string $fieldname, array $element, array $data)
92
    {
93 3
        $getMethod = 'get' . $fieldname;
94 3
        if (strpos($element['type'], 'DataProviderInterface[]') !== false) {
95 1
            $data = $this->getDataProviderCollectionData($provider, $fieldname, $data, $getMethod);
96
        }
97
        elseif (
98 3
            strpos($element['type'], 'DataProviderInterface') !== false
99 3
            && $provider->{$getMethod}() instanceof DataProviderInterface
100
        ) {
101 1
            $anyDataProvider = new AnyDataProvider($provider->{$getMethod}());
102 1
            $data[$fieldname] = $anyDataProvider->toArray();
103
        }
104 3
        elseif ($element['is_dataprovider'] && $provider->{$getMethod}() instanceof AbstractDataProvider) {
105
            $data[$fieldname] = $this->convertToArray($provider->{$getMethod}());
106
        }
107 3
        elseif ($element['is_collection']) {
108 1
            $data = $this->getCollectionData($provider, $fieldname, $data, $getMethod);
109
        }
110
        else {
111 3
            $data[$fieldname] = $provider->{$getMethod}();
112
        }
113 3
        return $data;
114
    }
115
116
    /**
117
     * @param array $data
118
     * @param array $element
119
     * @param string $fieldname
120
     */
121 1
    private function setChildData(array $data, array $element, string $fieldname): void
122
    {
123 1
        foreach ($data[$fieldname] as $childData) {
124 1
            $anyDataProvider = new AnyDataProvider();
125 1
            $anyDataProvider->fromArray($childData);
126 1
            $this->{$element['name']}[] = $anyDataProvider->getDataProvider();
127
        }
128 1
    }
129
130
    /**
131
     * @param array $data
132
     * @param array $element
133
     * @param string $fieldname
134
     */
135 1
    private function setAnyDataProviderValues(array $data, array $element, string $fieldname): void
136
    {
137 1
        $anyDataProvider = new AnyDataProvider();
138 1
        $anyDataProvider->fromArray($data[$fieldname]);
139 1
        $this->{$element['name']} = $anyDataProvider->getDataProvider();
140 1
    }
141
142
    /**
143
     * @param array $data
144
     * @param array $element
145
     * @param string $fieldname
146
     */
147 1
    private function setOneDataProviderValue(array $data, array $element, string $fieldname): void
148
    {
149 1
        $dataProvider = new $element['type']();
150 1
        if (\is_array($data[$fieldname])) {
151 1
            $dataProvider->fromArray($data[$fieldname]);
152
        }
153 1
        $this->{$element['name']} = $dataProvider;
154 1
    }
155
156
    /**
157
     * @param array $data
158
     * @param array $element
159
     * @param string $fieldname
160
     */
161 2
    private function setCollectionValues(array $data, array $element, string $fieldname): void
162
    {
163 2
        foreach ($data[$fieldname] as $childData) {
164 2
            $dataProvider = new $element['singleton_type']();
165 2
            $dataProvider->fromArray($childData);
166 2
            $this->{$element['name']}[] = $dataProvider;
167
        }
168 2
    }
169
170
    /**
171
     * @param \Xervice\DataProvider\Business\Model\DataProvider\DataProviderInterface $provider
172
     * @param string $fieldname
173
     * @param array $data
174
     * @param string $getMethod
175
     *
176
     * @return array
177
     */
178 1
    private function getDataProviderCollectionData(
179
        DataProviderInterface $provider,
180
        string $fieldname,
181
        array $data,
182
        string $getMethod
183
    ): array {
184 1
        $data[$fieldname] = [];
185 1
        foreach ($provider->{$getMethod}() as $child) {
186 1
            $anyDataProvider = new AnyDataProvider($child);
187 1
            $data[$fieldname][] = $anyDataProvider->toArray();
188
        }
189 1
        return $data;
190
    }
191
192
    /**
193
     * @param \Xervice\DataProvider\Business\Model\DataProvider\DataProviderInterface $provider
194
     * @param string $fieldname
195
     * @param array $data
196
     * @param string $getMethod
197
     *
198
     * @return array
199
     */
200 1
    private function getCollectionData(
201
        DataProviderInterface $provider,
202
        string $fieldname,
203
        array $data,
204
        string $getMethod
205
    ): array {
206 1
        $data[$fieldname] = [];
207 1
        foreach ($provider->{$getMethod}() as $child) {
208 1
            $data[$fieldname][] = $child->toArray();
209
        }
210 1
        return $data;
211
    }
212
213
    /**
214
     * @param string $methodName
215
     *
216
     * @return string
217
     */
218 1
    private function convertUnderlines(string $methodName): string
219
    {
220 1
        return preg_replace_callback(
221 1
            '@\_([a-z]{1,1})@',
222
            function ($matches) {
223 1
                return strtoupper($matches[1] ?? '');
224 1
            },
225 1
            $methodName
226
        );
227
    }
228
229
    /**
230
     * @return array
231
     */
232
    abstract protected function getElements(): array;
233
}
234