PluginProbe ʕ •ᴥ•ʔ
WP All Export – Drag & Drop Export to Any Custom CSV, XML & Excel / 1.2.10
WP All Export – Drag & Drop Export to Any Custom CSV, XML & Excel v1.2.10
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 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.10 1.4.11 1.4.12 1.4.13 1.4.14 1.4.15 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0
wp-all-export / classes / XMLWriter.php
wp-all-export / classes Last commit date
CdataStrategy.php 4 years ago CdataStrategyAlways.php 4 years ago CdataStrategyFactory.php 4 years ago CdataStrategyIllegalCharacters.php 4 years ago CdataStrategyIllegalCharactersHtmlEntities.php 4 years ago CdataStrategyNever.php 4 years ago XMLWriter.php 4 years ago chunk.php 4 years ago config.php 4 years ago download.php 4 years ago handler.php 4 years ago helper.php 4 years ago input.php 4 years ago installer.php 4 years ago session.php 4 years ago wpallimport.php 4 years ago zip.php 4 years ago
XMLWriter.php
420 lines
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 preg_match_all("%(\{[^\}\{]*\})%", $node_tpl, $matches);
154 $xpaths = array_unique($matches[0]);
155
156 if (!empty($xpaths)) {
157 foreach ($xpaths as $xpath) {
158 if (!in_array(preg_replace("%[\{\}]%", "", $xpath), $founded_values)) {
159 $node_tpl = str_replace($xpath, "", $node_tpl);
160 }
161 }
162 }
163
164 foreach ($article as $key => $value) {
165 switch ($key) {
166 case 'id':
167 $node_tpl = str_replace('{'.$key.'}', '{' . $value . '}', $node_tpl);
168 break;
169 default:
170 // replace [ and ]
171 $v = str_replace(']', 'CLOSEBRAKET', str_replace('[', 'OPENBRAKET', $value));
172 // replace { and }
173 $v = str_replace('}', 'CLOSECURVE', str_replace('{', 'OPENCURVE', $v));
174 // replace ( and )
175 $v = str_replace(')', 'CLOSECIRCLE', str_replace('(', 'OPENCIRCLE', $v));
176
177 $originalValue = $v;
178
179 if (is_array($v)) {
180 foreach($v as &$val) {
181 $val = str_replace("\"","**DOUBLEQUOT**",$val);
182 $val = str_replace("'","**SINGLEQUOT**",$val);
183 }
184
185 $delimiter = uniqid();
186 $node_tpl = preg_replace('%\[(.*)\{'.$key.'\}([^\[]*)\]%', "[$1explode('" . $delimiter . "', '" . implode($delimiter, $v) . "')$2]", $node_tpl);
187 $v = "[explode('" . $delimiter . "', '" . implode($delimiter, $v) . "')]";
188 $v = str_replace('<','**LT**', $v);
189 $v = str_replace('>','**GT**', $v);
190 } else {
191 $v = '{' . $v . '}';
192 }
193
194 $arrayTypes = array(
195 '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'
196 );
197
198 // We have an empty array, which is transformed into {}
199 if(in_array($key, $arrayTypes) && $v == "{}") {
200 $delimiter = uniqid();
201 $node_tpl = preg_replace('%\[(.*)\{'.$key.'\}([^\[]*)\]%', "[$1explode('" . $delimiter . "', '" . implode($delimiter, array()) . "')$2]", $node_tpl);
202 $v = "[explode('" . $delimiter . "', '" . implode($delimiter, array()) . "')]";
203 }
204
205 // We have an array with just one value (Which is transformed into a string)
206 if(in_array($key, $arrayTypes) && count($originalValue) == 1) {
207 $delimiter = uniqid();
208 $node_tpl = preg_replace('%\[(.*)\{'.$key.'\}([^\[]*)\]%', "[$1explode('" . $delimiter . "', '" . implode($delimiter, array($originalValue)) . "')$2]", $node_tpl);
209 $v = "[explode('" . $delimiter . "', '" . implode($delimiter, array($originalValue)) . "')]";
210 }
211
212 $node_tpl = str_replace('{' . $key . '}', $v, $node_tpl);
213
214 break;
215 }
216 }
217
218 $xml .= $node_tpl;
219
220 }
221
222 $this->articles = array();
223 $wpaeString = new WpaeString();
224 $xmlPrepreocesor = new WpaeXmlProcessor($wpaeString);
225 return $xmlPrepreocesor->process($xml);
226 }
227
228 public static function getIndentationCount($content, $str)
229 {
230 $lines = explode("\r", $content);
231 foreach ($lines as $lineNumber => $line) {
232 if (strpos($line, $str) !== false) {
233 return substr_count($line, "\t");
234 }
235 }
236
237 return -1;
238 }
239
240 public static function indentTag($tag, $indentationCount, $index)
241 {
242 if($index == 0) {
243 $indentationString = "";
244 } else {
245 $indentationString = str_repeat("\t", $indentationCount);
246 }
247
248 return $indentationString . $tag;
249 }
250
251 /**
252 * @param string $xml
253 * @return mixed|string
254 *
255 * @throws WpaeInvalidStringException
256 * @throws WpaeMethodNotFoundException
257 */
258 public static function preprocess_xml($xml = '')
259 {
260 $xml = str_replace('<![CDATA[', 'DOMCdataSection', $xml);
261
262 preg_match_all("%(\[[^\]\[]*\])%", $xml, $matches);
263 $snipets = empty($matches) ? array() : array_unique($matches[0]);
264 $simple_snipets = array();
265 preg_match_all("%(\{[^\}\{]*\})%", $xml, $matches);
266 $xpaths = array_unique($matches[0]);
267
268 if (!empty($xpaths)) {
269 foreach ($xpaths as $xpath) {
270 if (!in_array($xpath, $snipets)) $simple_snipets[] = $xpath;
271 }
272 }
273
274 if (!empty($snipets)) {
275 foreach ($snipets as $snipet) {
276 // if function is found
277 if (preg_match("%\w+\(.*\)%", $snipet)) {
278
279 $filtered = trim(trim(trim($snipet, "]"), "["));
280 $filtered = preg_replace("%[\{\}]%", "\"", $filtered);
281 $filtered = str_replace('CLOSEBRAKET', ']', str_replace('OPENBRAKET', '[', $filtered));
282 $filtered = str_replace('CLOSECURVE', '}', str_replace('OPENCURVE', '{', $filtered));
283 $filtered = str_replace('CLOSECIRCLE', ')', str_replace('OPENCIRCLE', '(', $filtered));
284
285 $functionName = self::sanitizeFunctionName($filtered);
286
287 $numberOfSingleQuotes = substr_count($filtered, "'");
288 $numberOfDoubleQuotes = substr_count($filtered, "\"");
289
290 if ($numberOfSingleQuotes % 2 || $numberOfDoubleQuotes % 2) {
291 throw new WpaeInvalidStringException($functionName);
292 }
293
294 if (!function_exists($functionName)) {
295 throw new WpaeMethodNotFoundException($functionName);
296 }
297
298 $values = eval("return " . $filtered . ";");
299
300 $v = '';
301 if (is_array($values)) {
302 $tag = false;
303
304 preg_match_all("%(<[\w]+[\s|>]{1})" . preg_quote($snipet) . "%", $xml, $matches);
305
306 if (!empty($matches[1])) {
307 $tag = array_shift($matches[1]);
308 }
309 if (empty($tag)) $tag = "<item>";
310
311 $indentationCount = self::getIndentationCount($xml, $tag);
312
313 $i = 0;
314 foreach ($values as $number => $value) {
315 $v .= self::indentTag($tag . self::maybe_cdata($value) . str_replace("<", "</", $tag) . "\n", $indentationCount, $i);
316 $i++;
317 }
318
319 $xml = str_replace($tag . $snipet . str_replace("<", "</", $tag), $v, $xml);
320 } else {
321 $xml = str_replace($snipet, self::maybe_cdata($values), $xml);
322 }
323 }
324 }
325 }
326
327 if (!empty($simple_snipets)) {
328 foreach ($simple_snipets as $snipet) {
329 $filtered = preg_replace("%[\{\}]%", "", $snipet);
330
331 $is_attribute = false;
332
333 //Encode data in attributes
334 if (strpos($xml, "\"$snipet\"") !== false || strpos($xml, "'$snipet'") !== false) {
335 $is_attribute = true;
336 $filtered = str_replace('&amp;', '&', $filtered);
337 $filtered = str_replace('&', '&amp;', $filtered);
338 $filtered = str_replace('\'', '&#x27;', $filtered);
339 $filtered = str_replace('"', '&quot;', $filtered);
340 $filtered = str_replace('<', '&lt;', $filtered);
341 $filtered = str_replace('>', '&gt;', $filtered);
342 }
343
344 $filtered = str_replace('CLOSEBRAKET', ']', str_replace('OPENBRAKET', '[', $filtered));
345 $filtered = str_replace('CLOSECURVE', '}', str_replace('OPENCURVE', '{', $filtered));
346 $filtered = str_replace('CLOSECIRCLE', ')', str_replace('OPENCIRCLE', '(', $filtered));
347
348 if ($is_attribute) {
349 $xml = str_replace($snipet, $filtered, $xml);
350 } else {
351 $xml = str_replace($snipet, self::maybe_cdata($filtered), $xml);
352 }
353 }
354 }
355
356 $xml = str_replace('DOMCdataSection', '<![CDATA[', $xml);
357
358 return $xml;
359 }
360
361 /**
362 * @param $v
363 * @return string
364 */
365 public static function maybe_cdata($v)
366 {
367
368 if (XmlExportEngine::$is_preview) {
369 $v = str_replace('&amp;', '&', $v);
370 $v = htmlspecialchars($v);
371 }
372
373 if (XmlExportEngine::$is_preview && !XmlExportEngine::$exportOptions['show_cdata_in_preview']) {
374 return $v;
375 }
376
377 $cdataStrategyFactory = new CdataStrategyFactory();
378
379 if (!isset(XmlExportEngine::$exportOptions['custom_xml_cdata_logic'])) {
380 XmlExportEngine::$exportOptions['custom_xml_cdata_logic'] = 'auto';
381 }
382
383 $cdataStrategy = $cdataStrategyFactory->create_strategy(XmlExportEngine::$exportOptions['custom_xml_cdata_logic']);
384 $is_wrap_into_cdata = $cdataStrategy->should_cdata_be_applied($v);
385
386 if ($is_wrap_into_cdata === false) {
387 return $v;
388 } else {
389 if (XmlExportEngine::$is_preview && XmlExportEngine::$exportOptions['show_cdata_in_preview']) {
390 return 'CDATABEGIN' . $v . 'CDATACLOSE';
391 } else {
392 return "<![CDATA[" . $v . "]]>";
393 }
394 }
395 }
396
397 /**
398 * @param $filtered
399 * @return mixed
400 */
401 private static function sanitizeFunctionName($filtered)
402 {
403 $functionName = preg_replace('/"[^"]+"/', '', $filtered);
404 $functionName = preg_replace('/\'[^\']+\'/', '', $functionName);
405
406 $firstSingleQuote = strpos($functionName, '\'');
407 $firstDoubleQuote = strpos($functionName, '"');
408
409 if ($firstDoubleQuote < $firstSingleQuote && $firstDoubleQuote != 0) {
410 $functionName = explode('"', $functionName);
411 $functionName = $functionName[0];
412 } else if ($firstSingleQuote != 0) {
413 $functionName = explode('\'', $functionName);
414 $functionName = $functionName[0];
415 }
416 $functionName = str_replace(array('(', ')', ',', ' ', '\'', '"'), '', $functionName);
417
418 return $functionName;
419 }
420 }