PluginProbe ʕ •ᴥ•ʔ
WP All Export – Drag & Drop Export to Any Custom CSV, XML & Excel / 1.4.13
WP All Export – Drag & Drop Export to Any Custom CSV, XML & Excel v1.4.13
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 / controllers / admin / export.php
wp-all-export / controllers / admin Last commit date
export.php 2 years ago feedback.php 10 years ago help.php 12 years ago manage.php 4 years ago partners.php 8 months ago settings.php 4 years ago
export.php
586 lines
1 <?php
2
3 /**
4 * Export configuration wizard
5 *
6 * @author Max Tsiplyakov <makstsiplyakov@gmail.com>
7 */
8 #[\AllowDynamicProperties]
9 class PMXE_Admin_Export extends PMXE_Controller_Admin
10 {
11
12 protected $isWizard = true; // indicates whether controller is in wizard mode (otherwise it called to be delegated an edit action)
13
14 protected function init()
15 {
16
17 parent::init();
18
19 if ('PMXE_Admin_Manage' == PMXE_Plugin::getInstance()->getAdminCurrentScreen()->base) { // prereqisites are not checked when flow control is deligated
20 $id = $this->input->get('id');
21 $this->data['export'] = $export = new PMXE_Export_Record();
22 if (!$id or $export->getById($id)->isEmpty()) { // specified import is not found
23 wp_redirect(esc_url_raw(add_query_arg('page', 'pmxe-admin-manage', admin_url('admin.php'))));
24 die();
25 }
26 $this->isWizard = false;
27 $export->fix_template_options();
28 } else {
29 $action = PMXE_Plugin::getInstance()->getAdminCurrentScreen()->action;
30 $this->_step_ready($action);
31 }
32
33 // preserve id parameter as part of baseUrl
34 $id = $this->input->get('id') and $this->baseUrl = esc_url_raw(add_query_arg('id', $id, $this->baseUrl));
35
36 }
37
38 public function set($var, $val)
39 {
40 $this->{$var} = $val;
41 }
42
43 public function get($var)
44 {
45 return $this->{$var};
46 }
47
48 /**
49 * Checks whether corresponding step of wizard is complete
50 * @param string $action
51 * @return bool
52 */
53 protected function _step_ready($action)
54 {
55
56 // step #1: xml selction - has no prerequisites
57 if ('index' == $action) return true;
58
59 if ('element' == $action) return true;
60
61 $this->data['update_previous'] = $update_previous = new PMXE_Export_Record();
62
63 $update_previous->getById(PMXE_Plugin::$session->update_previous);
64
65 if (!$update_previous->isEmpty()) {
66 $update_previous->fix_template_options();
67 }
68
69 if ('options' == $action) return true;
70
71 if (!PMXE_Plugin::$session->has_session()) {
72 wp_redirect_or_javascript($this->baseUrl);
73 die();
74 }
75
76 if ('process' == $action) return true;
77
78 }
79
80 /**
81 * Step #1: Choose CPT
82 */
83 public function index()
84 {
85 if ($this->input->post('is_submitted')) {
86 check_admin_referer('choose-cpt', '_wpnonce_choose-cpt');
87 }
88
89 $action = $this->input->get('action');
90
91 $DefaultOptions = array(
92 'cpt' => '',
93 'export_to' => 'xml',
94 'export_type' => 'specific',
95 'wp_query' => '',
96 'filter_rules_hierarhy' => '',
97 'product_matching_mode' => 'strict',
98 'wp_query_selector' => 'wp_query',
99 'auto_generate' => 0,
100 'taxonomy_to_export' => '',
101 'sub_post_type_to_export' => '',
102 'created_at_version' => PMXE_VERSION
103 );
104
105 if (!in_array($action, array('index'))) {
106 PMXE_Plugin::$session->clean_session();
107 $this->data['preload'] = false;
108 } else {
109 $DefaultOptions = (PMXE_Plugin::$session->has_session() ? PMXE_Plugin::$session->get_clear_session_data() : array()) + $DefaultOptions;
110 $this->data['preload'] = true;
111 }
112
113 $this->data['post'] = $post = $this->input->post($DefaultOptions);
114
115 if (is_array($this->data['post']['cpt'])) $this->data['post']['cpt'] = $this->data['post']['cpt'][0];
116
117 // Delete history
118 if(is_dir(PMXE_ROOT_DIR.'/history')) {
119 $history_files = PMXE_Helper::safe_glob(PMXE_ROOT_DIR . '/history/*', PMXE_Helper::GLOB_RECURSE | PMXE_Helper::GLOB_PATH);
120 if (!empty($history_files)) {
121 foreach ($history_files as $filePath) {
122 @file_exists($filePath) and @unlink($filePath);
123 }
124 }
125 }
126
127 if (!class_exists('XMLReader') or !class_exists('XMLWriter')) {
128 $this->errors->add('form-validation', __('Required PHP components are missing.<br/><br/>WP All Export requires XMLReader, and XMLWriter PHP modules to be installed.<br/>These are standard features of PHP, and are necessary for WP All Export to write the files you are trying to export.<br/>Please contact your web hosting provider and ask them to install and activate the DOMDocument, XMLReader, and XMLWriter PHP modules.', 'wp_all_export_plugin'));
129 }
130
131 if ($this->input->post('is_submitted')) {
132
133 PMXE_Plugin::$session->set('export_type', $post['export_type']);
134 PMXE_Plugin::$session->set('filter_rules_hierarhy', $post['filter_rules_hierarhy']);
135 PMXE_Plugin::$session->set('product_matching_mode', $post['product_matching_mode']);
136 PMXE_Plugin::$session->set('wp_query_selector', $post['wp_query_selector']);
137 PMXE_Plugin::$session->set('taxonomy_to_export', $post['taxonomy_to_export']);
138 PMXE_Plugin::$session->set('created_at_version', $post['created_at_version']);
139 PMXE_Plugin::$session->set('sub_post_type_to_export', $post['sub_post_type_to_export']);
140
141 if (!empty($post['auto_generate'])) {
142 $auto_generate = XmlCsvExport::auto_generate_export_fields($post, $this->errors);
143
144 foreach ($auto_generate as $key => $value) {
145 PMXE_Plugin::$session->set($key, $value);
146 }
147
148 PMXE_Plugin::$session->save_data();
149 } else {
150 $engine = new XmlExportEngine($post, $this->errors);
151 $engine->init_additional_data();
152 }
153 }
154
155 if ($this->input->post('is_submitted') and !$this->errors->get_error_codes()) {
156
157 PMXE_Plugin::$session->save_data();
158
159 if (!empty($post['auto_generate'])) {
160 wp_redirect(esc_url_raw(add_query_arg(['action' => 'options','_wpnonce_options' => wp_create_nonce('options')], $this->baseUrl)));
161 die();
162 } else {
163 wp_redirect(esc_url_raw(add_query_arg(['action' => 'template','_wpnonce_template' => wp_create_nonce('template')], $this->baseUrl)));
164 die();
165 }
166
167 }
168
169 $this->render();
170 }
171
172 /**
173 * Step #2: Export Template
174 */
175 public function template()
176 {
177
178 check_admin_referer( 'template', '_wpnonce_template' );
179
180
181 $template = new PMXE_Template_Record();
182
183 $default = PMXE_Plugin::get_default_import_options();
184
185 $this->data['dismiss_warnings'] = 0;
186
187 if ($this->isWizard) {
188 // New export
189 $DefaultOptions = (PMXE_Plugin::$session->has_session() ? PMXE_Plugin::$session->get_clear_session_data() : array()) + $default;
190 $post = $this->input->post($DefaultOptions);
191 } else {
192 // Edit export
193 $DefaultOptions = $this->data['export']->options + $default;
194
195 if (empty($this->data['export']->options['export_variations'])) {
196 $DefaultOptions['export_variations'] = XmlExportEngine::VARIABLE_PRODUCTS_EXPORT_PARENT_AND_VARIATION;
197 }
198 if (empty($this->data['export']->options['export_variations_title'])) {
199 $DefaultOptions['export_variations_title'] = XmlExportEngine::VARIATION_USE_DEFAULT_TITLE;
200 }
201 $post = $this->input->post($DefaultOptions);
202 $post['scheduled'] = $this->data['export']->scheduled;
203
204 foreach ($post as $key => $value) {
205 PMXE_Plugin::$session->set($key, $value);
206 }
207 $this->data['dismiss_warnings'] = get_option('wpae_dismiss_warnings_' . $this->data['export']->id, 0);
208 }
209
210 $max_input_vars = @ini_get('max_input_vars');
211
212 if (ctype_digit($max_input_vars) && count($_POST, COUNT_RECURSIVE) >= $max_input_vars) {
213 $this->errors->add('form-validation', sprintf(__('You\'ve reached your max_input_vars limit of %d. Please contact your web host to increase it.', 'wp_all_export_plugin'), $max_input_vars));
214 }
215
216 PMXE_Plugin::$session->save_data();
217
218 $this->data['post'] =& $post;
219
220 PMXE_Plugin::$session->set('is_loaded_template', '');
221
222 $this->data['engine'] = null;
223
224 XmlExportEngine::$exportQuery = PMXE_Plugin::$session->get('exportQuery');
225
226 if (($load_template = $this->input->post('load_template'))) { // init form with template selected
227 if (!$template->getById($load_template)->isEmpty()) {
228 $template_options = $template->options;
229 unset($template_options['cpt']);
230 unset($template_options['wp_query']);
231 unset($template_options['filter_rules_hierarhy']);
232 unset($template_options['product_matching_mode']);
233 unset($template_options['wp_query_selector']);
234 $this->data['post'] = array_merge($post, $template_options);
235 PMXE_Plugin::$session->set('is_loaded_template', $load_template);
236 }
237
238 } elseif ($this->input->post('is_submitted')) {
239
240 if (empty($post['cc_type'][0]) && !in_array($post['xml_template_type'], array('custom', 'XmlGoogleMerchants'))) {
241 $this->errors->add('form-validation', __('You haven\'t selected any columns for export.', 'wp_all_export_plugin'));
242 }
243
244 if ('csv' == $post['export_to'] and '' == $post['delimiter']) {
245 $this->errors->add('form-validation', __('CSV delimiter must be specified.', 'wp_all_export_plugin'));
246 }
247
248 if ('xml' == $post['export_to'] && !in_array($post['xml_template_type'], array('custom', 'XmlGoogleMerchants'))) {
249 $post['main_xml_tag'] = preg_replace('/[^a-z0-9_]/i', '', $post['main_xml_tag']);
250 if (empty($post['main_xml_tag'])) {
251 $this->errors->add('form-validation', __('Main XML Tag is required.', 'wp_all_export_plugin'));
252 }
253
254 $post['record_xml_tag'] = preg_replace('/[^a-z0-9_]/i', '', $post['record_xml_tag']);
255 if (empty($post['record_xml_tag'])) {
256 $this->errors->add('form-validation', __('Single Record XML Tag is required.', 'wp_all_export_plugin'));
257 }
258
259 if ($post['main_xml_tag'] == $post['record_xml_tag']) {
260 $this->errors->add('form-validation', __('Main XML Tag equals to Single Record XML Tag.', 'wp_all_export_plugin'));
261 }
262 }
263
264 if (($post['export_to'] == XmlExportEngine::EXPORT_TYPE_XML) && in_array($post['xml_template_type'], array('custom', 'XmlGoogleMerchants'))) {
265
266 if (empty($post['custom_xml_template'])) {
267 $this->errors->add('form-validation', __('XML template is empty.', 'wp_all_export_plugin'));
268 }
269
270 // Convert Custom XML template to default
271 if (!empty($post['custom_xml_template'])) {
272
273 $post['custom_xml_template'] = str_replace('<ID>', '<id>', $post['custom_xml_template']);
274 $post['custom_xml_template'] = str_replace('</ID>', '</id>', $post['custom_xml_template']);
275
276 $post['custom_xml_template'] = str_replace("<!-- BEGIN POST LOOP -->", "<!-- BEGIN LOOP -->", $post['custom_xml_template']);
277 $post['custom_xml_template'] = str_replace("<!-- END POST LOOP -->", "<!-- END LOOP -->", $post['custom_xml_template']);
278
279 $this->data['engine'] = new XmlExportEngine($post, $this->errors);
280
281 $this->data['engine']->init_additional_data();
282
283 $this->data = array_merge($this->data, $this->data['engine']->init_available_data());
284
285 $result = $this->data['engine']->parse_custom_xml_template();
286
287 if (!$this->errors->get_error_codes()) {
288 $post = array_merge($post, $result);
289 }
290 }
291 }
292
293 if (!$this->errors->get_error_codes()) {
294
295 if (!empty($post['name']) and !empty($post['save_template_as'])) { // save template in database
296 $template->getByName($post['name'])->set(array(
297 'name' => $post['name'],
298 'options' => $post
299 ))->save();
300 PMXE_Plugin::$session->set('saved_template', $template->id);
301 }
302
303 if ($this->isWizard) {
304 foreach ($this->data['post'] as $key => $value) {
305 PMXE_Plugin::$session->set($key, $value);
306 }
307 PMXE_Plugin::$session->save_data();
308 wp_redirect(esc_url_raw(add_query_arg(['action' => 'options','_wpnonce_options' => wp_create_nonce('options')], $this->baseUrl)));
309 die();
310 } else {
311 $this->data['export']->set(array('options' => $post, 'settings_update_on' => date('Y-m-d H:i:s')))->save();
312
313 if (!empty($post['friendly_name'])) {
314 $this->data['export']->set(array('friendly_name' => $post['friendly_name'], 'scheduled' => (($post['is_scheduled']) ? $post['scheduled_period'] : '')))->save();
315 }
316
317 wp_redirect(esc_url_raw(add_query_arg(array('page' => 'pmxe-admin-manage', 'pmxe_nt' => urlencode(__('Options updated', 'pmxi_plugin')),'_wpnonce_options' => wp_create_nonce('options')) + array_intersect_key($_GET, array_flip($this->baseUrlParamNames)), admin_url('admin.php'))));
318 die();
319 }
320 }
321 }
322
323 if (empty($this->data['engine'])) {
324
325 $this->data['engine'] = new XmlExportEngine($post, $this->errors);
326
327 $this->data['engine']->init_additional_data();
328
329 $this->data = array_merge($this->data, $this->data['engine']->init_available_data());
330 }
331
332 $this->data['available_data_view'] = $this->data['engine']->render();
333
334 $this->data['available_fields_view'] = $this->data['engine']->render_new_field();
335
336 if (class_exists('SitePress')) {
337 global $sitepress;
338 $langs = $sitepress->get_active_languages();
339 if (!empty($langs)) {
340 // prepare active languages list
341 $language_list = array('all' => 'All');
342 foreach ($langs as $code => $langInfo) {
343 $language_list[$code] = "<img width='18' height='12' src='" . esc_attr($sitepress->get_flag_url($code)) . "' style='position:relative; top: 2px;'/> " . esc_html($langInfo['display_name']);
344 if(isset($this->default_language)){
345 if ($code == $this->default_language) $language_list[$code] .= ' ( <strong>default</strong> )';
346 }
347
348 }
349 }
350 $this->data['wpml_options'] = $language_list;
351 }
352
353 $this->render();
354 }
355
356 /**
357 * Step #3: Export Options
358 */
359 public function options()
360 {
361 check_admin_referer( 'options', '_wpnonce_options' );
362
363 $default = PMXE_Plugin::get_default_import_options();
364
365 if ($this->isWizard) {
366
367 $DefaultOptions = (PMXE_Plugin::$session->has_session() ? PMXE_Plugin::$session->get_clear_session_data() : array()) + $default;
368 $post = $this->input->post($DefaultOptions);
369
370 if(isset($post['update_previous'])) {
371 $exportId = $post['update_previous'];
372 } else {
373 $exportId = false;
374 }
375
376 if(!$exportId) {
377 $export = $this->data['update_previous'];
378 $export->set(
379 array(
380 'triggered' => 0,
381 'processing' => 0,
382 'exported' => 0,
383 'executing' => 0,
384 'canceled' => 0,
385 'options' => $post,
386 'friendly_name' => $this->getFriendlyName($post),
387 'last_activity' => date('Y-m-d H:i:s')
388
389 )
390 )->save();
391
392 PMXE_Plugin::$session->set('update_previous', $export->id);
393 PMXE_Plugin::$session->set('friendly_name', $this->getFriendlyName($post));
394 PMXE_Plugin::$session->save_data();
395 $exportId = $export->id;
396 }
397 $this->data['export_id'] = $exportId;
398 $this->data['export'] = new PMXE_Export_Record();
399 $this->data['export'] = $this->data['export']->getBy('id', $exportId);
400
401 if(empty($post['friendly_name'])) {
402 $post['friendly_name'] = $this->getFriendlyName($post);
403 }
404 }
405 else {
406 $DefaultOptions = $this->data['export']->options + $default;
407 if (empty($this->data['export']->options['export_variations'])) {
408 $DefaultOptions['export_variations'] = XmlExportEngine::VARIABLE_PRODUCTS_EXPORT_PARENT_AND_VARIATION;
409 }
410 if (empty($this->data['export']->options['export_variations_title'])) {
411 $DefaultOptions['export_variations_title'] = XmlExportEngine::VARIATION_USE_DEFAULT_TITLE;
412 }
413 $post = $this->input->post($DefaultOptions);
414 $post['scheduled'] = $this->data['export']->scheduled;
415
416 foreach ($post as $key => $value) {
417 PMXE_Plugin::$session->set($key, $value);
418 }
419 PMXE_Plugin::$session->save_data();
420 $this->data['export_id'] = $this->data['export']->id;
421 }
422
423 $this->data['engine'] = new XmlExportEngine($post, $this->errors);
424
425 $this->data['engine']->init_available_data();
426
427 $this->data['post'] =& $post;
428
429 if ($this->input->post('is_submitted')) {
430
431 if ($post['is_generate_templates'] and '' == $post['template_name']) {
432 $friendly_name = $this->getFriendlyName($post);
433 $post['template_name'] = $friendly_name;
434 }
435
436 if ($this->isWizard) {
437 if (!$this->errors->get_error_codes()) {
438 foreach ($this->data['post'] as $key => $value) {
439 PMXE_Plugin::$session->set($key, $value);
440 }
441 PMXE_Plugin::$session->save_data();
442 wp_redirect(esc_url_raw(add_query_arg('action', 'process', $this->baseUrl)));
443 die();
444 }
445 } else {
446 $this->errors->remove('count-validation');
447 if (!$this->errors->get_error_codes()) {
448 $this->data['export']->set(array('options' => $post, 'settings_update_on' => date('Y-m-d H:i:s')))->save();
449 if (!empty($post['friendly_name'])) {
450 $this->data['export']->set(array('friendly_name' => $post['friendly_name'], 'scheduled' => (($post['is_scheduled']) ? $post['scheduled_period'] : '')))->save();
451 }
452 wp_redirect(esc_url_raw(add_query_arg(array('page' => 'pmxe-admin-manage', 'pmxe_nt' => urlencode(__('Options updated', 'wp_all_export_plugin'))) + array_intersect_key($_GET, array_flip($this->baseUrlParamNames)), admin_url('admin.php'))));
453 die();
454 }
455 }
456 }
457
458 $this->render();
459 }
460
461 /**
462 * Step #4: Export Processing
463 */
464 public function process()
465 {
466 @set_time_limit(0);
467
468 $export = $this->data['update_previous'];
469
470 if (!PMXE_Plugin::is_ajax()) {
471
472 if ("" == PMXE_Plugin::$session->friendly_name) {
473
474 $post_types = PMXE_Plugin::$session->get('cpt');
475 if (!empty($post_types)) {
476 if (in_array('users', $post_types)) {
477 $friendly_name = 'Users Export - ' . date("Y F d H:i");
478 } elseif (in_array('shop_customer', $post_types)) {
479 $friendly_name = 'Customers Export - ' . date("Y F d H:i");
480 } elseif (in_array('comments', $post_types)) {
481 $friendly_name = 'Comments Export - ' . date("Y F d H:i");
482 } elseif (in_array('taxonomies', $post_types)) {
483 $tx = get_taxonomy(PMXE_Plugin::$session->get('taxonomy_to_export'));
484 if (!empty($tx->labels->name)) {
485 $friendly_name = $tx->labels->name . ' Export - ' . date("Y F d H:i");
486 } else {
487 $friendly_name = 'Taxonomy Terms Export - ' . date("Y F d H:i");
488 }
489 } else {
490 $post_type_details = get_post_type_object(array_shift($post_types));
491 $friendly_name = $post_type_details->labels->name . ' Export - ' . date("Y F d H:i");
492 }
493 } else {
494 $friendly_name = 'WP_Query Export - ' . date("Y F d H:i");
495 }
496
497 PMXE_Plugin::$session->set('friendly_name', $friendly_name);
498 }
499
500 PMXE_Plugin::$session->set('file', '');
501 PMXE_Plugin::$session->save_data();
502
503 $export->set(
504 array(
505 'triggered' => 0,
506 'processing' => 0,
507 'exported' => 0,
508 'executing' => 1,
509 'canceled' => 0,
510 'options' => PMXE_Plugin::$session->get_clear_session_data(),
511 'friendly_name' => PMXE_Plugin::$session->friendly_name,
512 'scheduled' => (PMXE_Plugin::$session->is_scheduled) ? PMXE_Plugin::$session->scheduled_period : '',
513 //'registered_on' => date('Y-m-d H:i:s'),
514 'last_activity' => date('Y-m-d H:i:s')
515 )
516 )->save();
517
518 // create an import for this export
519 if ($export->options['export_to'] == 'csv' || !in_array($export->options['xml_template_type'], array('custom', 'XmlGoogleMerchants'))) PMXE_Wpallimport::create_an_import($export);
520 PMXE_Plugin::$session->set('update_previous', $export->id);
521 PMXE_Plugin::$session->save_data();
522
523 do_action('pmxe_before_export', $export->id);
524
525 }
526
527 $this->render();
528 }
529
530 /**
531 * @param $post
532 * @return string
533 */
534 protected function getFriendlyName($post)
535 {
536 $friendly_name = '';
537 $post_types = PMXE_Plugin::$session->get('cpt');
538 if (!empty($post_types)) {
539 if (in_array('users', $post_types)) {
540 $friendly_name = 'Users Export - ' . date("Y F d H:i");
541 return $friendly_name;
542 } elseif (in_array('shop_customer', $post_types)) {
543 $friendly_name = 'Customers Export - ' . date("Y F d H:i");
544 return $friendly_name;
545 } elseif (in_array('comments', $post_types)) {
546 $friendly_name = 'Comments Export - ' . date("Y F d H:i");
547 return $friendly_name;
548 } elseif (in_array('taxonomies', $post_types)) {
549 $tx = get_taxonomy($post['taxonomy_to_export']);
550 if (!empty($tx->labels->name)) {
551 $friendly_name = $tx->labels->name . ' Export - ' . date("Y F d H:i");
552 return $friendly_name;
553 } else {
554 $friendly_name = 'Taxonomy Terms Export - ' . date("Y F d H:i");
555 return $friendly_name;
556 }
557 } else {
558 $is_rapid_add_on_export = PMXE_Helper::is_rapid_export_addon($post_types);
559 if($is_rapid_add_on_export) {
560 return 'Gravity Forms Entries Export - ' . date("Y F d H:i");
561 }
562
563 $post_type_details = get_post_type_object(array_shift($post_types));
564 $friendly_name = $post_type_details->labels->name . ' Export - ' . date("Y F d H:i");
565 return $friendly_name;
566 }
567 } else {
568 $friendly_name = 'WP_Query Export - ' . date("Y F d H:i");
569 return $friendly_name;
570 }
571 }
572
573 function insertAfter($input, $index, $newKey, $element) {
574 if (!array_key_exists($index, $input)) {
575 throw new Exception("Index not found");
576 }
577 $tmpArray = array();
578 foreach ($input as $key => $value) {
579 $tmpArray[$key] = $value;
580 if ($key === $index) {
581 $tmpArray[$newKey] = $element;
582 }
583 }
584 return $tmpArray;
585 }
586 }