WP Staging – DB & File Duplicator & Migration - Version 2.3.5

Version Description

  • New: Enable Optimizer as default option
  • New: Add filter to exclude strings from search & replace, docs: https://wp-staging.com/docs/actions-and-filters/
  • New: Add filter to change search & replace parameters
  • New: Add language files and change text domain to slug of the plugin
  • New: Disable heartbeat api and user login check for wp staging processing
  • New: Add issue reporting form
  • New: Check if clone subfolder already exists before creating clone
  • Fix: Changing file copy limit not working
Download this release

Release Info

Developer ReneHermi
Plugin Icon 128x128 WP Staging – DB & File Duplicator & Migration
Version 2.3.5
Comparing to
See all releases

Code changes from version 2.3.4 to 2.3.5

Files changed (36) hide show
  1. apps/Backend/Administrator.php +71 -23
  2. apps/Backend/Modules/Jobs/Data.php +10 -4
  3. apps/Backend/Modules/Jobs/Directories.php +4 -7
  4. apps/Backend/Modules/Jobs/Multisite/Data.php +1 -47
  5. apps/Backend/Modules/Jobs/Multisite/Directories.php +14 -13
  6. apps/Backend/Modules/Jobs/Multisite/SearchReplace.php +94 -74
  7. apps/Backend/Modules/Jobs/Scan.php +6 -1
  8. apps/Backend/Modules/Jobs/SearchReplace.php +53 -79
  9. apps/Backend/Modules/Views/Forms/Settings.php +3 -1
  10. apps/Backend/Upgrade/Upgrade.php +138 -130
  11. apps/Backend/public/css/wpstg-admin.css +114 -0
  12. apps/Backend/public/img/admin_dashboard.png +0 -0
  13. apps/Backend/public/js/wpstg-admin.js +184 -375
  14. apps/Backend/views/_includes/header.php +3 -2
  15. apps/Backend/views/_includes/messages/staging-directory-permission-problem.php +1 -1
  16. apps/Backend/views/_includes/messages/transient.php +2 -2
  17. apps/Backend/views/_includes/report-issue.php +33 -0
  18. apps/Backend/views/clone/ajax/delete-confirmation.php +7 -7
  19. apps/Backend/views/clone/ajax/scan.php +15 -15
  20. apps/Backend/views/clone/ajax/single-overview.php +8 -8
  21. apps/Backend/views/clone/ajax/start.php +20 -42
  22. apps/Backend/views/clone/ajax/update.php +2 -2
  23. apps/Backend/views/clone/index.php +9 -8
  24. apps/Backend/views/clone/multi-site/index.php +1 -1
  25. apps/Backend/views/clone/single-site/index.php +12 -4
  26. apps/Backend/views/settings/{index.php → main-settings.php} +65 -65
  27. apps/Backend/views/tools/tabs/import_export.php +6 -6
  28. apps/Core/Forms/Elements/Select.php +1 -1
  29. apps/Core/Utils/Report.php +85 -0
  30. apps/Core/WPStaging.php +26 -22
  31. languages/wp-staging-en_gb.mo +0 -0
  32. languages/wp-staging-en_gb.po +418 -0
  33. languages/wp-staging-it.mo +0 -0
  34. languages/wp-staging-it.po +418 -0
  35. readme.txt +15 -49
  36. wp-staging.php +2 -2
