PluginProbe
WP All Export – Drag & Drop Export to Any Custom CSV, XML & Excel / 1.1.2
WP All Export – Drag & Drop Export to Any Custom CSV, XML & Excel v1.1.2
trunk 0.9.0 0.9.1 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.2.0 1.2.1 1.2.10 1.2.2 1.2.3 1.2.4 All 57 releases
wp-all-export / classes / XMLWriter.php

XMLWriter.php in WP All Export – Drag & Drop Export to Any Custom CSV, XML & Excel 1.1.2, at classes/XMLWriter.php

412 lines 14.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 // Handle eval errors that cause the script to finish
4 $wpaeErrorHandler = new WpaePhpInterpreterErrorHandler();
5 register_shutdown_function(array($wpaeErrorHandler, 'handle'));
6
7 /**
8 * Class PMXE_XMLWriter
9 */
10 class PMXE_XMLWriter extends XMLWriter
11 {
12 /**
13 * @var array
14 */
15 public $articles = array();
16
17
18 /**
19 * @param array $articles
20 */
21 public function writeArticle($articles = array())
22 {
23
24 $article = array_shift($articles);
25
26 if (!empty($articles)) {
27
28 $keys = array();
29 foreach ($articles as $a) {
30
31 foreach ($a as $key => $value) {
32
33 if (!isset($article[$key])) {
34 $article[$key] = array($value);
35 } else {
36 if (is_array($article[$key])){
37 array_push($article[$key], $value);
38 }
39 else{
40 $article[$key] = array($article[$key], $value);
41 }
42 }
43
44 if (!in_array($key, $keys)) $keys[] = $key;
45 }
46 }
47 }
48
49 if (!empty($article)) {
50 foreach ($article as $key => $value) {
51 if (!is_array($value) && strpos($value, '#delimiter#') !== FALSE) {
52 $article[$key] = explode('#delimiter#', $value);
53 }
54 }
55 }
56
57 $this->articles[] = $article;
58 }
59
60 /**
61 * @param $ns
62 * @param $element
63 * @param $uri
64 * @param $value
65 * @return bool
66 */
67 public function putElement($ns, $element, $uri, $value)
68 {
69 if (in_array(XmlExportEngine::$exportOptions['xml_template_type'], array('custom', 'XmlGoogleMerchants'))) return true;
70
71 if (empty($ns)) {
72 return $this->writeElement($element, $value);
73 } else {
74 return $this->writeElementNS($ns, $element, $uri, $value);
75 }
76 }
77
78 /**
79 * @param $ns
80 * @param $element
81 * @param $uri
82 * @return bool
83 */
84 public function beginElement($ns, $element, $uri)
85 {
86 if (in_array(XmlExportEngine::$exportOptions['xml_template_type'], array('custom', 'XmlGoogleMerchants'))) return true;
87
88 if (empty($ns)) {
89 return $this->startElement($element);
90 } else {
91 return $this->startElementNS($ns, $element, $uri);
92 }
93 }
94
95 /**
96 * @return bool
97 */
98 public function closeElement()
99 {
100
101 if (in_array(XmlExportEngine::$exportOptions['xml_template_type'], array('custom', 'XmlGoogleMerchants'))) return true;
102
103 return $this->endElement();
104 }
105
106 /**
107 * @param $value
108 * @param $element_name
109 *
110 * @return bool
111 */
112 public function writeData($value, $element_name)
113 {
114 if (in_array(XmlExportEngine::$exportOptions['xml_template_type'], array('custom', 'XmlGoogleMerchants'))) return true;
115
116 $cdataStrategyFactory = new CdataStrategyFactory();
117
118 if (!isset(XmlExportEngine::$exportOptions['custom_xml_cdata_logic'])) {
119 XmlExportEngine::$exportOptions['custom_xml_cdata_logic'] = 'auto';
120 }
121 $cdataStrategy = $cdataStrategyFactory->create_strategy(XmlExportEngine::$exportOptions['custom_xml_cdata_logic']);
122 $is_wrap_into_cdata = $cdataStrategy->should_cdata_be_applied($value);
123
124 $wrap_value_into_cdata = apply_filters('wp_all_export_is_wrap_value_into_cdata', $is_wrap_into_cdata, $value, $element_name);
125
126 if ($wrap_value_into_cdata === false) {
127 $this->writeRaw($value);
128 } else {
129 if (XmlExportEngine::$is_preview && XmlExportEngine::$exportOptions['show_cdata_in_preview']) {
130 $this->text('CDATABEGIN' . $value . 'CDATACLOSE');
131 } else if (XmlExportEngine::$is_preview && !XmlExportEngine::$exportOptions['show_cdata_in_preview']) {
132 return $this->text($value);
133 } else {
134 $this->writeCdata($value);
135 }
136 }
137 }
138
139 /**
140 * @return mixed|string
141 */
142 public function wpae_flush()
143 {
144 if (!in_array(XmlExportEngine::$exportOptions['xml_template_type'], array('custom', 'XmlGoogleMerchants'))) return $this->flush(true);
145
146 $xml = '';
147 foreach ($this->articles as $article) {
148
149 $founded_values = array_keys($article);
150 $node_tpl = XmlExportEngine::$exportOptions['custom_xml_template_loop'];
151
152 // clean up XPaths for not found values
153 $node_tpl = str_replace('{ID}', '{id}', $node_tpl);
154 preg_match_all("%(\{[^\}\{]*\})%", $node_tpl, $matches);
155 $xpaths = array_unique($matches[0]);
156
157 if (!empty($xpaths)) {
158 foreach ($xpaths as $xpath) {
159 if (!in_array(preg_replace("%[\{\}]%", "", $xpath), $founded_values)) {
160 $node_tpl = str_replace($xpath, "", $node_tpl);
161 }
162 }
163 }
164
165 foreach ($article as $key => $value) {
166 switch ($key) {
167 case 'id':
168 $node_tpl = str_replace('{id}', '{' . $value . '}', $node_tpl);
169 break;
170 default:
171 // replace [ and ]
172 $v = str_replace(']', 'CLOSEBRAKET', str_replace('[', 'OPENBRAKET', $value));
173 // replace { and }
174 $v = str_replace('}', 'CLOSECURVE', str_replace('{', 'OPENCURVE', $v));
175 // replace ( and )
176 $v = str_replace(')', 'CLOSECIRCLE', str_replace('(', 'OPENCIRCLE', $v));
177
178 $originalValue = $v;
179
180 if (is_array($v)) {
181 $delimiter = uniqid();
182 $v = "[explode('" . $delimiter . "', '" . implode($delimiter, $v) . "')]";
183 } else {
184 $v = '{' . $v . '}';
185 }
186
187 $arrayTypes = array(
188 'Product Tags', 'Tags', 'Product Categories', 'Categories', 'Image URL', 'Image Filename', 'Image Path', 'Image ID', 'Image Title', 'Image Caption', 'Image Description', 'Image Alt Text', 'Product Type', 'Categories'
189 );
190
191 // We have an empty array, which is transformed into {}
192 if(in_array($key, $arrayTypes) && $v == "{}") {
193 $delimiter = uniqid();
194 $v = "[explode('" . $delimiter . "', '" . implode($delimiter, array()) . "')]";
195 }
196
197 // We have an array with just one value (Which is transformed into a string)
198 if(in_array($key, $arrayTypes) && count($originalValue) == 1) {
199 $delimiter = uniqid();
200 $v = "[explode('" . $delimiter . "', '" . implode($delimiter, array($originalValue)) . "')]";
201 }
202
203 $node_tpl = str_replace('{' . $key . '}', $v, $node_tpl);
204
205 break;
206 }
207 }
208
209 $xml .= $node_tpl;
210
211 }
212
213 $this->articles = array();
214
215 $wpaeString = new WpaeString();
216 $xmlPrepreocesor = new WpaeXmlProcessor($wpaeString);
217 return $xmlPrepreocesor->process($xml);
218 }
219
220 public static function getIndentationCount($content, $str)
221 {
222 $lines = explode("\r", $content);
223 foreach ($lines as $lineNumber => $line) {
224 if (strpos($line, $str) !== false) {
225 return substr_count($line, "\t");
226 }
227 }
228
229 return -1;
230 }
231
232 public static function indentTag($tag, $indentationCount, $index)
233 {
234 if($index == 0) {
235 $indentationString = "";
236 } else {
237 $indentationString = str_repeat("\t", $indentationCount);
238 }
239
240 return $indentationString . $tag;
241 }
242
243 /**
244 * @param string $xml
245 * @return mixed|string
246 *
247 * @throws WpaeInvalidStringException
248 * @throws WpaeMethodNotFoundException
249 */
250 public static function preprocess_xml($xml = '')
251 {
252 $xml = str_replace('<![CDATA[', 'DOMCdataSection', $xml);
253
254 preg_match_all("%(\[[^\]\[]*\])%", $xml, $matches);
255 $snipets = empty($matches) ? array() : array_unique($matches[0]);
256 $simple_snipets = array();
257 preg_match_all("%(\{[^\}\{]*\})%", $xml, $matches);
258 $xpaths = array_unique($matches[0]);
259
260 if (!empty($xpaths)) {
261 foreach ($xpaths as $xpath) {
262 if (!in_array($xpath, $snipets)) $simple_snipets[] = $xpath;
263 }
264 }
265
266 if (!empty($snipets)) {
267 foreach ($snipets as $snipet) {
268 // if function is found
269 if (preg_match("%\w+\(.*\)%", $snipet)) {
270
271 $filtered = trim(trim(trim($snipet, "]"), "["));
272 $filtered = preg_replace("%[\{\}]%", "\"", $filtered);
273 $filtered = str_replace('CLOSEBRAKET', ']', str_replace('OPENBRAKET', '[', $filtered));
274 $filtered = str_replace('CLOSECURVE', '}', str_replace('OPENCURVE', '{', $filtered));
275 $filtered = str_replace('CLOSECIRCLE', ')', str_replace('OPENCIRCLE', '(', $filtered));
276
277 $functionName = self::sanitizeFunctionName($filtered);
278
279 $numberOfSingleQuotes = substr_count($filtered, "'");
280 $numberOfDoubleQuotes = substr_count($filtered, "\"");
281
282 if ($numberOfSingleQuotes % 2 || $numberOfDoubleQuotes % 2) {
283 throw new WpaeInvalidStringException($functionName);
284 }
285
286 if (!function_exists($functionName)) {
287 throw new WpaeMethodNotFoundException($functionName);
288 }
289
290 $values = eval("return " . $filtered . ";");
291
292 $v = '';
293 if (is_array($values)) {
294 $tag = false;
295
296 preg_match_all("%(<[\w]+[\s|>]{1})" . preg_quote($snipet) . "%", $xml, $matches);
297
298 if (!empty($matches[1])) {
299 $tag = array_shift($matches[1]);
300 }
301 if (empty($tag)) $tag = "<item>";
302
303 $indentationCount = self::getIndentationCount($xml, $tag);
304
305 $i = 0;
306 foreach ($values as $number => $value) {
307 $v .= self::indentTag($tag . self::maybe_cdata($value) . str_replace("<", "</", $tag) . "\n", $indentationCount, $i);
308 $i++;
309 }
310
311 $xml = str_replace($tag . $snipet . str_replace("<", "</", $tag), $v, $xml);
312 } else {
313 $xml = str_replace($snipet, self::maybe_cdata($values), $xml);
314 }
315 }
316 }
317 }
318
319 if (!empty($simple_snipets)) {
320 foreach ($simple_snipets as $snipet) {
321 $filtered = preg_replace("%[\{\}]%", "", $snipet);
322
323 $is_attribute = false;
324
325 //Encode data in attributes
326 if (strpos($xml, "\"$snipet\"") !== false || strpos($xml, "'$snipet'") !== false) {
327 $is_attribute = true;
328 $filtered = str_replace('&amp;', '&', $filtered);
329 $filtered = str_replace('&', '&amp;', $filtered);
330 $filtered = str_replace('\'', '&#x27;', $filtered);
331 $filtered = str_replace('"', '&quot;', $filtered);
332 $filtered = str_replace('<', '&lt;', $filtered);
333 $filtered = str_replace('>', '&gt;', $filtered);
334 }
335
336 $filtered = str_replace('CLOSEBRAKET', ']', str_replace('OPENBRAKET', '[', $filtered));
337 $filtered = str_replace('CLOSECURVE', '}', str_replace('OPENCURVE', '{', $filtered));
338 $filtered = str_replace('CLOSECIRCLE', ')', str_replace('OPENCIRCLE', '(', $filtered));
339
340 if ($is_attribute) {
341 $xml = str_replace($snipet, $filtered, $xml);
342 } else {
343 $xml = str_replace($snipet, self::maybe_cdata($filtered), $xml);
344 }
345 }
346 }
347
348 $xml = str_replace('DOMCdataSection', '<![CDATA[', $xml);
349
350 return $xml;
351 }
352
353 /**
354 * @param $v
355 * @return string
356 */
357 public static function maybe_cdata($v)
358 {
359
360 if (XmlExportEngine::$is_preview) {
361 $v = str_replace('&amp;', '&', $v);
362 $v = htmlspecialchars($v);
363 }
364
365 if (XmlExportEngine::$is_preview && !XmlExportEngine::$exportOptions['show_cdata_in_preview']) {
366 return $v;
367 }
368
369 $cdataStrategyFactory = new CdataStrategyFactory();
370
371 if (!isset(XmlExportEngine::$exportOptions['custom_xml_cdata_logic'])) {
372 XmlExportEngine::$exportOptions['custom_xml_cdata_logic'] = 'auto';
373 }
374
375 $cdataStrategy = $cdataStrategyFactory->create_strategy(XmlExportEngine::$exportOptions['custom_xml_cdata_logic']);
376 $is_wrap_into_cdata = $cdataStrategy->should_cdata_be_applied($v);
377
378 if ($is_wrap_into_cdata === false) {
379 return $v;
380 } else {
381 if (XmlExportEngine::$is_preview && XmlExportEngine::$exportOptions['show_cdata_in_preview']) {
382 return 'CDATABEGIN' . $v . 'CDATACLOSE';
383 } else {
384 return "<![CDATA[" . $v . "]]>";
385 }
386 }
387 }
388
389 /**
390 * @param $filtered
391 * @return mixed
392 */
393 private static function sanitizeFunctionName($filtered)
394 {
395 $functionName = preg_replace('/"[^"]+"/', '', $filtered);
396 $functionName = preg_replace('/\'[^\']+\'/', '', $functionName);
397
398 $firstSingleQuote = strpos($functionName, '\'');
399 $firstDoubleQuote = strpos($functionName, '"');
400
401 if ($firstDoubleQuote < $firstSingleQuote && $firstDoubleQuote != 0) {
402 $functionName = explode('"', $functionName);
403 $functionName = $functionName[0];
404 } else if ($firstSingleQuote != 0) {
405 $functionName = explode('\'', $functionName);
406 $functionName = $functionName[0];
407 }
408 $functionName = str_replace(array('(', ')', ',', ' ', '\'', '"'), '', $functionName);
409
410 return $functionName;
411 }
412 }