PageRenderTime 26ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/wp-all-export-pro/classes/XMLWriter.php

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