1
+ <?php
2
+
3
+ namespace darkfriend \helpers ;
4
+
5
+ /**
6
+ * Class Xml
7
+ * @package darkfriend\helpers
8
+ * @author darkfriend <hi@darkfriend.ru>
9
+ * @version 1.0.0
10
+ */
11
+ class Xml
12
+ {
13
+ protected static $ root = '<root/> ' ;
14
+
15
+ /**
16
+ * Convert array to xml
17
+ * @param mixed $data
18
+ * @param array $params = [
19
+ * 'root' => '<root/>',
20
+ * 'exception' => false,
21
+ * ]
22
+ * @return string
23
+ * @throws XmlException
24
+ */
25
+ public static function encode ($ data , $ params = array ())
26
+ {
27
+ \libxml_use_internal_errors (true );
28
+
29
+ if (empty ($ params ['root ' ])) {
30
+ $ params ['root ' ] = self ::$ root ;
31
+ }
32
+
33
+ $ xml = new SimpleXMLElement ($ params ['root ' ]);
34
+ $ xml = self ::generateXml ($ xml , $ data );
35
+
36
+ if (!static ::checkException ($ params )) {
37
+ return '' ;
38
+ }
39
+
40
+ return $ xml ->asXML ();
41
+ }
42
+
43
+ /**
44
+ * @param SimpleXMLElement $xml
45
+ * @param mixed $data
46
+ * @return SimpleXMLElement
47
+ */
48
+ public static function generateXml ($ xml , $ data )
49
+ {
50
+ /** @var $xml SimpleXMLElement */
51
+ if (is_array ($ data )) {
52
+ foreach ($ data as $ key =>$ item ) {
53
+ self ::addChild ($ xml ,$ key ,$ item );
54
+ }
55
+ } else {
56
+ self ::addChild ($ xml ,$ data );
57
+ }
58
+ return $ xml ;
59
+ }
60
+
61
+ /**
62
+ * Add child
63
+ * @param SimpleXMLElement $xml
64
+ * @param string $name
65
+ * @param array|string $params
66
+ * @return SimpleXMLElement
67
+ */
68
+ public static function addChild ($ xml , $ name , $ params = '' )
69
+ {
70
+ if (is_array ($ params )) {
71
+ $ value = null ;
72
+ if (key_exists ('@value ' ,$ params )) {
73
+ $ value = $ params ['@value ' ];
74
+ unset($ params ['@value ' ]);
75
+ }
76
+
77
+ $ namespace = null ;
78
+ if (key_exists ('@namespace ' ,$ params )) {
79
+ $ namespace = $ params ['@namespace ' ];
80
+ unset($ params ['@namespace ' ]);
81
+ }
82
+
83
+ $ child = $ xml ->addChild ($ name ,$ value , $ namespace );
84
+
85
+ if (key_exists ('@attributes ' ,$ params )) {
86
+ foreach ($ params ['@attributes ' ] as $ keyAttr =>$ attr ) {
87
+ $ child ->addAttribute ($ keyAttr , $ attr );
88
+ }
89
+ unset($ params ['@attributes ' ]);
90
+ }
91
+
92
+ if (key_exists ('@cdata ' ,$ params )) {
93
+ $ child ->addCData ($ params ['@cdata ' ]);
94
+ unset($ params ['@cdata ' ]);
95
+ }
96
+
97
+ foreach ($ params as $ key => $ item ) {
98
+ if (is_array ($ item )) {
99
+ self ::addChild ($ child ,$ key ,$ item );
100
+ } else {
101
+ $ child ->addChild ($ key ,$ item );
102
+ }
103
+ }
104
+ } else {
105
+ $ child = $ xml ->addChild ($ name , $ params );
106
+ }
107
+
108
+ return $ child ;
109
+ }
110
+
111
+ /**
112
+ * Decode XML string
113
+ * @param string $data
114
+ * @param array $params = [
115
+ * 'convert' => true,
116
+ * 'exception' => false,
117
+ * ]
118
+ * @return \darkfriend\helpers\SimpleXMLElement|array
119
+ * @throws XmlException
120
+ */
121
+ public static function decode ($ data , $ params = array ())
122
+ {
123
+ \libxml_use_internal_errors (true );
124
+
125
+ $ xml = \simplexml_load_string (
126
+ $ data ,
127
+ '\darkfriend\helpers\SimpleXMLElement ' ,
128
+ \LIBXML_NOCDATA
129
+ );
130
+
131
+ if (!static ::checkException ($ params )) {
132
+ return array ();
133
+ }
134
+
135
+ if (!isset ($ params ['convert ' ])) {
136
+ $ params ['convert ' ] = true ;
137
+ }
138
+
139
+ if ($ params ['convert ' ]) {
140
+ return self ::convertSimpleXml ($ xml );
141
+ } else {
142
+ return $ xml ;
143
+ }
144
+ }
145
+
146
+ /**
147
+ * Convert tree SimpleXMLElement
148
+ * @param SimpleXMLElement $xml
149
+ * @return array
150
+ */
151
+ public static function convertSimpleXml ($ xml )
152
+ {
153
+ $ res = array ();
154
+ /** @var SimpleXMLElement $item */
155
+ foreach ($ xml as $ key =>$ item ) {
156
+ if ($ item ->count ()>0 ) {
157
+ $ res [$ key ] = self ::convertSimpleXml ($ item );
158
+ } else {
159
+ $ res [$ key ] = self ::convertSimpleXmlItem ($ item );
160
+ }
161
+ }
162
+ return $ res ;
163
+ }
164
+
165
+ /**
166
+ * Convert item SimpleXMLElement
167
+ * @param SimpleXMLElement $item
168
+ * @return array|string
169
+ */
170
+ public static function convertSimpleXmlItem ($ item )
171
+ {
172
+ /** @var SimpleXMLElement $item */
173
+ $ attr = $ item ->attributes ();
174
+ if (!empty ($ attr )) {
175
+ $ element = (array ) $ attr ;
176
+ $ element ['@value ' ] = (string ) $ item ;
177
+ } else {
178
+ $ element = (string ) $ item ;
179
+ }
180
+ return $ element ;
181
+ }
182
+
183
+ /**
184
+ * Check error
185
+ * @param array $params = [
186
+ * 'exception' => true,
187
+ * ]
188
+ * @return bool if $params['exception'] === false
189
+ * @throws XmlException if $params['exception'] === true
190
+ */
191
+ public static function checkException ($ params = array ())
192
+ {
193
+ $ e = \libxml_get_errors ();
194
+
195
+ if (!$ e ) {
196
+ return true ;
197
+ }
198
+
199
+ $ strError = '' ;
200
+ foreach ($ e as $ key => $ xmlError ) {
201
+ $ strError .= "$ key: " .$ xmlError ->message . "\n" ;
202
+ }
203
+
204
+ if ($ params ['exception ' ]) {
205
+ throw new XmlException ("XML error: $ strError " , 100 , __FILE__ , __LINE__ );
206
+ }
207
+
208
+ return true ;
209
+ }
210
+
211
+ /**
212
+ * Set root element
213
+ * @param string $root
214
+ */
215
+ public static function setRootElement ($ root = '<root/> ' )
216
+ {
217
+ self ::$ root = $ root ;
218
+ }
219
+
220
+ /**
221
+ * Get root element
222
+ * @return string
223
+ */
224
+ public static function getRootElement ()
225
+ {
226
+ return self ::$ root ;
227
+ }
228
+ }
0 commit comments