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