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 / libraries / WpaeXmlProcessor.php
wp-all-export / libraries Last commit date
VariableProductTitle 8 years ago .gitkeep 8 years ago WpaeInvalidPhpException.php 8 years ago WpaeInvalidStringException.php 8 years ago WpaeMethodNotFoundException.php 8 years ago WpaePhpInterpreterErrorHandler.php 8 years ago WpaeString.php 8 years ago WpaeTooMuchRecursionException.php 8 years ago WpaeXmlProcessor.php 8 years ago XmlCsvExport.php 8 years ago XmlExportACF.php 8 years ago XmlExportComment.php 8 years ago XmlExportCpt.php 8 years ago XmlExportEngine.php 8 years ago XmlExportFiltering.php 8 years ago XmlExportMediaGallery.php 8 years ago XmlExportTaxonomy.php 8 years ago XmlExportUser.php 8 years ago XmlExportWooCommerce.php 8 years ago XmlExportWooCommerceCoupon.php 8 years ago XmlExportWooCommerceOrder.php 8 years ago XmlGoogleMerchants.php 8 years ago XmlSpec.php 8 years ago
WpaeXmlProcessor.php
674 lines
1 <?php
2
3 class WpaeXmlProcessor
4 {
5 const SNIPPET_DELIMITER = '*SNIPPET*';
6
7 /** @var array */
8 protected $tags;
9
10 /** @var string */
11 protected $xml;
12
13 /** @var DOMDocument */
14 private $dom;
15
16 private $step = 0;
17
18 /** @var WpaeString */
19 private $wpaeString;
20
21 public function __construct(WpaeString $wpaeString)
22 {
23 add_filter('wp_all_export_post_process_xml', array($this, 'wp_all_export_post_process_xml'), 10, 1);
24
25 $this->wpaeString = $wpaeString;
26 }
27
28 public function process($xml)
29 {
30 $this->step = 0;
31
32 $xml = $this->preprocessXml($xml);
33 $xml = $this->handleSimpleSnippets($xml);
34
35 // Add a snippet to trigger a process
36 $snippetCount = count($this->parseSnippetsInString($xml));
37 if($snippetCount == 0 ) {
38 $xml .="<filler>[str_replace('a','b','c')]</filler>";
39 }
40
41 // While we have snippets
42 if ($snippetCount = count($this->parseSnippetsInString($xml))) {
43
44 // $this->step++;
45 $xml = '<root>' . $xml . '</root>';
46 $this->initVariables($xml);
47 $root = $this->dom->getElementsByTagName("root");
48 $this->parseElement($root->item(0));
49 $response = $this->dom->saveXML($this->dom);
50
51 $xml = $this->cleanResponse($response);
52
53 // if ($this->step > 8) {
54 // throw new WpaeTooMuchRecursionException('Too much recursion');
55 // }
56 }
57
58 $xml = $this->postProcessXml($xml);
59 $xml = $this->decodeSpecialCharacters($xml);
60 $xml = $this->encodeSpecialCharsInAttributes($xml);
61
62 $xml = str_replace('**OPENSHORTCODE**', '[', $xml);
63 $xml = str_replace('**CLOSESHORTCODE**', ']', $xml);
64
65 return $this->pretify($xml);
66 }
67
68 /**
69 * @param $xml
70 * @return mixed
71 */
72 public function pretify($xml)
73 {
74 $xml = '<root>' . $xml . '</root>';
75 $this->initVariables($xml);
76 // $root = $this->dom->getElementsByTagName("root");
77 // $this->preprocess_attributes($root->item(0));
78
79 return "\n ".$this->cleanResponse($this->dom->saveXML($this->dom));
80 }
81
82 private function preprocess_attributes(DOMNode $element){
83 if($element->hasAttributes()){
84 for ($i = 0; $i < $element->attributes->length; $i++) {
85 $element->attributes->item($i)->nodeValue = $this->sanitizeAttribute($element->attributes->item($i)->nodeValue);
86 }
87 }
88 if ($element->hasChildNodes()) {
89 for ($i = 0; $i < $element->childNodes->length; $i++) {
90 $this->preprocess_attributes($element->childNodes->item($i));
91 }
92 }
93 }
94
95 private function parseElement(DOMNode $element)
96 {
97 if($element->hasAttributes() && $element->nodeValue == '') {
98
99 if ($element->hasChildNodes()) {
100 $has_text_elements = false;
101 for ($i = 0; $i < $element->childNodes->length; $i++) {
102 if ( $element->childNodes->item($i)->nodeType == XML_TEXT_NODE ){
103 $has_text_elements = true;
104 break;
105 }
106 }
107 if ( ! $has_text_elements ){
108 $nodeAttributes = $this->getNodeAttributes($element);
109 $snippets = $this->parseSnippetsInString($nodeAttributes);
110 if (!empty($snippets)){
111 $tagValues = array();
112 foreach ($snippets as $snippet) {
113 $wholeValue = str_replace("\n", '', $nodeAttributes);
114 $isInFunction = $this->wpaeString->isBetween($wholeValue, $snippet, '[',']');
115 $snippetValue = $this->processSnippet($snippet,$isInFunction);
116 $tagValues[$snippet] = $snippetValue;
117 }
118
119 // Doing this to replace multiple snippet in the same tag (not to treat them as array and
120 // replace the snippet with the first letter of the string
121 foreach ($snippets as $snippet) {
122 if(isset($tagValues[$snippet])){
123 //$element->nodeValue = str_replace($snippet, $tagValues[$snippet], $element->nodeValue);
124 $this->replaceSnippetInAttributes($element, $snippet, $tagValues[$snippet]);
125 }
126 }
127 }
128 }
129 for ($i = 0; $i < $element->childNodes->length; $i++) {
130 $this->parseElement($element->childNodes->item($i));
131 }
132 }
133 $textNode = new DOMText('##FILLER##');
134 $element->appendChild($textNode);
135 return $this->parseElement($textNode);
136 }
137 if ($element->nodeType === XML_TEXT_NODE) {
138 $nodeAttributes = $this->getNodeAttributes($element->parentNode);
139
140 $snippets = $this->parseSnippetsInString($element->nodeValue . $nodeAttributes);
141
142 $maxTagValues = 0;
143 $tagValues = array();
144
145 if (count($snippets) > 0) {
146
147 if (count($snippets) == 1) {
148 $snippet = $snippets[0];
149 $isInFunction = $this->wpaeString->isBetween($nodeAttributes.$element->nodeValue, $snippet, '[',']');
150
151 $snippetValues = $this->processSnippet($snippet, $isInFunction);
152
153 if (!is_array($snippetValues)) {
154 $element->nodeValue =
155 str_replace(
156 $snippet,
157 $snippetValues,
158 $element->nodeValue
159 );
160 $nodeXML = $this->cloneNode($element->parentNode, $snippet, $snippetValues);
161 $f = $this->dom->createDocumentFragment();
162 $f->appendXML($nodeXML);
163 $this->parseElement($f);
164 $element->parentNode->parentNode->replaceChild($f, $element->parentNode);
165
166 } else {
167 foreach ($snippetValues as $snippetValue) {
168 $newValueNode = $element->parentNode->cloneNode(true);
169 $newValueNode->nodeValue = str_replace($snippet, $snippetValue, $newValueNode->nodeValue);
170 $this->replaceSnippetInAttributes($newValueNode, $snippet, $snippetValue);
171 $this->elementCdata($newValueNode);
172 $element->parentNode->parentNode->insertBefore($newValueNode, $element->parentNode);
173 }
174 $element->parentNode->parentNode->removeChild($element->parentNode);
175 }
176 } else if (count($snippets) > 1) {
177 foreach ($snippets as $snippet) {
178 $wholeValue = $nodeAttributes.$element->nodeValue;
179 $wholeValue = str_replace("\n", '', $wholeValue);
180 $isInFunction = $this->wpaeString->isBetween($wholeValue, $snippet, '[',']');
181 $snippetValue = $this->processSnippet($snippet,$isInFunction);
182
183 $tagValues[$snippet] = $snippetValue;
184
185
186 if (count($tagValues[$snippet]) > $maxTagValues) {
187 $maxTagValues = count($tagValues[$snippet]);
188 }
189 }
190 //We have arrays
191 if ($maxTagValues > 1) {
192 for ($i = 0; $i < $maxTagValues; $i++) {
193 $elementClone = $element->parentNode->cloneNode(true);
194 $elementValue = $elementClone->nodeValue;
195
196 foreach ($snippets as $snippet) {
197 // We might have the case that
198 // there are arrays but also implodes in the same tag
199 if(is_array($tagValues[$snippet])) {
200 if (isset($tagValues[$snippet][$i])) {
201 $elementValue = str_replace($snippet, $tagValues[$snippet][$i], $elementValue);
202 $this->replaceSnippetInAttributes($elementClone, $snippet, $tagValues[$snippet][$i]);
203
204
205 } else {
206 $elementValue = str_replace($snippet, "", $elementValue);
207 $this->replaceSnippetInAttributes($elementClone, $snippet, "");
208 }
209 } else {
210 $elementValue = str_replace($snippet, $tagValues[$snippet], $elementValue);
211 $this->replaceSnippetInAttributes($elementClone, $snippet, $tagValues[$snippet]);
212 }
213 }
214 $elementClone->nodeValue = $elementValue;
215 $this->elementCdata($elementClone);
216 $element->parentNode->parentNode->insertBefore($elementClone, $element->parentNode);
217 }
218 $element->parentNode->parentNode->removeChild($element->parentNode);
219 } else {
220 // Doing this to replace multiple snippet in the same tag (not to treat them as array and
221 // replace the snippet with the first letter of the string
222 foreach ($snippets as $snippet) {
223 if(isset($tagValues[$snippet])){
224 $element->nodeValue = str_replace($snippet, $tagValues[$snippet], $element->nodeValue);
225 $this->replaceSnippetInAttributes($element->parentNode, $snippet, $tagValues[$snippet]);
226 }
227 }
228 }
229 }
230 }
231 $this->elementCdata($element);
232 } else {
233 if ($element->hasChildNodes()) {
234 $has_text_elements = false;
235 for ($i = 0; $i < $element->childNodes->length; $i++) {
236 if ( $element->childNodes->item($i)->nodeType == XML_TEXT_NODE ){
237 $has_text_elements = true;
238 break;
239 }
240 }
241 if ( ! $has_text_elements ){
242 $nodeAttributes = $this->getNodeAttributes($element);
243 $snippets = $this->parseSnippetsInString($nodeAttributes);
244 if (!empty($snippets)){
245 $tagValues = array();
246 foreach ($snippets as $snippet) {
247 $wholeValue = str_replace("\n", '', $nodeAttributes);
248 $isInFunction = $this->wpaeString->isBetween($wholeValue, $snippet, '[',']');
249 $snippetValue = $this->processSnippet($snippet,$isInFunction);
250 $tagValues[$snippet] = $snippetValue;
251 }
252
253 // Doing this to replace multiple snippet in the same tag (not to treat them as array and
254 // replace the snippet with the first letter of the string
255 foreach ($snippets as $snippet) {
256 if(isset($tagValues[$snippet])){
257 //$element->nodeValue = str_replace($snippet, $tagValues[$snippet], $element->nodeValue);
258 $this->replaceSnippetInAttributes($element, $snippet, $tagValues[$snippet]);
259 }
260 }
261 }
262 }
263 for ($i = 0; $i < $element->childNodes->length; $i++) {
264 $this->parseElement($element->childNodes->item($i));
265 }
266 }
267 }
268 }
269
270 /**
271 * @param $filtered
272 * @return mixed
273 */
274 private function sanitizeFunctionName($filtered)
275 {
276 $functionName = str_replace('array(','(', substr($filtered, 0, strpos($filtered, "(")));
277 return $functionName;
278 }
279
280 /**
281 * @param $originalTag
282 * @return array
283 */
284 private function parseSnippetsInString($originalTag)
285 {
286 $results = array();
287 $matches = array();
288 preg_match_all("%(\[[^\]\[]*\])%", $originalTag, $matches);
289
290 $snippets = empty($matches) ? array() : array_unique($matches[0]);
291
292 foreach ($snippets as $snippet) {
293 $isCdataString = '<![CDATA' . $snippet;
294
295 if (strpos($this->xml, $isCdataString) === false) {
296 $results[] = $snippet;
297 }
298 }
299
300 return $results;
301 }
302
303 /**
304 * @param $v
305 * @return string
306 */
307 private function maybe_cdata($v)
308 {
309 if (XmlExportEngine::$is_preview) {
310 $v = str_replace('&amp;', '&', $v);
311 $v = htmlspecialchars($v);
312 }
313
314 if (XmlExportEngine::$is_preview && !XmlExportEngine::$exportOptions['show_cdata_in_preview']) {
315 return $v;
316 }
317
318 $cdataStrategyFactory = new CdataStrategyFactory();
319
320 if (!isset(XmlExportEngine::$exportOptions['custom_xml_cdata_logic'])) {
321 XmlExportEngine::$exportOptions['custom_xml_cdata_logic'] = 'auto';
322 }
323 $cdataStrategy = $cdataStrategyFactory->create_strategy(XmlExportEngine::$exportOptions['custom_xml_cdata_logic']);
324 $is_wrap_into_cdata = $cdataStrategy->should_cdata_be_applied($this->decodeSpecialCharacters($v));
325
326 if ($is_wrap_into_cdata === false) {
327 return $v;
328 } else {
329 return 'CDATABEGIN' . $v . 'CDATACLOSE';
330 }
331 }
332
333 /**
334 * @param $filtered
335 * @param $functionName
336 * @throws WpaeInvalidStringException
337 */
338 private function checkCorrectNumberOfQuotes($filtered, $functionName)
339 {
340 $numberOfSingleQuotes = substr_count($filtered, "'");
341 $numberOfDoubleQuotes = substr_count($filtered, "\"");
342
343 if ($numberOfSingleQuotes % 2 || $numberOfDoubleQuotes % 2) {
344 throw new WpaeInvalidStringException($functionName);
345 }
346 }
347
348 /**
349 * @param $filtered
350 * @return mixed
351 */
352 private function sanitizeAttribute($filtered)
353 {
354 $filtered = str_replace('&amp;', '&', $filtered);
355 $filtered = str_replace('&', '&amp;', $filtered);
356 $filtered = str_replace("'", '&#x27;', $filtered);
357 $filtered = str_replace('"', '&quot;', $filtered);
358 $filtered = str_replace('<', '&lt;', $filtered);
359 $filtered = str_replace('>', '&gt;', $filtered);
360
361 return $filtered;
362 }
363
364 /**
365 * @param $functionName
366 * @throws WpaeMethodNotFoundException
367 */
368 private function checkIfFunctionExists($functionName)
369 {
370 if (!function_exists($functionName) && $functionName != 'array') {
371 throw new WpaeMethodNotFoundException($functionName);
372 }
373 }
374
375 /**
376 * @param $snippet
377 * @return mixed
378 */
379 private function sanitizeSnippet($snippet)
380 {
381 $sanitizedSnippet = str_replace(array('[', ']'), '', $snippet);
382 $sanitizedSnippet = str_replace('\'', '"', $sanitizedSnippet);
383
384 return $sanitizedSnippet;
385 }
386
387 /**
388 * @param $xml
389 *
390 * @return mixed
391 */
392 private function handleSimpleSnippets($xml)
393 {
394 preg_match_all("%(\[[^\]\[]*\])%", $xml, $matches);
395 $snippets = empty($matches) ? array() : array_unique($matches[0]);
396
397 $simple_snipets = array();
398 preg_match_all("%(\{[^\}\{]*\})%", $xml, $matches);
399 $xpaths = array_unique($matches[0]);
400
401 if (!empty($xpaths)) {
402 foreach ($xpaths as $xpath) {
403 if (!in_array($xpath, $snippets)) $simple_snipets[] = $xpath;
404 }
405 }
406
407 if (!empty($simple_snipets)) {
408 foreach ($simple_snipets as $snippet) {
409
410 $filtered = preg_replace("%[\{\}]%", "", $snippet);
411
412 //Encode data in attributes
413 if (strpos($xml, "\"$snippet\"") !== false || strpos($xml, "'$snippet'") !== false) {
414 $attributeValue = str_replace('&amp;', '&', $filtered);
415 $attributeValue = str_replace('&', '&amp;', $attributeValue);
416 $attributeValue = str_replace('\'', '&#x27;', $attributeValue);
417 $attributeValue = str_replace('"', '&quot;', $attributeValue);
418 $attributeValue = str_replace('<', '&lt;', $attributeValue);
419 $attributeValue = str_replace('>', '&gt;', $attributeValue);
420
421 $xml = str_replace("\"".$snippet."\"", "\"".$attributeValue."\"", $xml);
422 $xml = str_replace("'".$snippet."'", "\"".$attributeValue."\"", $xml);
423 }
424
425 $filteredEncoded = $this->encodeSpecialCharacters($filtered);
426
427 $xml = str_replace($snippet, self::SNIPPET_DELIMITER.$filteredEncoded.self::SNIPPET_DELIMITER, $xml);
428 }
429 }
430 return $xml;
431 }
432
433 /**
434 * @param $xml
435 *
436 * @return mixed
437 */
438 public function encodeSpecialCharsInAttributes($xml)
439 {
440 preg_match_all('/<.*?=["\'](.*?)["\'].*?>/', $xml, $attributes);
441 $attributes = $attributes[1];
442
443 foreach ($attributes as $attribute) {
444
445 $attribute = trim($attribute, "'\"");
446
447 if (!$this->wpaeString->isBetween($xml, $attribute, '<![CDATA[', ']]>')) {
448
449 $xml = str_replace(array('\'' . $attribute . '\'', '"' . $attribute . '"'), '"' . $attribute . '"', $xml);
450 }
451 }
452
453 return $xml;
454 }
455
456 /**
457 * @param $xml
458 * @return DOMDocument
459 */
460 private function initVariables($xml)
461 {
462 $this->xml = $xml;
463
464 $dom = new DOMDocument();
465 $dom->recover = true;
466 $dom->preserveWhiteSpace = false;
467 $dom->substituteEntities = false;
468 $dom->resolveExternals = false;
469 $dom->formatOutput = true;
470
471 $dom->loadXML($xml);
472 $this->dom = $dom;
473 }
474
475 /**
476 * @param $snippet
477 * @param bool $isInFunction
478 *
479 * @return mixed
480 * @throws WpaeInvalidStringException
481 * @throws WpaeMethodNotFoundException
482 */
483 private function processSnippet($snippet, $isInFunction = false)
484 {
485
486 $sanitizedSnippet = $this->sanitizeSnippet($snippet);
487
488 $sanitizedSnippet = str_replace(WpaeXmlProcessor::SNIPPET_DELIMITER, '"', $sanitizedSnippet);
489 $functionName = $this->sanitizeFunctionName($sanitizedSnippet);
490
491 $this->checkCorrectNumberOfQuotes($sanitizedSnippet, $functionName);
492 $this->checkIfFunctionExists($functionName);
493
494 $argsStr = preg_replace("%^".$functionName."\((.*)\)$%", "$1", $sanitizedSnippet);
495 preg_match_all("%(\"[^\"]*\")%", $argsStr, $matches);
496 if (!empty($matches[0])){
497 $args = $matches[0];
498 foreach ($args as $k => $arg){
499 $sanitizedSnippet = str_replace($arg, 'apply_filters("wp_all_export_post_process_xml", '. $arg .')' ,$sanitizedSnippet);
500 }
501 }
502
503 // Clean empty strings
504 $sanitizedSnippet = str_replace(array(', ,',',,'), ',"",', $sanitizedSnippet);
505
506 $snippetValue = eval('return ' . $sanitizedSnippet . ';');
507 $snippetValue = $this->encodeSpecialCharacters($snippetValue);
508
509 if(strpos($snippet, 'explode') !== false && $isInFunction) {
510 $snippetValue = 'array('."'" . implode("','", $snippetValue) . "'".')';
511 }
512
513 return $snippetValue;
514 }
515
516 public function wp_all_export_post_process_xml($value){
517 return $this->postProcessXml($this->decodeSpecialCharacters(str_replace('"','', $value)));
518 }
519
520 public function getNodeAttributes(DOMNode $dom)
521 {
522 $result = "";
523 if ($dom->hasAttributes()) {
524 for ($i = 0; $i < $dom->attributes->length; $i++)
525 $result .= $dom->attributes->item($i)->nodeValue;
526 }
527
528 return $result;
529 }
530
531 /**
532 * @param DOMNode $newValueNode
533 * @param $snippet
534 * @param $snippetValue
535 * @internal param $snippetValues
536 */
537 private function replaceSnippetInAttributes(DOMNode $newValueNode, $snippet, $snippetValue)
538 {
539 $snippetValue = $this->sanitizeAttribute($snippetValue);
540 if ($newValueNode->hasAttributes()) {
541 for ($i = 0; $i < $newValueNode->attributes->length; $i++) {
542 $newValueNode->attributes->item($i)->nodeValue =
543 str_replace(
544 $snippet,
545 $snippetValue,
546 $newValueNode->attributes->item($i)->nodeValue
547 );
548 }
549 }
550 }
551
552 /**
553 * @param DOMNode $element
554 */
555 private function elementCdata(DOMNode $element)
556 {
557 $hasSnippets = $this->parseSnippetsInString($element->nodeValue);
558
559 if (strpos($element->nodeValue, '<![CDATA[') === false && strpos($element->nodeValue, 'CDATABEGIN') === false && !$hasSnippets) {
560 $element->nodeValue = $this->maybe_cdata($element->nodeValue);
561 }
562 }
563
564 private function encodeSpecialCharacters($text)
565 {
566 $text = str_replace('&amp;', '&', $text);
567 $text = str_replace('&', '##amp##', $text);
568 $text = str_replace("'", '##x27##', $text);
569 $text = str_replace('"', '##quot##', $text);
570 $text = str_replace('<', '##lt##', $text);
571 $text = str_replace('>', '##gt##', $text);
572
573 return $text;
574 }
575
576 private function decodeSpecialCharacters($text)
577 {
578 $text = str_replace('##amp##', '&', $text);
579 $text = str_replace('##x27##', "'", $text);
580 $text = str_replace('##quot##', '"', $text);
581 $text = str_replace('##lt##', '<', $text);
582 $text = str_replace('##gt##', '>', $text);
583
584 return $text;
585 }
586
587 /**
588 * @param $xml
589 * @return mixed
590 */
591 private function postProcessXml($xml)
592 {
593 $xml = str_replace('CDATABEGIN', '<![CDATA[', $xml);
594 $xml = str_replace('CDATACLOSE', ']]>', $xml);
595
596 $xml = str_replace('CLOSEBRAKET', ']', str_replace('OPENBRAKET', '[', $xml));
597 $xml = str_replace('CLOSECURVE', '}', str_replace('OPENCURVE', '{', $xml));
598 $xml = str_replace('CLOSECIRCLE', ')', str_replace('OPENCIRCLE', '(', $xml));
599
600 $xml = str_replace('**SINGLEQUOT**', "'", $xml);
601 $xml = str_replace('**DOUBLEQUOT**', "\"", $xml);
602
603 $xml = str_replace('##FILLER##', '', $xml);
604 $xml = str_replace('<filler>c</filler>', '', $xml);
605 $xml = str_replace('<filler><![CDATA[c]]></filler>', '', $xml);
606 $xml = str_replace('<filler>CDATABEGINcCDATACLOSE</filler>', '', $xml);
607
608 $xml = str_replace('<comment>', '<!--', $xml);
609 $xml = str_replace('</comment>', '-->', $xml);
610
611 $xml = str_replace(self::SNIPPET_DELIMITER, '', $xml);
612
613 $xml = trim($xml);
614 return $xml;
615 }
616
617 /**
618 * @param $xml
619 * @return mixed
620 */
621 private function preprocessXml($xml)
622 {
623 $xml = str_replace('<!--', '<comment>', $xml);
624 $xml = str_replace('-->', '</comment>', $xml);
625
626 $xml = str_replace("\"{}\"", '""', $xml);
627 $xml = str_replace("{}", '""', $xml);
628 $xml = str_replace(">\"\"<", '><', $xml);
629 $xml = str_replace("[implode(',',{})]", "", $xml);
630 return $xml;
631 }
632
633 /**
634 * @param $xml
635 * @param $response
636 * @return mixed
637 */
638 private function cleanResponse($response)
639 {
640 $response = str_replace('<root>', '', $response);
641 $response = str_replace('</root>', '', $response);
642 $xml = str_replace("<?xml version=\"1.0\"?>", '', $response);
643 $xml = str_replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>", "", $xml);
644
645 return trim($xml);
646 }
647
648 /**
649 *
650 * Cloning DOMNode with including child DOMNode elements
651 *
652 * @param $node
653 * @return \DOMNode*
654 */
655 private function cloneNode(DOMNode $node, $snippet, $snippetValues){
656
657 $Document = new DOMDocument('1.0', 'UTF-8');
658 $Document->preserveWhiteSpace = false;
659 $Document->formatOutput = true;
660 $newElement = $Document->importNode($node, true);
661
662 $this->replaceSnippetInAttributes($newElement, $snippet, $snippetValues);
663
664 foreach ($newElement->childNodes as $child){
665 if ($child->nodeType === XML_TEXT_NODE) {
666 $this->elementCdata($child);
667 }
668 }
669
670 $Document->appendChild($newElement);
671 return trim(str_replace("<?xml version=\"1.0\" encoding=\"UTF-8\"?>","",$Document->saveXML()));
672
673 }
674 }