PluginProbe
WP All Export – Drag & Drop Export to Any Custom CSV, XML & Excel / 1.1.1
WP All Export – Drag & Drop Export to Any Custom CSV, XML & Excel v1.1.1
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 All 57 releases
wp-all-export / wp-all-export.php

wp-all-export.php in WP All Export – Drag & Drop Export to Any Custom CSV, XML & Excel 1.1.1, at wp-all-export.php

747 lines 24.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: WP All Export
4 Plugin URI: http://www.wpallimport.com/export/
5 Description: Export any post type to a CSV or XML file. Edit the exported data, and then re-import it later using WP All Import.
6 Version: 1.1.1
7 Author: Soflyy
8 */
9
10 require_once(__DIR__.'/classes/CdataStrategyFactory.php');
11
12 if( ! defined( 'PMXE_SESSION_COOKIE' ) )
13 define( 'PMXE_SESSION_COOKIE', '_pmxe_session' );
14
15 /**
16 * Plugin root dir with forward slashes as directory separator regardless of actuall DIRECTORY_SEPARATOR value
17 * @var string
18 */
19 define('PMXE_ROOT_DIR', str_replace('\\', '/', dirname(__FILE__)));
20 /**
21 * Plugin root url for referencing static content
22 * @var string
23 */
24 define('PMXE_ROOT_URL', rtrim(plugin_dir_url(__FILE__), '/'));
25
26 if ( class_exists('PMXE_Plugin') and PMXE_EDITION == "paid"){
27
28 function pmxe_notice(){
29
30 ?>
31 <div class="error">
32 <p>
33 <?php printf(__('Please de-activate and remove the free version of the WP All Export before activating the paid version.', 'wp_all_export_plugin')); ?>
34 </p>
35 </div>
36 <?php
37
38 deactivate_plugins( str_replace('\\', '/', dirname(__FILE__)) . '/wp-all-export.php');
39
40 }
41
42 add_action('admin_notices', 'pmxe_notice');
43
44 }
45 else {
46
47 /**
48 * Plugin prefix for making names unique (be aware that this variable is used in conjuction with naming convention,
49 * i.e. in order to change it one must not only modify this constant but also rename all constants, classes and functions which
50 * names composed using this prefix)
51 * @var string
52 */
53 define('PMXE_PREFIX', 'pmxe_');
54
55 define('PMXE_VERSION', '1.1.1');
56
57 define('PMXE_EDITION', 'free');
58
59 /**
60 * Plugin root uploads folder name
61 * @var string
62 */
63 define('WP_ALL_EXPORT_UPLOADS_BASE_DIRECTORY', 'wpallexport');
64 /**
65 * Plugin uploads folder name
66 * @var string
67 */
68 define('WP_ALL_EXPORT_UPLOADS_DIRECTORY', WP_ALL_EXPORT_UPLOADS_BASE_DIRECTORY . DIRECTORY_SEPARATOR . 'exports');
69
70 /**
71 * Plugin temp folder name
72 * @var string
73 */
74 define('WP_ALL_EXPORT_TEMP_DIRECTORY', WP_ALL_EXPORT_UPLOADS_BASE_DIRECTORY . DIRECTORY_SEPARATOR . 'temp');
75
76 /**
77 * Plugin temp folder name
78 * @var string
79 */
80 define('WP_ALL_EXPORT_CRON_DIRECTORY', WP_ALL_EXPORT_UPLOADS_BASE_DIRECTORY . DIRECTORY_SEPARATOR . 'exports');
81
82 /**
83 * Main plugin file, Introduces MVC pattern
84 *
85 * @singletone
86 * @author Pavel Kulbakin <p.kulbakin@gmail.com>
87 */
88 final class PMXE_Plugin {
89 /**
90 * Singletone instance
91 * @var PMXE_Plugin
92 */
93 protected static $instance;
94
95 /**
96 * Plugin options
97 * @var array
98 */
99 protected $options = array();
100
101 /**
102 * Plugin root dir
103 * @var string
104 */
105 const ROOT_DIR = PMXE_ROOT_DIR;
106 /**
107 * Plugin root URL
108 * @var string
109 */
110 const ROOT_URL = PMXE_ROOT_URL;
111 /**
112 * Prefix used for names of shortcodes, action handlers, filter functions etc.
113 * @var string
114 */
115 const PREFIX = PMXE_PREFIX;
116 /**
117 * Plugin file path
118 * @var string
119 */
120 const FILE = __FILE__;
121 /**
122 * Max allowed file size (bytes) to import in default mode
123 * @var int
124 */
125 const LARGE_SIZE = 0; // all files will importing in large import mode
126
127 /**
128 * WP All Import temp folder
129 * @var string
130 */
131 const TEMP_DIRECTORY = WP_ALL_EXPORT_TEMP_DIRECTORY;
132 /**
133 * WP All Import uploads folder
134 * @var string
135 */
136 const UPLOADS_DIRECTORY = WP_ALL_EXPORT_UPLOADS_DIRECTORY;
137 /**
138 * WP All Import uploads folder
139 * @var string
140 */
141 const CRON_DIRECTORY = WP_ALL_EXPORT_CRON_DIRECTORY;
142
143 public static $session = null;
144
145 public static $capabilities = 'manage_options';
146
147 /**
148 * Return singletone instance
149 * @return PMXE_Plugin
150 */
151 static public function getInstance() {
152 if (self::$instance == NULL) {
153 self::$instance = new self();
154 }
155 return self::$instance;
156 }
157
158 static public function getEddName(){
159 return 'WP All Export';
160 }
161
162 /**
163 * Common logic for requestin plugin info fields
164 */
165 public function __call($method, $args) {
166 if (preg_match('%^get(.+)%i', $method, $mtch)) {
167 $info = get_plugin_data(self::FILE);
168 if (isset($info[$mtch[1]])) {
169 return $info[$mtch[1]];
170 }
171 }
172 throw new Exception("Requested method " . get_class($this) . "::$method doesn't exist.");
173 }
174
175 /**
176 * Get path to plagin dir relative to wordpress root
177 * @param bool[optional] $noForwardSlash Whether path should be returned withot forwarding slash
178 * @return string
179 */
180 public function getRelativePath($noForwardSlash = false) {
181 $wp_root = str_replace('\\', '/', ABSPATH);
182 return ($noForwardSlash ? '' : '/') . str_replace($wp_root, '', self::ROOT_DIR);
183 }
184
185 /**
186 * Check whether plugin is activated as network one
187 * @return bool
188 */
189 public function isNetwork() {
190 if ( !is_multisite() )
191 return false;
192
193 $plugins = get_site_option('active_sitewide_plugins');
194 if (isset($plugins[plugin_basename(self::FILE)]))
195 return true;
196
197 return false;
198 }
199
200 /**
201 * Check whether permalinks is enabled
202 * @return bool
203 */
204 public function isPermalinks() {
205 global $wp_rewrite;
206
207 return $wp_rewrite->using_permalinks();
208 }
209
210 /**
211 * Return prefix for plugin database tables
212 * @return string
213 */
214 public function getTablePrefix() {
215 global $wpdb;
216
217 //return ($this->isNetwork() ? $wpdb->base_prefix : $wpdb->prefix) . self::PREFIX;
218 return $wpdb->prefix . self::PREFIX;
219 }
220
221 /**
222 * Return prefix for wordpress database tables
223 * @return string
224 */
225 public function getWPPrefix() {
226 global $wpdb;
227 return ($this->isNetwork()) ? $wpdb->base_prefix : $wpdb->prefix;
228 }
229
230 /**
231 * Class constructor containing dispatching logic
232 * @param string $rootDir Plugin root dir
233 * @param string $pluginFilePath Plugin main file
234 */
235 protected function __construct() {
236
237 // register autoloading method
238 spl_autoload_register(array($this, 'autoload'));
239
240 // register helpers
241 if (is_dir(self::ROOT_DIR . '/helpers')) foreach (PMXE_Helper::safe_glob(self::ROOT_DIR . '/helpers/*.php', PMXE_Helper::GLOB_RECURSE | PMXE_Helper::GLOB_PATH) as $filePath) {
242 require_once $filePath;
243 }
244
245 // init plugin options
246 $option_name = get_class($this) . '_Options';
247 $options_default = PMXE_Config::createFromFile(self::ROOT_DIR . '/config/options.php')->toArray();
248 $this->options = array_intersect_key(get_option($option_name, array()), $options_default) + $options_default;
249 $this->options = array_intersect_key($options_default, array_flip(array('info_api_url'))) + $this->options; // make sure hidden options apply upon plugin reactivation
250 if ('' == $this->options['cron_job_key']) $this->options['cron_job_key'] = wp_all_export_url_title(wp_all_export_rand_char(12));
251
252 update_option($option_name, $this->options);
253 $this->options = get_option(get_class($this) . '_Options');
254 register_activation_hook(self::FILE, array($this, 'activation'));
255
256 // register action handlers
257 if (is_dir(self::ROOT_DIR . '/actions')) if (is_dir(self::ROOT_DIR . '/actions')) foreach (PMXE_Helper::safe_glob(self::ROOT_DIR . '/actions/*.php', PMXE_Helper::GLOB_RECURSE | PMXE_Helper::GLOB_PATH) as $filePath) {
258 require_once $filePath;
259 $function = $actionName = basename($filePath, '.php');
260 if (preg_match('%^(.+?)[_-](\d+)$%', $actionName, $m)) {
261 $actionName = $m[1];
262 $priority = intval($m[2]);
263 } else {
264 $priority = 10;
265 }
266 add_action($actionName, self::PREFIX . str_replace('-', '_', $function), $priority, 99); // since we don't know at this point how many parameters each plugin expects, we make sure they will be provided with all of them (it's unlikely any developer will specify more than 99 parameters in a function)
267 }
268
269 // register filter handlers
270 if (is_dir(self::ROOT_DIR . '/filters')) foreach (PMXE_Helper::safe_glob(self::ROOT_DIR . '/filters/*.php', PMXE_Helper::GLOB_RECURSE | PMXE_Helper::GLOB_PATH) as $filePath) {
271 require_once $filePath;
272 $function = $actionName = basename($filePath, '.php');
273 if (preg_match('%^(.+?)[_-](\d+)$%', $actionName, $m)) {
274 $actionName = $m[1];
275 $priority = intval($m[2]);
276 } else {
277 $priority = 10;
278 }
279 add_filter($actionName, self::PREFIX . str_replace('-', '_', $function), $priority, 99); // since we don't know at this point how many parameters each plugin expects, we make sure they will be provided with all of them (it's unlikely any developer will specify more than 99 parameters in a function)
280 }
281
282 // register shortcodes handlers
283 if (is_dir(self::ROOT_DIR . '/shortcodes')) foreach (PMXE_Helper::safe_glob(self::ROOT_DIR . '/shortcodes/*.php', PMXE_Helper::GLOB_RECURSE | PMXE_Helper::GLOB_PATH) as $filePath) {
284 $tag = strtolower(str_replace('/', '_', preg_replace('%^' . preg_quote(self::ROOT_DIR . '/shortcodes/', '%') . '|\.php$%', '', $filePath)));
285 add_shortcode($tag, array($this, 'shortcodeDispatcher'));
286 }
287
288 // register admin page pre-dispatcher
289 add_action('admin_init', array($this, 'adminInit'));
290 add_action('admin_init', array($this, 'fix_db_schema'));
291 add_action('init', array($this, 'init'));
292 }
293
294 public function init(){
295 $this->load_plugin_textdomain();
296 }
297
298 /**
299 * pre-dispatching logic for admin page controllers
300 */
301 public function adminInit() {
302
303 // create history folder
304 $uploads = wp_upload_dir();
305
306 $wpallimportDirs = array( WP_ALL_EXPORT_UPLOADS_BASE_DIRECTORY, self::TEMP_DIRECTORY, self::UPLOADS_DIRECTORY, self::CRON_DIRECTORY);
307
308 foreach ($wpallimportDirs as $destination) {
309
310 $dir = $uploads['basedir'] . DIRECTORY_SEPARATOR . $destination;
311
312 if ( !is_dir($dir)) wp_mkdir_p($dir);
313
314 if ( ! @file_exists($dir . DIRECTORY_SEPARATOR . 'index.php') ) @touch( $dir . DIRECTORY_SEPARATOR . 'index.php' );
315
316 }
317
318 if ( ! is_dir($uploads['basedir'] . DIRECTORY_SEPARATOR . WP_ALL_EXPORT_UPLOADS_BASE_DIRECTORY) or ! is_writable($uploads['basedir'] . DIRECTORY_SEPARATOR . WP_ALL_EXPORT_UPLOADS_BASE_DIRECTORY)) {
319 die(sprintf(__('Uploads folder %s must be writable', 'wp_all_export_plugin'), $uploads['basedir'] . DIRECTORY_SEPARATOR . WP_ALL_EXPORT_UPLOADS_BASE_DIRECTORY));
320 }
321
322 if ( ! is_dir($uploads['basedir'] . DIRECTORY_SEPARATOR . self::UPLOADS_DIRECTORY) or ! is_writable($uploads['basedir'] . DIRECTORY_SEPARATOR . self::UPLOADS_DIRECTORY)) {
323 die(sprintf(__('Uploads folder %s must be writable', 'wp_all_export_plugin'), $uploads['basedir'] . DIRECTORY_SEPARATOR . self::UPLOADS_DIRECTORY));
324 }
325
326 self::$session = new PMXE_Handler();
327
328 $input = new PMXE_Input();
329 $page = strtolower($input->getpost('page', ''));
330
331 if (preg_match('%^' . preg_quote(str_replace('_', '-', self::PREFIX), '%') . '([\w-]+)$%', $page)) {
332 //$this->adminDispatcher($page, strtolower($input->getpost('action', 'index')));
333
334 $action = strtolower($input->getpost('action', 'index'));
335
336 // capitalize prefix and first letters of class name parts
337 $controllerName = preg_replace_callback('%(^' . preg_quote(self::PREFIX, '%') . '|_).%', array($this, "replace_callback"),str_replace('-', '_', $page));
338 $actionName = str_replace('-', '_', $action);
339 if (method_exists($controllerName, $actionName)) {
340
341 if ( ! get_current_user_id() or ! current_user_can(self::$capabilities)) {
342 // This nonce is not valid.
343 die( 'Security check' );
344
345 } else {
346
347 $this->_admin_current_screen = (object)array(
348 'id' => $controllerName,
349 'base' => $controllerName,
350 'action' => $actionName,
351 'is_ajax' => strpos($_SERVER["HTTP_ACCEPT"], 'json') !== false,
352 'is_network' => is_network_admin(),
353 'is_user' => is_user_admin(),
354 );
355 add_filter('current_screen', array($this, 'getAdminCurrentScreen'));
356 add_filter('admin_body_class', create_function('', 'return "' . 'wpallexport-plugin";'));
357
358 $controller = new $controllerName();
359 if ( ! $controller instanceof PMXE_Controller_Admin) {
360 throw new Exception("Administration page `$page` matches to a wrong controller type.");
361 }
362
363 if ($this->_admin_current_screen->is_ajax) { // ajax request
364 $controller->$action();
365 do_action('wpallexport_action_after');
366 die(); // stop processing since we want to output only what controller is randered, nothing in addition
367 } elseif ( ! $controller->isInline) {
368 @ob_start();
369 $controller->$action();
370 self::$buffer = @ob_get_clean();
371 } else {
372 self::$buffer_callback = array($controller, $action);
373 }
374 }
375
376 } else { // redirect to dashboard if requested page and/or action don't exist
377 wp_redirect(admin_url()); die();
378 }
379
380 }
381 }
382
383 /**
384 * Dispatch shorttag: create corresponding controller instance and call its index method
385 * @param array $args Shortcode tag attributes
386 * @param string $content Shortcode tag content
387 * @param string $tag Shortcode tag name which is being dispatched
388 * @return string
389 */
390 public function shortcodeDispatcher($args, $content, $tag) {
391
392 $controllerName = self::PREFIX . preg_replace_callback('%(^|_).%', array($this, "replace_callback"), $tag);// capitalize first letters of class name parts and add prefix
393 $controller = new $controllerName();
394 if ( ! $controller instanceof PMXE_Controller) {
395 throw new Exception("Shortcode `$tag` matches to a wrong controller type.");
396 }
397 ob_start();
398 $controller->index($args, $content);
399 return ob_get_clean();
400 }
401
402 static $buffer = NULL;
403 static $buffer_callback = NULL;
404
405 /**
406 * Dispatch admin page: call corresponding controller based on get parameter `page`
407 * The method is called twice: 1st time as handler `parse_header` action and then as admin menu item handler
408 * @param string[optional] $page When $page set to empty string ealier buffered content is outputted, otherwise controller is called based on $page value
409 */
410 public function adminDispatcher($page = '', $action = 'index') {
411 if ('' === $page) {
412 if ( ! is_null(self::$buffer)) {
413 echo '<div class="wrap">';
414 echo self::$buffer;
415 do_action('wpallexport_action_after');
416 echo '</div>';
417 } elseif ( ! is_null(self::$buffer_callback)) {
418 echo '<div class="wrap">';
419 call_user_func(self::$buffer_callback);
420 do_action('wpallexport_action_after');
421 echo '</div>';
422 } else {
423 throw new Exception('There is no previousely buffered content to display.');
424 }
425 }
426 }
427
428 public function replace_callback($matches){
429 return strtoupper($matches[0]);
430 }
431
432 protected $_admin_current_screen = NULL;
433 public function getAdminCurrentScreen()
434 {
435 return $this->_admin_current_screen;
436 }
437
438 /**
439 * Autoloader
440 * It's assumed class name consists of prefix folloed by its name which in turn corresponds to location of source file
441 * if `_` symbols replaced by directory path separator. File name consists of prefix folloed by last part in class name (i.e.
442 * symbols after last `_` in class name)
443 * When class has prefix it's source is looked in `models`, `controllers`, `shortcodes` folders, otherwise it looked in `core` or `library` folder
444 *
445 * @param string $className
446 * @return bool
447 */
448 public function autoload($className) {
449 $is_prefix = false;
450 $filePath = str_replace('_', '/', preg_replace('%^' . preg_quote(self::PREFIX, '%') . '%', '', strtolower($className), 1, $is_prefix)) . '.php';
451 if ( ! $is_prefix) { // also check file with original letter case
452 $filePathAlt = $className . '.php';
453 }
454 foreach ($is_prefix ? array('models', 'controllers', 'shortcodes', 'classes') : array('libraries') as $subdir) {
455 $path = self::ROOT_DIR . '/' . $subdir . '/' . $filePath;
456 if (is_file($path)) {
457 require $path;
458 return TRUE;
459 }
460 if ( ! $is_prefix) {
461 $pathAlt = self::ROOT_DIR . '/' . $subdir . '/' . $filePathAlt;
462 if (is_file($pathAlt)) {
463 require $pathAlt;
464 return TRUE;
465 }
466 }
467 }
468
469 if(strpos($className, '\\') !== false){
470 // project-specific namespace prefix
471 $prefix = 'Wpae\\';
472
473 // base directory for the namespace prefix
474 $base_dir = __DIR__ . '/src/';
475
476 // does the class use the namespace prefix?
477 $len = strlen($prefix);
478 if (strncmp($prefix, $className, $len) !== 0) {
479 // no, move to the next registered autoloader
480 return;
481 }
482
483 // get the relative class name
484 $relative_class = substr($className, $len);
485
486 // replace the namespace prefix with the base directory, replace namespace
487 // separators with directory separators in the relative class name, append
488 // with .php
489 $file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
490
491 // if the file exists, require it
492 if (file_exists($file)) {
493 require $file;
494 }
495 }
496
497 return FALSE;
498 }
499
500 /**
501 * Get plugin option
502 * @param string[optional] $option Parameter to return, all array of options is returned if not set
503 * @return mixed
504 */
505 public function getOption($option = NULL) {
506 $options = apply_filters('wp_all_export_config_options', $this->options);
507 if (is_null($option)) {
508 return $options;
509 } else if (isset($options[$option])) {
510 return $options[$option];
511 } else {
512 throw new Exception("Specified option is not defined for the plugin");
513 }
514 }
515 /**
516 * Update plugin option value
517 * @param string $option Parameter name or array of name => value pairs
518 * @param mixed[optional] $value New value for the option, if not set than 1st parameter is supposed to be array of name => value pairs
519 * @return array
520 */
521 public function updateOption($option, $value = NULL) {
522 is_null($value) or $option = array($option => $value);
523 if (array_diff_key($option, $this->options)) {
524 throw new Exception("Specified option is not defined for the plugin");
525 }
526 $this->options = $option + $this->options;
527 update_option(get_class($this) . '_Options', $this->options);
528
529 return $this->options;
530 }
531
532 /**
533 * Plugin activation logic
534 */
535 public function activation() {
536 // uncaught exception doesn't prevent plugin from being activated, therefore replace it with fatal error so it does
537 set_exception_handler(create_function('$e', 'trigger_error($e->getMessage(), E_USER_ERROR);'));
538
539 // create plugin options
540 $option_name = get_class($this) . '_Options';
541 $options_default = PMXE_Config::createFromFile(self::ROOT_DIR . '/config/options.php')->toArray();
542 $wpai_options = get_option($option_name, false);
543 if ( ! $wpai_options ) update_option($option_name, $options_default);
544
545 // create/update required database tables
546 require_once ABSPATH . 'wp-admin/includes/upgrade.php';
547 require self::ROOT_DIR . '/schema.php';
548 global $wpdb;
549
550 if (function_exists('is_multisite') && is_multisite()) {
551 // check if it is a network activation - if so, run the activation function for each blog id
552 if (isset($_GET['networkwide']) && ($_GET['networkwide'] == 1)) {
553 $old_blog = $wpdb->blogid;
554 // Get all blog ids
555 $blogids = $wpdb->get_col("SELECT blog_id FROM $wpdb->blogs");
556 foreach ($blogids as $blog_id) {
557 switch_to_blog($blog_id);
558 require self::ROOT_DIR . '/schema.php';
559 dbDelta($plugin_queries);
560 }
561 switch_to_blog($old_blog);
562 return;
563 }
564 }
565
566 dbDelta($plugin_queries);
567
568 }
569
570 /**
571 * Load Localisation files.
572 *
573 * Note: the first-loaded translation file overrides any following ones if the same translation is present
574 *
575 * @access public
576 * @return void
577 */
578 public function load_plugin_textdomain() {
579 $locale = apply_filters( 'plugin_locale', get_locale(), 'wp_all_export_plugin' );
580
581 load_plugin_textdomain( 'wp_all_export_plugin', false, dirname( plugin_basename( __FILE__ ) ) . "/i18n/languages" );
582 }
583
584 public function fix_db_schema(){
585
586 global $wpdb;
587
588 if ( ! empty($wpdb->charset))
589 $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
590 if ( ! empty($wpdb->collate))
591 $charset_collate .= " COLLATE $wpdb->collate";
592
593 $table_prefix = $this->getTablePrefix();
594
595 $wpdb->query("CREATE TABLE IF NOT EXISTS {$table_prefix}templates (
596 id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
597 name VARCHAR(200) NOT NULL DEFAULT '',
598 options LONGTEXT,
599 PRIMARY KEY (id)
600 ) $charset_collate;");
601
602 $wpdb->query("CREATE TABLE IF NOT EXISTS {$table_prefix}posts (
603 id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
604 post_id BIGINT(20) UNSIGNED NOT NULL,
605 export_id BIGINT(20) UNSIGNED NOT NULL,
606 iteration BIGINT(20) NOT NULL DEFAULT 0,
607 PRIMARY KEY (id)
608 ) $charset_collate;");
609
610 $table = $this->getTablePrefix() . 'exports';
611 $tablefields = $wpdb->get_results("DESCRIBE {$table};");
612 $iteration = false;
613 $parent_id = false;
614 $export_post_type = false;
615
616 // Check if field exists
617 foreach ($tablefields as $tablefield) {
618 if ('iteration' == $tablefield->Field) $iteration = true;
619 if ('parent_id' == $tablefield->Field) $parent_id = true;
620 if ('export_post_type' == $tablefield->Field) $export_post_type = true;
621 }
622
623 if ( ! $iteration ){
624 $wpdb->query("ALTER TABLE {$table} ADD `iteration` BIGINT(20) NOT NULL DEFAULT 0;");
625 }
626 if ( ! $parent_id ){
627 $wpdb->query("ALTER TABLE {$table} ADD `parent_id` BIGINT(20) NOT NULL DEFAULT 0;");
628 }
629 if ( ! $export_post_type ){
630 $wpdb->query("ALTER TABLE {$table} ADD `export_post_type` VARCHAR(64) NOT NULL DEFAULT '';");
631 }
632 }
633
634 /**
635 * Determine is current export was created before current version
636 */
637 public static function isExistingExport( $checkVersion = false ){
638
639 $input = new PMXE_Input();
640 $export_id = $input->get('id', 0);
641
642 if (empty($export_id)) $export_id = $input->get('export_id', 0);
643
644 // ID not found means this is new export
645 if (empty($export_id)) return false;
646
647 if ( ! $checkVersion ) $checkVersion = PMXE_VERSION;
648
649 $export = new PMXE_Export_Record();
650 $export->getById($export_id);
651 if ( ! $export->isEmpty() && (empty($export->options['created_at_version']) || version_compare($export->options['created_at_version'], $checkVersion) < 0 )){
652 return true;
653 }
654
655 return false;
656 }
657
658 /**
659 * Method returns default import options, main utility of the method is to avoid warnings when new
660 * option is introduced but already registered imports don't have it
661 */
662 public static function get_default_import_options() {
663 return array(
664 'cpt' => array(),
665 'whereclause' => '',
666 'joinclause' => '',
667 'filter_rules_hierarhy' => '',
668 'product_matching_mode' => 'parent',
669 'order_item_per_row' => 1,
670 'order_item_fill_empty_columns' => 1,
671 'filepath' => '',
672 'current_filepath' => '',
673 'bundlepath' => '',
674 'export_type' => 'specific',
675 'wp_query' => '',
676 'wp_query_selector' => 'wp_query',
677 'is_user_export' => false,
678 'is_comment_export' => false,
679 'export_to' => 'csv',
680 'export_to_sheet' => 'csv',
681 'delimiter' => ',',
682 'encoding' => 'UTF-8',
683 'is_generate_templates' => 1,
684 'is_generate_import' => 1,
685 'import_id' => 0,
686 'template_name' => '',
687 'is_scheduled' => 0,
688 'scheduled_period' => '',
689 'scheduled_email' => '',
690 'cc_label' => array(),
691 'cc_type' => array(),
692 'cc_value' => array(),
693 'cc_name' => array(),
694 'cc_php' => array(),
695 'cc_code' => array(),
696 'cc_sql' => array(),
697 'cc_options' => array(),
698 'cc_settings' => array(),
699 'friendly_name' => '',
700 'fields' => array('default', 'other', 'cf', 'cats'),
701 'ids' => array(),
702 'rules' => array(),
703 'records_per_iteration' => 50,
704 'include_bom' => 0,
705 'include_functions' => 1,
706 'split_large_exports' => 0,
707 'split_large_exports_count' => 10000,
708 'split_files_list' => array(),
709 'main_xml_tag' => 'data',
710 'record_xml_tag' => 'post',
711 'save_template_as' => 0,
712 'name' => '',
713 'export_only_new_stuff' => 0,
714 'creata_a_new_export_file' => 0,
715 'attachment_list' => array(),
716 'order_include_poducts' => 0,
717 'order_include_all_poducts' => 0,
718 'order_include_coupons' => 0,
719 'order_include_all_coupons' => 0,
720 'order_include_customers' => 0,
721 'order_include_all_customers' => 0,
722 'migration' => '',
723 'xml_template_type' => 'simple',
724 'custom_xml_template' => '',
725 'custom_xml_template_header' => '',
726 'custom_xml_template_loop' => '',
727 'custom_xml_template_footer' => '',
728 'custom_xml_template_options' => array(),
729 'custom_xml_cdata_logic' => 'auto',
730 'taxonomy_to_export' => '',
731 'created_at_version' => '',
732 'export_variations' => XmlExportEngine::VARIABLE_PRODUCTS_EXPORT_VARIATION,
733 'export_variations_title' => XmlExportEngine::VARIATION_USE_PARENT_TITLE,
734 'show_cdata_in_preview' => 0
735 );
736 }
737
738 public static function is_ajax(){
739 return (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && !empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') ? true : false ;
740 }
741
742 }
743
744 PMXE_Plugin::getInstance();
745
746 }
747