PluginProbe ʕ •ᴥ•ʔ
WP All Export – Drag & Drop Export to Any Custom CSV, XML & Excel / 1.4.6
WP All Export – Drag & Drop Export to Any Custom CSV, XML & Excel v1.4.6
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 / XmlExportEngine.php
wp-all-export / libraries Last commit date
VariableProductTitle 9 years ago .gitkeep 10 years ago WpaeInvalidPhpException.php 9 years ago WpaeInvalidStringException.php 9 years ago WpaeMethodNotFoundException.php 9 years ago WpaePhpInterpreterErrorHandler.php 2 years ago WpaeString.php 8 years ago WpaeTooMuchRecursionException.php 9 years ago WpaeXmlProcessor.php 2 years ago XmlCsvExport.php 2 years ago XmlExportComment.php 4 years ago XmlExportCpt.php 2 years ago XmlExportCustomRecord.php 3 years ago XmlExportEngine.php 2 years ago XmlExportFiltering.php 4 years ago XmlExportMediaGallery.php 3 years ago XmlExportTaxonomy.php 4 years ago XmlGoogleMerchants.php 9 years ago XmlSpec.php 9 years ago
XmlExportEngine.php
1343 lines
1 <?php
2
3 if ( ! class_exists('XmlExportEngine') ){
4
5 require_once dirname(__FILE__) . '/XmlExportComment.php';
6 require_once dirname(__FILE__) . '/XmlExportTaxonomy.php';
7
8 final class XmlExportEngine
9 {
10
11 const VARIABLE_PRODUCTS_EXPORT_PARENT_AND_VARIATION = 1;
12 const VARIABLE_PRODUCTS_EXPORT_VARIATION = 2;
13 const VARIABLE_PRODUCTS_EXPORT_PARENT = 3;
14
15 const VARIATION_USE_PARENT_TITLE = 1;
16 const VARIATION_USE_DEFAULT_TITLE = 2;
17
18 /**
19 * Custom XML Loop begin statement
20 * @var string
21 */
22 const XML_LOOP_START = '<!-- BEGIN LOOP -->';
23
24 /**
25 * Custom XML Loop end statement
26 * @var string
27 */
28 const XML_LOOP_END = '<!-- END LOOP -->';
29
30 const EXPORT_TYPE_GOOLE_MERCHANTS = 'XmlGoogleMerchants';
31 const EXPORT_TYPE_XML = 'xml';
32 const EXPORT_TYPE_CSV = 'csv';
33
34 public static $acf_export;
35 public static $woo_export = false;
36 public static $woo_order_export;
37 public static $woo_coupon_export;
38 public static $woo_refund_export;
39 public static $woo_review_export;
40 public static $user_export = false;
41 public static $comment_export;
42 public static $taxonomy_export;
43 public static $custom_record_export;
44
45 public static $is_woo_order_export = false;
46
47 public static $is_preview = false;
48
49 public static $implode = ',';
50
51 private $post;
52 private $_existing_meta_keys = array();
53 private $_existing_taxonomies = array();
54
55 private static $addons_service = false;
56
57 private $init_fields = array(
58 array(
59 'label' => 'id',
60 'name' => 'ID',
61 'type' => 'id'
62 ),
63 array(
64 'label' => 'title',
65 'name' => 'Title',
66 'type' => 'title'
67 ),
68 array(
69 'label' => 'content',
70 'name' => 'Content',
71 'type' => 'content'
72 )
73 );
74
75 public static $default_fields = array(
76 array(
77 'label' => 'id',
78 'name' => 'ID',
79 'type' => 'id'
80 ),
81 array(
82 'label' => 'title',
83 'name' => 'Title',
84 'type' => 'title'
85 ),
86 array(
87 'label' => 'content',
88 'name' => 'Content',
89 'type' => 'content'
90 ),
91 array(
92 'label' => 'excerpt',
93 'name' => 'Excerpt',
94 'type' => 'excerpt'
95 ),
96 array(
97 'label' => 'date',
98 'name' => 'Date',
99 'type' => 'date'
100 ),
101 array(
102 'label' => 'post_type',
103 'name' => 'Post Type',
104 'type' => 'post_type'
105 ),
106 array(
107 'label' => 'permalink',
108 'name' => 'Permalink',
109 'type' => 'permalink'
110 )
111 );
112
113 private $other_fields = array(
114 array(
115 'label' => 'status',
116 'name' => 'Status',
117 'type' => 'status'
118 ),
119
120 array(
121 'label' => 'author',
122 'name' => 'Author ID',
123 'type' => 'author'
124 ),
125
126 array(
127 'label' => 'author_username',
128 'name' => 'Author Username',
129 'type' => 'author_username'
130 ),
131
132 array(
133 'label' => 'author_email',
134 'name' => 'Author Email',
135 'type' => 'author_email'
136 ),
137
138 array(
139 'label' => 'author_first_name',
140 'name' => 'Author First Name',
141 'type' => 'author_first_name'
142 ),
143
144 array(
145 'label' => 'author_last_name',
146 'name' => 'Author Last Name',
147 'type' => 'author_last_name'
148 ),
149
150 array(
151 'label' => 'slug',
152 'name' => 'Slug',
153 'type' => 'slug'
154 ),
155 array(
156 'label' => 'format',
157 'name' => 'Format',
158 'type' => 'format'
159 ),
160 array(
161 'label' => 'template',
162 'name' => 'Template',
163 'type' => 'template'
164 ),
165 array(
166 'label' => 'parent',
167 'name' => 'Parent',
168 'type' => 'parent'
169 ),
170 array(
171 'label' => 'parent_slug',
172 'name' => 'Parent Slug',
173 'type' => 'parent_slug'
174 ),
175 array(
176 'label' => 'order',
177 'name' => 'Order',
178 'type' => 'order'
179 ),
180 array(
181 'label' => 'comment_status',
182 'name' => 'Comment Status',
183 'type' => 'comment_status'
184 ),
185 array(
186 'label' => 'ping_status',
187 'name' => 'Ping Status',
188 'type' => 'ping_status'
189 ),
190 array(
191 'label' => 'post_modified',
192 'name' => 'Post Modified Date',
193 'type' => 'post_modified'
194 )
195 );
196
197 private $available_sections = array();
198 private $filter_sections = array();
199
200 private $errors;
201
202 private $available_data = array(
203 'acf_groups' => array(),
204 'existing_acf_meta_keys' => array(),
205 'existing_meta_keys' => array(),
206 'init_fields' => array(),
207 'default_fields' => array(),
208 'other_fields' => array(),
209 'woo_data' => array(),
210 'existing_attributes' => array(),
211 'existing_taxonomies' => array()
212 );
213
214 private $filters;
215
216 public static $is_user_export = false;
217 public static $is_comment_export = false;
218 public static $is_taxonomy_export = false;
219 public static $is_custom_addon_export = false;
220 public static $post_types = array();
221 public static $exportOptions = array();
222 public static $exportQuery;
223 public static $exportID = false;
224 public static $exportRecord = false;
225 public static $globalAvailableSections;
226
227 public static $is_auto_generate_enabled = true;
228
229 public function __construct( $post, & $errors = false ){
230
231 $this->post = $post;
232 $this->errors = $errors;
233
234 $this->available_sections = array(
235 'default' => array(
236 'title' => __("Standard", "wp_all_export_plugin"),
237 'content' => 'default_fields'
238 ),
239 'media' => array(
240 'title' => __("Media", "wp_all_export_plugin"),
241 'content' => '',
242 'additional' => array(
243 'images' => array(
244 'title' => __("Images", "wp_all_export_plugin"),
245 'meta' => array(
246 array(
247 'name' => 'URL',
248 'label' => 'url',
249 'type' => 'image_url',
250 'auto' => 1
251 ),
252 array(
253 'name' => 'Filename',
254 'label' => 'filename',
255 'type' => 'image_filename'
256 ),
257 array(
258 'name' => 'Path',
259 'label' => 'path',
260 'type' => 'image_path'
261 ),
262 array(
263 'name' => 'ID',
264 'label' => 'image_id',
265 'type' => 'image_id'
266 ),
267 array(
268 'name' => 'Title',
269 'label' => 'title',
270 'type' => 'image_title',
271 'auto' => 1
272 ),
273 array(
274 'name' => 'Caption',
275 'label' => 'caption',
276 'type' => 'image_caption',
277 'auto' => 1
278 ),
279 array(
280 'name' => 'Description',
281 'label' => 'description',
282 'type' => 'image_description',
283 'auto' => 1
284 ),
285 array(
286 'name' => 'Alt Text',
287 'label' => 'alt',
288 'type' => 'image_alt',
289 'auto' => 1
290 ),
291 array(
292 'name' => 'Featured',
293 'label' => 'featured',
294 'type' => 'image_featured',
295 'auto' => 1
296 ),
297 )
298 ),
299 'attachments' => array(
300 'title' => __("Attachments", "wp_all_export_plugin"),
301 'meta' => array(
302 array(
303 'name' => 'URL',
304 'label' => 'url',
305 'type' => 'attachment_url',
306 'auto' => 1
307 ),
308 array(
309 'name' => 'Filename',
310 'label' => 'filename',
311 'type' => 'attachment_filename'
312 ),
313 array(
314 'name' => 'Path',
315 'label' => 'path',
316 'type' => 'attachment_path'
317 ),
318 array(
319 'name' => 'ID',
320 'label' => 'attachment_id',
321 'type' => 'attachment_id'
322 ),
323 array(
324 'name' => 'Title',
325 'label' => 'title',
326 'type' => 'attachment_title'
327 ),
328 array(
329 'name' => 'Caption',
330 'label' => 'caption',
331 'type' => 'attachment_caption'
332 ),
333 array(
334 'name' => 'Description',
335 'label' => 'description',
336 'type' => 'attachment_description'
337 ),
338 array(
339 'name' => 'Alt Text',
340 'label' => 'alt',
341 'type' => 'attachment_alt'
342 ),
343 )
344 )
345 )
346 ),
347 'cats' => array(
348 'title' => __("Taxonomies", "wp_all_export_plugin"),
349 'content' => 'existing_taxonomies'
350 ),
351 'cf' => array(
352 'title' => __("Custom Fields", "wp_all_export_plugin"),
353 'content' => 'existing_meta_keys'
354 ),
355 'other' => array(
356 'title' => __("Other", "wp_all_export_plugin"),
357 'content' => 'other_fields'
358 )
359 );
360
361 $this->available_sections = apply_filters('pmxe_available_sections', $this->available_sections);
362
363 $this->filter_sections = array(
364 'author' => array(
365 'title' => __("Author", "wp_all_export_plugin"),
366 'fields' => array(
367 'user_ID' => 'User ID',
368 'user_login' => 'User Login',
369 'user_nicename' => 'Nicename',
370 'user_email' => 'Email',
371 'user_registered' => 'Date Registered (Y-m-d H:i:s)',
372 'display_name' => 'Display Name',
373 'cf_first_name' => 'First Name',
374 'cf_last_name' => 'Last Name',
375 'nickname' => 'Nickname',
376 'description' => 'User Description',
377 'wp_capabilities' => 'User Role'
378 )
379 )
380 );
381
382 if ( 'specific' == $this->post['export_type'])
383 {
384
385 self::$post_types = ( ! is_array($this->post['cpt']) ) ? array($this->post['cpt']) : $this->post['cpt'];
386
387 if( \class_exists('WooCommerce') && XmlExportEngine::get_addons_service()->isWooCommerceAddonActive()) {
388 if (in_array('product', self::$post_types) and !in_array('product_variation', self::$post_types)) self::$post_types[] = 'product_variation';
389 } else if(\class_exists('WooCommerce') && in_array('product', self::$post_types) && XmlExportEngine::get_addons_service()->isWooCommerceProductAddonActive()) {
390 self::$post_types = ['product'];
391 }
392
393 self::$is_user_export = ( in_array('users', self::$post_types) or in_array('shop_customer', self::$post_types) ) ? true : false;
394
395 self::$is_comment_export = ( in_array('comments', self::$post_types) ) ? true : false;
396
397 self::$is_taxonomy_export = ( in_array('taxonomies', self::$post_types) ) ? true : false;
398
399 if(count(self::$post_types) === 1) {
400 if(strpos(self::$post_types[0], 'custom_') === 0 ) {
401 self::$is_custom_addon_export = true;
402 }
403 }
404 }
405 else
406 {
407 self::$is_user_export = ( 'wp_user_query' == $this->post['wp_query_selector'] );
408 self::$is_comment_export = ( 'wp_comment_query' == $this->post['wp_query_selector'] );
409 }
410
411 if ( ! self::$is_user_export && ! self::$is_comment_export && ! self::$is_taxonomy_export)
412 {
413 add_filter("wp_all_export_filters", array( &$this, "filter_export_filters"), 10, 1);
414
415 // When WPML is active and at least one post in the export has a trid
416 if (class_exists('SitePress'))
417 {
418 self::$default_fields[] = array(
419 'label' => 'wpml_trid',
420 'name' => 'WPML Translation ID',
421 'type' => 'wpml_trid'
422 );
423
424 self::$default_fields[] = array(
425 'label' => 'wpml_lang',
426 'name' => 'WPML Language Code',
427 'type' => 'wpml_lang'
428 );
429 }
430 }
431
432 self::$exportOptions = $post;
433
434 if ( ! empty(PMXE_Plugin::$session) and PMXE_Plugin::$session->has_session() )
435 {
436 $filter_args = array(
437 'filter_rules_hierarhy' => $this->post['filter_rules_hierarhy'],
438 'product_matching_mode' => $this->post['product_matching_mode'],
439 'taxonomy_to_export' => empty($this->post['taxonomy_to_export']) ? '' : $this->post['taxonomy_to_export']
440 );
441
442 $this->filters = \Wpae\Pro\Filtering\FilteringFactory::getFilterEngine();
443 $this->filters->init($filter_args);
444
445 $this->init();
446 }
447
448 if (empty(self::$exportOptions['delimiter'])) self::$exportOptions['delimiter'] = ',';
449
450 self::$implode = (self::$exportOptions['delimiter'] == ',') ? '|' : ',';
451
452 self::$implode = apply_filters('wp_all_export_implode_delimiter', self::$implode, self::$exportID);
453
454 if ( !empty(self::$exportOptions['xml_template_type']) && in_array(self::$exportOptions['xml_template_type'], array('custom', 'XmlGoogleMerchants')) ) self::$implode = '#delimiter#';
455
456 self::$comment_export = new XmlExportComment();
457 self::$taxonomy_export = new XmlExportTaxonomy();
458 self::$custom_record_export = new XmlExportCustomRecord();
459 self::$is_woo_order_export = in_array('shop_order', self::$post_types);
460
461 do_action('pmxe_init_addons');
462 }
463
464 // [FILTERS]
465
466 /**
467 *
468 * Filter data for advanced filtering
469 *
470 */
471 public function filter_export_filters($filters){
472 return array_merge($filters, $this->filter_sections);
473 }
474
475 // [\FILTERS]
476
477 protected function init(){
478
479 PMXE_Plugin::$session->set('is_user_export', self::$is_user_export);
480 PMXE_Plugin::$session->set('is_comment_export', self::$is_comment_export);
481 PMXE_Plugin::$session->set('is_taxonomy_export', self::$is_taxonomy_export);
482 PMXE_Plugin::$session->save_data();
483
484 if ('advanced' == $this->post['export_type']) {
485
486 if( "" == $this->post['wp_query'] ){
487 $this->errors->add('form-validation', __('WP Query field is required', 'pmxe_plugin'));
488 }
489 else if(!XmlExportEngine::get_addons_service()->isWooCommerceAddonActive() && strpos($this->post['wp_query'], 'product') !== false && \class_exists('WooCommerce')) {
490 $this->errors->add('form-validation', __('The WooCommerce Export Add-On Pro is required to Export WooCommerce Products', 'pmxe_plugin'));
491 }
492 else if(!XmlExportEngine::get_addons_service()->isWooCommerceAddonActive() && strpos($this->post['wp_query'], 'shop_order') !== false) {
493 $this->errors->add('form-validation', __('The WooCommerce Export Add-On Pro is required to Export WooCommerce Orders', 'pmxe_plugin'));
494 }
495 else if(!XmlExportEngine::get_addons_service()->isWooCommerceAddonActive() && strpos($this->post['wp_query'], 'shop_coupon') !== false) {
496 $this->errors->add('form-validation', __('The WooCommerce Export Add-On Pro is required to Export WooCommerce Coupons', 'pmxe_plugin'));
497 }
498 else
499 {
500 $this->filters->parse();
501
502 PMXE_Plugin::$session->set('whereclause', $this->filters->get('queryWhere'));
503 PMXE_Plugin::$session->set('joinclause', $this->filters->get('queryJoin'));
504 PMXE_Plugin::$session->set('wp_query', $this->post['wp_query']);
505 PMXE_Plugin::$session->save_data();
506 }
507 }
508 else
509 {
510 $this->filters->parse();
511
512 PMXE_Plugin::$session->set('cpt', self::$post_types);
513 PMXE_Plugin::$session->set('whereclause', $this->filters->get('queryWhere'));
514 PMXE_Plugin::$session->set('joinclause', $this->filters->get('queryJoin'));
515 PMXE_Plugin::$session->save_data();
516 }
517
518 PMXE_Plugin::$session->save_data();
519
520 }
521
522 public function init_additional_data(){
523
524 if(self::$woo_export) {
525 self::$woo_export->init_additional_data();
526 }
527
528 if(self::$woo_order_export) {
529 self::$woo_order_export->init_additional_data();
530 }
531 }
532
533 public function init_available_data(){
534
535 global $wpdb;
536 $table_prefix = $wpdb->prefix;
537
538 // Prepare existing taxonomies
539 if ( 'specific' == $this->post['export_type'] and ! self::$is_user_export and ! self::$is_comment_export and ! self::$is_taxonomy_export )
540 {
541 $this->_existing_taxonomies = wp_all_export_get_existing_taxonomies_by_cpt( self::$post_types[0] );
542
543 $this->_existing_meta_keys = wp_all_export_get_existing_meta_by_cpt( self::$post_types[0] );
544 }
545 if ( 'advanced' == $this->post['export_type'] and ! self::$is_user_export and ! self::$is_comment_export and ! self::$is_taxonomy_export )
546 {
547 $meta_keys = $wpdb->get_results("SELECT DISTINCT meta_key FROM {$table_prefix}postmeta WHERE {$table_prefix}postmeta.meta_key NOT LIKE '_edit%' AND {$table_prefix}postmeta.meta_key NOT LIKE '_oembed_%' LIMIT 1000");
548 if ( ! empty($meta_keys)){
549 $exclude_keys = array('_first_variation_attributes', '_is_first_variation_created');
550 foreach ($meta_keys as $meta_key) {
551 if ( strpos($meta_key->meta_key, "_tmp") === false && strpos($meta_key->meta_key, "_v_") === false && ! in_array($meta_key->meta_key, $exclude_keys))
552 $this->_existing_meta_keys[] = $meta_key->meta_key;
553 }
554 }
555
556 global $wp_taxonomies;
557
558 foreach ($wp_taxonomies as $key => $obj) { if (in_array($obj->name, array('nav_menu'))) continue;
559
560 if (strpos($obj->name, "pa_") !== 0 and strlen($obj->name) > 3)
561 $this->_existing_taxonomies[] = array(
562 'name' => empty($obj->label) ? $obj->name : $obj->label,
563 'label' => $obj->name,
564 'type' => 'cats'
565 );
566 }
567 }
568
569 if(self::$acf_export) {
570 // Prepare existing ACF groups & fields
571 self::$acf_export->init($this->_existing_meta_keys);
572 }
573
574 if(XmlExportEngine::$woo_export) {
575 // Prepare existing WooCommerce data
576 self::$woo_export->init($this->_existing_meta_keys);
577
578 if(self::get_addons_service()->isWooCommerceAddonActive()) {
579 // Prepare existing WooCommerce Coupon data
580 self::$woo_coupon_export->init($this->_existing_meta_keys);
581 }
582 }
583 if(XmlExportEngine::$woo_order_export) {
584 // Prepare existing WooCommerce Order data
585 self::$woo_order_export->init($this->_existing_meta_keys);
586
587
588 }
589
590 if(XmlExportEngine::$user_export) {
591 // Prepare existing Users data
592 self::$user_export->init($this->_existing_meta_keys);
593 }
594
595 // Prepare existing Comments data
596 self::$comment_export->init($this->_existing_meta_keys);
597
598 // Prepare existing Taxonomy data
599 self::$taxonomy_export->init($this->_existing_meta_keys);
600
601 return $this->get_available_data();
602 }
603
604 public function get_available_data(){
605
606 if(self::$acf_export) {
607 $this->available_data['acf_groups'] = self::$acf_export->get('_acf_groups');
608 $this->available_data['existing_acf_meta_keys'] = self::$acf_export->get('_existing_acf_meta_keys');
609 }
610
611 $this->available_data['existing_meta_keys'] = $this->_existing_meta_keys;
612 $this->available_data['existing_taxonomies'] = $this->_existing_taxonomies;
613
614 $this->available_data['init_fields'] = apply_filters('wp_all_export_init_fields', $this->init_fields);
615 $this->available_data['default_fields'] = apply_filters('wp_all_export_default_fields', self::$default_fields);
616 $this->available_data['other_fields'] = apply_filters('wp_all_export_other_fields', $this->other_fields);
617
618 $this->available_data = apply_filters("wp_all_export_available_data", $this->available_data);
619
620 return $this->available_data;
621
622 }
623
624 public function get_fields_options( $field_keys = array() ){
625
626 $fields = array(
627 'ids' => array(),
628 'cc_label' => array(),
629 'cc_php' => array(),
630 'cc_code' => array(),
631 'cc_sql' => array(),
632 'cc_options' => array(),
633 'cc_type' => array(),
634 'cc_value' => array(),
635 'cc_name' => array(),
636 'cc_settings' => array()
637 );
638
639 self::$woo_order_export->get_fields_options( $fields, $field_keys );
640
641 $available_sections = apply_filters("wp_all_export_available_sections", $this->available_sections);
642
643 foreach ($available_sections as $slug => $section)
644 {
645 if ( ! empty($this->available_data[$section['content']]) ):
646
647 foreach ($this->available_data[$section['content']] as $field)
648 {
649
650 $field_key = (is_array($field)) ? $field['name'] : $field;
651
652 if ( ! in_array($field_key, $field_keys) ) continue;
653
654 $fields['ids'][] = 1;
655 $fields['cc_label'][] = (is_array($field)) ? $field['label'] : $field;
656 $fields['cc_php'][] = '';
657 $fields['cc_code'][] = '';
658 $fields['cc_sql'][] = '';
659 $fields['cc_options'][] = '';
660 $fields['cc_type'][] = (is_array($field)) ? $field['type'] : $slug;
661 $fields['cc_value'][] = (is_array($field)) ? $field['label'] : $field;
662 $fields['cc_name'][] = $field_key;
663 $fields['cc_settings'][] = '';
664 }
665 endif;
666
667 if ( ! empty($section['additional']) )
668 {
669 foreach ($section['additional'] as $sub_slug => $sub_section)
670 {
671
672 foreach ($sub_section['meta'] as $field) {
673 $key_to_check = (is_array($field)) ? $field['name'] : $field;
674
675 if ( in_array($sub_slug, array('images', 'attachments')) ){
676 $key_to_check = preg_replace("%s$%","",ucfirst($sub_slug)) . ' ' . $key_to_check;
677 }
678
679 if ( ! in_array($key_to_check, $field_keys) ) continue;
680
681 $field_options = ( in_array($sub_slug, array('images', 'attachments')) ) ? esc_attr('{"is_export_featured":true,"is_export_attached":true,"image_separator":"|"}') : '0';
682
683 $fields['ids'][] = 1;
684 $fields['cc_label'][] = (is_array($field)) ? $field['label'] : $field;
685 $fields['cc_php'][] = '';
686 $fields['cc_code'][] = '';
687 $fields['cc_sql'][] = '';
688 $fields['cc_options'][] = $field_options;
689 $fields['cc_type'][] = (is_array($field)) ? $field['type'] : $sub_slug;
690 $fields['cc_value'][] = (is_array($field)) ? $field['label'] : $field;
691 $fields['cc_name'][] = $key_to_check;
692 $fields['cc_settings'][] = '';
693 }
694 }
695 }
696 }
697
698 if ( ! self::$is_comment_export )
699 {
700 if(self::$acf_export) {
701 self::$acf_export->get_fields_options( $fields, $field_keys );
702 }
703 }
704
705 $sort_fields = array();
706 foreach ($field_keys as $i => $field_key){
707 foreach ($fields['cc_name'] as $j => $cc_name){
708 if (!empty($cc_name) && $cc_name == $field_key){
709 $sort_fields['ids'][] = 1;
710 $sort_fields['cc_label'][] = $fields['cc_label'][$j];
711 $sort_fields['cc_php'][] = $fields['cc_php'][$j];
712 $sort_fields['cc_code'][] = $fields['cc_code'][$j];
713 $sort_fields['cc_sql'][] = $fields['cc_sql'][$j];
714 $sort_fields['cc_options'][] = $fields['cc_options'][$j];
715 $sort_fields['cc_type'][] = $fields['cc_type'][$j];
716 $sort_fields['cc_value'][] = $fields['cc_value'][$j];
717 $sort_fields['cc_name'][] = $fields['cc_name'][$j];
718 $sort_fields['cc_settings'][] = $fields['cc_settings'][$j];
719 break;
720 }
721 }
722 }
723
724 return $sort_fields;
725
726 }
727
728 public function render(){
729
730 $i = 0;
731
732 ob_start();
733
734 $available_sections = apply_filters("wp_all_export_available_sections", $this->available_sections);
735 self::$globalAvailableSections = $available_sections;
736
737 if(self::$woo_order_export) {
738 // Render Available WooCommerce Orders Data
739 self::$woo_order_export->render($i);
740 }
741
742 foreach ($available_sections as $slug => $section)
743 {
744
745 if ( ! empty($this->available_data[$section['content']]) or ! empty($section['additional']) ):
746 ?>
747 <p class="wpae-available-fields-group"><?php echo esc_html($section['title']); ?><span class="wpae-expander">+</span></p>
748 <div class="wpae-custom-field">
749 <?php
750 if($slug == 'cf' && XmlExportEngine::$is_user_export) {
751 ?>
752 <div class="wpallexport-free-edition-notice">
753 <a class="upgrade_link" target="_blank" href="https://www.wpallimport.com/checkout/?edd_action=add_to_cart&download_id=5839967&edd_options%5Bprice_id%5D=1&utm_source=export-plugin-free&utm_medium=upgrade-notice&utm_campaign=export-user-meta">Upgrade to the Pro edition of WP All Export to Export User Meta</a>
754 </div>
755 <?php
756 }
757 ?>
758 <?php
759 if($slug == 'other' && XmlExportEngine::$is_user_export) {
760 ?>
761 <div class="wpallexport-free-edition-notice">
762 <a class="upgrade_link" target="_blank" href="https://www.wpallimport.com/checkout/?edd_action=add_to_cart&download_id=5839967&edd_options%5Bprice_id%5D=1&utm_source=export-plugin-free&utm_medium=upgrade-notice&utm_campaign=export-advanced-user-data">Upgrade to the Pro edition of WP All Export to Export Advanced Fields</a>
763 </div>
764 <?php
765 }
766 $elementClass = "";
767 if(($slug == 'cf' || $slug == 'other') && XmlExportEngine::$is_user_export){
768 $elementClass = 'wpallexport_disabled';
769 }
770 ?>
771 <ul>
772 <?php if ( ! empty($this->available_data[$section['content']]) ): ?>
773 <li class="<?php echo esc_attr($elementClass); ?>">
774 <div class="default_column" rel="">
775 <label class="wpallexport-element-label"><?php esc_html_e("All", "wp_all_export_plugin") . ' ' . esc_html($section['title']); ?></label>
776 <input type="hidden" name="rules[]" value="<?php echo esc_attr("pmxe_" . $slug); ?>"/>
777 </div>
778 </li>
779 <?php
780 foreach ($this->available_data[$section['content']] as $field)
781 {
782 $field_type = is_array($field) ? $field['type'] : $slug;
783 $field_name = is_array($field) ? $field['name'] : $field;
784
785 if ( $field_type == 'cf' && $field_name == '_thumbnail_id' ) continue;
786
787 $is_auto_field = ( ! empty($field['auto']) or self::$is_auto_generate_enabled and ('specific' != $this->post['export_type'] or 'specific' == $this->post['export_type'] and (! in_array(self::$post_types[0], array('product')) || !\class_exists('WooCommerce'))));
788
789 ?>
790 <li class="pmxe_<?php echo $slug; ?> <?php if ( $is_auto_field ) echo 'wp_all_export_auto_generate';?> <?php echo esc_attr($elementClass);?>">
791 <div class="custom_column" rel="<?php echo ($i + 1);?>">
792 <label class="wpallexport-xml-element"><?php echo esc_html(is_array($field) ? $field['name'] : $field); ?></label>
793 <input type="hidden" name="ids[]" value="1"/>
794 <input type="hidden" name="cc_label[]" value="<?php echo esc_html(is_array($field) ? $field['label'] : $field); ?>"/>
795 <input type="hidden" name="cc_php[]" value="0"/>
796 <input type="hidden" name="cc_code[]" value=""/>
797 <input type="hidden" name="cc_sql[]" value="0"/>
798 <input type="hidden" name="cc_options[]" value="0"/>
799 <input type="hidden" name="cc_type[]" value="<?php echo esc_html(is_array($field) ? $field['type'] : $slug); ?>"/>
800 <input type="hidden" name="cc_value[]" value="<?php echo esc_html(is_array($field) ? $field['label'] : $field); ?>"/>
801 <input type="hidden" name="cc_name[]" value="<?php echo esc_html(is_array($field) ? $field['name'] : $field); ?>"/>
802 <input type="hidden" name="cc_settings[]" value="0"/>
803 </div>
804 </li>
805 <?php
806 $i++;
807 }
808 endif;
809
810 if ( ! empty($section['additional']) )
811 {
812 foreach ($section['additional'] as $sub_slug => $sub_section)
813 {
814
815 ?>
816 <li class="available_sub_section">
817 <p class="wpae-available-fields-group"><?php echo esc_html($sub_section['title']); ?><span
818 class="wpae-expander">+</span></p>
819 <div class="wpae-custom-field">
820 <?php
821 $show_additional_subsection = apply_filters("wp_all_export_show_additional_subsection", true, $sub_slug, $sub_section);
822 do_action("wp_all_export_before_available_subsection", $sub_slug, $sub_section);
823
824
825 if($show_additional_subsection) { ?>
826
827 <ul>
828 <li>
829 <div class="default_column" rel="">
830 <label class="wpallexport-element-label"><?php echo __("All", "wp_all_export_plugin") . ' ' . esc_html($sub_section['title']); ?></label>
831 <input type="hidden" name="rules[]"
832 value="<?php echo esc_attr("pmxe_" . $slug . "_" . $sub_slug); ?>"/>
833 </div>
834 </li>
835 <?php
836 foreach ($sub_section['meta'] as $field) {
837 $is_auto_field = empty($field['auto']) ? false : true;
838 $field_options = (in_array($sub_slug, array('images', 'attachments'))) ? esc_attr('{"is_export_featured":true,"is_export_attached":true,"image_separator":"|"}') : '0';
839 ?>
840 <li class="<?php echo esc_attr("pmxe_" . $slug . "_" . $sub_slug); ?> <?php if ($is_auto_field) echo 'wp_all_export_auto_generate'; ?>">
841 <div class="custom_column" rel="<?php echo($i + 1); ?>">
842 <label class="wpallexport-xml-element"><?php echo (is_array($field)) ? esc_html(XmlExportEngine::sanitizeFieldName($field['name'])) : esc_html($field); ?></label>
843 <input type="hidden" name="ids[]" value="1"/>
844 <input type="hidden" name="cc_label[]"
845 value="<?php echo (is_array($field)) ? esc_attr($field['label']) : esc_attr($field); ?>"/>
846 <input type="hidden" name="cc_php[]" value="0"/>
847 <input type="hidden" name="cc_code[]" value="0"/>
848 <input type="hidden" name="cc_sql[]" value="0"/>
849 <input type="hidden" name="cc_options[]"
850 value="<?php echo esc_attr($field_options); ?>"/>
851 <input type="hidden" name="cc_type[]"
852 value="<?php echo (is_array($field)) ? esc_attr($field['type']) : esc_attr($sub_slug); ?>"/>
853 <input type="hidden" name="cc_value[]"
854 value="<?php echo (is_array($field)) ? esc_attr($field['label']) : esc_attr($field); ?>"/>
855 <input type="hidden" name="cc_name[]"
856 value="<?php echo (is_array($field)) ? esc_attr(XmlExportEngine::sanitizeFieldName($field['name'])) : esc_attr($field); ?>"/>
857 <input type="hidden" name="cc_settings[]" value=""/>
858 </div>
859 </li>
860 <?php
861 $i++;
862
863 }
864 ?>
865 </ul>
866 <?php
867 }
868 ?>
869 </div>
870 </li>
871 <?php
872
873 }
874 }
875 ?>
876 </ul>
877 </div>
878 <?php
879 endif;
880 }
881
882 if ( ! self::$is_comment_export )
883 {
884 if(self::$acf_export) {
885 // Render Available ACF
886 self::$acf_export->render($i);
887 } else {
888 if(!self::get_addons_service()->isAcfAddonActive()) {
889 ?>
890 <p class="wpae-available-fields-group">ACF<span class="wpae-expander">+</span></p>
891 <div class="wpae-custom-field">
892
893 <div class="wpallexport-free-edition-notice">
894 <a class="upgrade_link" target="_blank"
895 href="https://www.wpallimport.com/checkout/?edd_action=add_to_cart&download_id=5839953&edd_options%5Bprice_id%5D=1&utm_source=export-plugin-free&utm_medium=upgrade-notice&utm_campaign=export-advanced-custom-fields">Upgrade to the ACF Export Package to Export Advanced Custom Fields</a>
896 </div>
897 </div>
898 <?php
899 }
900
901 }
902 }
903
904 return ob_get_clean();
905
906 }
907
908 public function render_filters(){
909
910 $available_sections = apply_filters("wp_all_export_available_sections", apply_filters('wp_all_export_filters', $this->available_sections) );
911
912 if(self::$woo_order_export) {
913 // Render Filters for WooCommerce Orders
914 self::$woo_order_export->render_filters();
915 }
916
917 if(self::$is_custom_addon_export) {
918 if(class_exists('GF_Export_Add_On')) {
919 $addon = GF_Export_Add_On::get_instance();
920 $addon->render_filters();
921 unset($available_sections);
922 }
923
924 }
925
926 if ( ! empty($available_sections) )
927 {
928 $exclude = array('wpml_lang', 'wpml_trid');
929
930 foreach ($available_sections as $slug => $section)
931 {
932 if ( ! empty($section['content']) and ! empty($this->available_data[$section['content']]) or ! empty($section['fields'])):
933 ?>
934
935 <optgroup label="<?php echo esc_attr($section['title']); ?>">
936
937 <?php if ( ! empty($section['content']) && ! empty($this->available_data[$section['content']]) ): ?>
938
939 <?php foreach ($this->available_data[$section['content']] as $field) : ?>
940
941 <?php
942
943 $field_label = is_array($field) ? $field['label'] : $field;
944 $field_type = is_array($field) ? $field['type'] : $slug;
945 $field_name = is_array($field) ? $field['name'] : $field;
946
947 if ( in_array($field_label, $exclude) ) continue;
948
949 switch ($field_type)
950 {
951 case 'woo':
952 $exclude_fields = array('attributes');
953 if ( ! in_array($field_label, $exclude_fields)):
954 ?>
955 <option value="<?php echo esc_attr('cf_' . $field_label); ?>"><?php echo esc_html($field_name); ?></option>
956 <?php
957 endif;
958 break;
959 case 'cf':
960 ?>
961 <option value="<?php echo esc_attr('cf_' . $field_label); ?>"><?php echo esc_html($field_name); ?></option>
962 <?php
963 break;
964 case 'cats':
965 case 'attr':
966 ?>
967 <option value="<?php echo esc_attr('tx_' . $field_label); ?>"><?php echo esc_html($field_name); ?></option>
968 <?php
969 break;
970 default:
971
972 if (self::$is_user_export)
973 {
974 switch ($field_label)
975 {
976 case 'id':
977 $field_label = strtoupper($field_label);
978 break;
979 case 'user_nicename':
980 ?>
981 <option value="user_role"><?php esc_html_e('User Role', 'wp_all_export_plugin'); ?></option>
982 <?php
983 break;
984 }
985 }
986 else
987 {
988 switch ($field_label) {
989 case 'id':
990 $field_label = strtoupper($field_label);
991 break;
992 case 'parent':
993 case 'author':
994 case 'author_username':
995 case 'author_email':
996 case 'author_first_name':
997 case 'author_last_name':
998 case 'status':
999 case 'title':
1000 case 'content':
1001 case 'date':
1002 case 'excerpt':
1003 $field_label = 'post_' . $field_label;
1004 break;
1005 case 'permalink':
1006 $field_label = 'guid';
1007 break;
1008 case 'slug':
1009 $field_label = 'post_name';
1010 break;
1011 case 'order':
1012 $field_label = 'menu_order';
1013 break;
1014 case 'template':
1015 $field_label = 'cf__wp_page_template';
1016 break;
1017 case 'format':
1018 $field_label = 'tx_post_format';
1019 break;
1020 default:
1021 # code...
1022 break;
1023 }
1024 }
1025 ?>
1026 <option value="<?php echo esc_attr($field_label); ?>"><?php echo esc_html($field_name); ?></option>
1027 <?php
1028 break;
1029 }
1030 ?>
1031
1032 <?php endforeach; ?>
1033
1034 <?php endif; ?>
1035
1036 <?php if ( ! empty($section['fields'])): ?>
1037
1038 <?php foreach ($section['fields'] as $key => $title) : ?>
1039
1040 <option value="<?php echo esc_attr($key); ?>"><?php echo esc_html($title); ?></option>
1041
1042 <?php endforeach; ?>
1043
1044 <?php endif; ?>
1045
1046 </optgroup>
1047
1048 <?php
1049
1050 endif;
1051
1052 if ( ! empty($section['additional']) )
1053 {
1054 foreach ($section['additional'] as $sub_slug => $sub_section)
1055 {
1056 if ( $sub_slug == 'attributes' ) {
1057 ?>
1058 <optgroup label="<?php echo esc_attr($sub_section['title']); ?>">
1059 <?php
1060 foreach ($sub_section['meta'] as $field) :
1061 if ( isset( $field['type'] ) ) {
1062 switch ( $field['type'] ) {
1063 case 'attr':
1064 ?>
1065 <option value="<?php echo esc_attr('tx_' . $field['label']); ?>"><?php echo esc_html($field['name']); ?></option>
1066 <?php
1067 break;
1068 case 'cf':
1069 ?>
1070 <option value="<?php echo esc_attr('cf_' . $field['label']); ?>"><?php echo esc_html($field['name']); ?></option>
1071 <?php
1072 break;
1073 default:
1074 # code...
1075 break;
1076 }
1077 }
1078
1079 endforeach;
1080 ?>
1081 </optgroup>
1082 <?php
1083 }
1084 }
1085 }
1086 }
1087 }
1088
1089 if ( ! self::$is_comment_export )
1090 {
1091 if(self::$acf_export) {
1092 // Render Available ACF
1093 self::$acf_export->render_filters();
1094 }
1095 }
1096
1097 }
1098
1099 public function render_new_field(){
1100
1101 ob_start();
1102
1103 $available_sections = apply_filters("wp_all_export_available_sections", $this->available_sections);
1104
1105 if(self::$woo_order_export) {
1106 // Render Available WooCommerce Orders Data
1107 self::$woo_order_export->render_new_field();
1108 }
1109
1110 if ( ! empty($available_sections) ):?>
1111
1112 <select class="wp-all-export-chosen-select" name="column_value_type" style="width:350px;">
1113
1114 <?php
1115 foreach ($available_sections as $slug => $section)
1116 {
1117 if($slug === 'product_data' && !self::get_addons_service()->isWooCommerceAddonActive()) {
1118 unset($section['additional']);
1119 }
1120
1121 if ( ! empty($this->available_data[$section['content']]) or ! empty($section['additional']) ):
1122 ?>
1123 <optgroup label="<?php echo esc_attr($section['title']); ?>">
1124
1125 <?php
1126 if ( ! empty($this->available_data[$section['content']]) )
1127 {
1128 foreach ($this->available_data[$section['content']] as $field)
1129 {
1130 $field_label = is_array($field) ? $field['label'] : $field;
1131 $field_type = is_array($field) ? $field['type'] : $slug;
1132 $field_name = is_array($field) ? $field['name'] : $field;
1133 $field_options = empty ($field['options']) ? '' : $field['options'];
1134
1135 if ( $field_type == 'cf' && $field_name == '_thumbnail_id' || ($field_type=='other')) continue;
1136 $elementDisabled = "";
1137 if(($section['title'] == 'Custom Fields' || $section['title'] == 'Other') && XmlExportEngine::$is_user_export) {
1138 $elementDisabled = "disabled='disabled'";
1139 }
1140 ?>
1141 <option
1142 value="<?php echo esc_attr($field_type);?>"
1143 label="<?php echo esc_attr($field_label);?>"
1144 <?php echo esc_html($elementDisabled); ?>
1145 options="<?php echo esc_attr($field_options); ?>"><?php echo esc_html($field_name);?></option>
1146 <?php
1147 }
1148 }
1149 ?>
1150
1151 </optgroup>
1152
1153 <?php
1154
1155 if ( ! empty($section['additional']) )
1156 {
1157 foreach ($section['additional'] as $sub_slug => $sub_section)
1158 {
1159 ?>
1160 <optgroup label="<?php echo esc_attr($sub_section['title']); ?>">
1161
1162 <?php
1163 foreach ($sub_section['meta'] as $field)
1164 {
1165 $field_label = is_array($field) ? $field['label'] : $field;
1166 $field_type = is_array($field) ? $field['type'] : $slug;
1167 $field_name = is_array($field) ? $field['name'] : $field;
1168 $field_options = empty($field['options']) ? '{"is_export_featured":true,"is_export_attached":true,"image_separator":"|"}' : $field['options'];
1169 ?>
1170 <option
1171 value="<?php echo esc_attr($field_type);?>"
1172 label="<?php echo esc_attr($field_label);?>"
1173 options="<?php echo esc_attr($field_options); ?>"><?php echo esc_html($field_name);?></option>
1174 <?php
1175 }
1176 ?>
1177 </optgroup>
1178 <?php
1179 }
1180 }
1181 endif;
1182 }
1183
1184 if ( ! self::$is_comment_export )
1185 {
1186 if(self::$acf_export) {
1187 // Render Available ACF
1188 self::$acf_export->render_new_field();
1189 }
1190 }
1191
1192 ?>
1193 <optgroup label="Advanced">
1194 <option value="sql" label="sql"><?php esc_html_e("SQL Query", "wp_all_export_plugin"); ?></option>
1195 </optgroup>
1196 </select>
1197 <?php
1198 endif;
1199
1200 return ob_get_clean();
1201
1202 }
1203
1204 public function parse_custom_xml_template(){
1205
1206 preg_match("%". self::XML_LOOP_START ."(.*)". self::XML_LOOP_END ."%", $this->post['custom_xml_template'], $matches);
1207 $parts = explode(self::XML_LOOP_START, $this->post['custom_xml_template']);
1208 $loopContent = $parts[1];
1209 $parts = explode(self::XML_LOOP_END, $loopContent);
1210 $loopContent = $parts[0];
1211 $line_numbers = substr_count($loopContent, "\n") +1;
1212
1213 $result['original_post_loop'] = $loopContent;
1214 $result['line_numbers'] = $line_numbers;
1215
1216 $custom_xml_template = str_replace("\n", "", $this->post['custom_xml_template']);
1217 // retrieve XML header
1218 preg_match("%(.*)". self::XML_LOOP_START ."%", $custom_xml_template, $matches);
1219 $result['custom_xml_template_header'] = empty($matches[1]) ? '' : rtrim($matches[1]);
1220 // retrieve XML POST LOOP
1221 preg_match("%". self::XML_LOOP_START ."(.*)". self::XML_LOOP_END ."%", $custom_xml_template, $matches);
1222 $result['custom_xml_template_loop'] = empty($matches[1]) ? '' : rtrim($matches[1]);
1223 // retrieve XML footer
1224 preg_match("%". self::XML_LOOP_END ."(.*)%", $custom_xml_template, $matches);
1225 $result['custom_xml_template_footer'] = empty($matches[1]) ? '' : $matches[1];
1226
1227 // Validate Custom XML Template header
1228 if ( empty($result['custom_xml_template_header']) )
1229 {
1230 $this->errors->add('form-validation', __('Missing custom XML template header.', 'wp_all_export_plugin'));
1231 }
1232 // Validate Custom XML Template post LOOP
1233 if ( empty($result['custom_xml_template_loop']) )
1234 {
1235 $this->errors->add('form-validation', __('Missing custom XML template post loop.', 'wp_all_export_plugin'));
1236 }
1237 // Validate Custom XML Template footer
1238 if ( empty($result['custom_xml_template_footer']) )
1239 {
1240 $this->errors->add('form-validation', __('Missing custom XML template footer.', 'wp_all_export_plugin'));
1241 }
1242
1243 if ( ! $this->errors->get_error_codes()) {
1244
1245 // retrieve all placeholders in the XML loop
1246 preg_match_all("%(\[[^\]\[]*\])%", $result['custom_xml_template_loop'], $matches);
1247 $loop_placeholders = empty($matches) ? array() : $matches[0];
1248
1249 $field_keys = array();
1250 // looking for placeholders e.q. {Post Type}, {Title}
1251 if ( ! empty($loop_placeholders) ){
1252
1253 foreach ($loop_placeholders as $snippet) {
1254 preg_match("%\{(.*)\}%", $snippet, $matches);
1255 if ( ! empty($matches[1]) ) $field_keys[] = $matches[1];
1256 }
1257 }
1258
1259 preg_match_all("%(\{[^\}\{]*\})%", $result['custom_xml_template_loop'], $matches);
1260 $loop_placeholders = empty($matches) ? array() : $matches[0];
1261
1262 $field_keys = array();
1263 // looking for placeholders e.q. {Post Type}, {Title}
1264 if ( ! empty($loop_placeholders) ){
1265
1266 foreach ($loop_placeholders as $snippet) {
1267 preg_match("%\{(.*)\}%", $snippet, $matches);
1268 if ( ! empty($matches[1]) and ! in_array($matches[1], $field_keys)) $field_keys[] = $matches[1];
1269 }
1270 }
1271
1272 if (!empty($field_keys)){
1273 $result['custom_xml_template_options'] = $this->get_fields_options( $field_keys );
1274 }
1275 }
1276 return $result;
1277 }
1278
1279 /**
1280 * __get function.
1281 *
1282 * @access public
1283 * @param mixed $key
1284 * @return mixed
1285 */
1286 public function __get( $key ) {
1287 return $this->get( $key );
1288 }
1289
1290 /**
1291 * Get a session variable
1292 *
1293 * @param string $key
1294 * @param mixed $default used if the session variable isn't set
1295 * @return mixed value of session variable
1296 */
1297 public function get( $key, $default = null ) {
1298 return isset( $this->{$key} ) ? $this->{$key} : $default;
1299 }
1300
1301 public static function getProductVariationMode()
1302 {
1303 if(!isset(self::$exportOptions['export_variations'])) {
1304 self::$exportOptions['export_variations'] = self::VARIABLE_PRODUCTS_EXPORT_PARENT_AND_VARIATION;
1305 }
1306
1307 return apply_filters('wp_all_export_product_variation_mode', self::$exportOptions['export_variations'], self::$exportID);
1308 }
1309
1310 public static function getProductVariationTitleMode()
1311 {
1312 if(!isset(self::$exportOptions['export_variations_title'])) {
1313 self::$exportOptions['export_variations_title'] = self::VARIATION_USE_PARENT_TITLE;
1314 }
1315
1316 return self::$exportOptions['export_variations_title'];
1317 }
1318
1319 public static function sanitizeFieldName($fieldName)
1320 {
1321 if (class_exists('XmlExportWooCommerce') && XmlExportWooCommerce::$is_active) {
1322 return urldecode($fieldName);
1323 }
1324
1325 return $fieldName;
1326 }
1327
1328 public static function get_addons() {
1329 return apply_filters('pmxe_addons', []);
1330 }
1331
1332 public static function get_addons_service()
1333 {
1334 if(!self::$addons_service) {
1335 self::$addons_service = new Wpae\App\Service\Addons\AddonService();
1336 }
1337
1338 return self::$addons_service;
1339 }
1340 }
1341
1342 }
1343