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