PluginProbe ʕ •ᴥ•ʔ
WP All Import – Drag & Drop Import for CSV, XML, Excel & Google Sheets / trunk
WP All Import – Drag & Drop Import for CSV, XML, Excel & Google Sheets vtrunk
3.9.5 3.9.6 4.0.0 4.0.1 4.1.0 trunk 2.12 2.13 2.14 3.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.2.0 3.2.1 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 3.2.8 3.2.9 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.3.8 3.3.9 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.6 3.4.7 3.4.8 3.4.9 3.5.0 3.5.1 3.5.2 3.5.3 3.5.4 3.5.5 3.5.6 3.5.7 3.5.8 3.5.9 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.6.8 3.6.9 3.7.0 3.7.1 3.7.2 3.7.3 3.7.3-beta-1.0 3.7.4 3.7.4-beta-1.0 3.7.5 3.7.6 3.7.7 3.7.8 3.7.9 3.8.0 3.9.0 3.9.1 3.9.2 3.9.3 3.9.4
wp-all-import / classes / render.php
wp-all-import / classes Last commit date
XmlStreamReader 3 weeks ago partner-discount-sdk 3 weeks ago api.php 3 weeks ago arraytoxml.php 3 weeks ago chunk.php 3 weeks ago config.php 2 years ago download.php 3 weeks ago error.php 3 weeks ago handler.php 3 weeks ago helper.php 3 weeks ago input.php 3 weeks ago nested.php 3 weeks ago rapidaddon.php 3 weeks ago render.php 3 weeks ago session.php 9 months ago upload.php 3 weeks ago zip.php 10 years ago
render.php
316 lines
1 <?php
2 if ( ! class_exists('PMXI_Render')){
3
4 class PMXI_Render{
5
6 public function __construct(){
7
8 }
9
10 public static function xml_find_repeating(DOMElement $el, $path = '/')
11 {
12 $path .= $el->nodeName;
13 if ( ! $el->parentNode instanceof DOMDocument) {
14 $path .= '[1]';
15 }
16 $children = array();
17 foreach ($el->childNodes as $child) {
18 if ($child instanceof DOMElement) {
19 if ( ! empty($children[$child->nodeName])) {
20 return $path . '/' . $child->nodeName;
21 } else {
22 $children[$child->nodeName] = true;
23 }
24 }
25 }
26 // reaching this point means we didn't find anything among current element children, so recursively ask children to find something in them
27 foreach ($el->childNodes as $child) {
28 if ($child instanceof DOMElement) {
29 $result = slef::xml_find_repeating($child, $path . '/');
30 if ($result) {
31 return $result;
32 }
33 }
34 }
35 // reaching this point means we didn't find anything, so return element itself if the function was called for it
36 if ('/' . $el->nodeName == $path) {
37 return $path;
38 }
39
40 return NULL;
41 }
42
43 public static function render_csv_element(DOMElement $el, $shorten = false, $path = '/', $ind = 1, $lvl = 0)
44 {
45 $path .= $el->nodeName;
46 if ( ! $el->parentNode instanceof DOMDocument and $ind > 0) {
47 $path .= "[$ind]";
48 }
49
50 echo '<div class="xml-element csv_element lvl-' . esc_attr($lvl) . ' lvl-mod4-' . esc_attr($lvl % 4) . '" title="' . esc_attr($path) . '">';
51 if ($el->hasChildNodes()) {
52 $is_render_collapsed = $ind > 1;
53 if ($lvl) echo '<div class="csv-tag opening"><span class="csv-tag-name">' . esc_html($el->nodeName) . '</span>'; echo '</div>';
54 if (1 == $el->childNodes->length and $el->childNodes->item(0) instanceof DOMText) {
55 $child = $el->childNodes->item(0);
56 if (!empty($child->wholeText)){
57 self::render_csv_text(trim($child->wholeText), $shorten, $is_render_collapsed);
58 }
59 elseif (is_callable(array($child, 'nodeValue'), true) && isset($child->nodeValue)){
60 self::render_csv_text(trim($child->nodeValue), $shorten, $is_render_collapsed);
61 }
62 } else {
63 echo '<div class="csv-content' . ($is_render_collapsed ? ' collapsed' : '') . '">';
64 $indexes = array();
65 foreach ($el->childNodes as $child) {
66 if ($child instanceof DOMElement) {
67 empty($indexes[$child->nodeName]) and $indexes[$child->nodeName] = 0; $indexes[$child->nodeName]++;
68 self::render_csv_element($child, $shorten, $path . '/', $indexes[$child->nodeName], $lvl + 1);
69 } elseif ($child instanceof DOMText) {
70 self::render_csv_text(trim($child->wholeText), $shorten);
71 } elseif ($child instanceof DOMComment) {
72 if (preg_match('%\[pmxi_more:(\d+)\]%', $child->nodeValue, $mtch)) {
73 $no = intval($mtch[1]);
74 echo '<div class="xml-more">[ &dArr; ' . wp_kses( /* translators: 1: count, 2: element/elements label */ sprintf(__('<strong>%1$s</strong> %2$s more', 'wp-all-import'), intval($no), esc_html(_n('element', 'elements', $no, 'wp-all-import'))), array('strong' => array()) ) . ' &dArr; ]</div>';
75 }
76 }
77 }
78 echo '</div>';
79 }
80 //echo '<div class="xml-tag closing"><span class="xml-tag-name">' . $el->nodeName . '</span></div>';
81 } else {
82 echo '<div class="xml-tag opening empty"><span class="xml-tag-name">' . wp_kses_post($el->nodeName) . '</span>'; self::render_xml_attributes($el); echo '</div>';
83 }
84 echo '</div>';
85 }
86
87 protected static function render_csv_text($text, $shorten = false, $is_render_collapsed = false)
88 {
89 if (empty($text) and 0 !== (int)$text) {
90 return; // do not display empty text nodes
91 }
92 if (preg_match('%\[more:(\d+)\]%', $text, $mtch)) {
93 $no = intval($mtch[1]);
94 echo '<div class="xml-more">[ &dArr; ' . wp_kses( /* translators: 1: count, 2: element/elements label */ sprintf(__('<strong>%1$s</strong> %2$s more', 'wp-all-import'), intval($no), esc_html(_n('element', 'elements', $no, 'wp-all-import'))), array('strong' => array()) ) . ' &dArr; ]</div>';
95 return;
96 }
97 $more = '';
98 if ($shorten and preg_match('%^(.*?\s+){20}(?=\S)%', $text, $mtch)) {
99 $text = $mtch[0];
100 $more = '<span class="xml-more">[' . esc_html__('more', 'wp-all-import') . ']</span>';
101 }
102 $is_short = strlen($text) <= 40;
103 $newtext = htmlspecialchars($text);
104 //$newtext = preg_replace('%(?<!\s)\b(?!\s|\W[\w\s])|\w{20}%', '$0&#8203;', $newtext); // put explicit breaks for xml content to wrap
105 echo '<div class="xml-content textonly' . ($is_short ? ' short' : '') . ($is_render_collapsed ? ' collapsed' : '') . ' '. (is_numeric($text) ? 'is_numeric' : '') .'">' . wp_kses_post($newtext . $more) . '</div>';
106 }
107 public static $option_paths = array();
108 public static function render_xml_elements_for_filtring(DOMElement $el, $originPath ='', $lvl = 0){
109 $path = $originPath;
110 if ("" != $path){
111 if ($lvl > 1) $path .= "->" . $el->nodeName; else $path = $el->nodeName;
112 if (empty(self::$option_paths[$path]))
113 self::$option_paths[$path] = 1;
114 else
115 self::$option_paths[$path]++;
116 echo '<option value="'. esc_attr($path) .'['. esc_attr(self::$option_paths[$path]) .']">' . esc_html($path) . '['. esc_html(self::$option_paths[$path]) .']</option>';
117 }
118 else $path = $el->nodeName;
119
120 foreach ($el->attributes as $attr) {
121 if (empty($originPath)){
122 echo '<option value="@' . esc_attr($attr->nodeName).'">@' . esc_html($attr->nodeName) . '</option>';
123 }
124 else{
125 echo '<option value="'. esc_attr($path) .'['. esc_attr(self::$option_paths[$path]) .']'. '/@' . esc_attr($attr->nodeName).'">'. esc_html($path) .'['. esc_html(self::$option_paths[$path]) .']'. '@' . esc_html($attr->nodeName) . '</option>';
126 }
127 }
128 if ($el->hasChildNodes()) {
129 foreach ($el->childNodes as $child) {
130 if ($child instanceof DOMElement)
131 self::render_xml_elements_for_filtring($child, $path, $lvl + 1);
132 }
133 }
134 }
135
136 public static function render_xml_element(DOMElement $el, $shorten = false, $path = '/', $ind = 1, $lvl = 0)
137 {
138 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
139 $render_whole_tree = apply_filters('wp_all_import_is_render_whole_xml_tree', true);
140
141 $path .= $el->nodeName;
142 $alternativePath = $path;
143 if ( ! $el->parentNode instanceof DOMDocument and $ind > 0) {
144 $path .= "[$ind]";
145 }
146
147 echo '<div class="xml-element lvl-' . esc_attr($lvl) . ' lvl-mod4-' . esc_attr($lvl % 4) . '" title="' . esc_attr($path) . '">';
148 //if ($el->hasAttributes()){
149 echo '<div class="xml-element-xpaths">'; self::render_element_xpaths($el, $alternativePath, $ind, $lvl); echo '</div>';
150 //}
151 if ($el->hasChildNodes()) {
152 $is_render_collapsed = $ind > 1;
153 if ($el->childNodes->length > 1 or ! $el->childNodes->item(0) instanceof DOMText or strlen(trim($el->childNodes->item(0)->wholeText)) > 40) {
154 echo '<div class="xml-expander">' . ($is_render_collapsed ? '+' : '-') . '</div>';
155 }
156 echo '<div class="xml-tag opening">&lt;<span class="xml-tag-name">' . esc_html($el->nodeName) . '</span>'; self::render_xml_attributes($el, $path . '/'); echo '&gt;</div>';
157 if (1 == $el->childNodes->length and $el->childNodes->item(0) instanceof DOMText) {
158 $item = $el->childNodes->item(0);
159 if (!empty($item->wholeText)){
160 self::render_xml_text(trim($item->wholeText), $shorten, $is_render_collapsed);
161 }
162 else{
163 self::render_xml_text(trim($item->nodeValue), $shorten, $is_render_collapsed);
164 }
165 } else {
166 echo '<div class="xml-content' . ($is_render_collapsed ? ' collapsed' : '') . '">';
167 $indexes = array();
168 foreach ($el->childNodes as $eli => $child) {
169 if ($child instanceof DOMElement) {
170 empty($indexes[$child->nodeName]) and $indexes[$child->nodeName] = 0; $indexes[$child->nodeName]++;
171 if ( $render_whole_tree || $indexes[$child->nodeName] === 1){
172 self::render_xml_element($child, $shorten, $path . '/', $indexes[$child->nodeName], $lvl + 1);
173 }
174 } elseif ($child instanceof DOMCdataSection) {
175 self::render_xml_text(trim($child->wholeText), $shorten, false, true);
176 } elseif ($child instanceof DOMText) {
177 if ( $el->childNodes->item($eli - 1) and ($el->childNodes->item($eli - 1) instanceof DOMCdataSection) ){
178
179 }
180 elseif( $el->childNodes->item($eli + 1) and ($el->childNodes->item($eli + 1) instanceof DOMCdataSection) ){
181
182 }
183 else{
184 self::render_xml_text(trim($child->wholeText), $shorten);
185 }
186 } elseif ($child instanceof DOMComment) {
187 if (preg_match('%\[pmxi_more:(\d+)\]%', $child->nodeValue, $mtch)) {
188 $no = intval($mtch[1]);
189 echo '<div class="xml-more">[ &dArr; ' . wp_kses( /* translators: 1: count, 2: element/elements label */ sprintf(__('<strong>%1$s</strong> %2$s more', 'wp-all-import'), intval($no), esc_html(_n('element', 'elements', $no, 'wp-all-import'))), array('strong' => array()) ) . ' &dArr; ]</div>';
190 }
191 }
192 }
193 echo '</div>';
194 }
195 echo '<div class="xml-tag closing">&lt;/<span class="xml-tag-name">' . esc_html($el->nodeName) . '</span>&gt;</div>';
196 } else {
197 echo '<div class="xml-tag opening empty">&lt;<span class="xml-tag-name">' . esc_html($el->nodeName) . '</span>'; self::render_xml_attributes($el); echo '/&gt;</div>';
198 }
199 echo '</div>';
200 }
201
202 protected static function render_xml_text($text, $shorten = false, $is_render_collapsed = false, $is_cdata = false)
203 {
204 if (empty($text) and 0 !== (int)$text) {
205 return; // do not display empty text nodes
206 }
207 if (preg_match('%\[more:(\d+)\]%', $text, $mtch)) {
208 $no = intval($mtch[1]);
209 echo '<div class="xml-more">[ &dArr; ' . wp_kses( /* translators: 1: count, 2: element/elements label */ sprintf(__('<strong>%1$s</strong> %2$s more', 'wp-all-import'), intval($no), esc_html(_n('element', 'elements', $no, 'wp-all-import'))), array('strong' => array()) ) . ' &dArr; ]</div>';
210 return;
211 }
212 $more = '';
213 if ($shorten and preg_match('%^(.*?\s+){20}(?=\S)%', $text, $mtch)) {
214 $text = $mtch[0];
215 $more = '<span class="xml-more">[' . esc_html__('more', 'wp-all-import') . ']</span>';
216 }
217 $is_short = strlen($text) <= 40;
218 $text = htmlspecialchars($text);
219 if ($is_cdata){
220 $text = "<span class='wpallimport-cdata'>" . htmlspecialchars("<![CDATA[") . "</span> " . $text . " <span class='wpallimport-cdata'>" . htmlspecialchars("]]>") . "</span>";
221 }
222 //$text = preg_replace('%(?<!\s)\b(?!\s|\W[\w\s])|\w{20}%', '$0&#8203;', $text); // put explicit breaks for xml content to wrap
223 echo '<div class="xml-content textonly' . ($is_short ? ' short' : '') . ($is_render_collapsed ? ' collapsed' : '') . '">' . esc_html($text . $more) . '</div>';
224 }
225
226 public static function get_xml_path(DOMElement $el, DOMXPath $xpath)
227 {
228 for($p = '', $doc = $el; $doc and ! $doc instanceof DOMDocument; $doc = $doc->parentNode) {
229 if (($ind = $xpath->query('preceding-sibling::' . $doc->nodeName, $doc)->length)) {
230 $p = '[' . ++$ind . ']' . $p;
231 } elseif ( ! $doc->parentNode instanceof DOMDocument) {
232 $p = '[' . ($ind = 1) . ']' . $p;
233 }
234 $p = '/' . $doc->nodeName . $p;
235 }
236 return $p;
237 }
238
239 protected static function render_xml_attributes(DOMElement $el, $path = '/')
240 {
241 foreach ($el->attributes as $attr) {
242 echo ' <span class="xml-attr" title="' . esc_attr($path) . '@' . esc_attr($attr->nodeName) . '"><span class="xml-attr-name">' . esc_html($attr->nodeName) . '</span>=<span class="xml-attr-value">"' . esc_attr($attr->value) . '"</span></span>';
243 }
244 }
245
246 protected static function render_element_xpaths(DOMElement $el, $path = '/', $ind = 1, $lvl = 0){
247 ?>
248 <ul id="menu-<?php echo esc_attr(str_replace('/', '-', $path)); ?>" class="ui-helper-hidden">
249 <?php foreach ($el->attributes as $attr) : if ( empty($attr->value) ) continue; ?>
250 <li data-command="action1" title="<?php echo esc_attr($path . '[@'. $attr->nodeName .' = "' . $attr->value . '"]'); ?>">
251 <a href="#"><?php echo wp_kses_post($path . '[@'. $attr->nodeName .' = "' . $attr->value) . '"]'; ?></a>
252 </li>
253 <li data-command="action2" title="<?php echo esc_attr($path . '[@'. $attr->nodeName .'[contains(.,"' . $attr->value . '")]]'); ?>">
254 <a href="#"><?php echo wp_kses_post($path . '[@'. $attr->nodeName .'[contains(.,"' . $attr->value) . '")]]'; ?></a>
255 </li>
256 <?php endforeach; ?>
257 <?php
258 $altNode = null;
259 $altNodeText = null;
260 $parentNode = $el->parentNode;
261 $grandNode = $parentNode->parentNode;
262
263 if ( ! $grandNode instanceof DOMDocument and $grandNode instanceof DOMElement ){
264
265 $equalsElements = 0;
266 foreach ($grandNode->childNodes as $child) {
267 if ($child instanceof DOMElement) {
268 if ($child->nodeName == $parentNode->nodeName){
269 $equalsElements++;
270 if ($equalsElements > 1)
271 break;
272 }
273 }
274 }
275
276 if ($equalsElements > 1){
277 if ($parentNode->hasChildNodes()) {
278 foreach ($parentNode->childNodes as $i => $child) {
279 if ($child instanceof DOMElement) {
280 if ($child->nodeName != $el->nodeName){
281 $altNode = $child;
282 if ($child->hasChildNodes()){
283 foreach ($child->childNodes as $i => $txtChild) {
284 if ($txtChild instanceof DOMText) {
285 $altNodeText = $txtChild;
286 break;
287 }
288 }
289 }
290 break;
291 }
292 }
293 }
294 }
295
296 if ( ! empty($altNode) and !empty($altNodeText) ){
297
298 $pathArgs = explode('/', $path);
299 array_pop($pathArgs);
300 array_pop($pathArgs);
301 $vpath = esc_attr(implode('/', $pathArgs) . '/' . $parentNode->nodeName . '[contains('. $altNode->nodeName .',"' . esc_attr($altNodeText->wholeText) . '")]/' . $el->nodeName);
302 ?>
303 <li data-command="action3" title="<?php echo esc_attr($vpath); ?>">
304 <a href="#"><?php echo esc_html($vpath); ?></a>
305 </li>
306 <?php
307
308 }
309 }
310 }
311 ?>
312 </ul>
313 <?php
314 }
315 }
316 }