PluginProbe ʕ •ᴥ•ʔ
WP All Export – Drag & Drop Export to Any Custom CSV, XML & Excel / trunk
WP All Export – Drag & Drop Export to Any Custom CSV, XML & Excel vtrunk
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 / XmlExportCpt.php
wp-all-export / libraries Last commit date
VariableProductTitle 2 months ago .gitkeep 11 years ago WpaeInvalidPhpException.php 9 years ago WpaeInvalidStringException.php 9 years ago WpaeMethodNotFoundException.php 9 years ago WpaePhpInterpreterErrorHandler.php 2 months ago WpaeString.php 9 years ago WpaeTooMuchRecursionException.php 9 years ago XmlCsvExport.php 2 months ago XmlExportCpt.php 2 months ago XmlExportCustomRecord.php 2 months ago XmlExportEngine.php 2 months ago XmlExportFiltering.php 2 months ago XmlExportMediaGallery.php 2 months ago XmlExportTaxonomy.php 2 months ago
XmlExportCpt.php
851 lines
1 <?php
2
3
4 // phpcs:ignoreFile WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound,WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound,WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedClassFound -- legitimate plugin prefixes (pmxe/PMXE/wpae/Wpae/wp_all_export/wpallexport/XmlExport/CdataStrategy/VariableProductTitle/Soflyy/GF_Export); Plugin Check does not honor phpcs.xml prefix declaration
5 use Wpae\App\Service\VariationOptions\VariationOptionsFactory;
6
7 final class XmlExportCpt
8 {
9 private static $userData = array();
10
11 public static function prepare_data($entry, $exportOptions,
12 $xmlWriter, &$acfs, &$woo, &$woo_order, $implode_delimiter, $preview, $is_item_data = false, $subID = false)
13 {
14 $variationOptionsFactory = new VariationOptionsFactory();
15 $variationOptions = $variationOptionsFactory->createVariationOptions(PMXE_EDITION);
16 if($entry instanceof \WP_Post) {
17 $entry = $variationOptions->preprocessPost($entry);
18 }
19
20 $article = array();
21
22 if(!isset($entry->ID)) {
23 $entryId = $entry->order_id ?? $entry->id;
24 $entry->ID = $entry->id;
25 } else {
26 $entryId = $entry->order_id ?? $entry->ID;
27 }
28
29 // associate exported post with import
30 if (!$is_item_data and wp_all_export_is_compatible() && isset($exportOptions['is_generate_import']) && isset($exportOptions['import_id'])) {
31
32 $postRecord = new \PMXI_Post_Record();
33 $postRecord->clear();
34 $postRecord->getBy(array(
35 'post_id' => $entryId,
36 'import_id' => $exportOptions['import_id'],
37 ));
38
39 if ($postRecord->isEmpty()) {
40 $postRecord->set(array(
41 'post_id' => $entryId,
42 'import_id' => $exportOptions['import_id'],
43 'unique_key' => $entryId,
44 'product_key' => $entryId
45 ))->save();
46 }
47 unset($postRecord);
48 }
49
50 $is_xml_export = false;
51
52 if (!empty($xmlWriter) && $exportOptions['export_to'] == XmlExportEngine::EXPORT_TYPE_XML && !in_array($exportOptions['xml_template_type'], array('custom', 'XmlGoogleMerchants'))) {
53 $is_xml_export = true;
54 }
55
56 if (isset($exportOptions['ids']) && is_array($exportOptions['ids'])) {
57 foreach ($exportOptions['ids'] as $ID => $value) {
58 if(is_array($exportOptions['cpt'] ?? '') && in_array('shop_order', $exportOptions['cpt'])) {
59 $pType = 'shop_order';
60 } else {
61 $pType = $entry->post_type ?? $entry->type;
62 }
63
64 if ($is_item_data and $subID != $ID) continue;
65
66 // skip shop order items data
67 if ($pType == "shop_order" and strpos($exportOptions['cc_label'][$ID], "item_data__") !== false and !$is_item_data) continue;
68
69 $fieldName = apply_filters('wp_all_export_field_name', wp_all_export_parse_field_name($exportOptions['cc_name'][$ID]), XmlExportEngine::$exportID);
70 $fieldValue = str_replace("item_data__", "", $exportOptions['cc_value'][$ID]);
71 $fieldLabel = str_replace("item_data__", "", $exportOptions['cc_label'][$ID]);
72 $fieldSql = $exportOptions['cc_sql'][$ID];
73 $fieldPhp = $exportOptions['cc_php'][$ID];
74 $fieldCode = $exportOptions['cc_code'][$ID];
75 $fieldType = $exportOptions['cc_type'][$ID];
76 $fieldOptions = $exportOptions['cc_options'][$ID];
77 $fieldSettings = empty($exportOptions['cc_settings'][$ID]) ? $fieldOptions : $exportOptions['cc_settings'][$ID];
78
79 $fieldSnippet = (!empty($fieldPhp) and !empty($fieldCode)) ? $fieldCode : false;
80
81 if (empty($fieldName) or empty($fieldType) or !is_numeric($ID)) continue;
82
83 $element_name = (!empty($fieldName)) ? $fieldName : 'untitled_' . $ID;
84 $element_name_ns = '';
85
86 if ($is_xml_export) {
87 $element_name = (!empty($fieldName)) ? preg_replace('/[^a-z0-9_:-]/i', '', $fieldName) : 'untitled_' . $ID;
88
89 if (strpos($element_name, ":") !== false) {
90 $element_name_parts = explode(":", $element_name);
91 $element_name_ns = (empty($element_name_parts[0])) ? '' : $element_name_parts[0];
92 $element_name = (empty($element_name_parts[1])) ? 'untitled_' . $ID : preg_replace('/[^a-z0-9_-]/i', '', $element_name_parts[1]);
93 }
94 }
95
96 $addons = XmlExportEngine::get_addons();
97 $addonFieldOptions = maybe_unserialize($fieldOptions);
98
99 if (in_array($fieldType, $addons)) {
100 $article = apply_filters(
101 "pmxe_{$fieldType}_addon_export_field",
102 $article,
103 $addonFieldOptions,
104 $exportOptions,
105 $ID,
106 $entry,
107 $entry->ID,
108 $xmlWriter,
109 $element_name,
110 $element_name_ns,
111 $fieldSnippet,
112 $preview
113 );
114 }
115
116 switch ($fieldType) {
117 case 'id':
118 // For ID columns make first element in lowercase for Excel export
119 if ($element_name == 'ID' && !$ID && isset($exportOptions['export_to']) && $exportOptions['export_to'] == 'csv' && isset($exportOptions['export_to_sheet']) && $exportOptions['export_to_sheet'] != 'csv') {
120 $element_name = 'id';
121 }
122 wp_all_export_write_article($article, $element_name, apply_filters('pmxe_post_id', pmxe_filter($entry->ID, $fieldSnippet), $entry->ID));
123 break;
124 case 'permalink':
125 wp_all_export_write_article($article, $element_name, apply_filters('pmxe_post_guid', pmxe_filter(get_permalink(), $fieldSnippet), $entry->ID));
126 break;
127 case 'post_type':
128 if ($entry->post_type == 'product_variation') $pType = 'product';
129 wp_all_export_write_article($article, $element_name, apply_filters('pmxe_post_type', pmxe_filter($pType, $fieldSnippet), $entry->ID));
130 break;
131 case 'title':
132 $val = apply_filters('pmxe_post_title', pmxe_filter($entry->post_title, $fieldSnippet));
133 wp_all_export_write_article($article, $element_name, ($preview) ? trim(preg_replace('~[\r\n]+~', ' ', htmlspecialchars((string) $val))) : $val, $entry->ID);
134 break;
135 case 'content':
136 $postContent = $entry->post_content;
137
138 $field_settings = (!empty($fieldSettings)) ? json_decode($fieldSettings, true) : false;
139 if (empty($field_settings) or $field_settings['export_images_from_gallery']) {
140 // search for images in galleries
141 $galleries = array();
142 if (preg_match_all('%\[gallery[^\]]*ids="([^\s\]]*)"[^\]]*\]%is', $postContent, $matches, PREG_PATTERN_ORDER)) {
143 $galleries = array_unique(array_filter($matches[1]));
144 }
145 if (!empty($galleries)) {
146 foreach ($galleries as $key => $gallery) {
147 $gallery_images = array();
148 $imgs = array_unique(array_filter(explode(",", $gallery)));
149 if (!empty($imgs)) {
150 foreach ($imgs as $img) {
151 if (is_numeric($img)) {
152 $gallery_images[] = wp_get_attachment_url($img) . "|" . wp_get_attachment_caption($img);
153 }
154 }
155 }
156 $gallery_images = array_unique($gallery_images);
157 $postContent = str_replace("ids=\"" . implode(",", $imgs) . "\"", "ids=\"" . implode(",", $gallery_images) . "\"", $postContent);
158 }
159 }
160 }
161
162 if (isset($exportOptions['export_to']) && $exportOptions['export_to'] == XmlExportEngine::EXPORT_TYPE_XML && $exportOptions['xml_template_type'] == 'custom') {
163 $postContent = str_replace('[', '**OPENSHORTCODE**', $postContent);
164 $postContent = str_replace(']', '**CLOSESHORTCODE**', $postContent);
165 }
166
167 $val = apply_filters('pmxe_post_content', pmxe_filter($postContent, $fieldSnippet), $entry->ID);
168 wp_all_export_write_article($article, $element_name, ($preview) ? trim(preg_replace('~[\r\n]+~', ' ', htmlspecialchars((string) $val))) : $val);
169 break;
170
171 // Media Attachments
172 case 'attachments':
173 case 'attachment_id':
174 case 'attachment_url':
175 case 'attachment_filename':
176 case 'attachment_path':
177 case 'attachment_title':
178 case 'attachment_caption':
179 case 'attachment_description':
180 case 'attachment_alt':
181
182 XmlExportMediaGallery::getInstance($entry->ID);
183
184 $attachment_data = XmlExportMediaGallery::get_attachments($fieldType);
185
186 wp_all_export_write_article($article, $element_name, apply_filters('pmxe_' . $fieldType, pmxe_filter(implode($implode_delimiter, $attachment_data), $fieldSnippet), $entry->ID));
187
188 break;
189
190 // Media Images
191 case 'media':
192 case 'image_id':
193 case 'image_url':
194 case 'image_filename':
195 case 'image_path':
196 case 'image_title':
197 case 'image_caption':
198 case 'image_description':
199 case 'image_alt':
200 case 'image_featured':
201
202 $field_options = json_decode($fieldOptions, true);
203
204 XmlExportMediaGallery::getInstance($entry->ID);
205
206 $images_data = XmlExportMediaGallery::get_images($fieldType, $field_options);
207
208 $images_separator = empty($field_options['image_separator']) ? $implode_delimiter : $field_options['image_separator'];
209
210 wp_all_export_write_article($article, $element_name, apply_filters('pmxe_' . $fieldType, pmxe_filter(implode($images_separator, $images_data), $fieldSnippet), $entry->ID));
211
212 break;
213
214
215 case 'date':
216 $post_date = prepare_date_field_value($fieldSettings, get_post_time('U', true, $entry->ID), "Ymd");
217 wp_all_export_write_article($article, $element_name, apply_filters('pmxe_post_date', pmxe_filter($post_date, $fieldSnippet), $entry->ID));
218 break;
219 case 'post_modified':
220 $post_date = prepare_date_field_value($fieldSettings, get_post_modified_time('U', true, $entry->ID), "Ymd");
221 wp_all_export_write_article($article, $element_name, apply_filters('pmxe_post_modified_date', pmxe_filter($post_date, $fieldSnippet), $entry->ID));
222 break;
223 case 'parent':
224 wp_all_export_write_article($article, $element_name, apply_filters('pmxe_post_parent', pmxe_filter($entry->post_parent, $fieldSnippet), $entry->ID));
225 break;
226 case 'parent_slug':
227 $val = '';
228 if ($entry->post_parent != 0) {
229 $pages = get_post_ancestors($entry->ID);
230 $slugs = array();
231 if (!empty($pages)) {
232 foreach ($pages as $page) {
233 $the_post = get_post($page);
234 $slugs[] = $the_post->post_name;
235 }
236 $val = implode("/", array_reverse($slugs));
237 } else {
238 $the_post = get_post($entry->ID);
239 $val = $the_post->post_name;
240 }
241 } else {
242 $val = $entry->post_parent;
243 }
244 wp_all_export_write_article($article, $element_name, apply_filters('pmxe_post_parent_slug', pmxe_filter($val, $fieldSnippet), $entry->ID));
245 break;
246 case 'comment_status':
247 wp_all_export_write_article($article, $element_name, apply_filters('pmxe_comment_status', pmxe_filter($entry->comment_status, $fieldSnippet), $entry->ID));
248 break;
249 case 'ping_status':
250 wp_all_export_write_article($article, $element_name, apply_filters('pmxe_ping_status', pmxe_filter($entry->ping_status, $fieldSnippet), $entry->ID));
251 break;
252 case 'template':
253 wp_all_export_write_article($article, $element_name, apply_filters('pmxe_post_template', pmxe_filter(get_post_meta($entry->ID, '_wp_page_template', true), $fieldSnippet), $entry->ID));
254 break;
255 case 'order':
256 wp_all_export_write_article($article, $element_name, apply_filters('pmxe_menu_order', pmxe_filter($entry->menu_order, $fieldSnippet), $entry->ID));
257 break;
258 case 'status':
259 wp_all_export_write_article($article, $element_name, apply_filters('pmxe_post_status', pmxe_filter($entry->post_status, $fieldSnippet), $entry->ID));
260 break;
261 case 'format':
262 wp_all_export_write_article($article, $element_name, apply_filters('pmxe_post_format', pmxe_filter(get_post_format($entry->ID), $fieldSnippet), $entry->ID));
263 break;
264 case 'author':
265 wp_all_export_write_article($article, $element_name, apply_filters('pmxe_post_author', pmxe_filter($entry->post_author, $fieldSnippet), $entry->ID));
266 break;
267 case 'author_username':
268 $userData = self::getUserdata($entry->post_author);
269 if (is_object($userData)) {
270 $userDataValue = $userData->user_login;
271 } else {
272 $userDataValue = '';
273 }
274
275 wp_all_export_write_article($article, $element_name, apply_filters('pmxe_post_author', pmxe_filter($userDataValue, $fieldSnippet), $entry->ID));
276 break;
277 case 'author_email':
278 $userData = self::getUserdata($entry->post_author);
279 if (is_object($userData)) {
280 $userDataValue = $userData->user_email;
281 } else {
282 $userDataValue = '';
283 }
284
285 wp_all_export_write_article($article, $element_name, apply_filters('pmxe_post_author', pmxe_filter($userDataValue, $fieldSnippet), $entry->ID));
286 break;
287 case 'author_first_name':
288 $userData = self::getUserdata($entry->post_author);
289 if (is_object($userData)) {
290 $userDataValue = $userData->first_name;
291 } else {
292 $userDataValue = '';
293 }
294
295 wp_all_export_write_article($article, $element_name, apply_filters('pmxe_post_author', pmxe_filter($userDataValue, $fieldSnippet), $entry->ID));
296 break;
297 case 'author_last_name':
298 $userData = self::getUserdata($entry->post_author);
299 if (is_object($userData)) {
300 $userDataValue = $userData->last_name;
301 } else {
302 $userDataValue = '';
303 }
304
305 wp_all_export_write_article($article, $element_name, apply_filters('pmxe_post_author', pmxe_filter($userDataValue, $fieldSnippet), $entry->ID));
306 break;
307 case 'slug':
308 wp_all_export_write_article($article, $element_name, apply_filters('pmxe_post_slug', pmxe_filter($entry->post_name, $fieldSnippet), $entry->ID));
309 break;
310 case 'excerpt':
311 $val = apply_filters('pmxe_post_excerpt', pmxe_filter($entry->post_excerpt, $fieldSnippet), $entry->ID);
312 wp_all_export_write_article($article, $element_name, ($preview) ? trim(preg_replace('~[\r\n]+~', ' ', htmlspecialchars((string) $val))) : $val);
313 break;
314 case 'cf':
315 if (!empty($fieldValue)) {
316
317 // Clear the meta values from the previous iteration.
318 $cur_meta_values = null;
319
320 $val = "";
321
322 // Retrieve meta from *wc_orders_meta table if order export and HPOS enabled. Ensure a valid order
323 // object is returned.
324 if ( $pType === 'shop_order' && PMXE_Plugin::hposEnabled() && $order = wc_get_order( $entry->order_id ?? $entry->ID )) {
325
326 $metaName = 'get' . $fieldValue;
327
328 if(method_exists('WC_Order', $metaName)) {
329 $cur_meta_values = $order->$metaName();
330 }else {
331 $cur_meta_values = $order->get_meta( $fieldValue );
332 }
333 }
334
335 // Retrieve meta from *postmeta table if no value was found above.
336 if ( empty( $cur_meta_values ) ) {
337 $cur_meta_values = get_post_meta( $entry->order_id ?? $entry->ID, $fieldValue );
338 }
339
340 if (!empty($cur_meta_values) and is_array($cur_meta_values)) {
341 foreach ($cur_meta_values as $key => $cur_meta_value) {
342 if (empty($val)) {
343 $val = maybe_serialize($cur_meta_value);
344 } else {
345 $val = $val . $implode_delimiter . maybe_serialize($cur_meta_value);
346 }
347 }
348 $val = pmxe_filter($val, $fieldSnippet);
349 wp_all_export_write_article($article, $element_name, ($preview) ? trim(preg_replace('~[\r\n]+~', ' ', htmlspecialchars((string) $val))) : $val);
350 }
351
352 if (empty($cur_meta_values)) {
353 if (empty($article[$element_name])) {
354 wp_all_export_write_article($article, $element_name, apply_filters('pmxe_custom_field', pmxe_filter('', $fieldSnippet), $fieldValue, $entry->ID));
355 }
356 }
357 }
358 break;
359
360 case 'acf':
361
362 if(XmlExportEngine::get_addons_service()->isAcfAddonActive()) {
363
364 if (!empty($fieldLabel) and class_exists('acf')) {
365
366 global $acf;
367
368 $field_options = unserialize($fieldOptions);
369
370 if (!$is_xml_export) {
371 switch ($field_options['type']) {
372 case 'textarea':
373 case 'oembed':
374 case 'wysiwyg':
375 case 'wp_wysiwyg':
376 case 'date_time_picker':
377 case 'date_picker':
378
379 $field_value = get_field($fieldLabel, $entry->ID, false);
380
381 break;
382
383 default:
384
385 $field_value = get_field($fieldLabel, $entry->ID);
386
387 break;
388 }
389 } else {
390 $field_value = get_field($fieldLabel, $entry->ID);
391 }
392
393 // Sanitize field value to prevent ACF addon crashes
394 $sanitized_field_value = self::sanitizeAcfFieldValue($field_value, $field_options, $fieldLabel, $entry->ID);
395
396 try {
397 XmlExportACF::export_acf_field(
398 $sanitized_field_value,
399 $exportOptions,
400 $ID,
401 $entry->ID,
402 $article,
403 $xmlWriter,
404 $acfs,
405 $element_name,
406 $element_name_ns,
407 $fieldSnippet,
408 $field_options['group_id'],
409 $preview
410 );
411 } catch (Exception $e) {
412 // Fallback: if ACF addon still fails, export the raw value
413 wp_all_export_write_article($article, $element_name, $sanitized_field_value);
414 }
415 }
416 }
417
418 break;
419
420 case 'woo':
421
422 if ($is_xml_export) {
423 if (XmlExportEngine::get_addons_service()->isWooCommerceAddonActive() || XmlExportEngine::get_addons_service()->isWooCommerceProductAddonActive()) {
424 XmlExportEngine::$woo_export->export_xml($xmlWriter, $entry, $exportOptions, $ID);
425 }
426 } else {
427 if (XmlExportEngine::get_addons_service()->isWooCommerceAddonActive() || XmlExportEngine::get_addons_service()->isWooCommerceProductAddonActive()) {
428 XmlExportEngine::$woo_export->export_csv($article, $woo, $entry, $exportOptions, $ID);
429 }
430 }
431
432 break;
433
434 case 'woo_order':
435
436 if ($is_xml_export) {
437 if (XmlExportEngine::get_addons_service()->isWooCommerceAddonActive() || XmlExportEngine::get_addons_service()->isWooCommerceOrderAddonActive()) {
438 XmlExportEngine::$woo_order_export->export_xml($xmlWriter, $entry, $exportOptions, $ID, $preview);
439 }
440 } else {
441 if (XmlExportEngine::get_addons_service()->isWooCommerceAddonActive() || XmlExportEngine::get_addons_service()->isWooCommerceOrderAddonActive()) {
442 XmlExportEngine::$woo_order_export->export_csv($article, $woo_order, $entry, $exportOptions, $ID, $preview);
443 }
444 }
445
446 break;
447
448 case 'attr':
449
450 if (!empty($fieldValue)) {
451 if ($entry->post_type != 'product_variation') {
452 $txes_list = get_the_terms($entry->ID, $fieldValue);
453 if (!is_wp_error($txes_list) and !empty($txes_list)) {
454 $attr_new = array();
455 foreach ($txes_list as $t) {
456 $attr_new[] = $t->name;
457 }
458 wp_all_export_write_article($article, $element_name, apply_filters('pmxe_woo_attribute', pmxe_filter(implode($implode_delimiter, $attr_new), $fieldSnippet), $entry->ID, $fieldValue));
459 } else {
460 // Write empty value (so the functions are still applied)
461 wp_all_export_write_article($article, $element_name, pmxe_filter('', $fieldSnippet));
462 }
463 } else {
464 $attribute_pa = apply_filters('pmxe_woo_attribute', get_post_meta($entry->ID, 'attribute_' . strtolower(urlencode($fieldValue)), true), $entry->ID, $fieldValue);
465 $term = get_term_by('slug', $attribute_pa, $fieldValue);
466 if ($term and !is_wp_error($term)) {
467 $attribute_pa = pmxe_filter($term->name, $fieldSnippet);
468 } else {
469 // Write empty value (so the functions are still applied)
470 $attribute_pa = pmxe_filter('', $fieldSnippet);
471 }
472
473 wp_all_export_write_article($article, $element_name, $attribute_pa);
474 }
475
476 // if ( ! in_array($element_name, $attributes)) $attributes[] = $element_name;
477 }
478 break;
479
480 case 'cats':
481
482 if (!empty($fieldValue)) {
483
484 // get categories from parent product in case when variation exported
485 if ($fieldLabel != 'product_shipping_class') {
486 // get categories from parent product in case when variation exported
487 $entry_id = ($entry->post_type == 'product_variation') ? $entry->post_parent : $entry->ID;
488 } else {
489 $entry_id = $entry->ID;
490 }
491
492 // switch to post language if WPML installed
493 if (class_exists('SitePress')) {
494 $post_type = get_post_type($entry_id);
495 $post_type = apply_filters('wpml_element_type', $post_type);
496 $post_language_details = apply_filters('wpml_element_language_details',
497 null,
498 array(
499 'element_id' => $entry_id,
500 'element_type' => $post_type
501 )
502 );
503 $language_code = empty($post_language_details->language_code) ? '' : $post_language_details->language_code;
504 $current_language = apply_filters('wpml_current_language', null);
505 do_action('wpml_switch_language', $language_code);
506 }
507
508 $txes_list = get_the_terms($entry_id, $fieldValue);
509
510 $hierarchy_groups = array();
511
512 if (!is_wp_error($txes_list) and !empty($txes_list)) {
513 $txes_ids = array();
514
515 foreach ($txes_list as $t) {
516 $txes_ids[] = $t->term_id;
517 }
518
519 foreach ($txes_list as $t) {
520 if (wp_all_export_check_children_assign($t->term_id, $fieldValue, $txes_ids)) {
521 $ancestors = get_ancestors($t->term_id, $fieldValue);
522 if (count($ancestors) > 0) {
523 $hierarchy_group = array();
524 for ($i = count($ancestors) - 1; $i >= 0; $i--) {
525 $term = get_term_by('id', $ancestors[$i], $fieldValue);
526 if ($term) {
527 $hierarchy_group[] = $term->name;
528 }
529 }
530 $hierarchy_group[] = $t->name;
531 $hierarchy_groups[] = implode('>', $hierarchy_group);
532 } else {
533 $hierarchy_groups[] = $t->name;
534 }
535 }
536 }
537
538 // if ( empty($hierarchy_groups) ) $hierarchy_groups = '';
539 }
540
541 wp_all_export_write_article($article, $element_name, apply_filters('pmxe_post_taxonomy', pmxe_filter(implode($implode_delimiter, $hierarchy_groups), $fieldSnippet), $entry->ID));
542
543 // if ( ! in_array($element_name, $taxes)) $taxes[] = $element_name;
544
545 if ($fieldLabel == 'product_type') {
546
547 if ($entry->post_type == 'product_variation') $article[$element_name] = 'variable';
548
549 }
550
551 // swith to current language if WPML installed
552 if (class_exists('SitePress')) {
553 do_action('wpml_switch_language', $current_language);
554 }
555 }
556
557 break;
558
559 case 'sql':
560
561 if (!empty($fieldSql)) {
562 global $wpdb;
563 // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared,WordPress.DB.PreparedSQLPlaceholders.UnsupportedPlaceholder,WordPress.DB.PreparedSQLPlaceholders.UnsupportedIdentifierPlaceholder,WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare,WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,PluginCheck.Security.DirectDB.UnescapedDBParameter -- $fieldSql is admin-saved custom SQL from export template options (cc_sql); editing requires the manage_options capability; %%ID%% token is replaced with %d placeholder before being bound through $wpdb->prepare() with $entry->ID
564 $val = $wpdb->get_var($wpdb->prepare(stripcslashes(str_replace("%%ID%%", "%d", $fieldSql)), $entry->ID));
565 if (!empty($fieldPhp) and !empty($fieldCode)) {
566 // if shortcode defined
567 if (strpos($fieldCode, '[') === 0) {
568 $val = do_shortcode(str_replace("%%VALUE%%", $val, $fieldCode));
569 } else {
570 // phpcs:ignore Generic.PHP.ForbiddenFunctions.Found -- intentional: executes saved WP_Query argument string
571 $val = eval('return ' . stripcslashes(str_replace("%%VALUE%%", $val, $fieldCode)) . ';');
572 }
573 }
574 wp_all_export_write_article($article, $element_name, apply_filters('pmxe_sql_field', $val, $element_name, $entry->ID));
575 }
576 break;
577
578 case 'wpml_trid':
579
580 $post_type = get_post_type($entry->ID);
581
582 $post_type = apply_filters('wpml_element_type', $post_type);
583
584 $post_language_details = apply_filters('wpml_element_language_details',
585 null,
586 array(
587 'element_id' => $entry->ID,
588 'element_type' => $post_type
589 )
590 );
591
592 $trid = empty($post_language_details->trid) ? '' : $post_language_details->trid;
593
594 wp_all_export_write_article($article, $element_name, apply_filters('pmxe_trid_field', $trid, $element_name, $entry->ID));
595
596 break;
597
598 case 'wpml_lang':
599
600 $post_type = get_post_type($entry->ID);
601
602 $post_type = apply_filters('wpml_element_type', $post_type);
603
604 $post_language_details = apply_filters('wpml_element_language_details',
605 null,
606 array(
607 'element_id' => $entry->ID,
608 'element_type' => $post_type
609 )
610 );
611
612 $language_code = empty($post_language_details->language_code) ? '' : $post_language_details->language_code;
613
614 wp_all_export_write_article($article, $element_name, apply_filters('pmxe_trid_field', $language_code, $element_name, $entry->ID));
615
616 break;
617
618 default:
619 # code...
620 break;
621
622 }
623 if ($is_xml_export and isset($article[$element_name])) {
624 $element_name_in_file = XmlCsvExport::_get_valid_header_name($element_name);
625
626 $element_name_in_file = str_replace(' ', '', $element_name_in_file);
627 $element_name_in_file = str_replace('-', '_', $element_name_in_file);
628 $element_name_in_file = str_replace('/', '_', $element_name_in_file);
629
630 if(is_numeric(substr($element_name_in_file, 0, 1))){
631 $element_name_in_file = 'prepend_' . $element_name_in_file;
632 }
633
634 $xmlWriter = apply_filters('wp_all_export_add_before_element', $xmlWriter, $element_name_in_file, XmlExportEngine::$exportID, $entry->ID);
635
636 $xmlWriter->beginElement($element_name_ns, $element_name_in_file, null);
637 $xmlWriter->writeData($article[$element_name], $element_name_in_file);
638 $xmlWriter->closeElement();
639
640 $xmlWriter = apply_filters('wp_all_export_add_after_element', $xmlWriter, $element_name_in_file, XmlExportEngine::$exportID, $entry->ID);
641 }
642 }
643 }
644
645 return $article;
646 }
647
648 public static function prepare_import_template($exportOptions, &$templateOptions, &$cf_list, &$attr_list, &$taxs_list, $element_name, $ID)
649 {
650 $options = $exportOptions;
651
652 $element_type = $options['cc_type'][$ID];
653
654 $is_xml_template = $options['export_to'] == 'xml';
655
656 $implode_delimiter = XmlExportEngine::$implode;
657
658 switch ($element_type) {
659 case 'id':
660 if ($element_name == 'ID' && !$ID && $exportOptions['export_to'] == 'csv' && $exportOptions['export_to_sheet'] != 'csv') {
661 $element_name = 'id';
662 }
663 $templateOptions['unique_key'] = '{' . $element_name . '[1]}';
664 $templateOptions['tmp_unique_key'] = '{' . $element_name . '[1]}';
665 $templateOptions['single_product_id'] = '{' . $element_name . '[1]}';
666 break;
667 case 'title':
668 $templateOptions[$element_type] = '{' . $element_name . '[1]}';
669 $templateOptions['is_update_' . $options['cc_type'][$ID]] = 1;
670 $templateOptions['single_product_id_first_is_variation'] = '{' . $element_name . '[1]}';
671 break;
672 case 'content':
673 case 'author':
674 $templateOptions[$element_type] = '{' . $element_name . '[1]}';
675 $templateOptions['is_update_' . $options['cc_type'][$ID]] = 1;
676 break;
677 case 'slug':
678 $templateOptions['post_slug'] = '{' . $element_name . '[1]}';
679 $templateOptions['is_update_' . $options['cc_type'][$ID]] = 1;
680 break;
681 case 'parent_slug':
682 $templateOptions['is_multiple_page_parent'] = 'no';
683 $templateOptions['single_page_parent'] = '{' . $element_name . '[1]}';
684 $templateOptions['is_update_parent'] = 1;
685 break;
686 case 'parent':
687 $templateOptions['single_product_parent_id'] = '{' . $element_name . '[1]}';
688 $templateOptions['single_product_id_first_is_parent_id'] = '{' . $element_name . '[1]}';
689 break;
690 case 'excerpt':
691 $templateOptions['post_excerpt'] = '{' . $element_name . '[1]}';
692 $templateOptions['is_update_' . $options['cc_type'][$ID]] = 1;
693 break;
694 case 'status':
695 $templateOptions['status_xpath'] = '{' . $element_name . '[1]}';
696 $templateOptions['is_update_status'] = 1;
697 break;
698 case 'comment_status':
699 $templateOptions['comment_status_xpath'] = '{' . $element_name . '[1]}';
700 $templateOptions['is_update_comment_status'] = 1;
701 break;
702 case 'date':
703 $templateOptions[$element_type] = '{' . $element_name . '[1]}';
704 $templateOptions['is_update_dates'] = 1;
705 break;
706 case 'order':
707 $templateOptions[$element_type] = '{' . $element_name . '[1]}';
708 $templateOptions['is_update_menu_order'] = 1;
709 $templateOptions['single_product_menu_order'] = '{' . $element_name . '[1]}';
710 break;
711 case 'post_type':
712
713 if (empty($options['cpt'])) {
714 $templateOptions['is_override_post_type'] = 1;
715 $templateOptions['post_type_xpath'] = '{' . $element_name . '[1]}';
716 }
717 break;
718
719 case 'cf':
720
721 if (!empty($options['cc_value'][$ID])) {
722 $exclude_cf = array('_thumbnail_id');
723
724 if (strpos($options['cc_value'][$ID], 'attribute_') === 0 and !in_array($options['cc_value'][$ID], $attr_list)) {
725 $templateOptions['attribute_name'][] = str_replace('attribute_', '', $options['cc_value'][$ID]);
726 $templateOptions['attribute_value'][] = '{' . $element_name . '[1]}';
727 $templateOptions['in_variations'][] = "1";
728 $templateOptions['is_visible'][] = "1";
729 $templateOptions['is_taxonomy'][] = "0";
730 $templateOptions['create_taxonomy_in_not_exists'][] = "0";
731 $attr_list[] = $options['cc_value'][$ID];
732 } elseif (!in_array($options['cc_value'][$ID], $cf_list) and !in_array($options['cc_value'][$ID], $exclude_cf)) {
733 $cf_list[] = $options['cc_value'][$ID];
734
735 $templateOptions['custom_name'][] = $options['cc_value'][$ID];
736 $templateOptions['custom_value'][] = '{' . $element_name . '[1]}';
737 $templateOptions['custom_format'][] = 0;
738 }
739 }
740
741 break;
742
743 case 'attr':
744
745 if (!empty($options['cc_value'][$ID]) and !in_array($options['cc_value'][$ID], $attr_list)) {
746 $templateOptions['attribute_name'][] = str_replace('pa_', '', $options['cc_value'][$ID]);
747 $templateOptions['attribute_value'][] = '{' . $element_name . '[1]}';
748 $templateOptions['in_variations'][] = "1";
749 $templateOptions['is_visible'][] = "1";
750 $templateOptions['is_taxonomy'][] = "1";
751 $templateOptions['create_taxonomy_in_not_exists'][] = "1";
752 $attr_list[] = $options['cc_value'][$ID];
753 }
754
755 break;
756 case 'cats':
757 if (!empty($options['cc_value'][$ID])) {
758 switch ($options['cc_label'][$ID]) {
759 case 'product_type':
760 $templateOptions['is_multiple_product_type'] = 'no';
761 $templateOptions['single_product_type'] = '{' . $element_name . '[1]}';
762 break;
763 case 'product_shipping_class':
764 $templateOptions['is_multiple_product_shipping_class'] = 'no';
765 $templateOptions['single_product_shipping_class'] = '{' . $element_name . '[1]}';
766 break;
767 default:
768 $taxonomy = $options['cc_value'][$ID];
769 $templateOptions['tax_assing'][$taxonomy] = 1;
770
771 if (is_taxonomy_hierarchical($taxonomy)) {
772 $templateOptions['tax_logic'][$taxonomy] = 'hierarchical';
773 $templateOptions['tax_hierarchical_logic_entire'][$taxonomy] = 1;
774 $templateOptions['multiple_term_assing'][$taxonomy] = 1;
775 $templateOptions['tax_hierarchical_delim'][$taxonomy] = '>';
776 $templateOptions['is_tax_hierarchical_group_delim'][$taxonomy] = 1;
777 $templateOptions['tax_hierarchical_group_delim'][$taxonomy] = $is_xml_template ? '|' : $implode_delimiter;
778 $templateOptions['tax_hierarchical_xpath'][$taxonomy] = array('{' . $element_name . '[1]}');
779 } else {
780 $templateOptions['tax_logic'][$taxonomy] = 'multiple';
781 $templateOptions['multiple_term_assing'][$taxonomy] = 1;
782 $templateOptions['tax_multiple_xpath'][$taxonomy] = '{' . $element_name . '[1]}';
783 $templateOptions['tax_multiple_delim'][$taxonomy] = $is_xml_template ? '|' : $implode_delimiter;
784 }
785 $taxs_list[] = $taxonomy;
786 break;
787 }
788 }
789 break;
790 }
791 }
792
793 static function getUserdata($userId)
794 {
795 if (!isset(self::$userData[$userId])) {
796 self::$userData[$userId] = get_userdata($userId);
797 }
798 return self::$userData[$userId];
799 }
800
801 /**
802 * Sanitize ACF field values to prevent addon crashes from corrupted data
803 *
804 * @param mixed $field_value The field value from ACF
805 * @param array $field_options The field configuration
806 * @param string $field_label The field label
807 * @param int $entry_id The post ID for logging
808 * @return mixed Sanitized field value
809 */
810 private static function sanitizeAcfFieldValue($field_value, $field_options, $field_label, $entry_id) {
811 // If field value is null or empty, return as-is
812 if (empty($field_value) && $field_value !== 0 && $field_value !== '0') {
813 return $field_value;
814 }
815
816 $field_type = isset($field_options['type']) ? $field_options['type'] : 'unknown';
817
818 // Handle corrupted data where arrays became strings
819 if (is_string($field_value) && $field_value === 'Array') {
820 return '';
821 }
822
823 // Handle specific field types that expect arrays
824 switch ($field_type) {
825 case 'google_map':
826 if (is_string($field_value) && strpos($field_value, 'Array') === 0) {
827 return null;
828 }
829 if (is_string($field_value) && $field_value !== 'Array') {
830 return $field_value;
831 }
832 break;
833
834 case 'repeater':
835 case 'flexible_content':
836 case 'group':
837 case 'gallery':
838 case 'relationship':
839 case 'post_object':
840 if (is_string($field_value) && (strpos($field_value, 'Array') === 0 || $field_value === 'Array')) {
841 return array();
842 }
843 break;
844 }
845
846 // For all other cases, return the value as-is
847 return $field_value;
848 }
849 }
850
851