Cancelled
Push — master ( 2f64eb...0d1d70 )
by Mike
01:08
created

XmlMerger::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
5
namespace Xervice\DataProvider\Business\Model\Parser;
6
7
use Xervice\DataProvider\Business\Model\DataProvider\AnyDataProvider;
8
use Xervice\DataProvider\Business\Model\DataProvider\DataProviderInterface;
9
10
class XmlMerger implements XmlMergerInterface
11
{
12
    /**
13
     * @var array
14
     */
15
    private $mergedXml = [];
16
17
    /**
18
     * @var string
19
     */
20
    private $namespace;
21
22
    /**
23
     * @param string $namespace
24
     */
25 10
    public function __construct(string $namespace)
26
    {
27 10
        $this->namespace = $namespace;
28 10
    }
29
30
    /**
31
     * @param string $xmlContent
32
     */
33 10
    public function addXml(string $xmlContent): void
34
    {
35 10
        $xml = \simplexml_load_string($xmlContent);
36
37 10
        foreach ($xml->DataProvider as $xmlDataProvider) {
38 10
            $dataProvider = $this->parseDataProvider($xmlDataProvider);
39
40 10
            foreach ($xmlDataProvider->DataElement as $element) {
41 10
                $fieldName = (string)$element->attributes()['name'];
42
43 10
                if (isset($this->mergedXml[$dataProvider]['elements'][$fieldName])) {
44
                    $this->mergedXml[$dataProvider]['elements'][$fieldName] = array_merge(
45
                        $this->mergedXml[$dataProvider]['elements'][$fieldName],
46
                        $this->getElementData($element, $this->mergedXml[$dataProvider])
47
                    );
48
                }
49
                else {
50 10
                    $this->mergedXml[$dataProvider]['elements'][$fieldName] = $this->getElementData($element, $this->mergedXml[$dataProvider]);
51
                }
52
            }
53
        }
54
55
56 10
    }
57
58
    /**
59
     * @return array
60
     */
61 10
    public function getData(): array
62
    {
63 10
        return $this->mergedXml;
64
    }
65
66
    /**
67
     * @param \SimpleXMLElement $xmlDataProvider
68
     *
69
     * @return string
70
     */
71 10
    private function parseDataProvider(\SimpleXMLElement $xmlDataProvider): string
72
    {
73 10
        $dataProvider = (string)$xmlDataProvider->attributes()['name'];
74 10
        if (!isset($this->mergedXml[$dataProvider])) {
75 10
            $this->mergedXml[$dataProvider] = [
76 10
                'configs' => [
77 10
                    'convertUnderlines' => (bool)$xmlDataProvider->attributes()['ConvertUnderlines'] ?? false,
78 10
                    'deprecated' => (bool)$xmlDataProvider->attributes()['deprecated'] ?? false
79
                ],
80
                'elements' => []
81
            ];
82
        }
83
84 10
        return $dataProvider;
85
    }
86
87
    /**
88
     * @param \SimpleXMLElement $element
89
     *
90
     * @return array
91
     */
92 10
    private function getElementData(\SimpleXMLElement $element, array $dataProvider): array
93
    {
94 10
        $type = (string)$element->attributes()['type'];
95
96 10
        $type = ($type !== 'double') ? $type : 'float';
97
98
        $data = [
99 10
            'name' => (string)$element->attributes()['name'],
100 10
            'allownull' => (bool)$element->attributes()['allownull'],
101 10
            'default' => (string)$element->attributes()['default'],
102 10
            'type' => $this->getVariableType($type),
103 10
            'is_collection' => $this->isCollection($type),
104 10
            'is_dataprovider' => $this->isDataProvider($type),
105 10
            'isCamelCase' => $dataProvider['configs']['convertUnderlines']
106
        ];
107
108 10
        $singleton = (string)$element->attributes()['singleton'];
109 10
        if ($singleton !== '') {
110 10
            $data['singleton'] = (string)$element->attributes()['singleton'];
111 10
            $data['singleton_type'] = $this->getSingleVariableType($type);
112
        }
113
114 10
        return $data;
115
    }
116
117
    /**
118
     * @param string $type
119
     *
120
     * @return bool
121
     */
122 10
    private function isDataProvider(string $type): bool
123
    {
124 10
        return (!$this->isSimpleType($type) && !$this->isCollection($type));
125
    }
126
127
    /**
128
     * @param string $type
129
     *
130
     * @return bool
131
     */
132 10
    private function isCollection(string $type): bool
133
    {
134 10
        return strpos($type, '[]') !== false;
135
    }
136
137
    /**
138
     * @param string $type
139
     *
140
     * @return bool
141
     */
142 10
    private function isSimpleType(string $type): bool
143
    {
144
        $validTypes = [
145 10
            'int',
146
            'string',
147
            'bool',
148
            'double',
149
            'float',
150
            'array',
151
            'DataProviderInterface',
152
            'DataProviderInterface[]',
153
            DataProviderInterface::class,
154
            DataProviderInterface::class . '[]'
155
        ];
156
157 10
        return \in_array($type, $validTypes, true);
158
    }
159
160
    /**
161
     * @param string $type
162
     *
163
     * @return string
164
     */
165 10
    private function getVariableType(string $type): string
166
    {
167 10
        if (!$this->isSimpleType($type)) {
168 10
            $namespace = ltrim($this->namespace, '\\');
169 10
            $type =  '\\' . $namespace .'\\' . $type . 'DataProvider';
170
        }
171
172 10
        if ($type === 'DataProviderInterface') {
173 10
            $type = '\\' . DataProviderInterface::class;
174
        }
175
176 10
        if ($type === 'DataProviderInterface[]') {
177 10
            $type = '\\' . DataProviderInterface::class . '[]';
178
        }
179
180 10
        if (strpos($type, '[]') !== false) {
181 10
            $type = str_replace('[]', '', $type) . '[]';
182
        }
183
184 10
        return $type;
185
    }
186
187
    /**
188
     * @param string $type
189
     *
190
     * @return string
191
     */
192 10
    private function getSingleVariableType(string $type): string
193
    {
194 10
        if (!$this->isSimpleType($type)) {
195 10
            $namespace = ltrim($this->namespace, '\\');
196 10
            $type = '\\' . $namespace .'\\' . $type . 'DataProvider';
197
        }
198
199 10
        if ($type === 'DataProviderInterface') {
200
            $type = '\\' . DataProviderInterface::class;
201
        }
202
203 10
        if ($type === 'DataProviderInterface[]') {
204 10
            $type = '\\' . DataProviderInterface::class . '[]';
205
        }
206
207 10
        if (strpos($type, '[]') !== false) {
208 10
            $type = str_replace('[]', '', $type);
209
        }
210
211 10
        return $type;
212
    }
213
}