apps/Backend/Administrator.php CHANGED
@@ -27,6 +27,7 @@ use WPStaging\Backend\Activation;
27
use WPStaging\WPStaging;
28
use WPStaging\Backend\Pro\Modules\Jobs\Processing;
29
use WPStaging\Backend\Pro\Licensing;
30
31
/**
32
* Class Administrator
@@ -75,7 +76,7 @@ class Administrator extends InjectionAware {
75
$loader = $this->di->get( "loader" );
76
77
$Activation = new \WPStaging\Backend\Activation\Activation();
78
-
79
$Welcome = new Activation\Welcome();
80
81
$loader->addAction( "activated_plugin", $Activation, 'deactivate_other_instances' );
@@ -108,11 +109,11 @@ class Administrator extends InjectionAware {
108
$loader->addAction( "wp_ajax_wpstg_hide_beta", $this, "ajaxHideBeta" );
109
$loader->addAction( "wp_ajax_wpstg_logs", $this, "ajaxLogs" );
110
$loader->addAction( "wp_ajax_wpstg_check_disk_space", $this, "ajaxCheckFreeSpace" );
111
112
// Ajax hooks pro Version
113
$loader->addAction( "wp_ajax_wpstg_scan", $this, "ajaxPushScan" );
114
$loader->addAction( "wp_ajax_wpstg_push_processing", $this, "ajaxPushProcessing" );
115
- //$loader->addAction( "wp_ajax_wpstg_copy_database", $this, "ajaxCopyDatabase" );
116
}
117
118
/**
@@ -138,7 +139,7 @@ class Administrator extends InjectionAware {
138
public function sanitizeOptions( $data = array() ) {
139
$sanitized = $this->sanitizeData( $data );
140
141
- add_settings_error( "wpstg-notices", '', __( "Settings updated.", "wpstg" ), "updated" );
142
143
// Return sanitized data
144
//return $sanitized;
@@ -168,34 +169,34 @@ class Administrator extends InjectionAware {
168
169
// Main WP Staging Menu
170
add_menu_page(
171
- "WP-Staging", __( "WP Staging", "wpstg" ), "manage_options", "wpstg_clone", array($this, "getClonePage"), $logo
172
);
173
174
// Page: Clone
175
add_submenu_page(
176
- "wpstg_clone", __( "WP Staging Jobs", "wpstg" ), __( "Sites / Start", "wpstg" ), "manage_options", "wpstg_clone", array($this, "getClonePage")
177
);
178
179
// Page: Settings
180
add_submenu_page(
181
- "wpstg_clone", __( "WP Staging Settings", "wpstg" ), __( "Settings", "wpstg" ), "manage_options", "wpstg-settings", array($this, "getSettingsPage")
182
);
183
184
// Page: Tools
185
add_submenu_page(
186
- "wpstg_clone", __( "WP Staging Tools", "wpstg" ), __( "Tools", "wpstg" ), "manage_options", "wpstg-tools", array($this, "getToolsPage")
187
);
188
// Page: Tools
189
add_submenu_page(
190
- "wpstg_clone", __( "WP Staging Welcome", "wpstg" ), __( "Get WP Staging Pro", "wpstg" ), "manage_options", "wpstg-welcome", array($this, "getWelcomePage")
191
);
192
193
if( class_exists( 'WPStaging\Backend\Pro\Licensing\Licensing' ) ) {
194
// Page: License
195
add_submenu_page(
196
- "wpstg_clone", __( "WP Staging License", "wpstg" ), __( "License", "wpstg" ), "manage_options", "wpstg-license", array($this, "getLicensePage")
197
);
198
- }
199
}
200
201
/**
@@ -204,8 +205,8 @@ class Administrator extends InjectionAware {
204
public function getSettingsPage() {
205
// Tabs
206
$tabs = new Tabs( array(
207
- "general" => __( "General", "wpstg" )
208
- ) );
209
210
211
$this->di
@@ -215,7 +216,7 @@ class Administrator extends InjectionAware {
215
->set( "forms", new FormSettings( $tabs ) );
216
217
218
- require_once "{$this->path}views/settings/index.php";
219
}
220
221
/**
@@ -227,7 +228,7 @@ class Administrator extends InjectionAware {
227
228
require_once "{$this->path}views/clone/index.php";
229
}
230
-
231
/**
232
* Welcome Page
233
*/
@@ -241,9 +242,9 @@ class Administrator extends InjectionAware {
241
public function getToolsPage() {
242
// Tabs
243
$tabs = new Tabs( array(
244
- "import_export" => __( "Import/Export", "wpstg" ),
245
- "system_info" => __( "System Info", "wpstg" )
246
- ) );
247
248
$this->di->set( "tabs", $tabs );
249
@@ -285,14 +286,14 @@ class Administrator extends InjectionAware {
285
$fileExtension = explode( '.', $_FILES["import_file"]["name"] );
286
$fileExtension = end( $fileExtension );
287
if( "json" !== $fileExtension ) {
288
- wp_die( "Please upload a valid .json file", "wpstg" );
289
}
290
291
292
$importFile = $_FILES["import_file"]["tmp_name"];
293
294
if( empty( $importFile ) ) {
295
- wp_die( __( "Please upload a file to import", "wpstg" ) );
296
}
297
298
update_option( "wpstg_settings", json_decode( file_get_contents( $importFile, true ) ) );
@@ -379,11 +380,11 @@ class Administrator extends InjectionAware {
379
// Get license data
380
$license = get_option( 'wpstg_license_status' );
381
382
-
383
if( \WPStaging\WPStaging::getSlug() === 'wp-staging-pro' ) {
384
require_once "{$this->path}Pro/views/single-overview-pro.php";
385
} else {
386
- require_once "{$this->path}views/clone/ajax/single-overview.php";
387
}
388
389
wp_die();
@@ -416,6 +417,8 @@ class Administrator extends InjectionAware {
416
$cloneNameLength = strlen( $cloneName );
417
$clones = get_option( "wpstg_existing_clones_beta", array() );
418
419
// Check clone name length
420
if( $cloneNameLength < 1 || $cloneNameLength > 16 ) {
421
echo wp_send_json( array(
@@ -425,7 +428,12 @@ class Administrator extends InjectionAware {
425
} elseif( array_key_exists( $cloneName, $clones ) ) {
426
echo wp_send_json( array(
427
"status" => "failed",
428
- "message" => "Clone name is already in use, please choose an another clone name"
429
) );
430
}
431
@@ -634,7 +642,7 @@ class Administrator extends InjectionAware {
634
635
if( !class_exists( 'WPStaging\Backend\Pro\Modules\Jobs\Scan' ) ) {
636
return false;
637
- }
638
639
// Scan
640
$scan = new Pro\Modules\Jobs\Scan();
@@ -674,4 +682,44 @@ class Administrator extends InjectionAware {
674
require_once "{$this->path}Pro/views/licensing.php";
675
}
676
677
}
27
use WPStaging\WPStaging;
28
use WPStaging\Backend\Pro\Modules\Jobs\Processing;
29
use WPStaging\Backend\Pro\Licensing;
30
+ use WPStaging\Utils\Report;
31
32
/**
33
* Class Administrator
76
$loader = $this->di->get( "loader" );
77
78
$Activation = new \WPStaging\Backend\Activation\Activation();
79
+
80
$Welcome = new Activation\Welcome();
81
82
$loader->addAction( "activated_plugin", $Activation, 'deactivate_other_instances' );
109
$loader->addAction( "wp_ajax_wpstg_hide_beta", $this, "ajaxHideBeta" );
110
$loader->addAction( "wp_ajax_wpstg_logs", $this, "ajaxLogs" );
111
$loader->addAction( "wp_ajax_wpstg_check_disk_space", $this, "ajaxCheckFreeSpace" );
112
+ $loader->addAction( "wp_ajax_wpstg_send_report", $this, "ajaxSendReport" );
113
114
// Ajax hooks pro Version
115
$loader->addAction( "wp_ajax_wpstg_scan", $this, "ajaxPushScan" );
116
$loader->addAction( "wp_ajax_wpstg_push_processing", $this, "ajaxPushProcessing" );
117
}
118
119
/**
139
public function sanitizeOptions( $data = array() ) {
140
$sanitized = $this->sanitizeData( $data );
141
142
+ add_settings_error( "wpstg-notices", '', __( "Settings updated.", "wp-staging" ), "updated" );
143
144
// Return sanitized data
145
//return $sanitized;
169
170
// Main WP Staging Menu
171
add_menu_page(
172
+ "WP-Staging", __( "WP Staging", "wp-staging" ), "manage_options", "wpstg_clone", array($this, "getClonePage"), $logo
173
);
174
175
// Page: Clone
176
add_submenu_page(
177
+ "wpstg_clone", __( "WP Staging Jobs", "wp-staging" ), __( "Sites / Start", "wp-staging" ), "manage_options", "wpstg_clone", array($this, "getClonePage")
178
);
179
180
// Page: Settings
181
add_submenu_page(
182
+ "wpstg_clone", __( "WP Staging Settings", "wp-staging" ), __( "Settings", "wp-staging" ), "manage_options", "wpstg-settings", array($this, "getSettingsPage")
183
);
184
185
// Page: Tools
186
add_submenu_page(
187
+ "wpstg_clone", __( "WP Staging Tools", "wp-staging" ), __( "Tools", "wp-staging" ), "manage_options", "wpstg-tools", array($this, "getToolsPage")
188
);
189
// Page: Tools
190
add_submenu_page(
191
+ "wpstg_clone", __( "WP Staging Welcome", "wp-staging" ), __( "Get WP Staging Pro", "wp-staging" ), "manage_options", "wpstg-welcome", array($this, "getWelcomePage")
192
);
193
194
if( class_exists( 'WPStaging\Backend\Pro\Licensing\Licensing' ) ) {
195
// Page: License
196
add_submenu_page(
197
+ "wpstg_clone", __( "WP Staging License", "wp-staging" ), __( "License", "wp-staging" ), "manage_options", "wpstg-license", array($this, "getLicensePage")
198
);
199
+ }
200
}
201
202
/**
205
public function getSettingsPage() {
206
// Tabs
207
$tabs = new Tabs( array(
208
+ "general" => __( "General", "wp-staging" )
209
+ ) );
210
211
212
$this->di
216
->set( "forms", new FormSettings( $tabs ) );
217
218
219
+ require_once "{$this->path}views/settings/main-settings.php";
220
}
221
222
/**
228
229
require_once "{$this->path}views/clone/index.php";
230
}
231
+
232
/**
233
* Welcome Page
234
*/
242
public function getToolsPage() {
243
// Tabs
244
$tabs = new Tabs( array(
245
+ "import_export" => __( "Import/Export", "wp-staging" ),
246
+ "system_info" => __( "System Info", "wp-staging" )
247
+ ) );
248
249
$this->di->set( "tabs", $tabs );
250
286
$fileExtension = explode( '.', $_FILES["import_file"]["name"] );
287
$fileExtension = end( $fileExtension );
288
if( "json" !== $fileExtension ) {
289
+ wp_die( "Please upload a valid .json file", "wp-staging" );
290
}
291
292
293
$importFile = $_FILES["import_file"]["tmp_name"];
294
295
if( empty( $importFile ) ) {
296
+ wp_die( __( "Please upload a file to import", "wp-staging" ) );
297
}
298
299
update_option( "wpstg_settings", json_decode( file_get_contents( $importFile, true ) ) );
380
// Get license data
381
$license = get_option( 'wpstg_license_status' );
382
383
+
384
if( \WPStaging\WPStaging::getSlug() === 'wp-staging-pro' ) {
385
require_once "{$this->path}Pro/views/single-overview-pro.php";
386
} else {
387
+ require_once "{$this->path}views/clone/ajax/single-overview.php";
388
}
389
390
wp_die();
417
$cloneNameLength = strlen( $cloneName );
418
$clones = get_option( "wpstg_existing_clones_beta", array() );
419
420
+ $clonePath = trailingslashit(get_home_path()) . $cloneName;
421
+
422
// Check clone name length
423
if( $cloneNameLength < 1 || $cloneNameLength > 16 ) {
424
echo wp_send_json( array(
428
} elseif( array_key_exists( $cloneName, $clones ) ) {
429
echo wp_send_json( array(
430
"status" => "failed",
431
+ "message" => "Clone name is already in use, please choose an another clone name."
432
+ ) );
433
+ } elseif( is_dir( $clonePath ) ) {
434
+ echo wp_send_json( array(
435
+ "status" => "failed",
436
+ "message" => "Clone directory " . $clonePath . " already exists. Use another clone name."
437
) );
438
}
439
642
643
if( !class_exists( 'WPStaging\Backend\Pro\Modules\Jobs\Scan' ) ) {
644
return false;
645
+ }
646
647
// Scan
648
$scan = new Pro\Modules\Jobs\Scan();
682
require_once "{$this->path}Pro/views/licensing.php";
683
}
684
685
+ /**
686
+ *
687
+ * @param type $args
688
+ */
689
+ public function ajaxSendReport( $args = array() ) {
690
+ // Set params
691
+ if( empty( $args ) ) {
692
+ $args = stripslashes_deep( $_POST );
693
+ }
694
+ // Set e-mail
695
+ $email = null;
696
+ if( isset( $args['wpstg_email'] ) ) {
697
+ $email = trim( $args['wpstg_email'] );
698
+ }
699
+
700
+ // Set message
701
+ $message = null;
702
+ if( isset( $args['wpstg_message'] ) ) {
703
+ $message = trim( $args['wpstg_message'] );
704
+ }
705
+
706
+ // Set syslog
707
+ $syslog = false;
708
+ if( isset( $args['wpstg_syslog'] ) ) {
709
+ $syslog = ( bool ) $args['wpstg_syslog'];
710
+ }
711
+
712
+ // Set terms
713
+ $terms = false;
714
+ if( isset( $args['wpstg_terms'] ) ) {
715
+ $terms = ( bool ) $args['wpstg_terms'];
716
+ }
717
+
718
+ $report = new Report($this->di);
719
+ $errors = $report->send( $email, $message, $terms, $syslog );
720
+
721
+ echo json_encode( array('errors' => $errors) );
722
+ exit;
723
+ }
724
+
725
}
apps/Backend/Modules/Jobs/Data.php CHANGED
@@ -380,6 +380,8 @@ class Data extends JobExecutable {
380
return true;
381
}
382
383
$update = $this->db->query(
384
$this->db->prepare(
385
"UPDATE {$this->prefix}usermeta SET meta_key = replace(meta_key, %s, %s) WHERE meta_key LIKE %s", $this->db->prefix, $this->prefix, $this->db->prefix . "_%"
@@ -391,11 +393,14 @@ class Data extends JobExecutable {
391
$this->returnException( "Data Crunching Step 4: Failed to update {$this->prefix}usermeta meta_key database table prefixes; {$this->db->last_error}" );
392
return false;
393
}
394
return true;
395
}
396
397
/**
398
- * Update $table_prefix in wp-config.php
399
* @return bool
400
*/
401
protected function step5() {
@@ -665,7 +670,7 @@ class Data extends JobExecutable {
665
* @return bool
666
*/
667
protected function step12() {
668
- $this->log( "Preparing Data Step12: Updating db prefix in {$this->prefix}options. Error: {$this->db->last_error}" );
669
670
// Skip - Table does not exist
671
if( false === $this->isTable( $this->prefix . 'options' ) ) {
@@ -678,8 +683,9 @@ class Data extends JobExecutable {
678
return true;
679
}
680
681
682
- $this->log( "Updating db option_names in {$this->prefix}options. Error: {$this->db->last_error}" );
683
684
// Filter the rows below. Do not update them!
685
$filters = array(
@@ -688,7 +694,7 @@ class Data extends JobExecutable {
688
'wp_mail_smtp_debug',
689
);
690
691
- $filters = apply_filters( 'wpstg_filter_options_replace', $filters );
692
693
$where = "";
694
foreach ( $filters as $filter ) {
380
return true;
381
}
382
383
+ $this->debugLog("SQL: UPDATE {$this->prefix}usermeta SET meta_key = replace(meta_key, {$this->db->prefix}, {$this->prefix}) WHERE meta_key LIKE {$this->db->prefix}_%");
384
+
385
$update = $this->db->query(
386
$this->db->prepare(
387
"UPDATE {$this->prefix}usermeta SET meta_key = replace(meta_key, %s, %s) WHERE meta_key LIKE %s", $this->db->prefix, $this->prefix, $this->db->prefix . "_%"
393
$this->returnException( "Data Crunching Step 4: Failed to update {$this->prefix}usermeta meta_key database table prefixes; {$this->db->last_error}" );
394
return false;
395
}
396
+
397
+
398
+
399
return true;
400
}
401
402
/**
403
+ * Update Table prefix in wp-config.php
404
* @return bool
405
*/
406
protected function step5() {
670
* @return bool
671
*/
672
protected function step12() {
673
+ $this->log( "Preparing Data Step12: Updating db prefix in {$this->prefix}options." );
674
675
// Skip - Table does not exist
676
if( false === $this->isTable( $this->prefix . 'options' ) ) {
683
return true;
684
}
685
686
+ $notice = isset( $this->db->last_error ) ? 'Last error: ' . $this->db->last_error : '';
687
688
+ $this->log( "Updating option_name in {$this->prefix}options. {$notice}" );
689
690
// Filter the rows below. Do not update them!
691
$filters = array(
694
'wp_mail_smtp_debug',
695
);
696
697
+ $filters = apply_filters( 'wpstg_data_excl_rows', $filters );
698
699
$where = "";
700
foreach ( $filters as $filter ) {
apps/Backend/Modules/Jobs/Directories.php CHANGED
@@ -141,7 +141,7 @@ class Directories extends JobExecutable {
141
$iterator = new \WPStaging\Iterators\RecursiveFilterNewLine( $iterator );
142
143
// Exclude uploads, plugins or themes
144
- $iterator = new \WPStaging\Iterators\RecursiveFilterExclude( $iterator, apply_filters( 'wpstg_exclude_content', $excludeWpContent ) );
145
// Recursively iterate over content directory
146
$iterator = new \RecursiveIteratorIterator( $iterator, \RecursiveIteratorIterator::LEAVES_ONLY, \RecursiveIteratorIterator::CATCH_GET_CHILD );
147
@@ -532,13 +532,10 @@ class Directories extends JobExecutable {
532
* @return bool
533
*/
534
protected function isDirectoryExcluded( $directory ) {
535
-
536
- $directory = $this->sanitizeDirectorySeparator($directory);
537
-
538
foreach ( $this->options->excludedDirectories as $excludedDirectory ) {
539
- //echo $this->sanitizeDirectorySeparator($excludedDirectory). '</br>';
540
- //echo $this->sanitizeDirectorySeparator($directory). '</br>';
541
- if( strpos( $directory, $this->sanitizeDirectorySeparator($excludedDirectory) ) === 0 ) {
542
return true;
543
}
544
}
141
$iterator = new \WPStaging\Iterators\RecursiveFilterNewLine( $iterator );
142
143
// Exclude uploads, plugins or themes
144
+ $iterator = new \WPStaging\Iterators\RecursiveFilterExclude( $iterator, apply_filters( 'wpstg_clone_excl_folders', $excludeWpContent ) );
145
// Recursively iterate over content directory
146
$iterator = new \RecursiveIteratorIterator( $iterator, \RecursiveIteratorIterator::LEAVES_ONLY, \RecursiveIteratorIterator::CATCH_GET_CHILD );
147
532
* @return bool
533
*/
534
protected function isDirectoryExcluded( $directory ) {
535
+ $directory = $this->sanitizeDirectorySeparator( $directory );
536
foreach ( $this->options->excludedDirectories as $excludedDirectory ) {
537
+ $excludedDirectory = $this->sanitizeDirectorySeparator( $excludedDirectory );
538
+ if( strpos( $directory, $excludedDirectory ) === 0 ) {
539
return true;
540
}
541
}
apps/Backend/Modules/Jobs/Multisite/Data.php CHANGED
@@ -195,19 +195,6 @@ class Data extends JobExecutable {
195
// return '/' . str_replace( '/', '', $dir ) . '/';
196
}
197
198
- /**
199
- * Get path to wp-config.php if it's located in parent folder and not root level
200
- * @return mixed string | boolean
201
- */
202
- // protected function getPathWpConfig() {
203
- // $dir = trailingslashit( dirname( ABSPATH ) );
204
- //
205
- // if( is_file( $dir . 'wp-config.php' ) ) {
206
- // return $dir . 'wp-config.php';
207
- // }
208
- // return false;
209
- // }
210
-
211
/**
212
* Copy wp-config.php if it is located outside of root one level up
213
* @todo Needs some more testing before it will be released
@@ -399,39 +386,6 @@ class Data extends JobExecutable {
399
$this->returnException( "Data Crunching Step 4: Failed to update {$this->prefix}usermeta meta_key database table prefixes; {$this->db->last_error}" );
400
return false;
401
}
402
-
403
- // if( false === $this->isTable( $this->prefix . 'options' ) ) {
404
- // return true;
405
- // }
406
-
407
- // $this->log( "Updating db option_names in {$this->prefix}options. Error: {$this->db->last_error}" );
408
- //
409
- // // Filter the rows below. Do not update them!
410
- // $filters = array(
411
- // 'wp_mail_smtp',
412
- // 'wp_mail_smtp_version',
413
- // 'wp_mail_smtp_debug',
414
- // );
415
- //
416
- // $filters = apply_filters('wpstg_filter_options_replace', $filters);
417
- //
418
- // $where = "";
419
- // foreach($filters as $filter){
420
- // $where .= " AND option_name <> '" . $filter . "'";
421
- // }
422
- //
423
- // $updateOptions = $this->db->query(
424
- // $this->db->prepare(
425
- // "UPDATE IGNORE {$this->prefix}options SET option_name= replace(option_name, %s, %s) WHERE option_name LIKE %s" . $where, $this->db->prefix, $this->prefix, $this->db->prefix . "_%"
426
- // )
427
- // );
428
- //
429
- // if( !$updateOptions ) {
430
- // $this->log( "Preparing Data Step4: Failed to update db option_names in {$this->prefix}options. Error: {$this->db->last_error}", Logger::TYPE_ERROR );
431
- // $this->returnException( "Data Crunching Step 4: Failed to update db option_names in {$this->prefix}options. Error: {$this->db->last_error}" );
432
- // return false;
433
- // }
434
-
435
return true;
436
}
437
@@ -874,7 +828,7 @@ class Data extends JobExecutable {
874
'wp_mail_smtp_debug',
875
);
876
877
- $filters = apply_filters('wpstg_filter_options_replace', $filters);
878
879
$where = "";
880
foreach($filters as $filter){
195
// return '/' . str_replace( '/', '', $dir ) . '/';
196
}
197
198
/**
199
* Copy wp-config.php if it is located outside of root one level up
200
* @todo Needs some more testing before it will be released
386
$this->returnException( "Data Crunching Step 4: Failed to update {$this->prefix}usermeta meta_key database table prefixes; {$this->db->last_error}" );
387
return false;
388
}
389
return true;
390
}
391
828
'wp_mail_smtp_debug',
829
);
830
831
+ $filters = apply_filters('wpstg_data_excl_rows', $filters);
832
833
$where = "";
834
foreach($filters as $filter){
apps/Backend/Modules/Jobs/Multisite/Directories.php CHANGED
@@ -83,7 +83,7 @@ class Directories extends JobExecutable {
83
try {
84
85
// Iterate over wp root directory
86
- $iterator = new \DirectoryIterator( ABSPATH );
87
88
$this->log( "Scanning / for files" );
89
@@ -117,10 +117,9 @@ class Directories extends JobExecutable {
117
118
// Skip it
119
if( $this->isDirectoryExcluded( WP_CONTENT_DIR ) ) {
120
return true;
121
}
122
-
123
-
124
// open file handle
125
$files = $this->open( $this->filename, 'a' );
126
@@ -161,7 +160,7 @@ class Directories extends JobExecutable {
161
$iterator = new \WPStaging\Iterators\RecursiveFilterNewLine( $iterator );
162
163
// Exclude sites, uploads, plugins or themes
164
- $iterator = new \WPStaging\Iterators\RecursiveFilterExclude( $iterator, $excludePaths );
165
// Recursively iterate over content directory
166
$iterator = new \RecursiveIteratorIterator( $iterator, \RecursiveIteratorIterator::LEAVES_ONLY, \RecursiveIteratorIterator::CATCH_GET_CHILD );
167
@@ -198,7 +197,8 @@ class Directories extends JobExecutable {
198
private function getWpIncludesFiles() {
199
200
// Skip it
201
- if( $this->isDirectoryExcluded( ABSPATH . 'wp-includes' . DIRECTORY_SEPARATOR ) ) {
202
return true;
203
}
204
@@ -208,12 +208,11 @@ class Directories extends JobExecutable {
208
try {
209
210
// Iterate over wp-admin directory
211
- $iterator = new \WPStaging\Iterators\RecursiveDirectoryIterator( ABSPATH . 'wp-includes' . DIRECTORY_SEPARATOR );
212
213
// Exclude new line file names
214
$iterator = new \WPStaging\Iterators\RecursiveFilterNewLine( $iterator );
215
216
- // Exclude uploads, plugins or themes
217
// Recursively iterate over wp-includes directory
218
$iterator = new \RecursiveIteratorIterator( $iterator, \RecursiveIteratorIterator::LEAVES_ONLY, \RecursiveIteratorIterator::CATCH_GET_CHILD );
219
@@ -250,7 +249,8 @@ class Directories extends JobExecutable {
250
private function getWpAdminFiles() {
251
252
// Skip it
253
- if( $this->isDirectoryExcluded( ABSPATH . 'wp-admin' . DIRECTORY_SEPARATOR ) ) {
254
return true;
255
}
256
@@ -260,12 +260,11 @@ class Directories extends JobExecutable {
260
try {
261
262
// Iterate over wp-admin directory
263
- $iterator = new \WPStaging\Iterators\RecursiveDirectoryIterator( ABSPATH . 'wp-admin' . DIRECTORY_SEPARATOR );
264
265
// Exclude new line file names
266
$iterator = new \WPStaging\Iterators\RecursiveFilterNewLine( $iterator );
267
268
- // Exclude uploads, plugins or themes
269
// Recursively iterate over content directory
270
$iterator = new \RecursiveIteratorIterator( $iterator, \RecursiveIteratorIterator::LEAVES_ONLY, \RecursiveIteratorIterator::CATCH_GET_CHILD );
271
@@ -388,7 +387,7 @@ class Directories extends JobExecutable {
388
389
try {
390
391
- // Iterate over wp-admin directory
392
$iterator = new \WPStaging\Iterators\RecursiveDirectoryIterator( $folder );
393
394
// Exclude new line file names
@@ -417,7 +416,8 @@ class Directories extends JobExecutable {
417
// Write path line
418
foreach ( $iterator as $item ) {
419
if( $item->isFile() ) {
420
- if( $this->write( $files, $strings->getLastElemAfterString( '/', $folder ) . DIRECTORY_SEPARATOR . $iterator->getSubPathName() . PHP_EOL ) ) {
421
$this->options->totalFiles++;
422
// Add current file size
423
$this->options->totalFileSize += $iterator->getSize();
@@ -583,9 +583,10 @@ class Directories extends JobExecutable {
583
$this->files = explode( PHP_EOL, $this->files );
584
}
585
586
/**
587
* Replace forward slash with current directory separator
588
- * Windows Compatibility Fix
589
* @param string $path Path
590
*
591
* @return string
83
try {
84
85
// Iterate over wp root directory
86
+ $iterator = new \DirectoryIterator( \WPStaging\WPStaging::getWPpath() );
87
88
$this->log( "Scanning / for files" );
89
117
118
// Skip it
119
if( $this->isDirectoryExcluded( WP_CONTENT_DIR ) ) {
120
+ $this->log( "Skip " . \WPStaging\WPStaging::getWPpath() . 'wp-content' . DIRECTORY_SEPARATOR);
121
return true;
122
}
123
// open file handle
124
$files = $this->open( $this->filename, 'a' );
125
160
$iterator = new \WPStaging\Iterators\RecursiveFilterNewLine( $iterator );
161
162
// Exclude sites, uploads, plugins or themes
163
+ $iterator = new \WPStaging\Iterators\RecursiveFilterExclude( $iterator, apply_filters( 'wpstg_clone_mu_excl_folders', $excludePaths ) );
164
// Recursively iterate over content directory
165
$iterator = new \RecursiveIteratorIterator( $iterator, \RecursiveIteratorIterator::LEAVES_ONLY, \RecursiveIteratorIterator::CATCH_GET_CHILD );
166
197
private function getWpIncludesFiles() {
198
199
// Skip it
200
+ if( $this->isDirectoryExcluded( \WPStaging\WPStaging::getWPpath() . 'wp-includes' . DIRECTORY_SEPARATOR ) ) {
201
+ $this->log( "Skip " . \WPStaging\WPStaging::getWPpath() . 'wp-includes' . DIRECTORY_SEPARATOR);
202
return true;
203
}
204
208
try {
209
210
// Iterate over wp-admin directory
211
+ $iterator = new \WPStaging\Iterators\RecursiveDirectoryIterator( \WPStaging\WPStaging::getWPpath() . 'wp-includes' . DIRECTORY_SEPARATOR );
212
213
// Exclude new line file names
214
$iterator = new \WPStaging\Iterators\RecursiveFilterNewLine( $iterator );
215
216
// Recursively iterate over wp-includes directory
217
$iterator = new \RecursiveIteratorIterator( $iterator, \RecursiveIteratorIterator::LEAVES_ONLY, \RecursiveIteratorIterator::CATCH_GET_CHILD );
218
249
private function getWpAdminFiles() {
250
251
// Skip it
252
+ if( $this->isDirectoryExcluded( \WPStaging\WPStaging::getWPpath() . 'wp-admin' . DIRECTORY_SEPARATOR ) ) {
253
+ $this->log( "Skip " . \WPStaging\WPStaging::getWPpath() . 'wp-admin' . DIRECTORY_SEPARATOR);
254
return true;
255
}
256
260
try {
261
262
// Iterate over wp-admin directory
263
+ $iterator = new \WPStaging\Iterators\RecursiveDirectoryIterator( \WPStaging\WPStaging::getWPpath() . 'wp-admin' . DIRECTORY_SEPARATOR );
264
265
// Exclude new line file names
266
$iterator = new \WPStaging\Iterators\RecursiveFilterNewLine( $iterator );
267
268
// Recursively iterate over content directory
269
$iterator = new \RecursiveIteratorIterator( $iterator, \RecursiveIteratorIterator::LEAVES_ONLY, \RecursiveIteratorIterator::CATCH_GET_CHILD );
270
387
388
try {
389
390
+ // Iterate over extra directory
391
$iterator = new \WPStaging\Iterators\RecursiveDirectoryIterator( $folder );
392
393
// Exclude new line file names
416
// Write path line
417
foreach ( $iterator as $item ) {
418
if( $item->isFile() ) {
419
+ //if( $this->write( $files, $strings->getLastElemAfterString( '/', $folder ) . DIRECTORY_SEPARATOR . $iterator->getSubPathName() . PHP_EOL ) ) {
420
+ if( $this->write( $files, str_replace( \WPStaging\WPStaging::getWPpath(), '', $folder ) . DIRECTORY_SEPARATOR . $iterator->getSubPathName() . PHP_EOL ) ) {
421
$this->options->totalFiles++;
422
// Add current file size
423
$this->options->totalFileSize += $iterator->getSize();
583
$this->files = explode( PHP_EOL, $this->files );
584
}
585
586
+
587
/**
588
* Replace forward slash with current directory separator
589
+ *
590
* @param string $path Path
591
*
592
* @return string
apps/Backend/Modules/Jobs/Multisite/SearchReplace.php CHANGED
@@ -109,13 +109,6 @@ class SearchReplace extends JobExecutable {
109
return true;
110
}
111
112
- // private function convertExcludedTables() {
113
- // $tmp = array();
114
- // foreach ( $this->options->excludedTables as $table ) {
115
- // $tmp[] = str_replace( $this->options->prefix, $this->tmpPrefix, $table );
116
- // }
117
- // $this->options->excludedTables = $tmp;
118
- // }
119
120
/**
121
* Stop Execution immediately
@@ -231,41 +224,38 @@ class SearchReplace extends JobExecutable {
231
// Search URL example.com/staging and root path to staging site /var/www/htdocs/staging
232
$args['search_for'] = array(
233
rtrim( $this->multisiteHomeUrl, "/" ) . $this->getSubDir(),
234
- ABSPATH
235
);
236
237
238
$args['replace_with'] = array(
239
rtrim( $this->multisiteHomeUrl, "/" ) . $this->getSubDir() . '/' . $this->options->cloneDirectoryName,
240
- rtrim( ABSPATH, '/' ) . '/' . $this->options->cloneDirectoryName
241
);
242
} else {
243
$args['search_for'] = array(
244
rtrim( $this->multisiteHomeUrl, '/' ),
245
- ABSPATH
246
);
247
$args['replace_with'] = array(
248
rtrim( $this->multisiteHomeUrl, '/' ) . '/' . $this->options->cloneDirectoryName,
249
- rtrim( ABSPATH, '/' ) . '/' . $this->options->cloneDirectoryName
250
);
251
}
252
253
- // // Search URL example.com/staging and root path to staging site /var/www/htdocs/staging
254
- // $args['search_for'] = array(
255
- // $this->multisiteHomeUrl,
256
- // ABSPATH
257
- // );
258
- //
259
- //
260
- // $args['replace_with'] = array(
261
- // rtrim( $this->multisiteHomeUrl, '/' ) . '/' . $this->options->cloneDirectoryName,
262
- // rtrim( ABSPATH, '/' ) . '/' . $this->options->cloneDirectoryName
263
- // );
264
$args['replace_guids'] = 'off';
265
$args['dry_run'] = 'off';
266
$args['case_insensitive'] = false;
267
$args['replace_guids'] = 'off';
268
269
// Get a list of columns in this table.
270
list( $primary_key, $columns ) = $this->get_columns( $table );
271
@@ -273,7 +263,6 @@ class SearchReplace extends JobExecutable {
273
// We commented this to search & replace through tables which have no primary keys like wp_revslider_slides
274
// @todo test this carefully. If it causes (performance) issues we need to activate it again!
275
// @since 2.4.4
276
-
277
// if( null === $primary_key ) {
278
// return false;
279
// }
@@ -285,7 +274,7 @@ class SearchReplace extends JobExecutable {
285
// Grab the content of the table.
286
$data = $this->db->get_results( "SELECT * FROM $table LIMIT $start, $end", ARRAY_A );
287
288
- // Filter certain rows (of other plugins)
289
$filter = array(
290
'Admin_custome_login_Slidshow',
291
'Admin_custome_login_Social',
@@ -297,7 +286,7 @@ class SearchReplace extends JobExecutable {
297
'Admin_custome_login_Version',
298
);
299
300
- apply_filters('wpstg_fiter_search_replace_rows', $filter);
301
302
// Loop through the data.
303
foreach ( $data as $row ) {
@@ -307,7 +296,7 @@ class SearchReplace extends JobExecutable {
307
$upd = false;
308
309
// Skip rows below
310
- if (isset($row['option_name']) && in_array($row['option_name'], $filter)){
311
continue;
312
}
313
@@ -316,6 +305,7 @@ class SearchReplace extends JobExecutable {
316
continue;
317
}
318
319
foreach ( $columns as $column ) {
320
321
$dataRow = $row[$column];
@@ -331,6 +321,11 @@ class SearchReplace extends JobExecutable {
331
}
332
333
334
// Check options table
335
if( $this->options->prefix . 'options' === $table ) {
336
@@ -352,14 +347,30 @@ class SearchReplace extends JobExecutable {
352
}
353
}
354
355
- // Run a search replace on the data that'll respect the serialisation.
356
$i = 0;
357
- foreach ( $args['search_for'] as $replace ) {
358
- $dataRow = $this->recursive_unserialize_replace( $args['search_for'][$i], $args['replace_with'][$i], $dataRow, false, $args['case_insensitive'] );
359
$i++;
360
}
361
unset( $replace );
362
unset( $i );
363
364
// Something was changed
365
if( $row[$column] != $dataRow ) {
@@ -404,48 +415,45 @@ class SearchReplace extends JobExecutable {
404
* @param string $from String we're looking to replace.
405
* @param string $to What we want it to be replaced with
406
* @param array $data Used to pass any subordinate arrays back to in.
407
- * @param boolean $serialised Does the array passed via $data need serialising.
408
* @param sting|boolean $case_insensitive Set to 'on' if we should ignore case, false otherwise.
409
*
410
* @return string|array The original array with all elements replaced as needed.
411
*/
412
- private function recursive_unserialize_replace( $from = '', $to = '', $data = '', $serialised = false, $case_insensitive = false ) {
413
try {
414
-
415
- if( is_string( $data ) && !is_serialized_string( $data ) && ( $unserialized = $this->unserialize( $data ) ) !== false ) {
416
$data = $this->recursive_unserialize_replace( $from, $to, $unserialized, true, $case_insensitive );
417
} elseif( is_array( $data ) ) {
418
- $_tmp = array();
419
foreach ( $data as $key => $value ) {
420
- $_tmp[$key] = $this->recursive_unserialize_replace( $from, $to, $value, false, $case_insensitive );
421
}
422
423
- $data = $_tmp;
424
- unset( $_tmp );
425
- }
426
-
427
- // Submitted by Tina Matter
428
- elseif( $this->isValidObject($data) ) {
429
- $_tmp = $data; // new $data_class( );
430
$props = get_object_vars( $data );
431
foreach ( $props as $key => $value ) {
432
- $_tmp->$key = $this->recursive_unserialize_replace( $from, $to, $value, false, $case_insensitive );
433
}
434
-
435
- $data = $_tmp;
436
- unset( $_tmp );
437
- } elseif( is_serialized_string( $data ) ) {
438
- if (false !== ($data = $this->unserialize($data)) ) {
439
- $data = $this->str_replace( $from, $to, $data, $case_insensitive );
440
- $data = serialize( $data );
441
}
442
} else {
443
if( is_string( $data ) ) {
444
$data = $this->str_replace( $from, $to, $data, $case_insensitive );
445
}
446
}
447
448
- if( $serialised ) {
449
return serialize( $data );
450
}
451
} catch ( Exception $error ) {
@@ -460,28 +468,28 @@ class SearchReplace extends JobExecutable {
460
* Can not use is_object alone because in php 7.2 it's returning true even though object is __PHP_Incomplete_Class_Name
461
* @return boolean
462
*/
463
- private function isValidObject($data){
464
- if( !is_object( $data ) || gettype( $data ) != 'object' ) {
465
- return false;
466
- }
467
-
468
- $invalid_class_props = get_object_vars( $data );
469
-
470
- if (!isset($invalid_class_props['__PHP_Incomplete_Class_Name'])){
471
- // Assume it must be an valid object
472
- return true;
473
- }
474
-
475
- $invalid_object_class = $invalid_class_props['__PHP_Incomplete_Class_Name'];
476
-
477
- if( !empty( $invalid_object_class ) ) {
478
- return false;
479
- }
480
481
- // Assume it must be an valid object
482
- return true;
483
- }
484
-
485
/**
486
* Mimics the mysql_real_escape_string function. Adapted from a post by 'feedr' on php.net.
487
* @link http://php.net/manual/en/function.mysql-real-escape-string.php#101248
@@ -530,10 +538,22 @@ class SearchReplace extends JobExecutable {
530
* @return string
531
*/
532
private function str_replace( $from, $to, $data, $case_insensitive = false ) {
533
if( 'on' === $case_insensitive ) {
534
- $data = str_ireplace( $from, $to, $data );
535
} else {
536
- $data = str_replace( $from, $to, $data );
537
}
538
539
return $data;
109
return true;
110
}
111
112
113
/**
114
* Stop Execution immediately
224
// Search URL example.com/staging and root path to staging site /var/www/htdocs/staging
225
$args['search_for'] = array(
226
rtrim( $this->multisiteHomeUrl, "/" ) . $this->getSubDir(),
227
+ ABSPATH,
228
+ str_replace( '/', '\/', rtrim( $this->multisiteHomeUrl, '/' ) ) . str_replace( '/', '\/', $this->getSubDir() ) // // Used by revslider and several visual editors
229
);
230
231
232
$args['replace_with'] = array(
233
rtrim( $this->multisiteHomeUrl, "/" ) . $this->getSubDir() . '/' . $this->options->cloneDirectoryName,
234
+ rtrim( ABSPATH, '/' ) . '/' . $this->options->cloneDirectoryName,
235
+ str_replace( '/', '\/', rtrim( $this->multisiteHomeUrl, "/" ) ) . str_replace( '/', '\/', $this->getSubDir() ) . '\/' . $this->options->cloneDirectoryName, // Used by revslider and several visual editors
236
);
237
} else {
238
$args['search_for'] = array(
239
rtrim( $this->multisiteHomeUrl, '/' ),
240
+ ABSPATH,
241
+ str_replace( '/', '\/', rtrim( $this->multisiteHomeUrl, '/' ) )
242
);
243
$args['replace_with'] = array(
244
rtrim( $this->multisiteHomeUrl, '/' ) . '/' . $this->options->cloneDirectoryName,
245
+ rtrim( ABSPATH, '/' ) . '/' . $this->options->cloneDirectoryName,
246
+ str_replace( '/', '\/', rtrim( $this->multisiteHomeUrl, '/' ) ) . '\/' . $this->options->cloneDirectoryName,
247
);
248
}
249
250
$args['replace_guids'] = 'off';
251
$args['dry_run'] = 'off';
252
$args['case_insensitive'] = false;
253
$args['replace_guids'] = 'off';
254
+ $args['replace_mails'] = 'off';
255
256
+ // Allow filtering of search & replace parameters
257
+ $args = apply_filters('wpstg_clone_searchreplace_params', $args);
258
+
259
// Get a list of columns in this table.
260
list( $primary_key, $columns ) = $this->get_columns( $table );
261
263
// We commented this to search & replace through tables which have no primary keys like wp_revslider_slides
264
// @todo test this carefully. If it causes (performance) issues we need to activate it again!
265
// @since 2.4.4
266
// if( null === $primary_key ) {
267
// return false;
268
// }
274
// Grab the content of the table.
275
$data = $this->db->get_results( "SELECT * FROM $table LIMIT $start, $end", ARRAY_A );
276
277
+ // Filter certain option_name (of other plugins)
278
$filter = array(
279
'Admin_custome_login_Slidshow',
280
'Admin_custome_login_Social',
286
'Admin_custome_login_Version',
287
);
288
289
+ apply_filters( 'wpstg_clone_searchreplace_excl_rows', $filter );
290
291
// Loop through the data.
292
foreach ( $data as $row ) {
296
$upd = false;
297
298
// Skip rows below
299
+ if( isset( $row['option_name'] ) && in_array( $row['option_name'], $filter ) ) {
300
continue;
301
}
302
305
continue;
306
}
307
308
+
309
foreach ( $columns as $column ) {
310
311
$dataRow = $row[$column];
321
}
322
323
324
+ // Skip mail addresses
325
+ if( 'off' === $args['replace_mails'] && false !== strpos( $dataRow, '@' . $this->homeUrl ) ) {
326
+ continue;
327
+ }
328
+
329
// Check options table
330
if( $this->options->prefix . 'options' === $table ) {
331
347
}
348
}
349
350
+ // Check the path delimiter for / or \/ and remove one of those which prevents from resulting in wrong syntax like domain.com/staging\/.
351
+ // 1. local.wordpress.test -> local.wordpress.test/staging
352
+ // 2. local.wordpress.test\/ -> local.wordpress.test\/staging\/
353
+ $tmp = $args;
354
+ if ( false === strpos( $dataRow, $tmp['search_for'][0] )){
355
+ array_shift($tmp['search_for']); // rtrim( $this->homeUrl, '/' ),
356
+ array_shift($tmp['replace_with']); // rtrim( $this->homeUrl, '/' ) . '/' . $this->options->cloneDirectoryName,
357
+ } else {
358
+ unset($tmp['search_for'][1]);
359
+ unset($tmp['replace_with'][1]);
360
+ // recount array
361
+ $tmp['search_for'] = array_values($tmp['search_for']);
362
+ $tmp['replace_with'] = array_values($tmp['replace_with']);
363
+ }
364
+
365
+ // Run a search replace on the data row and respect the serialisation.
366
$i = 0;
367
+ foreach ( $tmp['search_for'] as $replace ) {
368
+ $dataRow = $this->recursive_unserialize_replace( $tmp['search_for'][$i], $tmp['replace_with'][$i], $dataRow, false, $args['case_insensitive'] );
369
$i++;
370
}
371
unset( $replace );
372
unset( $i );
373
+ unset( $tmp );
374
375
// Something was changed
376
if( $row[$column] != $dataRow ) {
415
* @param string $from String we're looking to replace.
416
* @param string $to What we want it to be replaced with
417
* @param array $data Used to pass any subordinate arrays back to in.
418
+ * @param boolean $serialized Does the array passed via $data need serialising.
419
* @param sting|boolean $case_insensitive Set to 'on' if we should ignore case, false otherwise.
420
*
421
* @return string|array The original array with all elements replaced as needed.
422
*/
423
+ private function recursive_unserialize_replace( $from = '', $to = '', $data = '', $serialized = false, $case_insensitive = false ) {
424
try {
425
+ // Some unserialized data cannot be re-serialized eg. SimpleXMLElements
426
+ if( is_serialized( $data ) && ( $unserialized = @unserialize( $data ) ) !== false ) {
427
$data = $this->recursive_unserialize_replace( $from, $to, $unserialized, true, $case_insensitive );
428
} elseif( is_array( $data ) ) {
429
+ $tmp = array();
430
foreach ( $data as $key => $value ) {
431
+ $tmp[$key] = $this->recursive_unserialize_replace( $from, $to, $value, false, $case_insensitive );
432
}
433
434
+ $data = $tmp;
435
+ unset( $tmp );
436
+ } elseif( is_object( $data ) ) {
437
+ $tmp = $data;
438
$props = get_object_vars( $data );
439
foreach ( $props as $key => $value ) {
440
+ if( $key === '' || ord( $key[0] ) === 0 ) {
441
+ continue;
442
}
443
+ $tmp->$key = $this->recursive_unserialize_replace( $from, $to, $value, false, $case_insensitive );
444
}
445
+
446
+ $data = $tmp;
447
+ unset( $tmp );
448
} else {
449
if( is_string( $data ) ) {
450
+ if( !empty( $from ) && !empty( $to ) ) {
451
$data = $this->str_replace( $from, $to, $data, $case_insensitive );
452
}
453
}
454
+ }
455
456
+ if( $serialized ) {
457
return serialize( $data );
458
}
459
} catch ( Exception $error ) {
468
* Can not use is_object alone because in php 7.2 it's returning true even though object is __PHP_Incomplete_Class_Name
469
* @return boolean
470
*/
471
+ // private function isValidObject( $data ) {
472
+ // if( !is_object( $data ) || gettype( $data ) != 'object' ) {
473
+ // return false;
474
+ // }
475
+ //
476
+ // $invalid_class_props = get_object_vars( $data );
477
+ //
478
+ // if( !isset( $invalid_class_props['__PHP_Incomplete_Class_Name'] ) ) {
479
+ // // Assume it must be an valid object
480
+ // return true;
481
+ // }
482
+ //
483
+ // $invalid_object_class = $invalid_class_props['__PHP_Incomplete_Class_Name'];
484
+ //
485
+ // if( !empty( $invalid_object_class ) ) {
486
+ // return false;
487
+ // }
488
+ //
489
+ // // Assume it must be an valid object
490
+ // return true;
491
+ // }
492
493
/**
494
* Mimics the mysql_real_escape_string function. Adapted from a post by 'feedr' on php.net.
495
* @link http://php.net/manual/en/function.mysql-real-escape-string.php#101248
538
* @return string
539
*/
540
private function str_replace( $from, $to, $data, $case_insensitive = false ) {
541
+
542
+ // Add filter
543
+ $excludes = apply_filters( 'wpstg_clone_searchreplace_excl', array() );
544
+
545
+ // Build pattern
546
+ $regexExclude = '';
547
+ foreach ( $excludes as $exclude ) {
548
+ $regexExclude .= $exclude . '(*SKIP)(FAIL)|';
549
+ }
550
+
551
if( 'on' === $case_insensitive ) {
552
+ //$data = str_ireplace( $from, $to, $data );
553
+ $data = preg_replace( '#' . $regexExclude . preg_quote ( $from) . '#i', $to, $data );
554
} else {
555
+ //$data = str_replace( $from, $to, $data );
556
+ $data = preg_replace( '#' . $regexExclude . preg_quote($from) . '#', $to, $data );
557
}
558
559
return $data;
apps/Backend/Modules/Jobs/Scan.php CHANGED
@@ -239,7 +239,7 @@ class Scan extends Job {
239
foreach ( $tables as $table ) {
240
241
// Exclude WP Staging Tables
242
- // if (0 === strpos($table->Name, "wpstg"))
243
// {
244
// continue;
245
// }
@@ -293,6 +293,11 @@ class Scan extends Job {
293
* @param string $path
294
*/
295
protected function getSubDirectories( $path ) {
296
$directories = new \DirectoryIterator( $path );
297
298
foreach ( $directories as $directory ) {
239
foreach ( $tables as $table ) {
240
241
// Exclude WP Staging Tables
242
+ // if (0 === strpos($table->Name, "wp-staging"))
243
// {
244
// continue;
245
// }
293
* @param string $path
294
*/
295
protected function getSubDirectories( $path ) {
296
+
297
+ if (!is_readable($path)){
298
+ return false;
299
+ }
300
+
301
$directories = new \DirectoryIterator( $path );
302
303
foreach ( $directories as $directory ) {
apps/Backend/Modules/Jobs/SearchReplace.php CHANGED
@@ -45,12 +45,10 @@ class SearchReplace extends JobExecutable {
45
public function initialize() {
46
$this->total = count( $this->options->tables );
47
$this->db = WPStaging::getInstance()->get( "wpdb" );
48
- //$this->tmpPrefix = 'wpstgtmp_';
49
$this->tmpPrefix = $this->options->prefix;
50
$helper = new Helper();
51
//$this->homeUrl = $helper->get_home_url();
52
$this->homeUrl = $helper->get_home_url_without_scheme();
53
-
54
}
55
56
public function start() {
@@ -118,7 +116,6 @@ class SearchReplace extends JobExecutable {
118
return true;
119
}
120
121
-
122
/**
123
* Stop Execution immediately
124
* return mixed bool | json
@@ -216,7 +213,7 @@ class SearchReplace extends JobExecutable {
216
* @access public
217
* @param string $table The table to run the replacement on.
218
* @param int $page The page/block to begin the query on.
219
- * @param array $args An associative array containing arguements for this run.
220
* @return array
221
*/
222
private function searchReplace( $table, $page, $args ) {
@@ -226,33 +223,33 @@ class SearchReplace extends JobExecutable {
226
$table = esc_sql( $table );
227
$current_page = $this->options->job->start + $this->settings->querySRLimit;
228
$pages = $this->get_pages_in_table( $table );
229
- //$done = false;
230
231
232
if( $this->isSubDir() ) {
233
// Search URL example.com/staging and root path to staging site /var/www/htdocs/staging
234
$args['search_for'] = array(
235
rtrim( $this->homeUrl, "/" ) . $this->getSubDir(),
236
rtrim( ABSPATH, '/' ),
237
- $this->homeUrl . str_replace('/', '\/', $this->getSubDir()) // // Used by revslider and several visual editors
238
-
239
);
240
241
$args['replace_with'] = array(
242
rtrim( $this->homeUrl, "/" ) . $this->getSubDir() . '/' . $this->options->cloneDirectoryName,
243
rtrim( ABSPATH, '/' ) . '/' . $this->options->cloneDirectoryName,
244
- $this->homeUrl . str_replace('/', '\/', $this->getSubDir()) . '\/' . $this->options->cloneDirectoryName, // Used by revslider and several visual editors
245
);
246
} else {
247
$args['search_for'] = array(
248
rtrim( $this->homeUrl, '/' ),
249
rtrim( ABSPATH, '/' ),
250
- $this->homeUrl . '\/'
251
);
252
$args['replace_with'] = array(
253
rtrim( $this->homeUrl, '/' ) . '/' . $this->options->cloneDirectoryName,
254
rtrim( ABSPATH, '/' ) . '/' . $this->options->cloneDirectoryName,
255
- $this->homeUrl . '\/' . $this->options->cloneDirectoryName,
256
);
257
}
258
@@ -262,6 +259,11 @@ class SearchReplace extends JobExecutable {
262
$args['case_insensitive'] = false;
263
$args['replace_guids'] = 'off';
264
$args['replace_mails'] = 'off';
265
266
// Get a list of columns in this table.
267
list( $primary_key, $columns ) = $this->get_columns( $table );
@@ -270,7 +272,6 @@ class SearchReplace extends JobExecutable {
270
// We commented this to search & replace through tables which have no primary keys like wp_revslider_slides
271
// @todo test this carefully. If it causes (performance) issues we need to activate it again!
272
// @since 2.4.4
273
-
274
// if( null === $primary_key ) {
275
// return false;
276
// }
@@ -294,30 +295,22 @@ class SearchReplace extends JobExecutable {
294
'Admin_custome_login_Version',
295
);
296
297
- apply_filters('wpstg_fiter_search_replace_rows', $filter);
298
299
- // // Do not search & replace any strings below
300
- // $filterStrings = array(
301
- // '@' . $this->homeUrl // Mail addresses
302
- // );
303
-
304
- //apply_filters('wpstg_fiter_search_replace_strings', $filterStrings);
305
-
306
-
307
// Loop through the data.
308
foreach ( $data as $row ) {
309
- $current_row++;
310
$update_sql = array();
311
$where_sql = array();
312
$upd = false;
313
314
// Skip rows below
315
- if (isset($row['option_name']) && in_array($row['option_name'], $filter)){
316
continue;
317
}
318
319
// Skip rows with transients (They can store huge data and we need to save memory)
320
- if( isset( $row['option_name'] ) && strpos( $row['option_name'], '_transient' ) === 0 ) {
321
continue;
322
}
323
@@ -340,6 +333,7 @@ class SearchReplace extends JobExecutable {
340
continue;
341
}
342
343
// Check options table
344
if( $this->options->prefix . 'options' === $table ) {
345
@@ -349,7 +343,7 @@ class SearchReplace extends JobExecutable {
349
continue;
350
}
351
352
- // Skip this rows
353
if( 'wpstg_existing_clones_beta' === $dataRow ||
354
'wpstg_existing_clones' === $dataRow ||
355
'wpstg_settings' === $dataRow ||
@@ -360,16 +354,32 @@ class SearchReplace extends JobExecutable {
360
$should_skip = true;
361
}
362
}
363
364
365
- // Run a search replace on the data that'll respect the serialisation.
366
$i = 0;
367
- foreach ( $args['search_for'] as $replace ) {
368
- $dataRow = $this->recursive_unserialize_replace( $args['search_for'][$i], $args['replace_with'][$i], $dataRow, false, $args['case_insensitive'] );
369
$i++;
370
}
371
unset( $replace );
372
unset( $i );
373
374
// Something was changed
375
if( $row[$column] != $dataRow ) {
@@ -419,54 +429,6 @@ class SearchReplace extends JobExecutable {
419
*
420
* @return string|array The original array with all elements replaced as needed.
421
*/
422
- // private function recursive_unserialize_replace( $from = '', $to = '', $data = '', $serialised = false, $case_insensitive = false ) {
423
- // try {
424
- //
425
- // if( is_string( $data ) && !is_serialized_string( $data ) && ( $unserialized = $this->unserialize( $data ) ) !== false ) {
426
- // $data = $this->recursive_unserialize_replace( $from, $to, $unserialized, true, $case_insensitive );
427
- // } elseif( is_array( $data ) ) {
428
- // $_tmp = array();
429
- // foreach ( $data as $key => $value ) {
430
- // $_tmp[$key] = $this->recursive_unserialize_replace( $from, $to, $value, false, $case_insensitive );
431
- // }
432
- //
433
- // $data = $_tmp;
434
- // unset( $_tmp );
435
- // }
436
- //
437
- // // Submitted by Tina Matter
438
- // elseif( $this->isValidObject($data) ) {
439
- // $_tmp = $data; // new $data_class( );
440
- // $props = get_object_vars( $data );
441
- // foreach ( $props as $key => $value ) {
442
- // if( $key === '' || ord( $key[0] ) === 0 ) {
443
- // continue;
444
- // }
445
- // $_tmp->$key = $this->recursive_unserialize_replace( $from, $to, $value, false, $case_insensitive );
446
- // }
447
- //
448
- // $data = $_tmp;
449
- // unset($_tmp);
450
- // } elseif (is_serialized_string($data)) {
451
- // if (false !== ($data = $this->unserialize($data)) ) {
452
- // $data = $this->str_replace($from, $to, $data, $case_insensitive);
453
- // $data = serialize($data);
454
- // }
455
- // } else {
456
- // if( is_string( $data ) ) {
457
- // $data = $this->str_replace( $from, $to, $data, $case_insensitive );
458
- // }
459
- // }
460
- //
461
- // if( $serialised ) {
462
- // return serialize( $data );
463
- // }
464
- // } catch ( Exception $error ) {
465
- //
466
- // }
467
- //
468
- // return $data;
469
- // }
470
private function recursive_unserialize_replace( $from = '', $to = '', $data = '', $serialized = false, $case_insensitive = false ) {
471
try {
472
// Some unserialized data cannot be re-serialized eg. SimpleXMLElements
@@ -585,10 +547,22 @@ class SearchReplace extends JobExecutable {
585
* @return string
586
*/
587
private function str_replace( $from, $to, $data, $case_insensitive = false ) {
588
if( 'on' === $case_insensitive ) {
589
- $data = str_ireplace( $from, $to, $data );
590
} else {
591
- $data = str_replace( $from, $to, $data );
592
}
593
594
return $data;
@@ -682,8 +656,8 @@ class SearchReplace extends JobExecutable {
682
* Check if WP is installed in subdir
683
* @return boolean
684
*/
685
- private function isSubDir(){
686
- if ( get_option( 'siteurl' ) !== get_option( 'home' ) ) {
687
return true;
688
}
689
return false;
45
public function initialize() {
46
$this->total = count( $this->options->tables );
47
$this->db = WPStaging::getInstance()->get( "wpdb" );
48
$this->tmpPrefix = $this->options->prefix;
49
$helper = new Helper();
50
//$this->homeUrl = $helper->get_home_url();
51
$this->homeUrl = $helper->get_home_url_without_scheme();
52
}
53
54
public function start() {
116
return true;
117
}
118
119
/**
120
* Stop Execution immediately
121
* return mixed bool | json
213
* @access public
214
* @param string $table The table to run the replacement on.
215
* @param int $page The page/block to begin the query on.
216
+ * @param array $args An associative array containing arguments for this run.
217
* @return array
218
*/
219
private function searchReplace( $table, $page, $args ) {
223
$table = esc_sql( $table );
224
$current_page = $this->options->job->start + $this->settings->querySRLimit;
225
$pages = $this->get_pages_in_table( $table );
226
227
228
if( $this->isSubDir() ) {
229
// Search URL example.com/staging and root path to staging site /var/www/htdocs/staging
230
$args['search_for'] = array(
231
+ $this->homeUrl . str_replace( '/', '\/', $this->getSubDir() ), // // Used by revslider and several visual editors
232
rtrim( $this->homeUrl, "/" ) . $this->getSubDir(),
233
rtrim( ABSPATH, '/' ),
234
);
235
236
$args['replace_with'] = array(
237
+ $this->homeUrl . str_replace( '/', '\/', $this->getSubDir() ) . '\/' . $this->options->cloneDirectoryName, // Used by revslider and several visual editors
238
rtrim( $this->homeUrl, "/" ) . $this->getSubDir() . '/' . $this->options->cloneDirectoryName,
239
rtrim( ABSPATH, '/' ) . '/' . $this->options->cloneDirectoryName,
240
+
241
);
242
} else {
243
$args['search_for'] = array(
244
+ $this->homeUrl . '\/',
245
rtrim( $this->homeUrl, '/' ),
246
rtrim( ABSPATH, '/' ),
247
);
248
$args['replace_with'] = array(
249
+ $this->homeUrl . '\/' . $this->options->cloneDirectoryName . '\/',
250
rtrim( $this->homeUrl, '/' ) . '/' . $this->options->cloneDirectoryName,
251
rtrim( ABSPATH, '/' ) . '/' . $this->options->cloneDirectoryName,
252
+
253
);
254
}
255
259
$args['case_insensitive'] = false;
260
$args['replace_guids'] = 'off';
261
$args['replace_mails'] = 'off';
262
+ $args['skip_transients'] = 'on';
263
+
264
+
265
+ // Allow filtering of search & replace parameters
266
+ $args = apply_filters('wpstg_clone_searchreplace_params', $args);
267
268
// Get a list of columns in this table.
269
list( $primary_key, $columns ) = $this->get_columns( $table );
272
// We commented this to search & replace through tables which have no primary keys like wp_revslider_slides
273
// @todo test this carefully. If it causes (performance) issues we need to activate it again!
274
// @since 2.4.4
275
// if( null === $primary_key ) {
276
// return false;
277
// }
295
'Admin_custome_login_Version',
296
);
297
298
+ $filter = apply_filters( 'wpstg_clone_searchreplace_excl_rows', $filter );
299
300
// Loop through the data.
301
foreach ( $data as $row ) {
302
+ //$current_row++;
303
$update_sql = array();
304
$where_sql = array();
305
$upd = false;
306
307
// Skip rows below
308
+ if( isset( $row['option_name'] ) && in_array( $row['option_name'], $filter ) ) {
309
continue;
310
}
311
312
// Skip rows with transients (They can store huge data and we need to save memory)
313
+ if( isset( $row['option_name'] ) && 'on' === $args['skip_transients'] && false !== strpos( $row['option_name'], '_transient' ) ) {
314
continue;
315
}
316
333
continue;
334
}
335
336
+
337
// Check options table
338
if( $this->options->prefix . 'options' === $table ) {
339
343
continue;
344
}
345
346
+ // Skip this row
347
if( 'wpstg_existing_clones_beta' === $dataRow ||
348
'wpstg_existing_clones' === $dataRow ||
349
'wpstg_settings' === $dataRow ||
354
$should_skip = true;
355
}
356
}
357
+ $tmp = $args;
358
+ // Check the path delimiter for / or \/ and remove one of those which prevents from resulting in wrong syntax like domain.com/staging\/.
359
+ // 1. local.wordpress.test -> local.wordpress.test/staging
360
+ // 2. local.wordpress.test\/ -> local.wordpress.test\/staging\/
361
+ if ( false === strpos( $dataRow, $tmp['search_for'][0] )){
362
+ array_shift($tmp['search_for']); // rtrim( $this->homeUrl, '/' ),
363
+ array_shift($tmp['replace_with']); // rtrim( $this->homeUrl, '/' ) . '/' . $this->options->cloneDirectoryName,
364
+ } else {
365
+ unset($tmp['search_for'][1]);
366
+ unset($tmp['replace_with'][1]);
367
+ // recount array
368
+ $tmp['search_for'] = array_values($tmp['search_for']);
369
+ $tmp['replace_with'] = array_values($tmp['replace_with']);
370
+ }
371
372
373
+
374
+ // Run a search replace on the data row and respect the serialisation.
375
$i = 0;
376
+ foreach ( $tmp['search_for'] as $replace ) {
377
+ $dataRow = $this->recursive_unserialize_replace( $tmp['search_for'][$i], $tmp['replace_with'][$i], $dataRow, false, $args['case_insensitive'] );
378
$i++;
379
}
380
unset( $replace );
381
unset( $i );
382
+ unset( $tmp );
383
384
// Something was changed
385
if( $row[$column] != $dataRow ) {
429
*
430
* @return string|array The original array with all elements replaced as needed.
431
*/
432
private function recursive_unserialize_replace( $from = '', $to = '', $data = '', $serialized = false, $case_insensitive = false ) {
433
try {
434
// Some unserialized data cannot be re-serialized eg. SimpleXMLElements
547
* @return string
548
*/
549
private function str_replace( $from, $to, $data, $case_insensitive = false ) {
550
+
551
+ // Add filter
552
+ $excludes = apply_filters( 'wpstg_clone_searchreplace_excl', array() );
553
+
554
+ // Build pattern
555
+ $regexExclude = '';
556
+ foreach ( $excludes as $exclude ) {
557
+ $regexExclude .= $exclude . '(*SKIP)(FAIL)|';
558
+ }
559
+
560
if( 'on' === $case_insensitive ) {
561
+ //$data = str_ireplace( $from, $to, $data );
562
+ $data = preg_replace( '#' . $regexExclude . preg_quote ( $from) . '#i', $to, $data );
563
} else {
564
+ //$data = str_replace( $from, $to, $data );
565
+ $data = preg_replace( '#' . $regexExclude . preg_quote($from) . '#', $to, $data );
566
}
567
568
return $data;
656
* Check if WP is installed in subdir
657
* @return boolean
658
*/
659
+ private function isSubDir() {
660
+ if( get_option( 'siteurl' ) !== get_option( 'home' ) ) {
661
return true;
662
}
663
return false;
apps/Backend/Modules/Views/Forms/Settings.php CHANGED
@@ -88,7 +88,9 @@ class Settings {
88
);
89
90
$this->form["general"]->add(
91
- $element->setLabel( "File Copy Limit" )->setDefault( isset( $settings->fileLimit ) ? $settings->fileLimit : 1 )
92
);
93
94
88
);
89
90
$this->form["general"]->add(
91
+ $element->setLabel( "File Copy Limit" )
92
+ ->setDefault( isset( $settings->fileLimit ) ? $settings->fileLimit : 1 )
93
+
94
);
95
96
apps/Backend/Upgrade/Upgrade.php CHANGED
@@ -13,52 +13,57 @@ use WPStaging\Utils\Helper;
13
*/
14
// No Direct Access
15
if( !defined( "WPINC" ) ) {
16
- die;
17
}
18
19
class Upgrade {
20
21
- /**
22
* Previous Version number
23
- * @var string
24
- */
25
- private $previousVersion;
26
27
- /**
28
- * Clone data
29
- * @var obj
30
- */
31
- private $clones;
32
33
- /**
34
* Cron data
35
* @var obj
36
*/
37
private $cron;
38
39
/**
40
- * Logger
41
- * @var obj
42
- */
43
- private $logger;
44
-
45
- /**
46
- * db object
47
- * @var obj
48
- */
49
- private $db;
50
-
51
- public function __construct() {
52
53
// add wpstg_weekly_event to cron events
54
$this->cron = new \WPStaging\Cron\Cron;
55
56
// Previous version
57
$this->previousVersion = preg_replace( '/[^0-9.].*/', '', get_option( 'wpstg_version' ) );
58
-
59
- // Options earlier than version 2.0.0
60
- //$this->clones = get_option( "wpstg_existing_clones", array() );
61
62
// Logger
63
$this->logger = new Logger;
64
@@ -72,44 +77,44 @@ class Upgrade {
72
$this->upgrade2_2_0();
73
$this->setVersion();
74
}
75
-
76
/**
77
* Upgrade method 2.2.0
78
*/
79
- public function upgrade2_2_0(){
80
- // Previous version lower than 2.2.0
81
- if( version_compare( $this->previousVersion, '2.2.0', '<' ) ) {
82
- $this->upgradeElements();
83
- }
84
}
85
-
86
/**
87
* Add missing elements
88
*/
89
private function upgradeElements() {
90
// Current options
91
$sites = get_option( "wpstg_existing_clones_beta", array() );
92
-
93
- if( false === $sites || count($sites) === 0 ) {
94
return;
95
}
96
97
// Check if key prefix is missing and add it
98
foreach ( $sites as $key => $value ) {
99
- if (empty( $sites[$key]['directoryName'] )){
100
continue;
101
}
102
//!empty( $sites[$key]['prefix'] ) ? $sites[$key]['prefix'] = $value['prefix'] : $sites[$key]['prefix'] = $key . '_';
103
- !empty( $sites[$key]['prefix'] ) ?
104
- $sites[$key]['prefix'] = $value['prefix'] :
105
- $sites[$key]['prefix'] = $this->getStagingPrefix( $sites[$key]['directoryName'] );
106
}
107
-
108
- if( !empty($sites) ) {
109
- update_option( 'wpstg_existing_clones_beta', $sites );
110
}
111
}
112
-
113
/**
114
* Check and return prefix of the staging site
115
* @param string $directory
@@ -140,17 +145,18 @@ class Upgrade {
140
}
141
142
/**
143
* Upgrade method 2.0.3
144
*/
145
public function upgrade2_0_3() {
146
- // Previous version lower than 2.0.2 or new install
147
- if( false === $this->previousVersion || version_compare( $this->previousVersion, '2.0.2', '<' ) ) {
148
- $this->upgradeOptions();
149
- $this->upgradeClonesBeta();
150
- $this->upgradeNotices();
151
- }
152
- }
153
-
154
/**
155
* Upgrade method 2.1.2
156
* Sanitize the clone key value.
@@ -173,97 +179,99 @@ class Upgrade {
173
}
174
175
/**
176
- * Upgrade routine for new install
177
- */
178
- private function upgradeOptions() {
179
- // Write some default vars
180
- add_option( 'wpstg_installDate', date( 'Y-m-d h:i:s' ) );
181
- }
182
-
183
- /**
184
- * Write new version number into db
185
- * return bool
186
- */
187
- private function setVersion() {
188
- // Check if version number in DB is lower than version number in current plugin
189
- if( version_compare( $this->previousVersion, \WPStaging\WPStaging::VERSION, '<' ) ) {
190
- // Update Version number
191
- update_option( 'wpstg_version', preg_replace( '/[^0-9.].*/', '', \WPStaging\WPStaging::VERSION ) );
192
- // Update "upgraded from" version number
193
- update_option( 'wpstg_version_upgraded_from', preg_replace( '/[^0-9.].*/', '', $this->previousVersion ) );
194
-
195
- return true;
196
- }
197
- return false;
198
- }
199
-
200
- /**
201
- * Create a new db option for beta version 2.0.2
202
- * @return bool
203
- */
204
- private function upgradeClonesBeta() {
205
206
207
$new = array();
208
209
if( empty( $this->clones ) || count( $this->clones ) === 0 ) {
210
- return false;
211
- }
212
213
214
- foreach ( $this->clones as $key => &$value ) {
215
216
- // Skip the rest of the loop if data is already compatible to wpstg 2.0.2
217
- if( isset( $value['directoryName'] ) || !empty( $value['directoryName'] ) ) {
218
- continue;
219
- }
220
221
- $new[$value]['directoryName'] = $value;
222
- $new[$value]['path'] = get_home_path() . $value;
223
- $helper = new Helper();
224
- $new[$value]['url'] = $helper->get_home_url() . "/" . $value;
225
- $new[$value]['number'] = $key + 1;
226
- $new[$value]['version'] = $this->previousVersion;
227
//$new[$value]['prefix'] = $value;
228
- }
229
- unset( $value );
230
231
- if( empty( $new ) || false === update_option( 'wpstg_existing_clones_beta', $new ) ) {
232
- $this->logger->log( 'Failed to upgrade clone data from ' . $this->previousVersion . ' to ' . \WPStaging\WPStaging::VERSION );
233
- }
234
- }
235
236
- /**
237
* Upgrade Notices db options from wpstg 1.3 -> 2.0.1
238
- * Fix some logical db options
239
- */
240
- private function upgradeNotices() {
241
- $poll = get_option( "wpstg_start_poll", false );
242
- $beta = get_option( "wpstg_hide_beta", false );
243
- $rating = get_option( "wpstg_RatingDiv", false );
244
-
245
- if( $poll && $poll === "no" ) {
246
- update_option( 'wpstg_poll', 'no' );
247
- }
248
- if( $beta && $beta === "yes" ) {
249
- update_option( 'wpstg_beta', 'no' );
250
- }
251
- if( $rating && $rating === 'yes' ) {
252
- update_option( 'wpstg_rating', 'no' );
253
- }
254
- }
255
-
256
- /**
257
- * Throw a errror message via json and stop further execution
258
- * @param string $message
259
- */
260
- private function returnException($message = ''){
261
- wp_die( json_encode(array(
262
- 'job' => isset($this->options->currentJob) ? $this->options->currentJob : '',
263
- 'status' => false,
264
- 'message' => $message,
265
- 'error' => true
266
- )));
267
- }
268
269
}
13
*/
14
// No Direct Access
15
if( !defined( "WPINC" ) ) {
16
+ die;
17
}
18
19
class Upgrade {
20
21
+ /**
22
* Previous Version number
23
+ * @var string
24
+ */
25
+ private $previousVersion;
26
27
+ /**
28
+ * Clone data
29
+ * @var obj
30
+ */
31
+ private $clones;
32
+
33
+ /**
34
+ * Global settings
35
+ * @var type obj
36
+ */
37
+ private $settings;
38
39
+ /**
40
* Cron data
41
* @var obj
42
*/
43
private $cron;
44
45
/**
46
+ * Logger
47
+ * @var obj
48
+ */
49
+ private $logger;
50
+
51
+ /**
52
+ * db object
53
+ * @var obj
54
+ */
55
+ private $db;
56
+
57
+ public function __construct() {
58
59
// add wpstg_weekly_event to cron events
60
$this->cron = new \WPStaging\Cron\Cron;
61
62
// Previous version
63
$this->previousVersion = preg_replace( '/[^0-9.].*/', '', get_option( 'wpstg_version' ) );
64
65
+ $this->settings = (object)get_option( "wpstg_settings", array() );
66
+
67
// Logger
68
$this->logger = new Logger;
69
77
$this->upgrade2_2_0();
78
$this->setVersion();
79
}
80
+
81
/**
82
* Upgrade method 2.2.0
83
*/
84
+ public function upgrade2_2_0() {
85
+ // Previous version lower than 2.2.0
86
+ if( version_compare( $this->previousVersion, '2.2.0', '<' ) ) {
87
+ $this->upgradeElements();
88
+ }
89
}
90
+
91
/**
92
* Add missing elements
93
*/
94
private function upgradeElements() {
95
// Current options
96
$sites = get_option( "wpstg_existing_clones_beta", array() );
97
+
98
+ if( false === $sites || count( $sites ) === 0 ) {
99
return;
100
}
101
102
// Check if key prefix is missing and add it
103
foreach ( $sites as $key => $value ) {
104
+ if( empty( $sites[$key]['directoryName'] ) ) {
105
continue;
106
}
107
//!empty( $sites[$key]['prefix'] ) ? $sites[$key]['prefix'] = $value['prefix'] : $sites[$key]['prefix'] = $key . '_';
108
+ !empty( $sites[$key]['prefix'] ) ?
109
+ $sites[$key]['prefix'] = $value['prefix'] :
110
+ $sites[$key]['prefix'] = $this->getStagingPrefix( $sites[$key]['directoryName'] );
111
}
112
+
113
+ if( !empty( $sites ) ) {
114
+ update_option( 'wpstg_existing_clones_beta', $sites );
115
}
116
}
117
+
118
/**
119
* Check and return prefix of the staging site
120
* @param string $directory
145
}
146
147
/**
148
+ * NEW INSTALLATION
149
* Upgrade method 2.0.3
150
*/
151
public function upgrade2_0_3() {
152
+ // Previous version lower than 2.0.2 or new install
153
+ if( false === $this->previousVersion || version_compare( $this->previousVersion, '2.0.2', '<' ) ) {
154
+ $this->upgradeOptions();
155
+ $this->upgradeClonesBeta();
156
+ $this->upgradeNotices();
157
+ }
158
+ }
159
+
160
/**
161
* Upgrade method 2.1.2
162
* Sanitize the clone key value.
179
}
180
181
/**
182
+ * Upgrade routine for new install
183
+ */
184
+ private function upgradeOptions() {
185
+ // Write some default vars
186
+ add_option( 'wpstg_installDate', date( 'Y-m-d h:i:s' ) );
187
+ $this->settings->optimizer = 1;
188
+ update_option( 'wpstg_settings', $this->settings );
189
+ }
190
+
191
+ /**
192
+ * Write new version number into db
193
+ * return bool
194
+ */
195
+ private function setVersion() {
196
+ // Check if version number in DB is lower than version number in current plugin
197
+ if( version_compare( $this->previousVersion, \WPStaging\WPStaging::VERSION, '<' ) ) {
198
+ // Update Version number
199
+ update_option( 'wpstg_version', preg_replace( '/[^0-9.].*/', '', \WPStaging\WPStaging::VERSION ) );
200
+ // Update "upgraded from" version number
201
+ update_option( 'wpstg_version_upgraded_from', preg_replace( '/[^0-9.].*/', '', $this->previousVersion ) );
202
+
203
+ return true;
204
+ }
205
+ return false;
206
+ }
207
+
208
+ /**
209
+ * Create a new db option for beta version 2.0.2
210
+ * @return bool
211
+ */
212
+ private function upgradeClonesBeta() {
213
214
215
$new = array();
216
217
if( empty( $this->clones ) || count( $this->clones ) === 0 ) {
218
+ return false;
219
+ }
220
221
222
+ foreach ( $this->clones as $key => &$value ) {
223
224
+ // Skip the rest of the loop if data is already compatible to wpstg 2.0.2
225
+ if( isset( $value['directoryName'] ) || !empty( $value['directoryName'] ) ) {
226
+ continue;
227
+ }
228
229
+ $new[$value]['directoryName'] = $value;
230
+ $new[$value]['path'] = get_home_path() . $value;
231
+ $helper = new Helper();
232
+ $new[$value]['url'] = $helper->get_home_url() . "/" . $value;
233
+ $new[$value]['number'] = $key + 1;
234
+ $new[$value]['version'] = $this->previousVersion;
235
//$new[$value]['prefix'] = $value;
236
+ }
237
+ unset( $value );
238
239
+ if( empty( $new ) || false === update_option( 'wpstg_existing_clones_beta', $new ) ) {
240
+ $this->logger->log( 'Failed to upgrade clone data from ' . $this->previousVersion . ' to ' . \WPStaging\WPStaging::VERSION );
241
+ }
242
+ }
243
244
+ /**
245
* Upgrade Notices db options from wpstg 1.3 -> 2.0.1
246
+ * Fix some logical db options
247
+ */
248
+ private function upgradeNotices() {
249
+ $poll = get_option( "wpstg_start_poll", false );
250
+ $beta = get_option( "wpstg_hide_beta", false );
251
+ $rating = get_option( "wpstg_RatingDiv", false );
252
+
253
+ if( $poll && $poll === "no" ) {
254
+ update_option( 'wpstg_poll', 'no' );
255
+ }
256
+ if( $beta && $beta === "yes" ) {
257
+ update_option( 'wpstg_beta', 'no' );
258
+ }
259
+ if( $rating && $rating === 'yes' ) {
260
+ update_option( 'wpstg_rating', 'no' );
261
+ }
262
+ }
263
+
264
+ /**
265
+ * Throw a errror message via json and stop further execution
266
+ * @param string $message
267
+ */
268
+ private function returnException( $message = '' ) {
269
+ wp_die( json_encode( array(
270
+ 'job' => isset( $this->options->currentJob ) ? $this->options->currentJob : '',
271
+ 'status' => false,
272
+ 'message' => $message,
273
+ 'error' => true
274
+ ) ) );
275
+ }
276
277
}
apps/Backend/public/css/wpstg-admin.css CHANGED
@@ -822,4 +822,118 @@ color:#777777;
822
font-size: 13px;
823
font-weight: 400px;
824
float:right;
825
}
822
font-size: 13px;
823
font-weight: 400px;
824
float:right;
825
+ }
826
+
827
+ #wpstg-report-issue-button{
828
+ margin-left: 50px;
829
+ border: 1px solid #ef5a4b;
830
+ color: #ef5a4b;
831
+ background-color: white;
832
+ }
833
+
834
+ #wpstg-report-issue-button:hover {
835
+ background-color: #e74c3c;
836
+ color: #fff;
837
+ }
838
+
839
+ .wpstg-button{
840
+ display: inline-block;
841
+ background-color: transparent;
842
+ color: #95a5a6;
843
+ border-radius: 3px;
844
+ cursor: pointer;
845
+ padding: 2px 10px 2px 10px;
846
+ text-transform: uppercase;
847
+ font-weight: 500;
848
+ outline: 0;
849
+ transition: background-color .1s ease-in;
850
+ text-decoration: none;
851
+ }
852
+
853
+
854
+ .wpstg-report-issue-form {
855
+ position: absolute;
856
+ z-index: 9999;
857
+ width: 300px;
858
+ background-color: #fff;
859
+ margin: 6px 0 0;
860
+ padding: 15px 15px 10px;
861
+ border: 1px solid #e8e8e8;
862
+ border-radius: 3px;
863
+ box-shadow: 0 1px 0 0 #fff inset;
864
+ display: none;
865
+ margin-top: 67px;
866
+ margin-left: 123px;
867
+ }
868
+
869
+ .wpstg-report-show {
870
+ display: block;
871
+ }
872
+
873
+ .wpstg-field input[type=text], .wpstg-field textarea {
874
+ width: 100%;
875
+ font-weight: 400;
876
+ line-height: 1.4;
877
+ margin-bottom:4px;
878
+ }
879
+
880
+ .wpstg-report-email {
881
+ width: 100%;
882
+ font-weight: 400;
883
+ font-size: .8rem;
884
+ height: 2.3rem;
885
+ line-height: 2.3rem;
886
+ border-radius: 3px;
887
+ margin-bottom: 4px;
888
+ padding: 0 10px;
889
+ }
890
+
891
+ .wpstg-report-description {
892
+ border-radius: 3px;
893
+ font-size: .8rem;
894
+ padding: 6px 10px;
895
+ resize: none;
896
+ }
897
+
898
+ .wpstg-report-privacy-policy{
899
+ font-size:12px;
900
+ margin-bottom:15px;
901
+ }
902
+
903
+ #wpstg-report-cancel{
904
+ float:right;
905
+ margin-right: 5px;
906
+ }
907
+
908
+ .wpstg-buttons .spinner{
909
+ float:none;
910
+ margin: 0px 0px 0px 5px;
911
+ }
912
+
913
+ .wpstg-message {
914
+ -moz-box-sizing: border-box;
915
+ background-color: #f5e0de;
916
+ border-radius: 3px;
917
+ color: rgba(0,0,0,.6);
918
+ height: auto;
919
+ margin: 10px 0;
920
+ min-height: 18px;
921
+ padding: 6px 10px;
922
+ position: relative;
923
+ }
924
+
925
+ .wpstg-message.wpstg-error-message {
926
+ background-color: #f5e0de;
927
+ color: #b65147;
928
+ font-size: 12px;
929
+ }
930
+
931
+ .wpstg-message.wpstg-success-message{
932
+ background-color: #d7f8e0;
933
+ color: #515151;
934
+ }
935
+
936
+ .wpstg-message p {
937
+ margin: 3px 0;
938
+ font-size: 13px;
939
}
apps/Backend/public/img/admin_dashboard.png CHANGED
Binary file
apps/Backend/public/js/wpstg-admin.js CHANGED
@@ -95,18 +95,31 @@ var WPStaging = (function ($)
95
isAllChecked = false;
96
}
97
})
98
.on("click", ".wpstg-button-select", function (e) {
99
-
100
e.preventDefault();
101
-
102
$(".wpstg-db-table input").each(function () {
103
if ($(this).attr('name').match("^" + wpstg.tblprefix)) {
104
$(this).prop("checked", true);
105
} else {
106
$(this).prop("checked", false);
107
-
108
}
109
- });
110
})
111
// Expand Directories
112
.on("click", ".wpstg-expand-dirs", function (e) {
@@ -199,17 +212,6 @@ var WPStaging = (function ($)
199
that.getLogs = false;
200
that.progressBar = 0;
201
})
202
- // Display logs
203
- // .on("click", "#wpstg-show-log-button", function (e) {
204
- // e.preventDefault();
205
- // var $logDetails = cache.get("#wpstg-log-details");
206
- //
207
- // $logDetails.toggle();
208
- //
209
- // logscroll();
210
- //
211
- // that.getLogs = (false === that.getLogs);
212
- // });
213
214
cloneActions();
215
};
@@ -335,10 +337,10 @@ var WPStaging = (function ($)
335
if (response.length < 1)
336
{
337
showError(
338
- "Something went wrong! Error: No response. Go to WP Staging > Settings and lower 'File Copy Limit' and 'DB Query Limit'. Also set 'CPU Load Priority to low.'" +
339
- "Than try again. If that does not help, " +
340
- "<a href='https://wp-staging.com/support/' target='_blank'>open a support ticket</a> "
341
- );
342
}
343
344
$workFlow.removeClass("loading").html(response);
@@ -404,18 +406,18 @@ var WPStaging = (function ($)
404
statusCode: {
405
404: function (data) {
406
showError(
407
- "Something went wrong; can't find ajax request URL! Go to WP Staging > Settings and lower 'File Copy Limit' and 'DB Query Limit'. Also set 'CPU Load Priority to low.'" +
408
- "Than try again. If that does not help, " +
409
- "<a href='https://wp-staging.com/support/' target='_blank'>open a support ticket</a> "
410
- );
411
// Try again after 10 seconds
412
},
413
500: function () {
414
showError(
415
- "Something went wrong! Internal server error while processing the request! Go to WP Staging > Settings and lower 'File Copy Limit' and 'DB Query Limit'. Also set 'CPU Load Priority to low.'" +
416
- "Than try again. If that does not help, " +
417
- "<a href='https://wp-staging.com/support/' target='_blank'>open a support ticket</a> "
418
- );
419
}
420
}
421
});
@@ -463,13 +465,24 @@ var WPStaging = (function ($)
463
that.data,
464
function (response) {
465
466
if (response.length < 1)
467
{
468
showError(
469
- "Something went wrong! No response. Go to WP Staging > Settings and lower 'File Copy Limit' and 'DB Query Limit'. Also set 'CPU Load Priority to low.'" +
470
- "Than try again. If that does not help, " +
471
- "<a href='https://wp-staging.com/support/' target='_blank'>open a support ticket</a> "
472
- );
473
}
474
475
// Styling of elements
@@ -537,7 +550,7 @@ var WPStaging = (function ($)
537
var $this = $(this);
538
//if (!$this.parent(".wpstg-dir").parents(".wpstg-dir").children(".wpstg-expand-dirs").hasClass("disabled"))
539
//{
540
- includedDirectories.push($this.val());
541
//}
542
});
543
@@ -557,7 +570,7 @@ var WPStaging = (function ($)
557
var $this = $(this);
558
//if (!$this.parent(".wpstg-dir").parents(".wpstg-dir").children(".wpstg-expand-dirs").hasClass("disabled"))
559
//{
560
- excludedDirectories.push($this.val());
561
//}
562
});
563
@@ -641,11 +654,11 @@ var WPStaging = (function ($)
641
642
if (response.length < 1)
643
{
644
- showError(
645
- "Something went wrong! No response. Go to WP Staging > Settings and lower 'File Copy Limit' and 'DB Query Limit'. Also set 'CPU Load Priority to low.'" +
646
- "Than try again. If that does not help, " +
647
- "<a href='https://wp-staging.com/support/' target='_blank'>open a support ticket</a> "
648
- );
649
}
650
651
var $currentStep = cache.get(".wpstg-current-step");
@@ -708,11 +721,11 @@ var WPStaging = (function ($)
708
if (response) {
709
// Error
710
if ("undefined" !== typeof response.error && "undefined" !== typeof response.message) {
711
- showError(
712
- "Something went wrong! Error:" +response.message+ ". Go to WP Staging > Settings and lower 'File Copy Limit' and 'DB Query Limit'. Also set 'CPU Load Priority to low.'" +
713
- "Than try again. If that does not help, " +
714
- "<a href='https://wp-staging.com/support/' target='_blank'>open a support ticket</a> "
715
- );
716
console.log(response.message);
717
}
718
@@ -970,7 +983,7 @@ var WPStaging = (function ($)
970
971
that.timer('start');
972
973
- }
974
975
976
@@ -986,9 +999,9 @@ var WPStaging = (function ($)
986
}
987
988
989
-
990
//console.log("Start ajax processing");
991
-
992
// Show loader gif
993
cache.get("#wpstg-loader").show();
994
cache.get(".wpstg-loader").show();
@@ -997,7 +1010,7 @@ var WPStaging = (function ($)
997
cache.get('#wpstg-log-details').show();
998
999
WPStaging.ajax(
1000
- {
1001
action: "wpstg_clone_database",
1002
nonce: wpstg.nonce,
1003
//clone: cloneID,
@@ -1007,35 +1020,35 @@ var WPStaging = (function ($)
1007
extraDirectories: getIncludedExtraDirectories()
1008
},
1009
function (response)
1010
- {
1011
// Undefined Error
1012
if (false === response)
1013
- {
1014
showError(
1015
- "Something went wrong! Error: No response. Go to WP Staging > Settings and lower 'File Copy Limit' and 'DB Query Limit'. Also set 'CPU Load Priority to low.'" +
1016
- "Than try again. If that does not help, " +
1017
- "<a href='https://wp-staging.com/support/' target='_blank'>open a support ticket</a> "
1018
- );
1019
cache.get("#wpstg-loader").hide();
1020
cache.get(".wpstg-loader").hide();
1021
return;
1022
- }
1023
1024
// Throw Error
1025
if ("undefined" !== typeof (response.error) && response.error) {
1026
console.log(response.message);
1027
showError(
1028
- "Something went wrong! Error:" +response.message+ ". Go to WP Staging > Settings and lower 'File Copy Limit' and 'DB Query Limit'. Also set 'CPU Load Priority to low.'" +
1029
- "Than try again. If that does not help, " +
1030
- "<a href='https://wp-staging.com/support/' target='_blank'>open a support ticket</a> "
1031
- );
1032
-
1033
return;
1034
- }
1035
1036
// Add Log messages
1037
if ("undefined" !== typeof (response.last_msg) && response.last_msg)
1038
- {
1039
getLogs(response.last_msg);
1040
}
1041
// Continue processing
@@ -1055,11 +1068,12 @@ var WPStaging = (function ($)
1055
processing();
1056
} else if ('finished' === response.status || ("undefined" !== typeof (response.job_done) && response.job_done)) {
1057
finish(response);
1058
- };
1059
- },
1060
"json",
1061
false
1062
- );
1063
};
1064
1065
// Finish
@@ -1071,50 +1085,35 @@ var WPStaging = (function ($)
1071
getLogs();
1072
}
1073
1074
- // var response = {
1075
- // percentage: 100,
1076
- // job: 'finish'
1077
- // }
1078
progressBar(response);
1079
1080
1081
- // if (true === that.isCancelled || true === that.isFinished)
1082
- // {
1083
- // cache.get("#wpstg-loader").hide();
1084
- // cache.get("#wpstg-processing-header").html('Processing Complete');
1085
- // $("#wpstg-processing-status").text("Succesfully finished");
1086
- // that.timer('stop');
1087
- // return false;
1088
- // }
1089
-
1090
- // Add Log
1091
- if ("undefined" !== typeof (response.last_msg))
1092
- {
1093
- getLogs(response.last_msg);
1094
- }
1095
-
1096
- console.log("Cloning process finished");
1097
1098
cache.get("#wpstg-loader").hide();
1099
cache.get("#wpstg-processing-header").html('Processing Complete');
1100
$("#wpstg-processing-status").text("Succesfully finished");
1101
1102
- cache.get("#wpstg_staging_name").html(that.data.cloneID);
1103
- cache.get("#wpstg-finished-result").show();
1104
- //cache.get("#wpstg-cancel-cloning").prop("disabled", true);
1105
cache.get("#wpstg-cancel-cloning").hide();
1106
- cache.get("#wpstg-cancel-cloning-update").prop("disabled", true);
1107
-
1108
var $link1 = cache.get("#wpstg-clone-url-1");
1109
var $link = cache.get("#wpstg-clone-url");
1110
- $link1.attr("href", response.url);
1111
$link1.html(response.url);
1112
- $link.attr("href", response.url);
1113
-
1114
- cache.get("#wpstg-remove-clone").data("clone", that.data.cloneID);
1115
1116
- // Finished
1117
- that.isFinished = true;
1118
that.timer('stop');
1119
1120
@@ -1123,7 +1122,7 @@ var WPStaging = (function ($)
1123
1124
return false;
1125
1126
- }
1127
/**
1128
* Add percentage progress bar
1129
* @param object response
@@ -1132,7 +1131,7 @@ var WPStaging = (function ($)
1132
var progressBar = function (response, restart) {
1133
if ("undefined" === typeof (response.percentage))
1134
return false;
1135
-
1136
// //if (restart){
1137
// cache.get("#wpstg-db-progress").width('1%');
1138
// //}
@@ -1140,305 +1139,35 @@ var WPStaging = (function ($)
1140
if (response.job === 'database') {
1141
cache.get("#wpstg-progress-db").width(response.percentage * 0.2 + '%').html(response.percentage + '%');
1142
cache.get("#wpstg-processing-status").html(response.percentage.toFixed(0) + '%' + ' - Step 1 of 4 Cloning Database Tables...');
1143
- }
1144
1145
if (response.job === 'SearchReplace') {
1146
- cache.get("#wpstg-progress-db").css('background-color', '#3bc36b');
1147
- cache.get("#wpstg-progress-db").html('1. Database');
1148
cache.get("#wpstg-progress-sr").width(response.percentage * 0.1 + '%').html(response.percentage + '%');
1149
cache.get("#wpstg-processing-status").html(response.percentage.toFixed(0) + '%' + ' - Step 2 of 4 Preparing Database Data...');
1150
}
1151
1152
if (response.job === 'directories') {
1153
- cache.get("#wpstg-progress-sr").css('background-color', '#3bc36b');
1154
cache.get("#wpstg-progress-sr").html('2. Data');
1155
cache.get("#wpstg-progress-dirs").width(response.percentage * 0.1 + '%').html(response.percentage + '%');
1156
cache.get("#wpstg-processing-status").html(response.percentage.toFixed(0) + '%' + ' - Step 3 of 4 Getting files...');
1157
}
1158
if (response.job === 'files') {
1159
- cache.get("#wpstg-progress-dirs").css('background-color', '#3bc36b');
1160
cache.get("#wpstg-progress-dirs").html('3. Files');
1161
cache.get("#wpstg-progress-files").width(response.percentage * 0.6 + '%').html(response.percentage + '%');
1162
cache.get("#wpstg-processing-status").html(response.percentage.toFixed(0) + '%' + ' - Step 4 of 4 Copy files...');
1163
}
1164
if (response.job === 'finish') {
1165
cache.get("#wpstg-progress-files").css('background-color', '#3bc36b');
1166
- cache.get("#wpstg-progress-files").html('4. Copy Files');
1167
cache.get("#wpstg-processing-status").html(response.percentage.toFixed(0) + '%' + ' - Cloning Process Finished');
1168
}
1169
}
1170
1171
- // Step 1: Clone Database
1172
- // function cloneDatabase()
1173
- // {
1174
- // if (true === that.isCancelled)
1175
- // {
1176
- // return false;
1177
- // }
1178
- //
1179
- // if (true === that.getLogs)
1180
- // {
1181
- // getLogs();
1182
- // }
1183
- //
1184
- // setTimeout(
1185
- // function () {
1186
- // ajax(
1187
- // {
1188
- // action: "wpstg_clone_database",
1189
- // nonce: wpstg.nonce
1190
- // },
1191
- // function (response) {
1192
- // // Add percentage
1193
- // if ("undefined" !== typeof (response.percentage))
1194
- // {
1195
- // cache.get("#wpstg-db-progress").width(response.percentage + '%');
1196
- // }
1197
- // // Add Log
1198
- // if ("undefined" !== typeof (response.last_msg))
1199
- // {
1200
- // getLogs(response.last_msg);
1201
- // }
1202
- //
1203
- // // Continue clone DB
1204
- // if (false === response.status)
1205
- // {
1206
- // setTimeout(function () {
1207
- // cloneDatabase();
1208
- // }, wpstg.cpuLoad);
1209
- // }
1210
- // // Next Step
1211
- // else if (true === response.status)
1212
- // {
1213
- // //console.log('prepareDirectories ' + response.status);
1214
- // setTimeout(function () {
1215
- // prepareDirectories();
1216
- // }, wpstg.cpuLoad);
1217
- // }
1218
- // }
1219
- // );
1220
- // },
1221
- // 500
1222
- // );
1223
- // }
1224
1225
- // Step 2: Prepare Directories
1226
- // function prepareDirectories()
1227
- // {
1228
- // if (true === that.isCancelled)
1229
- // {
1230
- // return false;
1231
- // }
1232
- //
1233
- // if (true === that.getLogs)
1234
- // {
1235
- // getLogs();
1236
- // }
1237
- //
1238
- // setTimeout(
1239
- // function () {
1240
- // ajax(
1241
- // {
1242
- // action: "wpstg_clone_prepare_directories",
1243
- // nonce: wpstg.nonce
1244
- // },
1245
- // function (response) {
1246
- //
1247
- // // Error
1248
- // if ("undefined" !== typeof response.error && "undefined" !== typeof response.message) {
1249
- // showError(response.message);
1250
- // console.log(response.message);
1251
- // }
1252
- //
1253
- // // Add percentage
1254
- // if ("undefined" !== typeof (response.percentage))
1255
- // {
1256
- // cache.get("#wpstg-directories-progress").width(response.percentage + '%');
1257
- // }
1258
- //
1259
- // // Add Log
1260
- // if ("undefined" !== typeof (response.last_msg))
1261
- // {
1262
- // getLogs(response.last_msg);
1263
- // }
1264
- //
1265
- // if (false === response.status)
1266
- // {
1267
- // setTimeout(function () {
1268
- // prepareDirectories();
1269
- // }, wpstg.cpuLoad);
1270
- // }
1271
- // else if (true === response.status)
1272
- // {
1273
- // console.log('prepareDirectories' + response.status);
1274
- // cloneFiles();
1275
- // }
1276
- // }
1277
- // );
1278
- // },
1279
- // 500
1280
- // );
1281
- // }
1282
-
1283
- // Step 3: Clone Files
1284
- // function cloneFiles()
1285
- // {
1286
- // if (true === that.isCancelled)
1287
- // {
1288
- // return false;
1289
- // }
1290
- //
1291
- // if (true === that.getLogs)
1292
- // {
1293
- // getLogs();
1294
- // }
1295
- //
1296
- // ajax(
1297
- // {
1298
- // action: "wpstg_clone_files",
1299
- // nonce: wpstg.nonce
1300
- // },
1301
- // function (response) {
1302
- // // Add percentage
1303
- // if ("undefined" !== typeof (response.percentage))
1304
- // {
1305
- // cache.get("#wpstg-files-progress").width(response.percentage + '%');
1306
- // }
1307
- //
1308
- // // Add Log
1309
- // if ("undefined" !== typeof (response.last_msg))
1310
- // {
1311
- // getLogs(response.last_msg);
1312
- // }
1313
- //
1314
- // if (false === response.status)
1315
- // {
1316
- // setTimeout(function () {
1317
- // cloneFiles();
1318
- // }, wpstg.cpuLoad);
1319
- // }
1320
- // else if (true === response.status)
1321
- // {
1322
- // setTimeout(function () {
1323
- // replaceData();
1324
- // }, wpstg.cpuLoad);
1325
- // }
1326
- // }
1327
- // );
1328
- // }
1329
-
1330
- // Step 4: Replace Data
1331
- // function replaceData()
1332
- // {
1333
- // if (true === that.isCancelled)
1334
- // {
1335
- // return false;
1336
- // }
1337
- //
1338
- // if (true === that.getLogs)
1339
- // {
1340
- // console.log('getLogs1')
1341
- // getLogs();
1342
- // }
1343
- //
1344
- // ajax(
1345
- // {
1346
- // action: "wpstg_clone_replace_data",
1347
- // nonce: wpstg.nonce
1348
- // },
1349
- // function (response) {
1350
- // // Add percentage
1351
- // if ("undefined" !== typeof (response.percentage))
1352
- // {
1353
- // cache.get("#wpstg-links-progress").width(response.percentage + '%');
1354
- // }
1355
- //
1356
- // // Add Log
1357
- // if ("undefined" !== typeof (response.last_msg))
1358
- // {
1359
- // console.log('get Logs');
1360
- // getLogs(response.last_msg);
1361
- // }
1362
- //
1363
- // if (false === response.status)
1364
- // {
1365
- // setTimeout(function () {
1366
- // console.log('replace data');
1367
- // replaceData();
1368
- // }, wpstg.cpuLoad);
1369
- // }
1370
- // else if (true === response.status)
1371
- // {
1372
- // console.log('finish');
1373
- // finish();
1374
- // }
1375
- // }
1376
- // );
1377
- // }
1378
-
1379
- // Finish
1380
- // function finish()
1381
- // {
1382
- // if (true === that.getLogs)
1383
- // {
1384
- // getLogs();
1385
- // }
1386
- //
1387
- // if (true === that.isCancelled || true === that.isFinished)
1388
- // {
1389
- // cache.get("#wpstg-loader").hide();
1390
- // return false;
1391
- // }
1392
- //
1393
- // ajax(
1394
- // {
1395
- // action: "wpstg_clone_finish",
1396
- // nonce: wpstg.nonce
1397
- // },
1398
- // function (response)
1399
- // {
1400
- // // Invalid response
1401
- // if ("object" !== typeof (response))
1402
- // {
1403
- // showError(
1404
- // "Couldn't finish the cloning process properly. " +
1405
- // "Your clone has been copied but failed to do clean up and " +
1406
- // "saving its records to the database." +
1407
- // "Please contact support and provide your logs."
1408
- // );
1409
- //
1410
- // return;
1411
- // }
1412
- //
1413
- // // Add Log
1414
- // if ("undefined" !== typeof (response.last_msg))
1415
- // {
1416
- // getLogs(response.last_msg);
1417
- // }
1418
- //
1419
- // console.log("Cloning process finished");
1420
- //
1421
- // var $link1 = cache.get("#wpstg-clone-url-1");
1422
- // var $link = cache.get("#wpstg-clone-url");
1423
- //
1424
- // cache.get("#wpstg_staging_name").html(that.data.cloneID);
1425
- // cache.get("#wpstg-finished-result").show();
1426
- // cache.get("#wpstg-cancel-cloning").prop("disabled", true);
1427
- // cache.get("#wpstg-cancel-cloning-update").prop("disabled", true);
1428
- //// $link1.attr("href", $link1.attr("href") + '/' + response.directoryName);
1429
- //// $link1.append('/' + response.directoryName);
1430
- //// $link.attr("href", $link.attr("href") + '/' + response.directoryName);
1431
- // $link1.attr("href", response.url);
1432
- // $link.attr("href", response.url);
1433
- // cache.get("#wpstg-remove-clone").data("clone", that.data.cloneID);
1434
- //
1435
- // // Finished
1436
- // that.isFinished = true;
1437
- //
1438
- // finish();
1439
- // }
1440
- // );
1441
- // }
1442
});
1443
1444
@@ -1449,10 +1178,8 @@ var WPStaging = (function ($)
1449
that.init = (function () {
1450
loadOverview();
1451
elements();
1452
- //startUpdate();
1453
stepButtons();
1454
tabs();