Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 54 |
|
0.00% |
0 / 5 |
CRAP | |
0.00% |
0 / 1 |
ArrayToXML | |
0.00% |
0 / 54 |
|
0.00% |
0 / 5 |
462 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
buildXML | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
6 | |||
writeAttr | |
0.00% |
0 / 22 |
|
0.00% |
0 / 1 |
110 | |||
writeEl | |
0.00% |
0 / 17 |
|
0.00% |
0 / 1 |
56 | |||
isAssoc | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace App\Http\Services; |
4 | |
5 | use XmlWriter; |
6 | |
7 | class ArrayToXML |
8 | { |
9 | private $version; |
10 | |
11 | private $encoding; |
12 | |
13 | /** |
14 | * Construct ArrayToXML object with selected version and encoding |
15 | * |
16 | * @param string $xmlVersion XML Version, default 1.0 |
17 | * @param string $xmlEncoding XML Encoding, default UTF-8 |
18 | */ |
19 | public function __construct(string $xmlVersion = '1.0', string $xmlEncoding = 'UTF-8') |
20 | { |
21 | $this->version = $xmlVersion; |
22 | $this->encoding = $xmlEncoding; |
23 | } |
24 | |
25 | /** |
26 | * Build an XML Data Set |
27 | * |
28 | * @param array $data Associative Array containing values to be parsed into an XML Data Set(s) |
29 | * @param string $startElement Root Opening Tag, default data |
30 | * @return string XML String containing values |
31 | * @return mixed Boolean false on failure, string XML result on success |
32 | */ |
33 | public function buildXML(array $data, string $startElement = 'InstancyWrapper'): string |
34 | { |
35 | if (! is_array($data)) { |
36 | $err = 'Invalid variable type supplied, expected array not found on line '.__LINE__.' in Class: '.__CLASS__.' Method: '.__METHOD__; |
37 | trigger_error($err); |
38 | |
39 | return false; //return false error occurred |
40 | } |
41 | $xml = new XmlWriter(); |
42 | $xml->openMemory(); |
43 | $xml->startDocument($this->version, $this->encoding); |
44 | $xml->startElement($startElement); |
45 | |
46 | $data = $this->writeAttr($xml, $data); |
47 | $this->writeEl($xml, $data); |
48 | |
49 | $xml->endElement(); //write end element |
50 | //returns the XML results |
51 | return $xml->outputMemory(true); |
52 | } |
53 | |
54 | /** |
55 | * Write keys in $data prefixed with @ as XML attributes, if $data is an array. |
56 | * When an @ prefixed key is found, a '%' key is expected to indicate the element itself, |
57 | * and '#' prefixed key indicates CDATA content |
58 | * |
59 | * @param XMLWriter $xml object |
60 | * @param array $data with attributes filtered out |
61 | * @return array $data | $nonAttributes |
62 | */ |
63 | protected function writeAttr(XMLWriter $xml, array $data): array |
64 | { |
65 | if (is_array($data)) { |
66 | $nonAttributes = []; |
67 | foreach ($data as $key => $val) { |
68 | //handle an attribute with elements |
69 | if ($key[0] == '@') { |
70 | $xml->writeAttribute(substr($key, 1), $val); |
71 | } elseif ($key[0] == '%') { |
72 | if (is_array($val)) { |
73 | $nonAttributes = $val; |
74 | } else { |
75 | $xml->text($val); |
76 | } |
77 | } elseif ($key[0] == '#') { |
78 | if (is_array($val)) { |
79 | $nonAttributes = $val; |
80 | } else { |
81 | $xml->startElement(substr($key, 1)); |
82 | $xml->writeCData($val); |
83 | $xml->endElement(); |
84 | } |
85 | } elseif ($key[0] == '!') { |
86 | if (is_array($val)) { |
87 | $nonAttributes = $val; |
88 | } else { |
89 | $xml->writeCData($val); |
90 | } |
91 | } |
92 | //ignore normal elements |
93 | else { |
94 | $nonAttributes[$key] = $val; |
95 | } |
96 | } |
97 | |
98 | return $nonAttributes; |
99 | } else { |
100 | return $data; |
101 | } |
102 | } |
103 | |
104 | /** |
105 | * Write XML as per Associative Array |
106 | * |
107 | * @param XMLWriter $xml object |
108 | * @param array $data Associative Data Array |
109 | */ |
110 | protected function writeEl(XMLWriter $xml, array $data) |
111 | { |
112 | foreach ($data as $key => $value) { |
113 | if (is_array($value) && ! $this->isAssoc($value)) { //numeric array |
114 | foreach ($value as $itemValue) { |
115 | if (is_array($itemValue)) { |
116 | $xml->startElement($key); |
117 | $itemValue = $this->writeAttr($xml, $itemValue); |
118 | $this->writeEl($xml, $itemValue); |
119 | $xml->endElement(); |
120 | } else { |
121 | $itemValue = $this->writeAttr($xml, $itemValue); |
122 | $xml->writeElement($key, "$itemValue"); |
123 | } |
124 | } |
125 | } elseif (is_array($value)) { //associative array |
126 | $xml->startElement($key); |
127 | $value = $this->writeAttr($xml, $value); |
128 | $this->writeEl($xml, $value); |
129 | $xml->endElement(); |
130 | } else { //scalar |
131 | $value = $this->writeAttr($xml, $value); |
132 | $xml->writeElement($key, "$value"); |
133 | } |
134 | } |
135 | } |
136 | |
137 | /** |
138 | * Check if array is associative with string based keys |
139 | * |
140 | * @param array $array Array to check |
141 | */ |
142 | protected function isAssoc(array $array): bool |
143 | { |
144 | return (bool) count(array_filter(array_keys($array), 'is_string')); |
145 | } |
146 | } |