Version Description
- New: Increase cloning performance
- New: Show admin notice if php version and wordpress version do not meet requirements.
- New: Show error if there is not enough free diskspace
- New: Add resume function in case the cloning process interrupts
- New: Add italian translation
- New: Better looking admin notices
- Fix: Different scheme of siteurl and home leads to non available staging site. Show admin notice to ask user to fix that first before creating a staging site
- Fix: WP Staging welcome screen shown when any plugin is activated
- Fix: Lower default settings to 10000, cpu load low. File copy limit to 50
Download this release
Release Info
Developer | ReneHermi |
Plugin | WP Staging – DB & File Duplicator & Migration |
Version | 2.3.7 |
Comparing to | |
See all releases |
Code changes from version 2.3.6 to 2.3.7
- apps/Backend/Activation/Activation.php +13 -13
- apps/Backend/Administrator.php +5 -1
- apps/Backend/Modules/Jobs/Job.php +22 -7
- apps/Backend/Modules/Jobs/Multisite/Data.php +113 -53
- apps/Backend/Modules/Jobs/Multisite/Directories.php +60 -21
- apps/Backend/Modules/Jobs/Multisite/Files.php +29 -15
- apps/Backend/Modules/Jobs/Multisite/Finish.php +3 -3
- apps/Backend/Modules/Jobs/Multisite/SearchReplace.php +133 -34
- apps/Backend/Modules/Jobs/Scan.php +12 -10
- apps/Backend/Modules/Jobs/SearchReplace.php +8 -4
- apps/Backend/Modules/Jobs/Updating.php +239 -232
- apps/Backend/Modules/SystemInfo.php +9 -4
- apps/Backend/Notices/Notices.php +29 -17
- apps/Backend/public/css/wpstg-admin.css +14 -0
- apps/Backend/public/js/wpstg-admin.js +61 -39
- apps/Backend/views/_includes/messages/beta.php +1 -1
- apps/Backend/views/_includes/messages/cache-directory-permission-problem.php +1 -1
- apps/Backend/views/_includes/messages/logs-directory-permission-problem.php +1 -1
- apps/Backend/views/_includes/messages/staging-directory-permission-problem.php +1 -1
- apps/Backend/views/_includes/messages/uploads-cache-directory-permission-problem.php +1 -1
- apps/Backend/views/_includes/messages/vars-directory-permission-problem.php +1 -1
- apps/Backend/views/_includes/messages/wp-version-compatible-message.php +1 -1
- apps/Backend/views/_includes/messages/wrong-scheme.php +7 -0
- apps/Backend/views/clone/ajax/start.php +4 -0
- apps/Backend/views/welcome/welcome.php +2 -1
- apps/Core/Utils/Cache.php +188 -205
- apps/Core/Utils/Multisite.php +38 -5
- apps/Core/Utils/requirements-check.php +70 -0
- apps/Core/WPStaging.php +3 -3
- install.php +46 -0
- languages/wp-staging-it_1.mo +0 -0
- languages/wp-staging-it_1.po +418 -0
- readme.txt +14 -2
- wp-staging.php +60 -31
apps/Backend/Activation/Activation.php
CHANGED
@@ -8,7 +8,7 @@ if( !defined( "WPINC" ) ) {
|
|
8 |
}
|
9 |
|
10 |
use WPStaging\WPStaging;
|
11 |
-
use WPStaging\Backend\Optimizer\Optimizer;
|
12 |
use WPStaging\Cron\Cron;
|
13 |
|
14 |
class Activation {
|
@@ -45,17 +45,17 @@ class Activation {
|
|
45 |
}
|
46 |
}
|
47 |
|
48 |
-
public static function install_dependancies() {
|
49 |
-
// Register cron job.
|
50 |
-
$cron = new \WPStaging\Cron\Cron;
|
51 |
-
$cron->schedule_event();
|
52 |
-
|
53 |
-
// Install Optimizer
|
54 |
-
$optimizer = new Optimizer();
|
55 |
-
$optimizer->installOptimizer();
|
56 |
-
|
57 |
-
// Add the transient to redirect for class Welcome (not for multisites)
|
58 |
-
set_transient( 'wpstg_activation_redirect', true, 3600 );
|
59 |
-
}
|
60 |
|
61 |
}
|
8 |
}
|
9 |
|
10 |
use WPStaging\WPStaging;
|
11 |
+
//use WPStaging\Backend\Optimizer\Optimizer;
|
12 |
use WPStaging\Cron\Cron;
|
13 |
|
14 |
class Activation {
|
45 |
}
|
46 |
}
|
47 |
|
48 |
+
// public static function install_dependancies() {
|
49 |
+
// // Register cron job.
|
50 |
+
// $cron = new \WPStaging\Cron\Cron;
|
51 |
+
// $cron->schedule_event();
|
52 |
+
//
|
53 |
+
// // Install Optimizer
|
54 |
+
// $optimizer = new Optimizer();
|
55 |
+
// $optimizer->installOptimizer();
|
56 |
+
//
|
57 |
+
// // Add the transient to redirect for class Welcome (not for multisites)
|
58 |
+
// set_transient( 'wpstg_activation_redirect', true, 3600 );
|
59 |
+
// }
|
60 |
|
61 |
}
|
apps/Backend/Administrator.php
CHANGED
@@ -80,7 +80,7 @@ class Administrator extends InjectionAware {
|
|
80 |
$Welcome = new Activation\Welcome();
|
81 |
|
82 |
$loader->addAction( "activated_plugin", $Activation, 'deactivate_other_instances' );
|
83 |
-
|
84 |
$loader->addAction( "admin_menu", $this, "addMenu", 10 );
|
85 |
$loader->addAction( "admin_init", $this, "setOptionFormElements" );
|
86 |
$loader->addAction( "admin_init", $this, "upgrade" );
|
@@ -483,6 +483,10 @@ class Administrator extends InjectionAware {
|
|
483 |
|
484 |
$cloning = new Cloning();
|
485 |
|
|
|
|
|
|
|
|
|
486 |
wp_send_json( $cloning->start() );
|
487 |
}
|
488 |
|
80 |
$Welcome = new Activation\Welcome();
|
81 |
|
82 |
$loader->addAction( "activated_plugin", $Activation, 'deactivate_other_instances' );
|
83 |
+
//$loader->addAction( "activated_plugin", $Activation, 'install_dependancies' );
|
84 |
$loader->addAction( "admin_menu", $this, "addMenu", 10 );
|
85 |
$loader->addAction( "admin_init", $this, "setOptionFormElements" );
|
86 |
$loader->addAction( "admin_init", $this, "upgrade" );
|
483 |
|
484 |
$cloning = new Cloning();
|
485 |
|
486 |
+
// Uncomment these lines to test different error codes
|
487 |
+
//http_response_code(504);
|
488 |
+
//wp_send_json( '<html><body><head></head><body>test</body></html>' );
|
489 |
+
|
490 |
wp_send_json( $cloning->start() );
|
491 |
}
|
492 |
|
apps/Backend/Modules/Jobs/Job.php
CHANGED
@@ -80,10 +80,22 @@ abstract class Job implements JobInterface {
|
|
80 |
protected $maxRecursionLimit;
|
81 |
|
82 |
/**
|
83 |
-
* Multisite Home Url
|
84 |
* @var string
|
85 |
*/
|
86 |
-
protected $
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
|
88 |
/**
|
89 |
* @var int
|
@@ -99,7 +111,10 @@ abstract class Job implements JobInterface {
|
|
99 |
$this->maxMemoryLimit = $this->getMemoryInBytes( @ini_get( "memory_limit" ) );
|
100 |
|
101 |
$multisite = new Multisite;
|
102 |
-
$this->
|
|
|
|
|
|
|
103 |
|
104 |
//$this->maxExecutionTime = (int) ini_get("max_execution_time");
|
105 |
$this->maxExecutionTime = ( int ) 30;
|
@@ -172,11 +187,11 @@ abstract class Job implements JobInterface {
|
|
172 |
* Set default settings
|
173 |
*/
|
174 |
protected function setDefaultSettings() {
|
175 |
-
$this->settings->queryLimit = "
|
176 |
$this->settings->querySRLimit = "5000";
|
177 |
-
$this->settings->fileLimit = "
|
178 |
$this->settings->batchSize = "2";
|
179 |
-
$this->settings->cpuLoad = '
|
180 |
$this->settings->maxFileSize = 8;
|
181 |
update_option( 'wpstg_settings', $this->settings );
|
182 |
}
|
@@ -187,7 +202,7 @@ abstract class Job implements JobInterface {
|
|
187 |
protected function setLimits() {
|
188 |
|
189 |
if( !isset( $this->settings->cpuLoad ) ) {
|
190 |
-
$this->settings->cpuLoad = "
|
191 |
}
|
192 |
|
193 |
$memoryLimit = self::MAX_MEMORY_RATIO;
|
80 |
protected $maxRecursionLimit;
|
81 |
|
82 |
/**
|
83 |
+
* Multisite Home Url without Scheme
|
84 |
* @var string
|
85 |
*/
|
86 |
+
protected $multisiteHomeUrlWithoutScheme;
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Multisite home domain without scheme
|
90 |
+
* @var type
|
91 |
+
*/
|
92 |
+
protected $multisiteDomainWithoutScheme;
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Multisite home domain without scheme
|
96 |
+
* @var type
|
97 |
+
*/
|
98 |
+
protected $multisiteHomeDomain;
|
99 |
|
100 |
/**
|
101 |
* @var int
|
111 |
$this->maxMemoryLimit = $this->getMemoryInBytes( @ini_get( "memory_limit" ) );
|
112 |
|
113 |
$multisite = new Multisite;
|
114 |
+
$this->multisiteHomeUrlWithoutScheme = $multisite->getHomeUrlWithoutScheme();
|
115 |
+
$this->multisiteHomeDomain = $multisite->getHomeDomain();
|
116 |
+
$this->multisiteDomainWithoutScheme = $multisite->getHomeDomainWithoutScheme();
|
117 |
+
//$this->multisiteUrl = $multisite->getHomeDomain();
|
118 |
|
119 |
//$this->maxExecutionTime = (int) ini_get("max_execution_time");
|
120 |
$this->maxExecutionTime = ( int ) 30;
|
187 |
* Set default settings
|
188 |
*/
|
189 |
protected function setDefaultSettings() {
|
190 |
+
$this->settings->queryLimit = "10000";
|
191 |
$this->settings->querySRLimit = "5000";
|
192 |
+
$this->settings->fileLimit = "50";
|
193 |
$this->settings->batchSize = "2";
|
194 |
+
$this->settings->cpuLoad = 'low';
|
195 |
$this->settings->maxFileSize = 8;
|
196 |
update_option( 'wpstg_settings', $this->settings );
|
197 |
}
|
202 |
protected function setLimits() {
|
203 |
|
204 |
if( !isset( $this->settings->cpuLoad ) ) {
|
205 |
+
$this->settings->cpuLoad = "low";
|
206 |
}
|
207 |
|
208 |
$memoryLimit = self::MAX_MEMORY_RATIO;
|
apps/Backend/Modules/Jobs/Multisite/Data.php
CHANGED
@@ -29,7 +29,7 @@ class Data extends JobExecutable {
|
|
29 |
* @var string
|
30 |
*/
|
31 |
private $prefix;
|
32 |
-
|
33 |
/**
|
34 |
* Tables e.g wpstg3_options
|
35 |
* @var array
|
@@ -51,27 +51,27 @@ class Data extends JobExecutable {
|
|
51 |
$this->options->currentStep = 1;
|
52 |
}
|
53 |
}
|
54 |
-
|
55 |
/**
|
56 |
* Get a list of tables to copy
|
57 |
*/
|
58 |
-
private function getTables(){
|
59 |
$strings = new Strings();
|
60 |
$this->tables = array();
|
61 |
-
foreach($this->options->tables as $table){
|
62 |
$this->tables[] = $this->options->prefix . $strings->str_replace_first( $this->db->prefix, null, $table );
|
63 |
}
|
64 |
// Add extra global tables from main multisite (wpstgx_users and wpstgx_usermeta)
|
65 |
$this->tables[] = $this->options->prefix . $strings->str_replace_first( $this->db->prefix, null, 'users' );
|
66 |
$this->tables[] = $this->options->prefix . $strings->str_replace_first( $this->db->prefix, null, 'usermeta' );
|
67 |
-
|
68 |
}
|
|
|
69 |
/**
|
70 |
* Calculate Total Steps in This Job and Assign It to $this->options->totalSteps
|
71 |
* @return void
|
72 |
*/
|
73 |
protected function calculateTotalSteps() {
|
74 |
-
$this->options->totalSteps =
|
75 |
}
|
76 |
|
77 |
/**
|
@@ -157,7 +157,7 @@ class Data extends JobExecutable {
|
|
157 |
}
|
158 |
|
159 |
// Live Path === Staging path
|
160 |
-
if( $this->
|
161 |
return true;
|
162 |
}
|
163 |
|
@@ -247,26 +247,26 @@ class Data extends JobExecutable {
|
|
247 |
return true;
|
248 |
}
|
249 |
// Skip - Table is not selected or updated
|
250 |
-
if
|
251 |
-
$this->log("Preparing Data Step1: Skipping");
|
252 |
return true;
|
253 |
}
|
254 |
|
255 |
// Installed in sub-directory
|
256 |
if( $this->isSubDir() ) {
|
257 |
-
$this->log( "Preparing Data Step1: Updating siteurl and homeurl to " . rtrim( $this->
|
258 |
// Replace URLs
|
259 |
$result = $this->db->query(
|
260 |
$this->db->prepare(
|
261 |
-
"UPDATE {$this->prefix}options SET option_value = %s WHERE option_name = 'siteurl' or option_name='home'", rtrim( $this->
|
262 |
)
|
263 |
);
|
264 |
} else {
|
265 |
-
$this->log( "Preparing Data Step1: Updating siteurl and homeurl to " . rtrim( $this->
|
266 |
// Replace URLs
|
267 |
$result = $this->db->query(
|
268 |
$this->db->prepare(
|
269 |
-
"UPDATE {$this->prefix}options SET option_value = %s WHERE option_name = 'siteurl' or option_name='home'", $this->
|
270 |
)
|
271 |
);
|
272 |
}
|
@@ -288,14 +288,14 @@ class Data extends JobExecutable {
|
|
288 |
protected function step2() {
|
289 |
|
290 |
$this->log( "Preparing Data Step2: Updating row wpstg_is_staging_site in {$this->prefix}options {$this->db->last_error}" );
|
291 |
-
|
292 |
// Skip - Table does not exist
|
293 |
if( false === $this->isTable( $this->prefix . 'options' ) ) {
|
294 |
return true;
|
295 |
}
|
296 |
// Skip - Table is not selected or updated
|
297 |
-
if
|
298 |
-
$this->log("Preparing Data Step2: Skipping");
|
299 |
return true;
|
300 |
}
|
301 |
|
@@ -330,15 +330,15 @@ class Data extends JobExecutable {
|
|
330 |
protected function step3() {
|
331 |
|
332 |
$this->log( "Preparing Data Step3: Updating rewrite_rules in {$this->prefix}options {$this->db->last_error}" );
|
333 |
-
|
334 |
// Skip - Table does not exist
|
335 |
if( false === $this->isTable( $this->prefix . 'options' ) ) {
|
336 |
return true;
|
337 |
}
|
338 |
-
|
339 |
// Skip - Table is not selected or updated
|
340 |
-
if
|
341 |
-
|
342 |
return true;
|
343 |
}
|
344 |
|
@@ -368,10 +368,10 @@ class Data extends JobExecutable {
|
|
368 |
if( false === $this->isTable( $this->prefix . 'usermeta' ) ) {
|
369 |
return true;
|
370 |
}
|
371 |
-
|
372 |
// Skip - Table is not selected or updated
|
373 |
-
if
|
374 |
-
$this->log("Preparing Data Step4: Skipping");
|
375 |
return true;
|
376 |
}
|
377 |
|
@@ -406,7 +406,7 @@ class Data extends JobExecutable {
|
|
406 |
$content = str_replace( '$table_prefix', '$table_prefix = \'' . $this->prefix . '\';//', $content );
|
407 |
|
408 |
// Replace URLs
|
409 |
-
$content = str_replace( $this->
|
410 |
|
411 |
if( false === @file_put_contents( $path, $content ) ) {
|
412 |
$this->log( "Preparing Data Step5: Failed to update $table_prefix in {$path} to " . $this->prefix . ". Can't save contents", Logger::TYPE_ERROR );
|
@@ -473,15 +473,15 @@ class Data extends JobExecutable {
|
|
473 |
protected function step7() {
|
474 |
|
475 |
$this->log( "Preparing Data Step7: Updating wpstg_rmpermalinks_executed in {$this->prefix}options {$this->db->last_error}" );
|
476 |
-
|
477 |
// Skip - Table does not exist
|
478 |
if( false === $this->isTable( $this->prefix . 'options' ) ) {
|
479 |
return true;
|
480 |
}
|
481 |
-
|
482 |
// Skip - Table is not selected or updated
|
483 |
if( !in_array( $this->prefix . 'options', $this->tables ) ) {
|
484 |
-
$this->log("Preparing Data Step7: Skipping");
|
485 |
return true;
|
486 |
}
|
487 |
|
@@ -508,18 +508,18 @@ class Data extends JobExecutable {
|
|
508 |
protected function step8() {
|
509 |
|
510 |
$this->log( "Preparing Data Step8: Updating permalink_structure in {$this->prefix}options {$this->db->last_error}" );
|
511 |
-
|
512 |
// Skip - Table does not exist
|
513 |
if( false === $this->isTable( $this->prefix . 'options' ) ) {
|
514 |
return true;
|
515 |
}
|
516 |
-
|
517 |
// Skip - Table is not selected or updated
|
518 |
if( !in_array( $this->prefix . 'options', $this->tables ) ) {
|
519 |
$this->log( "Preparing Data Step8: Skipping" );
|
520 |
return true;
|
521 |
}
|
522 |
-
|
523 |
$result = $this->db->query(
|
524 |
$this->db->prepare(
|
525 |
"UPDATE {$this->prefix}options SET option_value = %s WHERE option_name = 'permalink_structure'", ' '
|
@@ -547,13 +547,13 @@ class Data extends JobExecutable {
|
|
547 |
if( false === $this->isTable( $this->prefix . 'options' ) ) {
|
548 |
return true;
|
549 |
}
|
550 |
-
|
551 |
// Skip - Table is not selected or updated
|
552 |
if( !in_array( $this->prefix . 'options', $this->tables ) ) {
|
553 |
$this->log( "Preparing Data Step9: Skipping" );
|
554 |
return true;
|
555 |
}
|
556 |
-
|
557 |
$result = $this->db->query(
|
558 |
$this->db->prepare(
|
559 |
"UPDATE {$this->prefix}options SET option_value = %s WHERE option_name = 'blog_public'", '0'
|
@@ -755,13 +755,13 @@ class Data extends JobExecutable {
|
|
755 |
$this->returnException( 'Data Crunching Step 8: Fatal Error ' . $this->prefix . 'options does not exist' );
|
756 |
return false;
|
757 |
}
|
758 |
-
|
759 |
// Skip - Table is not selected or updated
|
760 |
if( !in_array( $this->prefix . 'options', $this->tables ) ) {
|
761 |
-
$this->log("Preparing Data Step14: Skipping");
|
762 |
return true;
|
763 |
}
|
764 |
-
|
765 |
// Get active_plugins value from sub site options table
|
766 |
$active_plugins = $this->db->get_var( "SELECT option_value FROM {$this->db->prefix}options WHERE option_name = 'active_plugins' " );
|
767 |
|
@@ -799,41 +799,41 @@ class Data extends JobExecutable {
|
|
799 |
$this->log( "Data Crunching Step 14: Successfull!" );
|
800 |
return true;
|
801 |
}
|
802 |
-
|
803 |
/**
|
804 |
* Update Table Prefix in wp_options
|
805 |
* @return bool
|
806 |
*/
|
807 |
protected function step15() {
|
808 |
-
$this->log( "Preparing Data Step15: Updating db prefix in {$this->prefix}options.
|
809 |
|
810 |
// Skip - Table does not exist
|
811 |
if( false === $this->isTable( $this->prefix . 'options' ) ) {
|
812 |
return true;
|
813 |
}
|
814 |
-
|
815 |
// Skip - Table is not selected or updated
|
816 |
-
if
|
817 |
-
$this->log("Preparing Data Step4: Skipping");
|
818 |
return true;
|
819 |
}
|
820 |
|
821 |
-
|
822 |
-
$this->log( "Updating db option_names in {$this->prefix}options.
|
823 |
-
|
824 |
// Filter the rows below. Do not update them!
|
825 |
$filters = array(
|
826 |
'wp_mail_smtp',
|
827 |
'wp_mail_smtp_version',
|
828 |
'wp_mail_smtp_debug',
|
829 |
);
|
830 |
-
|
831 |
-
$filters = apply_filters('wpstg_data_excl_rows', $filters);
|
832 |
-
|
833 |
$where = "";
|
834 |
-
foreach($filters as $filter){
|
835 |
$where .= " AND option_name <> '" . $filter . "'";
|
836 |
-
}
|
837 |
|
838 |
$updateOptions = $this->db->query(
|
839 |
$this->db->prepare(
|
@@ -849,8 +849,63 @@ class Data extends JobExecutable {
|
|
849 |
|
850 |
return true;
|
851 |
}
|
852 |
-
|
853 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
854 |
|
855 |
/**
|
856 |
* Return URL to staging site
|
@@ -858,10 +913,10 @@ class Data extends JobExecutable {
|
|
858 |
*/
|
859 |
protected function getStagingSiteUrl() {
|
860 |
if( $this->isSubDir() ) {
|
861 |
-
return rtrim( $this->
|
862 |
}
|
863 |
|
864 |
-
return rtrim( $this->
|
865 |
}
|
866 |
|
867 |
/**
|
@@ -869,7 +924,12 @@ class Data extends JobExecutable {
|
|
869 |
* @return boolean
|
870 |
*/
|
871 |
protected function isSubDir() {
|
872 |
-
|
|
|
|
|
|
|
|
|
|
|
873 |
return true;
|
874 |
}
|
875 |
return false;
|
29 |
* @var string
|
30 |
*/
|
31 |
private $prefix;
|
32 |
+
|
33 |
/**
|
34 |
* Tables e.g wpstg3_options
|
35 |
* @var array
|
51 |
$this->options->currentStep = 1;
|
52 |
}
|
53 |
}
|
54 |
+
|
55 |
/**
|
56 |
* Get a list of tables to copy
|
57 |
*/
|
58 |
+
private function getTables() {
|
59 |
$strings = new Strings();
|
60 |
$this->tables = array();
|
61 |
+
foreach ( $this->options->tables as $table ) {
|
62 |
$this->tables[] = $this->options->prefix . $strings->str_replace_first( $this->db->prefix, null, $table );
|
63 |
}
|
64 |
// Add extra global tables from main multisite (wpstgx_users and wpstgx_usermeta)
|
65 |
$this->tables[] = $this->options->prefix . $strings->str_replace_first( $this->db->prefix, null, 'users' );
|
66 |
$this->tables[] = $this->options->prefix . $strings->str_replace_first( $this->db->prefix, null, 'usermeta' );
|
|
|
67 |
}
|
68 |
+
|
69 |
/**
|
70 |
* Calculate Total Steps in This Job and Assign It to $this->options->totalSteps
|
71 |
* @return void
|
72 |
*/
|
73 |
protected function calculateTotalSteps() {
|
74 |
+
$this->options->totalSteps = 16;
|
75 |
}
|
76 |
|
77 |
/**
|
157 |
}
|
158 |
|
159 |
// Live Path === Staging path
|
160 |
+
if( $this->multisiteHomeDomain . $this->options->cloneDirectoryName === $this->multisiteHomeDomain ) {
|
161 |
return true;
|
162 |
}
|
163 |
|
247 |
return true;
|
248 |
}
|
249 |
// Skip - Table is not selected or updated
|
250 |
+
if( !in_array( $this->prefix . 'options', $this->tables ) ) {
|
251 |
+
$this->log( "Preparing Data Step1: Skipping" );
|
252 |
return true;
|
253 |
}
|
254 |
|
255 |
// Installed in sub-directory
|
256 |
if( $this->isSubDir() ) {
|
257 |
+
$this->log( "Preparing Data Step1: Updating siteurl and homeurl to " . rtrim( $this->multisiteHomeDomain, "/" ) . $this->getSubDir() . $this->options->cloneDirectoryName );
|
258 |
// Replace URLs
|
259 |
$result = $this->db->query(
|
260 |
$this->db->prepare(
|
261 |
+
"UPDATE {$this->prefix}options SET option_value = %s WHERE option_name = 'siteurl' or option_name='home'", rtrim( $this->multisiteHomeDomain, "/" ) . $this->getSubDir() . $this->options->cloneDirectoryName
|
262 |
)
|
263 |
);
|
264 |
} else {
|
265 |
+
$this->log( "Preparing Data Step1: Updating siteurl and homeurl to " . rtrim( $this->multisiteHomeDomain, "/" ) . '/' . $this->options->cloneDirectoryName );
|
266 |
// Replace URLs
|
267 |
$result = $this->db->query(
|
268 |
$this->db->prepare(
|
269 |
+
"UPDATE {$this->prefix}options SET option_value = %s WHERE option_name = 'siteurl' or option_name='home'", $this->multisiteHomeDomain . '/' . $this->options->cloneDirectoryName
|
270 |
)
|
271 |
);
|
272 |
}
|
288 |
protected function step2() {
|
289 |
|
290 |
$this->log( "Preparing Data Step2: Updating row wpstg_is_staging_site in {$this->prefix}options {$this->db->last_error}" );
|
291 |
+
|
292 |
// Skip - Table does not exist
|
293 |
if( false === $this->isTable( $this->prefix . 'options' ) ) {
|
294 |
return true;
|
295 |
}
|
296 |
// Skip - Table is not selected or updated
|
297 |
+
if( !in_array( $this->prefix . 'options', $this->tables ) ) {
|
298 |
+
$this->log( "Preparing Data Step2: Skipping" );
|
299 |
return true;
|
300 |
}
|
301 |
|
330 |
protected function step3() {
|
331 |
|
332 |
$this->log( "Preparing Data Step3: Updating rewrite_rules in {$this->prefix}options {$this->db->last_error}" );
|
333 |
+
|
334 |
// Skip - Table does not exist
|
335 |
if( false === $this->isTable( $this->prefix . 'options' ) ) {
|
336 |
return true;
|
337 |
}
|
338 |
+
|
339 |
// Skip - Table is not selected or updated
|
340 |
+
if( !in_array( $this->prefix . 'options', $this->tables ) ) {
|
341 |
+
$this->log( "Preparing Data Step3: Skipping" );
|
342 |
return true;
|
343 |
}
|
344 |
|
368 |
if( false === $this->isTable( $this->prefix . 'usermeta' ) ) {
|
369 |
return true;
|
370 |
}
|
371 |
+
|
372 |
// Skip - Table is not selected or updated
|
373 |
+
if( !in_array( $this->prefix . 'usermeta', $this->tables ) ) {
|
374 |
+
$this->log( "Preparing Data Step4: Skipping" );
|
375 |
return true;
|
376 |
}
|
377 |
|
406 |
$content = str_replace( '$table_prefix', '$table_prefix = \'' . $this->prefix . '\';//', $content );
|
407 |
|
408 |
// Replace URLs
|
409 |
+
$content = str_replace( $this->multisiteHomeDomain, $this->multisiteHomeDomain . '/' . $this->options->cloneDirectoryName, $content );
|
410 |
|
411 |
if( false === @file_put_contents( $path, $content ) ) {
|
412 |
$this->log( "Preparing Data Step5: Failed to update $table_prefix in {$path} to " . $this->prefix . ". Can't save contents", Logger::TYPE_ERROR );
|
473 |
protected function step7() {
|
474 |
|
475 |
$this->log( "Preparing Data Step7: Updating wpstg_rmpermalinks_executed in {$this->prefix}options {$this->db->last_error}" );
|
476 |
+
|
477 |
// Skip - Table does not exist
|
478 |
if( false === $this->isTable( $this->prefix . 'options' ) ) {
|
479 |
return true;
|
480 |
}
|
481 |
+
|
482 |
// Skip - Table is not selected or updated
|
483 |
if( !in_array( $this->prefix . 'options', $this->tables ) ) {
|
484 |
+
$this->log( "Preparing Data Step7: Skipping" );
|
485 |
return true;
|
486 |
}
|
487 |
|
508 |
protected function step8() {
|
509 |
|
510 |
$this->log( "Preparing Data Step8: Updating permalink_structure in {$this->prefix}options {$this->db->last_error}" );
|
511 |
+
|
512 |
// Skip - Table does not exist
|
513 |
if( false === $this->isTable( $this->prefix . 'options' ) ) {
|
514 |
return true;
|
515 |
}
|
516 |
+
|
517 |
// Skip - Table is not selected or updated
|
518 |
if( !in_array( $this->prefix . 'options', $this->tables ) ) {
|
519 |
$this->log( "Preparing Data Step8: Skipping" );
|
520 |
return true;
|
521 |
}
|
522 |
+
|
523 |
$result = $this->db->query(
|
524 |
$this->db->prepare(
|
525 |
"UPDATE {$this->prefix}options SET option_value = %s WHERE option_name = 'permalink_structure'", ' '
|
547 |
if( false === $this->isTable( $this->prefix . 'options' ) ) {
|
548 |
return true;
|
549 |
}
|
550 |
+
|
551 |
// Skip - Table is not selected or updated
|
552 |
if( !in_array( $this->prefix . 'options', $this->tables ) ) {
|
553 |
$this->log( "Preparing Data Step9: Skipping" );
|
554 |
return true;
|
555 |
}
|
556 |
+
|
557 |
$result = $this->db->query(
|
558 |
$this->db->prepare(
|
559 |
"UPDATE {$this->prefix}options SET option_value = %s WHERE option_name = 'blog_public'", '0'
|
755 |
$this->returnException( 'Data Crunching Step 8: Fatal Error ' . $this->prefix . 'options does not exist' );
|
756 |
return false;
|
757 |
}
|
758 |
+
|
759 |
// Skip - Table is not selected or updated
|
760 |
if( !in_array( $this->prefix . 'options', $this->tables ) ) {
|
761 |
+
$this->log( "Preparing Data Step14: Skipping" );
|
762 |
return true;
|
763 |
}
|
764 |
+
|
765 |
// Get active_plugins value from sub site options table
|
766 |
$active_plugins = $this->db->get_var( "SELECT option_value FROM {$this->db->prefix}options WHERE option_name = 'active_plugins' " );
|
767 |
|
799 |
$this->log( "Data Crunching Step 14: Successfull!" );
|
800 |
return true;
|
801 |
}
|
802 |
+
|
803 |
/**
|
804 |
* Update Table Prefix in wp_options
|
805 |
* @return bool
|
806 |
*/
|
807 |
protected function step15() {
|
808 |
+
$this->log( "Preparing Data Step15: Updating db prefix in {$this->prefix}options." );
|
809 |
|
810 |
// Skip - Table does not exist
|
811 |
if( false === $this->isTable( $this->prefix . 'options' ) ) {
|
812 |
return true;
|
813 |
}
|
814 |
+
|
815 |
// Skip - Table is not selected or updated
|
816 |
+
if( !in_array( $this->prefix . 'options', $this->tables ) ) {
|
817 |
+
$this->log( "Preparing Data Step4: Skipping" );
|
818 |
return true;
|
819 |
}
|
820 |
|
821 |
+
|
822 |
+
$this->log( "Updating db option_names in {$this->prefix}options. " );
|
823 |
+
|
824 |
// Filter the rows below. Do not update them!
|
825 |
$filters = array(
|
826 |
'wp_mail_smtp',
|
827 |
'wp_mail_smtp_version',
|
828 |
'wp_mail_smtp_debug',
|
829 |
);
|
830 |
+
|
831 |
+
$filters = apply_filters( 'wpstg_data_excl_rows', $filters );
|
832 |
+
|
833 |
$where = "";
|
834 |
+
foreach ( $filters as $filter ) {
|
835 |
$where .= " AND option_name <> '" . $filter . "'";
|
836 |
+
}
|
837 |
|
838 |
$updateOptions = $this->db->query(
|
839 |
$this->db->prepare(
|
849 |
|
850 |
return true;
|
851 |
}
|
852 |
+
|
853 |
+
/**
|
854 |
+
* Change upload_path in wp_options (if it is defined)
|
855 |
+
* @return bool
|
856 |
+
*/
|
857 |
+
protected function step16() {
|
858 |
+
$this->log( "Preparing Data Step16: Updating upload_path {$this->prefix}options." );
|
859 |
+
|
860 |
+
// Skip - Table does not exist
|
861 |
+
if( false === $this->isTable( $this->prefix . 'options' ) ) {
|
862 |
+
return true;
|
863 |
+
}
|
864 |
+
|
865 |
+
$newUploadPath = $this->getNewUploadPath();
|
866 |
+
|
867 |
+
if( false === $newUploadPath ) {
|
868 |
+
$this->log( "Preparing Data Step16: Skipping" );
|
869 |
+
return true;
|
870 |
+
}
|
871 |
+
|
872 |
+
// Skip - Table is not selected or updated
|
873 |
+
if( !in_array( $this->prefix . 'options', $this->tables ) ) {
|
874 |
+
$this->log( "Preparing Data Step16: Skipping" );
|
875 |
+
return true;
|
876 |
+
}
|
877 |
+
|
878 |
+
$error = isset( $this->db->last_error ) ? 'Last error: ' . $this->db->last_error : '';
|
879 |
+
|
880 |
+
$this->log( "Updating upload_path in {$this->prefix}options. {$error}" );
|
881 |
+
|
882 |
+
$updateOptions = $this->db->query(
|
883 |
+
$this->db->prepare(
|
884 |
+
"UPDATE {$this->prefix}options SET option_value = %s WHERE option_name = 'upload_path'", $newUploadPath
|
885 |
+
)
|
886 |
+
);
|
887 |
+
|
888 |
+
if( !$updateOptions ) {
|
889 |
+
$this->log( "Preparing Data Step16: Failed to update upload_path in {$this->prefix}options. {$error}", Logger::TYPE_ERROR );
|
890 |
+
return true;
|
891 |
+
}
|
892 |
+
$this->Log( "Preparing Data: Finished Step 16 successfully" );
|
893 |
+
return true;
|
894 |
+
}
|
895 |
+
|
896 |
+
protected function getNewUploadPath() {
|
897 |
+
$uploadPath = get_option( 'upload_path' );
|
898 |
+
|
899 |
+
if( !$uploadPath ) {
|
900 |
+
return false;
|
901 |
+
}
|
902 |
+
|
903 |
+
$customSlug = str_replace( \WPStaging\WPStaging::getWPpath(), '', $uploadPath );
|
904 |
+
|
905 |
+
$newUploadPath = \WPStaging\WPStaging::getWPpath() . $this->options->cloneDirectoryName . DIRECTORY_SEPARATOR . $customSlug;
|
906 |
+
|
907 |
+
return $newUploadPath;
|
908 |
+
}
|
909 |
|
910 |
/**
|
911 |
* Return URL to staging site
|
913 |
*/
|
914 |
protected function getStagingSiteUrl() {
|
915 |
if( $this->isSubDir() ) {
|
916 |
+
return rtrim( $this->multisiteHomeDomain, "/" ) . $this->getSubDir() . $this->options->cloneDirectoryName;
|
917 |
}
|
918 |
|
919 |
+
return rtrim( $this->multisiteHomeDomain, "/" ) . '/' . $this->options->cloneDirectoryName;
|
920 |
}
|
921 |
|
922 |
/**
|
924 |
* @return boolean
|
925 |
*/
|
926 |
protected function isSubDir() {
|
927 |
+
// Compare names without scheme to bypass cases where siteurl and home have different schemes http / https
|
928 |
+
// This is happening much more often than you would expect
|
929 |
+
$siteurl = preg_replace( '#^https?://#', '', rtrim( get_option( 'siteurl' ), '/' ) );
|
930 |
+
$home = preg_replace( '#^https?://#', '', rtrim( get_option( 'home' ), '/' ) );
|
931 |
+
|
932 |
+
if( $home !== $siteurl ) {
|
933 |
return true;
|
934 |
}
|
935 |
return false;
|
apps/Backend/Modules/Jobs/Multisite/Directories.php
CHANGED
@@ -100,7 +100,6 @@ class Directories extends JobExecutable {
|
|
100 |
}
|
101 |
} catch ( \Exception $e ) {
|
102 |
$this->returnException( 'Error: ' . $e->getMessage() );
|
103 |
-
//throw new \Exception('Out of disk space.');
|
104 |
} catch ( \Exception $e ) {
|
105 |
// Skip bad file permissions
|
106 |
}
|
@@ -117,7 +116,7 @@ class Directories extends JobExecutable {
|
|
117 |
|
118 |
// Skip it
|
119 |
if( $this->isDirectoryExcluded( WP_CONTENT_DIR ) ) {
|
120 |
-
$this->log( "Skip " .
|
121 |
return true;
|
122 |
}
|
123 |
// open file handle
|
@@ -131,7 +130,7 @@ class Directories extends JobExecutable {
|
|
131 |
'plugins' . DIRECTORY_SEPARATOR . 'wps-hide-login',
|
132 |
'uploads' . DIRECTORY_SEPARATOR . 'sites'
|
133 |
);
|
134 |
-
|
135 |
/**
|
136 |
* Get user excluded folders
|
137 |
*/
|
@@ -169,7 +168,8 @@ class Directories extends JobExecutable {
|
|
169 |
// Write path line
|
170 |
foreach ( $iterator as $item ) {
|
171 |
if( $item->isFile() ) {
|
172 |
-
|
|
|
173 |
$this->options->totalFiles++;
|
174 |
|
175 |
// Add current file size
|
@@ -178,8 +178,8 @@ class Directories extends JobExecutable {
|
|
178 |
}
|
179 |
}
|
180 |
} catch ( \Exception $e ) {
|
181 |
-
|
182 |
-
throw new \Exception( 'Error: ' . $e->getMessage() );
|
183 |
} catch ( \Exception $e ) {
|
184 |
// Skip bad file permissions
|
185 |
}
|
@@ -198,7 +198,7 @@ class Directories extends JobExecutable {
|
|
198 |
|
199 |
// Skip it
|
200 |
if( $this->isDirectoryExcluded( \WPStaging\WPStaging::getWPpath() . 'wp-includes' . DIRECTORY_SEPARATOR ) ) {
|
201 |
-
$this->log( "Skip " .
|
202 |
return true;
|
203 |
}
|
204 |
|
@@ -250,7 +250,7 @@ class Directories extends JobExecutable {
|
|
250 |
|
251 |
// Skip it
|
252 |
if( $this->isDirectoryExcluded( \WPStaging\WPStaging::getWPpath() . 'wp-admin' . DIRECTORY_SEPARATOR ) ) {
|
253 |
-
$this->log( "Skip " .
|
254 |
return true;
|
255 |
}
|
256 |
|
@@ -291,20 +291,28 @@ class Directories extends JobExecutable {
|
|
291 |
$this->close( $files );
|
292 |
return true;
|
293 |
}
|
294 |
-
|
295 |
/**
|
296 |
* Step 4
|
297 |
-
* Get WP Content Uploads Files multisite folder wp-content/uploads/sites
|
298 |
*/
|
299 |
private function getWpContentUploadsSites() {
|
300 |
-
|
|
|
301 |
if( is_main_site() ) {
|
302 |
return true;
|
303 |
}
|
304 |
-
|
305 |
$blogId = get_current_blog_id();
|
306 |
|
307 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
308 |
|
309 |
// Skip it
|
310 |
if( $this->isDirectoryExcluded( $path ) ) {
|
@@ -323,7 +331,7 @@ class Directories extends JobExecutable {
|
|
323 |
'plugins' . DIRECTORY_SEPARATOR . 'wps-hide-login',
|
324 |
'uploads' . DIRECTORY_SEPARATOR . 'sites'
|
325 |
);
|
326 |
-
|
327 |
/**
|
328 |
* Get user excluded folders
|
329 |
*/
|
@@ -346,6 +354,7 @@ class Directories extends JobExecutable {
|
|
346 |
|
347 |
// Exclude sites, uploads, plugins or themes
|
348 |
$iterator = new \WPStaging\Iterators\RecursiveFilterExclude( $iterator, $excludePaths );
|
|
|
349 |
// Recursively iterate over content directory
|
350 |
$iterator = new \RecursiveIteratorIterator( $iterator, \RecursiveIteratorIterator::LEAVES_ONLY, \RecursiveIteratorIterator::CATCH_GET_CHILD );
|
351 |
$this->log( "Scanning /wp-content/uploads/sites/{$blogId} for its sub-directories and files" );
|
@@ -353,8 +362,9 @@ class Directories extends JobExecutable {
|
|
353 |
// Write path line
|
354 |
foreach ( $iterator as $item ) {
|
355 |
if( $item->isFile() ) {
|
356 |
-
|
357 |
-
|
|
|
358 |
$this->options->totalFiles++;
|
359 |
|
360 |
// Add current file size
|
@@ -363,8 +373,8 @@ class Directories extends JobExecutable {
|
|
363 |
}
|
364 |
}
|
365 |
} catch ( \Exception $e ) {
|
366 |
-
|
367 |
-
throw new \Exception( 'Error: ' . $e->getMessage() );
|
368 |
} catch ( \Exception $e ) {
|
369 |
// Skip bad file permissions
|
370 |
}
|
@@ -374,6 +384,36 @@ class Directories extends JobExecutable {
|
|
374 |
return true;
|
375 |
}
|
376 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
377 |
/**
|
378 |
* Step 5 - x
|
379 |
* Get extra folders of the wp root level
|
@@ -525,7 +565,7 @@ class Directories extends JobExecutable {
|
|
525 |
$this->prepareResponse( false, true );
|
526 |
return false;
|
527 |
}
|
528 |
-
|
529 |
if( $this->options->currentStep == 4 ) {
|
530 |
$this->getWpContentUploadsSites();
|
531 |
$this->prepareResponse( false, true );
|
@@ -583,7 +623,6 @@ class Directories extends JobExecutable {
|
|
583 |
$this->files = explode( PHP_EOL, $this->files );
|
584 |
}
|
585 |
|
586 |
-
|
587 |
/**
|
588 |
* Replace forward slash with current directory separator
|
589 |
*
|
@@ -605,7 +644,7 @@ class Directories extends JobExecutable {
|
|
605 |
$directory = $this->sanitizeDirectorySeparator( $directory );
|
606 |
foreach ( $this->options->excludedDirectories as $excludedDirectory ) {
|
607 |
$excludedDirectory = $this->sanitizeDirectorySeparator( $excludedDirectory );
|
608 |
-
if( strpos( $directory, $excludedDirectory ) === 0 ) {
|
609 |
return true;
|
610 |
}
|
611 |
}
|
100 |
}
|
101 |
} catch ( \Exception $e ) {
|
102 |
$this->returnException( 'Error: ' . $e->getMessage() );
|
|
|
103 |
} catch ( \Exception $e ) {
|
104 |
// Skip bad file permissions
|
105 |
}
|
116 |
|
117 |
// Skip it
|
118 |
if( $this->isDirectoryExcluded( WP_CONTENT_DIR ) ) {
|
119 |
+
$this->log( "Skip " . \WPStaging\WPStaging::getWPpath() . 'wp-content' . DIRECTORY_SEPARATOR );
|
120 |
return true;
|
121 |
}
|
122 |
// open file handle
|
130 |
'plugins' . DIRECTORY_SEPARATOR . 'wps-hide-login',
|
131 |
'uploads' . DIRECTORY_SEPARATOR . 'sites'
|
132 |
);
|
133 |
+
|
134 |
/**
|
135 |
* Get user excluded folders
|
136 |
*/
|
168 |
// Write path line
|
169 |
foreach ( $iterator as $item ) {
|
170 |
if( $item->isFile() ) {
|
171 |
+
$file = 'wp-content' . DIRECTORY_SEPARATOR . $iterator->getSubPathName() . PHP_EOL;
|
172 |
+
if( $this->write( $files, $file ) ) {
|
173 |
$this->options->totalFiles++;
|
174 |
|
175 |
// Add current file size
|
178 |
}
|
179 |
}
|
180 |
} catch ( \Exception $e ) {
|
181 |
+
$this->returnException( 'Error: ' . $e->getMessage() );
|
182 |
+
//throw new \Exception( 'Error: ' . $e->getMessage() );
|
183 |
} catch ( \Exception $e ) {
|
184 |
// Skip bad file permissions
|
185 |
}
|
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 |
|
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 |
|
291 |
$this->close( $files );
|
292 |
return true;
|
293 |
}
|
294 |
+
|
295 |
/**
|
296 |
* Step 4
|
297 |
+
* Get WP Content Uploads Files multisite folder wp-content/uploads/sites or wp-content/blogs.dir/ID/files
|
298 |
*/
|
299 |
private function getWpContentUploadsSites() {
|
300 |
+
|
301 |
+
// Skip if main site is cloned
|
302 |
if( is_main_site() ) {
|
303 |
return true;
|
304 |
}
|
305 |
+
|
306 |
$blogId = get_current_blog_id();
|
307 |
|
308 |
+
// Absolute path to uploads folder
|
309 |
+
//$path = WP_CONTENT_DIR . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . 'sites' . DIRECTORY_SEPARATOR . $blogId . DIRECTORY_SEPARATOR;
|
310 |
+
$path = $this->getAbsUploadPath();
|
311 |
+
|
312 |
+
// Skip it
|
313 |
+
if( !is_dir( $path ) ) {
|
314 |
+
return true;
|
315 |
+
}
|
316 |
|
317 |
// Skip it
|
318 |
if( $this->isDirectoryExcluded( $path ) ) {
|
331 |
'plugins' . DIRECTORY_SEPARATOR . 'wps-hide-login',
|
332 |
'uploads' . DIRECTORY_SEPARATOR . 'sites'
|
333 |
);
|
334 |
+
|
335 |
/**
|
336 |
* Get user excluded folders
|
337 |
*/
|
354 |
|
355 |
// Exclude sites, uploads, plugins or themes
|
356 |
$iterator = new \WPStaging\Iterators\RecursiveFilterExclude( $iterator, $excludePaths );
|
357 |
+
|
358 |
// Recursively iterate over content directory
|
359 |
$iterator = new \RecursiveIteratorIterator( $iterator, \RecursiveIteratorIterator::LEAVES_ONLY, \RecursiveIteratorIterator::CATCH_GET_CHILD );
|
360 |
$this->log( "Scanning /wp-content/uploads/sites/{$blogId} for its sub-directories and files" );
|
362 |
// Write path line
|
363 |
foreach ( $iterator as $item ) {
|
364 |
if( $item->isFile() ) {
|
365 |
+
//$file = 'wp-content' . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . 'sites' . DIRECTORY_SEPARATOR . $blogId . DIRECTORY_SEPARATOR . $iterator->getSubPathName() . PHP_EOL;
|
366 |
+
$file = $this->getRelUploadPath() . $iterator->getSubPathName() . PHP_EOL;
|
367 |
+
if( $this->write( $files, $file ) ) {
|
368 |
$this->options->totalFiles++;
|
369 |
|
370 |
// Add current file size
|
373 |
}
|
374 |
}
|
375 |
} catch ( \Exception $e ) {
|
376 |
+
$this->returnException( 'Error: ' . $e->getMessage() );
|
377 |
+
//throw new \Exception( 'Error: ' . $e->getMessage() );
|
378 |
} catch ( \Exception $e ) {
|
379 |
// Skip bad file permissions
|
380 |
}
|
384 |
return true;
|
385 |
}
|
386 |
|
387 |
+
/**
|
388 |
+
* Get absolute path to the upload folder e.g. /srv/www/wp-content/blogs.dir/ID/files or /srv/www/wp-content/uploads/sites/ID/
|
389 |
+
* @return type
|
390 |
+
*/
|
391 |
+
private function getAbsUploadPath() {
|
392 |
+
// Check first which method is used
|
393 |
+
$uploads = wp_upload_dir();
|
394 |
+
$basedir = $uploads['basedir'];
|
395 |
+
|
396 |
+
return trailingslashit($basedir);
|
397 |
+
|
398 |
+
// if( false === strpos( $basedir, 'blogs.dir' ) ) {
|
399 |
+
// // Since WP 3.5
|
400 |
+
// return 'wp-content' . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . 'sites' . DIRECTORY_SEPARATOR . get_current_blog_id();
|
401 |
+
// } else {
|
402 |
+
// // old blog structure
|
403 |
+
// return 'wp-content' . DIRECTORY_SEPARATOR . 'blogs.dir' . DIRECTORY_SEPARATOR . get_current_blog_id() . DIRECTORY_SEPARATOR . 'files';
|
404 |
+
// }
|
405 |
+
}
|
406 |
+
/**
|
407 |
+
* Get relative path to the upload folder like wp-content/uploads or wp-content/blogs.dir/2/files
|
408 |
+
* @return string
|
409 |
+
*/
|
410 |
+
private function getRelUploadPath() {
|
411 |
+
$uploads = wp_upload_dir();
|
412 |
+
$basedir = $uploads['basedir'];
|
413 |
+
|
414 |
+
return trailingslashit(str_replace(\WPStaging\WPStaging::getWPpath(), '', $basedir));
|
415 |
+
}
|
416 |
+
|
417 |
/**
|
418 |
* Step 5 - x
|
419 |
* Get extra folders of the wp root level
|
565 |
$this->prepareResponse( false, true );
|
566 |
return false;
|
567 |
}
|
568 |
+
|
569 |
if( $this->options->currentStep == 4 ) {
|
570 |
$this->getWpContentUploadsSites();
|
571 |
$this->prepareResponse( false, true );
|
623 |
$this->files = explode( PHP_EOL, $this->files );
|
624 |
}
|
625 |
|
|
|
626 |
/**
|
627 |
* Replace forward slash with current directory separator
|
628 |
*
|
644 |
$directory = $this->sanitizeDirectorySeparator( $directory );
|
645 |
foreach ( $this->options->excludedDirectories as $excludedDirectory ) {
|
646 |
$excludedDirectory = $this->sanitizeDirectorySeparator( $excludedDirectory );
|
647 |
+
if( strpos( trailingslashit( $directory ), trailingslashit( $excludedDirectory ) ) === 0 ) {
|
648 |
return true;
|
649 |
}
|
650 |
}
|
apps/Backend/Modules/Jobs/Multisite/Files.php
CHANGED
@@ -36,7 +36,7 @@ class Files extends JobExecutable {
|
|
36 |
*/
|
37 |
public function initialize() {
|
38 |
|
39 |
-
$this->destination =
|
40 |
|
41 |
$filePath = $this->cache->getCacheDir() . "files_to_copy." . $this->cache->getCacheExtension();
|
42 |
|
@@ -152,7 +152,7 @@ class Files extends JobExecutable {
|
|
152 |
* @return bool
|
153 |
*/
|
154 |
private function copyFile( $file ) {
|
155 |
-
$file = trim(
|
156 |
|
157 |
$directory = dirname( $file );
|
158 |
|
@@ -215,8 +215,8 @@ class Files extends JobExecutable {
|
|
215 |
* @return bool|string
|
216 |
*/
|
217 |
private function getDestination( $file ) {
|
218 |
-
$file = $this->
|
219 |
-
$relativePath = str_replace(
|
220 |
$destinationPath = $this->destination . $relativePath;
|
221 |
$destinationDirectory = dirname( $destinationPath );
|
222 |
|
@@ -228,6 +228,31 @@ class Files extends JobExecutable {
|
|
228 |
return $destinationPath;
|
229 |
}
|
230 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
231 |
/**
|
232 |
* Copy bigger files than $this->settings->batchSize
|
233 |
* @param string $src
|
@@ -337,15 +362,4 @@ class Files extends JobExecutable {
|
|
337 |
return false;
|
338 |
}
|
339 |
|
340 |
-
/**
|
341 |
-
* Replace relative path of file if its located in multisite upload folder wp-content/uploads/sites/x/
|
342 |
-
* @return boolean
|
343 |
-
*/
|
344 |
-
private function replaceMultisiteUploadFolder( $file ) {
|
345 |
-
$search = 'wp-content' . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . 'sites' . DIRECTORY_SEPARATOR . get_current_blog_id();
|
346 |
-
$replace = 'wp-content' . DIRECTORY_SEPARATOR . 'uploads';
|
347 |
-
|
348 |
-
return str_replace( $search, $replace, $file );
|
349 |
-
}
|
350 |
-
|
351 |
}
|
36 |
*/
|
37 |
public function initialize() {
|
38 |
|
39 |
+
$this->destination = \WPStaging\WPStaging::getWPpath() . $this->options->cloneDirectoryName . DIRECTORY_SEPARATOR;
|
40 |
|
41 |
$filePath = $this->cache->getCacheDir() . "files_to_copy." . $this->cache->getCacheExtension();
|
42 |
|
152 |
* @return bool
|
153 |
*/
|
154 |
private function copyFile( $file ) {
|
155 |
+
$file = trim( \WPStaging\WPStaging::getWPpath() . $file );
|
156 |
|
157 |
$directory = dirname( $file );
|
158 |
|
215 |
* @return bool|string
|
216 |
*/
|
217 |
private function getDestination( $file ) {
|
218 |
+
$file = $this->getMultisiteUploadFolder( $file );
|
219 |
+
$relativePath = str_replace( \WPStaging\WPStaging::getWPpath(), null, $file );
|
220 |
$destinationPath = $this->destination . $relativePath;
|
221 |
$destinationDirectory = dirname( $destinationPath );
|
222 |
|
228 |
return $destinationPath;
|
229 |
}
|
230 |
|
231 |
+
/**
|
232 |
+
* Replace relative path of file if its located in multisite upload folder
|
233 |
+
* wp-content/uploads/sites/SITEID or old wordpress structure wp-content/blogs.dir/SITEID/files
|
234 |
+
* @return boolean
|
235 |
+
*/
|
236 |
+
private function getMultisiteUploadFolder( $file ) {
|
237 |
+
// Check first which method is used
|
238 |
+
$uploads = wp_upload_dir();
|
239 |
+
$basedir = $uploads['basedir'];
|
240 |
+
|
241 |
+
if( false === strpos( $basedir, 'blogs.dir' ) ) {
|
242 |
+
// Since WP 3.5
|
243 |
+
$search = 'wp-content' . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . 'sites' . DIRECTORY_SEPARATOR . get_current_blog_id();
|
244 |
+
$replace = 'wp-content' . DIRECTORY_SEPARATOR . 'uploads';
|
245 |
+
$uploadsFolder = str_replace( $search, $replace, $file );
|
246 |
+
} else {
|
247 |
+
// old blog structure
|
248 |
+
$search = 'wp-content' . DIRECTORY_SEPARATOR . 'blogs.dir' . DIRECTORY_SEPARATOR . get_current_blog_id() . DIRECTORY_SEPARATOR . 'files';
|
249 |
+
$replace = 'wp-content' . DIRECTORY_SEPARATOR . 'uploads';
|
250 |
+
$uploadsFolder = str_replace( $search, $replace, $file );
|
251 |
+
}
|
252 |
+
|
253 |
+
return $uploadsFolder;
|
254 |
+
}
|
255 |
+
|
256 |
/**
|
257 |
* Copy bigger files than $this->settings->batchSize
|
258 |
* @param string $src
|
362 |
return false;
|
363 |
}
|
364 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
365 |
}
|
apps/Backend/Modules/Jobs/Multisite/Finish.php
CHANGED
@@ -41,8 +41,8 @@ class Finish extends Job
|
|
41 |
$return = array(
|
42 |
"directoryName" => $this->options->cloneDirectoryName,
|
43 |
"path" => ABSPATH . $this->options->cloneDirectoryName,
|
44 |
-
|
45 |
-
"url" => $this->
|
46 |
"number" => $this->options->cloneNumber,
|
47 |
"version" => \WPStaging\WPStaging::VERSION,
|
48 |
"status" => 'finished',
|
@@ -98,7 +98,7 @@ class Finish extends Job
|
|
98 |
"directoryName" => $this->options->cloneDirectoryName,
|
99 |
"path" => ABSPATH . $this->options->cloneDirectoryName,
|
100 |
//"url" => get_site_url() . '/' . $this->options->cloneDirectoryName,
|
101 |
-
"url" => $this->
|
102 |
"number" => $this->options->cloneNumber,
|
103 |
"version" => \WPStaging\WPStaging::VERSION,
|
104 |
"status" => false,
|
41 |
$return = array(
|
42 |
"directoryName" => $this->options->cloneDirectoryName,
|
43 |
"path" => ABSPATH . $this->options->cloneDirectoryName,
|
44 |
+
"url" => $this->multisiteHomeDomain . '/' . $this->options->cloneDirectoryName,
|
45 |
+
//"url" => $this->multisiteUrl . '/' . $this->options->cloneDirectoryName,
|
46 |
"number" => $this->options->cloneNumber,
|
47 |
"version" => \WPStaging\WPStaging::VERSION,
|
48 |
"status" => 'finished',
|
98 |
"directoryName" => $this->options->cloneDirectoryName,
|
99 |
"path" => ABSPATH . $this->options->cloneDirectoryName,
|
100 |
//"url" => get_site_url() . '/' . $this->options->cloneDirectoryName,
|
101 |
+
"url" => $this->multisiteHomeDomain . '/' . $this->options->cloneDirectoryName,
|
102 |
"number" => $this->options->cloneNumber,
|
103 |
"version" => \WPStaging\WPStaging::VERSION,
|
104 |
"status" => false,
|
apps/Backend/Modules/Jobs/Multisite/SearchReplace.php
CHANGED
@@ -109,7 +109,6 @@ class SearchReplace extends JobExecutable {
|
|
109 |
return true;
|
110 |
}
|
111 |
|
112 |
-
|
113 |
/**
|
114 |
* Stop Execution immediately
|
115 |
* return mixed bool | json
|
@@ -223,30 +222,37 @@ class SearchReplace extends JobExecutable {
|
|
223 |
if( $this->isSubDir() ) {
|
224 |
// Search URL example.com/staging and root path to staging site /var/www/htdocs/staging
|
225 |
$args['search_for'] = array(
|
226 |
-
rtrim( $this->
|
227 |
ABSPATH,
|
228 |
-
str_replace( '/', '\/', rtrim( $this->
|
|
|
229 |
);
|
230 |
|
231 |
|
232 |
$args['replace_with'] = array(
|
233 |
-
rtrim( $this->
|
234 |
rtrim( ABSPATH, '/' ) . '/' . $this->options->cloneDirectoryName,
|
235 |
-
str_replace( '/', '\/', rtrim( $this->
|
|
|
236 |
);
|
237 |
} else {
|
238 |
$args['search_for'] = array(
|
239 |
-
rtrim( $this->
|
240 |
ABSPATH,
|
241 |
-
str_replace( '/', '\/', rtrim( $this->
|
|
|
242 |
);
|
243 |
$args['replace_with'] = array(
|
244 |
-
rtrim( $this->
|
245 |
rtrim( ABSPATH, '/' ) . '/' . $this->options->cloneDirectoryName,
|
246 |
-
str_replace( '/', '\/', rtrim( $this->
|
|
|
247 |
);
|
248 |
}
|
249 |
|
|
|
|
|
|
|
250 |
$args['replace_guids'] = 'off';
|
251 |
$args['dry_run'] = 'off';
|
252 |
$args['case_insensitive'] = false;
|
@@ -254,8 +260,8 @@ class SearchReplace extends JobExecutable {
|
|
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 |
|
@@ -274,7 +280,7 @@ class SearchReplace extends JobExecutable {
|
|
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
|
278 |
$filter = array(
|
279 |
'Admin_custome_login_Slidshow',
|
280 |
'Admin_custome_login_Social',
|
@@ -284,13 +290,14 @@ class SearchReplace extends JobExecutable {
|
|
284 |
'Admin_custome_login_top',
|
285 |
'Admin_custome_login_dashboard',
|
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 ) {
|
293 |
-
|
294 |
$update_sql = array();
|
295 |
$where_sql = array();
|
296 |
$upd = false;
|
@@ -299,12 +306,12 @@ class SearchReplace extends JobExecutable {
|
|
299 |
if( isset( $row['option_name'] ) && in_array( $row['option_name'], $filter ) ) {
|
300 |
continue;
|
301 |
}
|
302 |
-
|
303 |
// Skip rows with transients (They can store huge data and we need to save memory)
|
304 |
if( isset( $row['option_name'] ) && strpos( $row['option_name'], '_transient' ) === 0 ) {
|
305 |
continue;
|
306 |
}
|
307 |
-
|
308 |
|
309 |
foreach ( $columns as $column ) {
|
310 |
|
@@ -322,7 +329,7 @@ class SearchReplace extends JobExecutable {
|
|
322 |
|
323 |
|
324 |
// Skip mail addresses
|
325 |
-
if( 'off' === $args['replace_mails'] && false !== strpos( $dataRow, '@' . $this->
|
326 |
continue;
|
327 |
}
|
328 |
|
@@ -351,20 +358,21 @@ class SearchReplace extends JobExecutable {
|
|
351 |
// 1. local.wordpress.test -> local.wordpress.test/staging
|
352 |
// 2. local.wordpress.test\/ -> local.wordpress.test\/staging\/
|
353 |
$tmp = $args;
|
354 |
-
if
|
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 |
}
|
@@ -388,7 +396,7 @@ class SearchReplace extends JobExecutable {
|
|
388 |
$result = $this->db->query( $sql );
|
389 |
|
390 |
if( !$result ) {
|
391 |
-
$this->log( "Error updating row {$current_row}", \WPStaging\Utils\Logger::TYPE_ERROR );
|
392 |
}
|
393 |
}
|
394 |
} // end row loop
|
@@ -403,6 +411,38 @@ class SearchReplace extends JobExecutable {
|
|
403 |
return true;
|
404 |
}
|
405 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
406 |
/**
|
407 |
* Adapted from interconnect/it's search/replace script.
|
408 |
*
|
@@ -439,7 +479,7 @@ class SearchReplace extends JobExecutable {
|
|
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 |
|
@@ -448,10 +488,10 @@ class SearchReplace extends JobExecutable {
|
|
448 |
} else {
|
449 |
if( is_string( $data ) ) {
|
450 |
if( !empty( $from ) && !empty( $to ) ) {
|
451 |
-
|
|
|
452 |
}
|
453 |
}
|
454 |
-
}
|
455 |
|
456 |
if( $serialized ) {
|
457 |
return serialize( $data );
|
@@ -463,6 +503,60 @@ class SearchReplace extends JobExecutable {
|
|
463 |
return $data;
|
464 |
}
|
465 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
466 |
/**
|
467 |
* Check if the object is a valid one and not __PHP_Incomplete_Class_Name
|
468 |
* Can not use is_object alone because in php 7.2 it's returning true even though object is __PHP_Incomplete_Class_Name
|
@@ -489,7 +583,7 @@ class SearchReplace extends JobExecutable {
|
|
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
|
@@ -547,13 +641,13 @@ class SearchReplace extends JobExecutable {
|
|
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
|
554 |
} else {
|
555 |
//$data = str_replace( $from, $to, $data );
|
556 |
-
$data = preg_replace( '#' . $regexExclude . preg_quote($from) . '#', $to, $data );
|
557 |
}
|
558 |
|
559 |
return $data;
|
@@ -648,7 +742,12 @@ class SearchReplace extends JobExecutable {
|
|
648 |
* @return boolean
|
649 |
*/
|
650 |
private function isSubDir() {
|
651 |
-
|
|
|
|
|
|
|
|
|
|
|
652 |
return true;
|
653 |
}
|
654 |
return false;
|
109 |
return true;
|
110 |
}
|
111 |
|
|
|
112 |
/**
|
113 |
* Stop Execution immediately
|
114 |
* return mixed bool | json
|
222 |
if( $this->isSubDir() ) {
|
223 |
// Search URL example.com/staging and root path to staging site /var/www/htdocs/staging
|
224 |
$args['search_for'] = array(
|
225 |
+
rtrim( $this->multisiteHomeUrlWithoutScheme, "/" ) . $this->getSubDir(),
|
226 |
ABSPATH,
|
227 |
+
str_replace( '/', '\/', rtrim( $this->multisiteHomeUrlWithoutScheme, '/' ) ) . str_replace( '/', '\/', $this->getSubDir() ), // // Used by revslider and several visual editors
|
228 |
+
$this->getImagePathLive()
|
229 |
);
|
230 |
|
231 |
|
232 |
$args['replace_with'] = array(
|
233 |
+
rtrim( $this->multisiteDomainWithoutScheme, "/" ) . $this->getSubDir() . '/' . $this->options->cloneDirectoryName,
|
234 |
rtrim( ABSPATH, '/' ) . '/' . $this->options->cloneDirectoryName,
|
235 |
+
str_replace( '/', '\/', rtrim( $this->multisiteDomainWithoutScheme, "/" ) ) . str_replace( '/', '\/', $this->getSubDir() ) . '\/' . $this->options->cloneDirectoryName, // Used by revslider and several visual editors
|
236 |
+
$this->getImagePathStaging()
|
237 |
);
|
238 |
} else {
|
239 |
$args['search_for'] = array(
|
240 |
+
rtrim( $this->multisiteHomeUrlWithoutScheme, '/' ),
|
241 |
ABSPATH,
|
242 |
+
str_replace( '/', '\/', rtrim( $this->multisiteHomeUrlWithoutScheme, '/' ) ),
|
243 |
+
$this->getImagePathLive()
|
244 |
);
|
245 |
$args['replace_with'] = array(
|
246 |
+
rtrim( $this->multisiteDomainWithoutScheme, '/' ) . '/' . $this->options->cloneDirectoryName,
|
247 |
rtrim( ABSPATH, '/' ) . '/' . $this->options->cloneDirectoryName,
|
248 |
+
str_replace( '/', '\/', rtrim( $this->multisiteDomainWithoutScheme, '/' ) ) . '\/' . $this->options->cloneDirectoryName,
|
249 |
+
$this->getImagePathStaging()
|
250 |
);
|
251 |
}
|
252 |
|
253 |
+
//$this->log( 'Search: ' . $this->multisiteHomeUrlWithoutScheme . ' Replace: ' . rtrim( $this->multisiteDomainWithoutScheme, '/' ) . '/' . $this->options->cloneDirectoryName );
|
254 |
+
|
255 |
+
|
256 |
$args['replace_guids'] = 'off';
|
257 |
$args['dry_run'] = 'off';
|
258 |
$args['case_insensitive'] = false;
|
260 |
$args['replace_mails'] = 'off';
|
261 |
|
262 |
// Allow filtering of search & replace parameters
|
263 |
+
$args = apply_filters( 'wpstg_clone_searchreplace_params', $args );
|
264 |
+
|
265 |
// Get a list of columns in this table.
|
266 |
list( $primary_key, $columns ) = $this->get_columns( $table );
|
267 |
|
280 |
// Grab the content of the table.
|
281 |
$data = $this->db->get_results( "SELECT * FROM $table LIMIT $start, $end", ARRAY_A );
|
282 |
|
283 |
+
// Filter certain rows option_name in wpstg_options
|
284 |
$filter = array(
|
285 |
'Admin_custome_login_Slidshow',
|
286 |
'Admin_custome_login_Social',
|
290 |
'Admin_custome_login_top',
|
291 |
'Admin_custome_login_dashboard',
|
292 |
'Admin_custome_login_Version',
|
293 |
+
'upload_path',
|
294 |
+
);
|
295 |
+
|
296 |
apply_filters( 'wpstg_clone_searchreplace_excl_rows', $filter );
|
297 |
|
298 |
// Loop through the data.
|
299 |
foreach ( $data as $row ) {
|
300 |
+
$current_row++;
|
301 |
$update_sql = array();
|
302 |
$where_sql = array();
|
303 |
$upd = false;
|
306 |
if( isset( $row['option_name'] ) && in_array( $row['option_name'], $filter ) ) {
|
307 |
continue;
|
308 |
}
|
309 |
+
|
310 |
// Skip rows with transients (They can store huge data and we need to save memory)
|
311 |
if( isset( $row['option_name'] ) && strpos( $row['option_name'], '_transient' ) === 0 ) {
|
312 |
continue;
|
313 |
}
|
314 |
+
|
315 |
|
316 |
foreach ( $columns as $column ) {
|
317 |
|
329 |
|
330 |
|
331 |
// Skip mail addresses
|
332 |
+
if( 'off' === $args['replace_mails'] && false !== strpos( $dataRow, '@' . $this->multisiteDomainWithoutScheme ) ) {
|
333 |
continue;
|
334 |
}
|
335 |
|
358 |
// 1. local.wordpress.test -> local.wordpress.test/staging
|
359 |
// 2. local.wordpress.test\/ -> local.wordpress.test\/staging\/
|
360 |
$tmp = $args;
|
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 |
// Run a search replace on the data row and respect the serialisation.
|
373 |
$i = 0;
|
374 |
foreach ( $tmp['search_for'] as $replace ) {
|
375 |
+
//$this->log( "Search for: {$tmp['search_for'][$i]} Replace with {$tmp['replace_with'][$i]}", \WPStaging\Utils\Logger::TYPE_ERROR );
|
376 |
$dataRow = $this->recursive_unserialize_replace( $tmp['search_for'][$i], $tmp['replace_with'][$i], $dataRow, false, $args['case_insensitive'] );
|
377 |
$i++;
|
378 |
}
|
396 |
$result = $this->db->query( $sql );
|
397 |
|
398 |
if( !$result ) {
|
399 |
+
$this->log( "Error updating row {$current_row} SQL: {$sql}", \WPStaging\Utils\Logger::TYPE_ERROR );
|
400 |
}
|
401 |
}
|
402 |
} // end row loop
|
411 |
return true;
|
412 |
}
|
413 |
|
414 |
+
/**
|
415 |
+
* Get path to multisite image folder e.g. wp-content/blogs.dir/ID/files or wp-content/uploads/sites/ID
|
416 |
+
* @return string
|
417 |
+
*/
|
418 |
+
private function getImagePathLive() {
|
419 |
+
// Check first which structure is used
|
420 |
+
$uploads = wp_upload_dir();
|
421 |
+
$basedir = $uploads['basedir'];
|
422 |
+
$blogId = get_current_blog_id();
|
423 |
+
|
424 |
+
if( false === strpos( $basedir, 'blogs.dir' ) ) {
|
425 |
+
// Since WP 3.5
|
426 |
+
$path = $blogId > 1 ?
|
427 |
+
'wp-content' . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR . 'sites' . DIRECTORY_SEPARATOR . get_current_blog_id() . DIRECTORY_SEPARATOR :
|
428 |
+
'wp-content' . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR;
|
429 |
+
} else {
|
430 |
+
// old blog structure
|
431 |
+
$path = $blogId > 1 ?
|
432 |
+
'wp-content' . DIRECTORY_SEPARATOR . 'blogs.dir' . DIRECTORY_SEPARATOR . get_current_blog_id() . DIRECTORY_SEPARATOR . 'files' . DIRECTORY_SEPARATOR :
|
433 |
+
'wp-content' . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR;
|
434 |
+
}
|
435 |
+
return $path;
|
436 |
+
}
|
437 |
+
|
438 |
+
/**
|
439 |
+
* Get path to staging site image path wp-content/uploads
|
440 |
+
* @return string
|
441 |
+
*/
|
442 |
+
private function getImagePathStaging() {
|
443 |
+
return 'wp-content' . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR;
|
444 |
+
}
|
445 |
+
|
446 |
/**
|
447 |
* Adapted from interconnect/it's search/replace script.
|
448 |
*
|
479 |
foreach ( $props as $key => $value ) {
|
480 |
if( $key === '' || ord( $key[0] ) === 0 ) {
|
481 |
continue;
|
482 |
+
}
|
483 |
$tmp->$key = $this->recursive_unserialize_replace( $from, $to, $value, false, $case_insensitive );
|
484 |
}
|
485 |
|
488 |
} else {
|
489 |
if( is_string( $data ) ) {
|
490 |
if( !empty( $from ) && !empty( $to ) ) {
|
491 |
+
$data = $this->str_replace( $from, $to, $data, $case_insensitive );
|
492 |
+
}
|
493 |
}
|
494 |
}
|
|
|
495 |
|
496 |
if( $serialized ) {
|
497 |
return serialize( $data );
|
503 |
return $data;
|
504 |
}
|
505 |
|
506 |
+
// private function recursive_unserialize_replace_( $from = '', $to = '', $data = '', $serialised = false, $case_insensitive = false ) {
|
507 |
+
// try {
|
508 |
+
//
|
509 |
+
// // Check first if its an object and repair it if necessary
|
510 |
+
// //$data = $this->fixObject($data);
|
511 |
+
//
|
512 |
+
// if( is_string( $data ) && !is_serialized_string( $data ) && ( $unserialized = $this->unserialize( $data ) ) !== false ) {
|
513 |
+
// $data = $this->recursive_unserialize_replace( $from, $to, $unserialized, true, $case_insensitive );
|
514 |
+
// } elseif( is_array( $data ) ) {
|
515 |
+
// $_tmp = array();
|
516 |
+
// foreach ( $data as $key => $value ) {
|
517 |
+
// $_tmp[$key] = $this->recursive_unserialize_replace( $from, $to, $value, false, $case_insensitive );
|
518 |
+
// }
|
519 |
+
//
|
520 |
+
// $data = $_tmp;
|
521 |
+
// unset( $_tmp );
|
522 |
+
// }
|
523 |
+
//
|
524 |
+
// // Submitted by Tina Matter
|
525 |
+
// elseif( $this->isValidObject( $data ) ) {
|
526 |
+
// $_tmp = $data; // new $data_class( );
|
527 |
+
// $props = get_object_vars( $data );
|
528 |
+
// foreach ( $props as $key => $value ) {
|
529 |
+
// if( $key === '' || ord( $key[0] ) === 0 ) {
|
530 |
+
// continue;
|
531 |
+
// }
|
532 |
+
// $_tmp->$key = $this->recursive_unserialize_replace( $from, $to, $value, false, $case_insensitive );
|
533 |
+
// }
|
534 |
+
//
|
535 |
+
// $data = $_tmp;
|
536 |
+
// unset( $_tmp );
|
537 |
+
// } elseif( is_serialized_string( $data ) ) {
|
538 |
+
// if( false !== ($data = $this->unserialize( $data )) ) {
|
539 |
+
// $data = $this->str_replace( $from, $to, $data, $case_insensitive );
|
540 |
+
// $data = serialize( $data );
|
541 |
+
// }
|
542 |
+
// } else {
|
543 |
+
// if( is_string( $data ) ) {
|
544 |
+
// $data = $this->str_replace( $from, $to, $data, $case_insensitive );
|
545 |
+
// }
|
546 |
+
// }
|
547 |
+
//
|
548 |
+
// if( $serialised ) {
|
549 |
+
// return serialize( $data );
|
550 |
+
// }
|
551 |
+
// } catch ( Exception $error ) {
|
552 |
+
//
|
553 |
+
// }
|
554 |
+
//
|
555 |
+
// return $data;
|
556 |
+
// }
|
557 |
+
|
558 |
+
|
559 |
+
|
560 |
/**
|
561 |
* Check if the object is a valid one and not __PHP_Incomplete_Class_Name
|
562 |
* Can not use is_object alone because in php 7.2 it's returning true even though object is __PHP_Incomplete_Class_Name
|
583 |
// // Assume it must be an valid object
|
584 |
// return true;
|
585 |
// }
|
586 |
+
|
587 |
/**
|
588 |
* Mimics the mysql_real_escape_string function. Adapted from a post by 'feedr' on php.net.
|
589 |
* @link http://php.net/manual/en/function.mysql-real-escape-string.php#101248
|
641 |
foreach ( $excludes as $exclude ) {
|
642 |
$regexExclude .= $exclude . '(*SKIP)(FAIL)|';
|
643 |
}
|
644 |
+
|
645 |
if( 'on' === $case_insensitive ) {
|
646 |
//$data = str_ireplace( $from, $to, $data );
|
647 |
+
$data = preg_replace( '#' . $regexExclude . preg_quote( $from ) . '#i', $to, $data );
|
648 |
} else {
|
649 |
//$data = str_replace( $from, $to, $data );
|
650 |
+
$data = preg_replace( '#' . $regexExclude . preg_quote( $from ) . '#', $to, $data );
|
651 |
}
|
652 |
|
653 |
return $data;
|
742 |
* @return boolean
|
743 |
*/
|
744 |
private function isSubDir() {
|
745 |
+
// Compare names without scheme to bypass cases where siteurl and home have different schemes http / https
|
746 |
+
// This is happening much more often than you would expect
|
747 |
+
$siteurl = preg_replace( '#^https?://#', '', rtrim( get_option( 'siteurl' ), '/' ) );
|
748 |
+
$home = preg_replace( '#^https?://#', '', rtrim( get_option( 'home' ), '/' ) );
|
749 |
+
|
750 |
+
if( $home !== $siteurl ) {
|
751 |
return true;
|
752 |
}
|
753 |
return false;
|
apps/Backend/Modules/Jobs/Scan.php
CHANGED
@@ -137,20 +137,23 @@ class Scan extends Job {
|
|
137 |
$data = reset( $directory );
|
138 |
unset( $directory[key( $directory )] );
|
139 |
|
|
|
140 |
$isChecked = (
|
141 |
empty( $this->options->includedDirectories ) ||
|
142 |
in_array( $data["path"], $this->options->includedDirectories )
|
143 |
);
|
144 |
|
145 |
-
|
146 |
// Include wp core folders and their sub dirs.
|
147 |
// Exclude all other folders (default setting)
|
|
|
|
|
148 |
$isDisabled = ($name !== 'wp-admin' &&
|
149 |
$name !== 'wp-includes' &&
|
150 |
$name !== 'wp-content') &&
|
151 |
-
false === strpos( strrev( $
|
152 |
-
false === strpos( strrev( $
|
153 |
-
false === strpos( strrev( $
|
154 |
|
155 |
// Extra class to differentiate between wp core and non core folders
|
156 |
$class = !$isDisabled ? 'wpstg-root' : 'wpstg-extra';
|
@@ -163,15 +166,15 @@ class Scan extends Job {
|
|
163 |
$output .= " checked";
|
164 |
//if ($forceDisabled || $isDisabled) $output .= " disabled";
|
165 |
|
166 |
-
$output .= " name='selectedDirectories[]' value='{$
|
167 |
|
168 |
$output .= "<a href='#' class='wpstg-expand-dirs ";
|
169 |
-
if( !$isChecked || $isDisabled )
|
170 |
$output .= " disabled";
|
|
|
171 |
$output .= "'>{$name}";
|
172 |
$output .= "</a>";
|
173 |
-
|
174 |
-
$output .= "<span class='wpstg-size-info'>{$this->formatSize( $data["size"] )}</span>";
|
175 |
|
176 |
if( !empty( $directory ) ) {
|
177 |
$output .= "<div class='wpstg-dir wpstg-subdir'>";
|
@@ -294,7 +297,7 @@ class Scan extends Job {
|
|
294 |
*/
|
295 |
protected function getSubDirectories( $path ) {
|
296 |
|
297 |
-
if
|
298 |
return false;
|
299 |
}
|
300 |
|
@@ -325,7 +328,6 @@ class Scan extends Job {
|
|
325 |
|
326 |
//echo $directory->getRealPath() . '<br>';
|
327 |
//echo 'abspath: ' . \WPStaging\WPStaging::getWPpath() . '<br>';
|
328 |
-
|
329 |
//if( strpos( $directory->getRealPath(), ABSPATH ) !== 0 ) {
|
330 |
if( strpos( $directory->getRealPath(), \WPStaging\WPStaging::getWPpath() ) !== 0 ) {
|
331 |
return false;
|
137 |
$data = reset( $directory );
|
138 |
unset( $directory[key( $directory )] );
|
139 |
|
140 |
+
|
141 |
$isChecked = (
|
142 |
empty( $this->options->includedDirectories ) ||
|
143 |
in_array( $data["path"], $this->options->includedDirectories )
|
144 |
);
|
145 |
|
146 |
+
|
147 |
// Include wp core folders and their sub dirs.
|
148 |
// Exclude all other folders (default setting)
|
149 |
+
$dataPath = isset( $data["path"] ) ? $data["path"] : '';
|
150 |
+
$dataSize = isset( $data["size"] ) ? $data["size"] : '';
|
151 |
$isDisabled = ($name !== 'wp-admin' &&
|
152 |
$name !== 'wp-includes' &&
|
153 |
$name !== 'wp-content') &&
|
154 |
+
false === strpos( strrev( $dataPath ), strrev( "wp-admin" ) ) &&
|
155 |
+
false === strpos( strrev( $dataPath ), strrev( "wp-includes" ) ) &&
|
156 |
+
false === strpos( strrev( $dataPath ), strrev( "wp-content" ) ) ? true : false;
|
157 |
|
158 |
// Extra class to differentiate between wp core and non core folders
|
159 |
$class = !$isDisabled ? 'wpstg-root' : 'wpstg-extra';
|
166 |
$output .= " checked";
|
167 |
//if ($forceDisabled || $isDisabled) $output .= " disabled";
|
168 |
|
169 |
+
$output .= " name='selectedDirectories[]' value='{$dataPath}'>";
|
170 |
|
171 |
$output .= "<a href='#' class='wpstg-expand-dirs ";
|
172 |
+
if( !$isChecked || $isDisabled ) {
|
173 |
$output .= " disabled";
|
174 |
+
}
|
175 |
$output .= "'>{$name}";
|
176 |
$output .= "</a>";
|
177 |
+
$output .= "<span class='wpstg-size-info'>{$this->formatSize( $dataSize )}</span>";
|
|
|
178 |
|
179 |
if( !empty( $directory ) ) {
|
180 |
$output .= "<div class='wpstg-dir wpstg-subdir'>";
|
297 |
*/
|
298 |
protected function getSubDirectories( $path ) {
|
299 |
|
300 |
+
if( !is_readable( $path ) ) {
|
301 |
return false;
|
302 |
}
|
303 |
|
328 |
|
329 |
//echo $directory->getRealPath() . '<br>';
|
330 |
//echo 'abspath: ' . \WPStaging\WPStaging::getWPpath() . '<br>';
|
|
|
331 |
//if( strpos( $directory->getRealPath(), ABSPATH ) !== 0 ) {
|
332 |
if( strpos( $directory->getRealPath(), \WPStaging\WPStaging::getWPpath() ) !== 0 ) {
|
333 |
return false;
|
apps/Backend/Modules/Jobs/SearchReplace.php
CHANGED
@@ -47,7 +47,6 @@ class SearchReplace extends JobExecutable {
|
|
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 |
|
@@ -293,7 +292,7 @@ class SearchReplace extends JobExecutable {
|
|
293 |
'Admin_custome_login_top',
|
294 |
'Admin_custome_login_dashboard',
|
295 |
'Admin_custome_login_Version',
|
296 |
-
'upload_path'
|
297 |
);
|
298 |
|
299 |
$filter = apply_filters( 'wpstg_clone_searchreplace_excl_rows', $filter );
|
@@ -398,7 +397,7 @@ class SearchReplace extends JobExecutable {
|
|
398 |
$result = $this->db->query( $sql );
|
399 |
|
400 |
if( !$result ) {
|
401 |
-
$this->log( "Error updating row {$current_row}", \WPStaging\Utils\Logger::TYPE_ERROR );
|
402 |
}
|
403 |
}
|
404 |
} // end row loop
|
@@ -658,7 +657,12 @@ class SearchReplace extends JobExecutable {
|
|
658 |
* @return boolean
|
659 |
*/
|
660 |
private function isSubDir() {
|
661 |
-
|
|
|
|
|
|
|
|
|
|
|
662 |
return true;
|
663 |
}
|
664 |
return false;
|
47 |
$this->db = WPStaging::getInstance()->get( "wpdb" );
|
48 |
$this->tmpPrefix = $this->options->prefix;
|
49 |
$helper = new Helper();
|
|
|
50 |
$this->homeUrl = $helper->get_home_url_without_scheme();
|
51 |
}
|
52 |
|
292 |
'Admin_custome_login_top',
|
293 |
'Admin_custome_login_dashboard',
|
294 |
'Admin_custome_login_Version',
|
295 |
+
'upload_path',
|
296 |
);
|
297 |
|
298 |
$filter = apply_filters( 'wpstg_clone_searchreplace_excl_rows', $filter );
|
397 |
$result = $this->db->query( $sql );
|
398 |
|
399 |
if( !$result ) {
|
400 |
+
$this->log( "Error updating row {$current_row} SQL: {$sql}", \WPStaging\Utils\Logger::TYPE_ERROR );
|
401 |
}
|
402 |
}
|
403 |
} // end row loop
|
657 |
* @return boolean
|
658 |
*/
|
659 |
private function isSubDir() {
|
660 |
+
// Compare names without scheme to bypass cases where siteurl and home have different schemes http / https
|
661 |
+
// This is happening much more often than you would expect
|
662 |
+
$siteurl = preg_replace( '#^https?://#', '', rtrim( get_option( 'siteurl' ), '/' ) );
|
663 |
+
$home = preg_replace( '#^https?://#', '', rtrim( get_option( 'home' ), '/' ) );
|
664 |
+
|
665 |
+
if( $home !== $siteurl ) {
|
666 |
return true;
|
667 |
}
|
668 |
return false;
|
apps/Backend/Modules/Jobs/Updating.php
CHANGED
@@ -1,248 +1,255 @@
|
|
1 |
<?php
|
|
|
2 |
namespace WPStaging\Backend\Modules\Jobs;
|
3 |
|
4 |
use WPStaging\Backend\Modules\Jobs\Exceptions\JobNotFoundException;
|
5 |
use WPStaging\WPStaging;
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
|
7 |
/**
|
8 |
* Class Cloning
|
9 |
* @package WPStaging\Backend\Modules\Jobs
|
10 |
*/
|
11 |
-
class Updating extends Job
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
// Excluded Tables
|
58 |
// if (isset($_POST["excludedTables"]) && is_array($_POST["excludedTables"]))
|
59 |
// {
|
60 |
// $this->options->excludedTables = $_POST["excludedTables"];
|
61 |
// }
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
} else {
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
if (!empty($matches[1])) {
|
131 |
-
$this->options->prefix = $matches[1];
|
132 |
-
} else {
|
133 |
-
$this->returnException("Fatal Error: Can not detect prefix from {$path}. Stopping for security reasons. Deleting this staging site and creating a new one could fix this issue. Otherwise contact us support@wp-staging.com");
|
134 |
-
wp_die("Fatal Error: Can not detect prefix from {$path}. Stopping for security reasons. Deleting this staging site and creating a new one could fix this issue. Otherwise contact us support@wp-staging.com");
|
135 |
-
}
|
136 |
}
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
|
202 |
-
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
211 |
-
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
<?php
|
2 |
+
|
3 |
namespace WPStaging\Backend\Modules\Jobs;
|
4 |
|
5 |
use WPStaging\Backend\Modules\Jobs\Exceptions\JobNotFoundException;
|
6 |
use WPStaging\WPStaging;
|
7 |
+
use WPStaging\Backend\Modules\Jobs\Multisite\Database as muDatabase;
|
8 |
+
use WPStaging\Backend\Modules\Jobs\Multisite\SearchReplace as muSearchReplace;
|
9 |
+
use WPStaging\Backend\Modules\Jobs\Multisite\Data as muData;
|
10 |
+
use WPStaging\Backend\Modules\Jobs\Multisite\Finish as muFinish;
|
11 |
+
use WPStaging\Backend\Modules\Jobs\Multisite\Directories as muDirectories;
|
12 |
+
use WPStaging\Backend\Modules\Jobs\Multisite\Files as muFiles;
|
13 |
|
14 |
/**
|
15 |
* Class Cloning
|
16 |
* @package WPStaging\Backend\Modules\Jobs
|
17 |
*/
|
18 |
+
class Updating extends Job {
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Initialize is called in \Job
|
22 |
+
*/
|
23 |
+
public function initialize() {
|
24 |
+
$this->db = WPStaging::getInstance()->get( "wpdb" );
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Save Chosen Cloning Settings
|
29 |
+
* @return bool
|
30 |
+
*/
|
31 |
+
public function save() {
|
32 |
+
if( !isset( $_POST ) || !isset( $_POST["cloneID"] ) ) {
|
33 |
+
return false;
|
34 |
+
}
|
35 |
+
|
36 |
+
// Generate Options
|
37 |
+
// Clone
|
38 |
+
$this->options->clone = $_POST["cloneID"];
|
39 |
+
$this->options->cloneDirectoryName = preg_replace( "#\W+#", '-', strtolower( $this->options->clone ) );
|
40 |
+
$this->options->cloneNumber = 1;
|
41 |
+
$this->options->includedDirectories = array();
|
42 |
+
$this->options->excludedDirectories = array();
|
43 |
+
$this->options->extraDirectories = array();
|
44 |
+
$this->options->excludedFiles = array('.htaccess', '.DS_Store', '.git', '.svn', '.tmp', 'desktop.ini', '.gitignore', '.log');
|
45 |
+
|
46 |
+
// Define mainJob to differentiate between cloning, updating and pushing
|
47 |
+
$this->options->mainJob = 'updating';
|
48 |
+
|
49 |
+
// Job
|
50 |
+
$this->options->job = new \stdClass();
|
51 |
+
|
52 |
+
// Check if clone data already exists and use that one
|
53 |
+
if( isset( $this->options->existingClones[$this->options->clone] ) ) {
|
54 |
+
$this->options->cloneNumber = $this->options->existingClones[$this->options->clone]['number'];
|
55 |
+
$this->options->prefix = $this->getStagingPrefix();
|
56 |
+
} else {
|
57 |
+
wp_die( 'Fatal Error: Can not update clone because there is no clone data.' );
|
58 |
+
}
|
59 |
+
|
60 |
+
|
61 |
+
// Excluded Tables
|
|
|
|
|
|
|
62 |
// if (isset($_POST["excludedTables"]) && is_array($_POST["excludedTables"]))
|
63 |
// {
|
64 |
// $this->options->excludedTables = $_POST["excludedTables"];
|
65 |
// }
|
66 |
+
// Included Tables
|
67 |
+
if( isset( $_POST["includedTables"] ) && is_array( $_POST["includedTables"] ) ) {
|
68 |
+
$this->options->tables = $_POST["includedTables"];
|
69 |
+
} else {
|
70 |
+
$this->options->tables = array();
|
71 |
+
}
|
72 |
+
|
73 |
+
// Excluded Directories
|
74 |
+
if( isset( $_POST["excludedDirectories"] ) && is_array( $_POST["excludedDirectories"] ) ) {
|
75 |
+
$this->options->excludedDirectories = $_POST["excludedDirectories"];
|
76 |
+
}
|
77 |
+
|
78 |
+
// Excluded Directories TOTAL
|
79 |
+
// Do not copy these folders and plugins
|
80 |
+
$excludedDirectories = array(
|
81 |
+
ABSPATH . 'wp-content' . DIRECTORY_SEPARATOR . 'cache',
|
82 |
+
ABSPATH . 'wp-content' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'wps-hide-login'
|
83 |
+
);
|
84 |
+
|
85 |
+
$this->options->excludedDirectories = array_merge( $excludedDirectories, $this->options->excludedDirectories );
|
86 |
+
|
87 |
+
// Included Directories
|
88 |
+
if( isset( $_POST["includedDirectories"] ) && is_array( $_POST["includedDirectories"] ) ) {
|
89 |
+
$this->options->includedDirectories = $_POST["includedDirectories"];
|
90 |
+
}
|
91 |
+
|
92 |
+
// Extra Directories
|
93 |
+
if( isset( $_POST["extraDirectories"] ) && !empty( $_POST["extraDirectories"] ) ) {
|
94 |
+
$this->options->extraDirectories = $_POST["extraDirectories"];
|
95 |
+
}
|
96 |
+
|
97 |
+
// Directories to Copy
|
98 |
+
$this->options->directoriesToCopy = array_merge(
|
99 |
+
$this->options->includedDirectories, $this->options->extraDirectories
|
100 |
+
);
|
101 |
+
|
102 |
+
array_unshift( $this->options->directoriesToCopy, ABSPATH );
|
103 |
+
|
104 |
+
// Delete files to copy listing
|
105 |
+
$this->cache->delete( "files_to_copy" );
|
106 |
+
|
107 |
+
return $this->saveOptions();
|
108 |
+
}
|
109 |
+
|
110 |
+
/**
|
111 |
+
* Check and return prefix of the staging site
|
112 |
+
*/
|
113 |
+
public function getStagingPrefix() {
|
114 |
+
// prefix not defined! Happens if staging site has ben generated with older version of wpstg
|
115 |
+
// Try to get staging prefix from wp-config.php of staging site
|
116 |
+
$this->options->prefix = $this->options->existingClones[$this->options->clone]['prefix'];
|
117 |
+
if( empty( $this->options->prefix ) ) {
|
118 |
+
// Throw error if wp-config.php is not readable
|
119 |
+
$path = ABSPATH . $this->options->cloneDirectoryName . "/wp-config.php";
|
120 |
+
if( false === ($content = @file_get_contents( $path )) ) {
|
121 |
+
$this->log( "Can not open {$path}. Can't read contents", Logger::TYPE_ERROR );
|
122 |
+
$this->returnException( "Fatal Error: Can not read {$path} to get correct table prefix. Stopping for security reasons. Deleting this staging site and creating a new one could fix this issue. Otherwise contact us support@wp-staging.com" );
|
123 |
+
wp_die( "Fatal Error: Can not read {$path} to get correct table prefix. Stopping for security reasons. Deleting this staging site and creating a new one could fix this issue. Otherwise contact us support@wp-staging.com" );
|
124 |
+
} else {
|
125 |
+
// Get prefix from wp-config.php
|
126 |
+
preg_match( "/table_prefix\s*=\s*'(\w*)';/", $content, $matches );
|
127 |
+
|
128 |
+
if( !empty( $matches[1] ) ) {
|
129 |
+
$this->options->prefix = $matches[1];
|
130 |
} else {
|
131 |
+
$this->returnException( "Fatal Error: Can not detect prefix from {$path}. Stopping for security reasons. Deleting this staging site and creating a new one could fix this issue. Otherwise contact us support@wp-staging.com" );
|
132 |
+
wp_die( "Fatal Error: Can not detect prefix from {$path}. Stopping for security reasons. Deleting this staging site and creating a new one could fix this issue. Otherwise contact us support@wp-staging.com" );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
133 |
}
|
134 |
+
}
|
135 |
+
}
|
136 |
+
|
137 |
+
// Die() if staging prefix is the same as the live prefix
|
138 |
+
if( $this->db->prefix == $this->options->prefix ) {
|
139 |
+
$this->log( "Fatal Error: Can not updatte staging site. Prefix. '{$this->options->prefix}' is used for the live site. Stopping for security reasons. Deleting this staging site and creating a new one could fix this issue. Otherwise contact us support@wp-staging.com" );
|
140 |
+
wp_die( "Fatal Error: Can not update staging site. Prefix. '{$this->options->prefix}' is used for the live site. Stopping for security reasons. Deleting this staging site and creating a new one could fix this issue. Otherwise contact us support@wp-staging.com" );
|
141 |
+
}
|
142 |
+
|
143 |
+
// Else
|
144 |
+
return $this->options->prefix;
|
145 |
+
}
|
146 |
+
|
147 |
+
/**
|
148 |
+
* Start the cloning job
|
149 |
+
*/
|
150 |
+
public function start() {
|
151 |
+
if( null === $this->options->currentJob ) {
|
152 |
+
$this->log( "Cloning job for {$this->options->clone} finished" );
|
153 |
+
return true;
|
154 |
+
}
|
155 |
+
|
156 |
+
$methodName = "job" . ucwords( $this->options->currentJob );
|
157 |
+
|
158 |
+
if( !method_exists( $this, $methodName ) ) {
|
159 |
+
$this->log( "Can't execute job; Job's method {$methodName} is not found" );
|
160 |
+
throw new JobNotFoundException( $methodName );
|
161 |
+
}
|
162 |
+
|
163 |
+
// Call the job
|
164 |
+
//$this->log("execute job: Job's method {$methodName}");
|
165 |
+
return $this->{$methodName}();
|
166 |
+
}
|
167 |
+
|
168 |
+
/**
|
169 |
+
* @param object $response
|
170 |
+
* @param string $nextJob
|
171 |
+
* @return object
|
172 |
+
*/
|
173 |
+
private function handleJobResponse( $response, $nextJob ) {
|
174 |
+
// Job is not done
|
175 |
+
if( true !== $response->status ) {
|
176 |
+
return $response;
|
177 |
+
}
|
178 |
+
|
179 |
+
$this->options->currentJob = $nextJob;
|
180 |
+
$this->options->currentStep = 0;
|
181 |
+
$this->options->totalSteps = 0;
|
182 |
+
|
183 |
+
// Save options
|
184 |
+
$this->saveOptions();
|
185 |
+
|
186 |
+
return $response;
|
187 |
+
}
|
188 |
+
|
189 |
+
/**
|
190 |
+
* Clone Database
|
191 |
+
* @return object
|
192 |
+
*/
|
193 |
+
public function jobDatabase() {
|
194 |
+
if( is_multisite() ) {
|
195 |
+
$database = new muDatabase();
|
196 |
+
} else {
|
197 |
+
$database = new Database();
|
198 |
+
}
|
199 |
+
return $this->handleJobResponse( $database->start(), "directories" );
|
200 |
+
}
|
201 |
+
|
202 |
+
/**
|
203 |
+
* Get All Files From Selected Directories Recursively Into a File
|
204 |
+
* @return object
|
205 |
+
*/
|
206 |
+
public function jobDirectories() {
|
207 |
+
if( is_multisite() ) {
|
208 |
+
$directories = new muDirectories();
|
209 |
+
} else {
|
210 |
+
$directories = new Directories();
|
211 |
+
}
|
212 |
+
return $this->handleJobResponse( $directories->start(), "files" );
|
213 |
+
}
|
214 |
+
|
215 |
+
/**
|
216 |
+
* Copy Files
|
217 |
+
* @return object
|
218 |
+
*/
|
219 |
+
public function jobFiles() {
|
220 |
+
if( is_multisite() ) {
|
221 |
+
$files = new muFiles();
|
222 |
+
} else {
|
223 |
+
$files = new Files();
|
224 |
+
}
|
225 |
+
return $this->handleJobResponse( $files->start(), "data" );
|
226 |
+
}
|
227 |
+
|
228 |
+
/**
|
229 |
+
* Replace Data
|
230 |
+
* @return object
|
231 |
+
*/
|
232 |
+
public function jobData() {
|
233 |
+
if( is_multisite() ) {
|
234 |
+
$data = new muData();
|
235 |
+
} else {
|
236 |
+
$data = new Data();
|
237 |
+
}
|
238 |
+
return $this->handleJobResponse( $data->start(), "finish" );
|
239 |
+
}
|
240 |
+
|
241 |
+
/**
|
242 |
+
* Save Clone Data
|
243 |
+
* @return object
|
244 |
+
*/
|
245 |
+
public function jobFinish() {
|
246 |
+
if( is_multisite() ) {
|
247 |
+
$finish = new muFinish();
|
248 |
+
} else {
|
249 |
+
$finish = new Finish();
|
250 |
+
}
|
251 |
+
$finish = new Finish();
|
252 |
+
return $this->handleJobResponse( $finish->start(), '' );
|
253 |
+
}
|
254 |
+
|
255 |
+
}
|
apps/Backend/Modules/SystemInfo.php
CHANGED
@@ -139,8 +139,9 @@ class SystemInfo extends InjectionAware {
|
|
139 |
|
140 |
$output = $this->info( "Multisite:", ($this->isMultiSite ? "Yes" : "No" ) );
|
141 |
$output .= $this->info( "Multisite Blog ID:", get_current_blog_id() );
|
142 |
-
$output .= $this->info( "MultiSite URL
|
143 |
$output .= $this->info( "MultiSite URL without scheme:", $multisite->getHomeUrlWithoutScheme() );
|
|
|
144 |
|
145 |
return apply_filters( "wpstg_sysinfo_after_multisite_info", $output );
|
146 |
|
@@ -159,7 +160,7 @@ class SystemInfo extends InjectionAware {
|
|
159 |
// Clones data < 1.1.6.x
|
160 |
$clones = ( object ) get_option( 'wpstg_existing_clones', array() );
|
161 |
// Clones data version > 2.x
|
162 |
-
$clonesBeta = get_option( 'wpstg_existing_clones_beta' );
|
163 |
|
164 |
|
165 |
$output = "-- WP Staging Settings" . PHP_EOL . PHP_EOL;
|
@@ -172,7 +173,6 @@ class SystemInfo extends InjectionAware {
|
|
172 |
|
173 |
$output .= PHP_EOL . PHP_EOL . "-- Available Sites Version < 1.1.6.x" . PHP_EOL . PHP_EOL;
|
174 |
|
175 |
-
$i = 1;
|
176 |
foreach ( $clones as $key => $value ) {
|
177 |
$output .= $this->info( "Site name & subfolder :", $value );
|
178 |
}
|
@@ -508,7 +508,12 @@ class SystemInfo extends InjectionAware {
|
|
508 |
* @return boolean
|
509 |
*/
|
510 |
private function isSubDir() {
|
511 |
-
|
|
|
|
|
|
|
|
|
|
|
512 |
return true;
|
513 |
}
|
514 |
return false;
|
139 |
|
140 |
$output = $this->info( "Multisite:", ($this->isMultiSite ? "Yes" : "No" ) );
|
141 |
$output .= $this->info( "Multisite Blog ID:", get_current_blog_id() );
|
142 |
+
$output .= $this->info( "MultiSite URL:", $multisite->getHomeURL() );
|
143 |
$output .= $this->info( "MultiSite URL without scheme:", $multisite->getHomeUrlWithoutScheme() );
|
144 |
+
$output .= $this->info( "MultiSite is Main Site:", is_main_site() ? 'Yes' : 'No' );
|
145 |
|
146 |
return apply_filters( "wpstg_sysinfo_after_multisite_info", $output );
|
147 |
|
160 |
// Clones data < 1.1.6.x
|
161 |
$clones = ( object ) get_option( 'wpstg_existing_clones', array() );
|
162 |
// Clones data version > 2.x
|
163 |
+
$clonesBeta = get_option( 'wpstg_existing_clones_beta', array() );
|
164 |
|
165 |
|
166 |
$output = "-- WP Staging Settings" . PHP_EOL . PHP_EOL;
|
173 |
|
174 |
$output .= PHP_EOL . PHP_EOL . "-- Available Sites Version < 1.1.6.x" . PHP_EOL . PHP_EOL;
|
175 |
|
|
|
176 |
foreach ( $clones as $key => $value ) {
|
177 |
$output .= $this->info( "Site name & subfolder :", $value );
|
178 |
}
|
508 |
* @return boolean
|
509 |
*/
|
510 |
private function isSubDir() {
|
511 |
+
// Compare names without scheme to bypass cases where siteurl and home have different schemes http / https
|
512 |
+
// This is happening much more often than you would expect
|
513 |
+
$siteurl = preg_replace( '#^https?://#', '', rtrim( get_option( 'siteurl' ), '/' ) );
|
514 |
+
$home = preg_replace( '#^https?://#', '', rtrim( get_option( 'home' ), '/' ) );
|
515 |
+
|
516 |
+
if( $home !== $siteurl ) {
|
517 |
return true;
|
518 |
}
|
519 |
return false;
|
apps/Backend/Notices/Notices.php
CHANGED
@@ -77,14 +77,10 @@ class Notices {
|
|
77 |
|
78 |
public function messages() {
|
79 |
|
80 |
-
$this->
|
81 |
|
82 |
-
|
83 |
-
if( !current_user_can( 'update_plugins' ) ) {
|
84 |
-
return;
|
85 |
-
}
|
86 |
|
87 |
-
$viewsNoticesPath = "{$this->path}views/_includes/messages/";
|
88 |
|
89 |
// Show rating review message on all admin pages
|
90 |
if( $this->canShow( "wpstg_rating", 7 ) ) {
|
@@ -92,26 +88,18 @@ class Notices {
|
|
92 |
}
|
93 |
|
94 |
|
95 |
-
// Display messages below
|
96 |
-
if( !$this->isAdminPage() ) {
|
97 |
return;
|
98 |
}
|
99 |
|
100 |
|
101 |
$varsDirectory = \WPStaging\WPStaging::getContentDir();
|
102 |
-
|
103 |
-
|
104 |
-
// Poll do not show any longer
|
105 |
-
/* if( $this->canShow( "wpstg_poll", 7 ) ) {
|
106 |
-
require_once "{$viewsNoticesPath}poll.php";
|
107 |
-
} */
|
108 |
-
|
109 |
-
// Cache directory in uploads is not writable
|
110 |
if( !wp_is_writable( $varsDirectory ) ) {
|
111 |
require_once "{$viewsNoticesPath}/uploads-cache-directory-permission-problem.php";
|
112 |
}
|
113 |
// Staging directory is not writable
|
114 |
-
if( !wp_is_writable(
|
115 |
require_once "{$viewsNoticesPath}/staging-directory-permission-problem.php";
|
116 |
}
|
117 |
|
@@ -130,6 +118,30 @@ class Notices {
|
|
130 |
require_once "{$viewsNoticesPath}transient.php";
|
131 |
delete_transient( "wp_staging_deactivated_notice_id" );
|
132 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
133 |
}
|
134 |
|
135 |
/**
|
77 |
|
78 |
public function messages() {
|
79 |
|
80 |
+
$viewsNoticesPath = "{$this->path}views/_includes/messages/";
|
81 |
|
82 |
+
$this->plugin_deactivated_notice();
|
|
|
|
|
|
|
83 |
|
|
|
84 |
|
85 |
// Show rating review message on all admin pages
|
86 |
if( $this->canShow( "wpstg_rating", 7 ) ) {
|
88 |
}
|
89 |
|
90 |
|
91 |
+
// Display messages below to admins only, only on admin panel
|
92 |
+
if( !current_user_can( "update_plugins" ) || !$this->isAdminPage() ) {
|
93 |
return;
|
94 |
}
|
95 |
|
96 |
|
97 |
$varsDirectory = \WPStaging\WPStaging::getContentDir();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
if( !wp_is_writable( $varsDirectory ) ) {
|
99 |
require_once "{$viewsNoticesPath}/uploads-cache-directory-permission-problem.php";
|
100 |
}
|
101 |
// Staging directory is not writable
|
102 |
+
if( !wp_is_writable( ABSPATH ) ) {
|
103 |
require_once "{$viewsNoticesPath}/staging-directory-permission-problem.php";
|
104 |
}
|
105 |
|
118 |
require_once "{$viewsNoticesPath}transient.php";
|
119 |
delete_transient( "wp_staging_deactivated_notice_id" );
|
120 |
}
|
121 |
+
// Rating
|
122 |
+
if( $this->canShow( "wpstg_rating", 7 ) ) {
|
123 |
+
require_once "{$viewsNoticesPath}rating.php";
|
124 |
+
}
|
125 |
+
|
126 |
+
// Different scheme in home and siteurl
|
127 |
+
if ($this->isDifferentScheme()){
|
128 |
+
require_once "{$viewsNoticesPath}wrong-scheme.php";
|
129 |
+
}
|
130 |
+
}
|
131 |
+
|
132 |
+
/**
|
133 |
+
* Check if the url scheme of siteurl and home is identical
|
134 |
+
* @return boolean
|
135 |
+
*/
|
136 |
+
private function isDifferentScheme(){
|
137 |
+
$siteurlScheme = parse_url(get_option('siteurl'), PHP_URL_SCHEME);
|
138 |
+
$homeScheme = parse_url(get_option('home'), PHP_URL_SCHEME);
|
139 |
+
|
140 |
+
if ($siteurlScheme === $homeScheme){
|
141 |
+
return false;
|
142 |
+
}
|
143 |
+
return true;
|
144 |
+
|
145 |
}
|
146 |
|
147 |
/**
|
apps/Backend/public/css/wpstg-admin.css
CHANGED
@@ -936,4 +936,18 @@ color:#777777;
|
|
936 |
.wpstg-message p {
|
937 |
margin: 3px 0;
|
938 |
font-size: 13px;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
939 |
}
|
936 |
.wpstg-message p {
|
937 |
margin: 3px 0;
|
938 |
font-size: 13px;
|
939 |
+
}
|
940 |
+
|
941 |
+
|
942 |
+
.wpstg-error {
|
943 |
+
display:block;
|
944 |
+
padding: 10px;
|
945 |
+
background-color: #f5e0de;
|
946 |
+
color:#b65147;
|
947 |
+
margin: 10px;
|
948 |
+
margin-left:0px;
|
949 |
+
}
|
950 |
+
|
951 |
+
#wpstg-resume-cloning {
|
952 |
+
display:none;
|
953 |
}
|
apps/Backend/public/js/wpstg-admin.js
CHANGED
@@ -49,11 +49,11 @@ var WPStaging = (function ($)
|
|
49 |
{
|
50 |
cache.get("#wpstg-try-again").css("display", "inline-block");
|
51 |
cache.get("#wpstg-cancel-cloning").text("Reset");
|
52 |
-
cache.get("#wpstg-cloning
|
|
|
|
|
53 |
cache.get("#wpstg-error-wrapper").show();
|
54 |
-
cache.get("#wpstg-error-details")
|
55 |
-
.show()
|
56 |
-
.html(message);
|
57 |
cache.get("#wpstg-removing-clone").removeClass("loading");
|
58 |
cache.get("#wpstg-loader").hide();
|
59 |
};
|
@@ -240,8 +240,6 @@ var WPStaging = (function ($)
|
|
240 |
that.isCancelled = true;
|
241 |
that.progressBar = 0;
|
242 |
|
243 |
-
|
244 |
-
//$("#wpstg-cloning-result").text("Please wait...this can take up a while.");
|
245 |
$("#wpstg-processing-status").text("Please wait...this can take up a while.");
|
246 |
$("#wpstg-loader, #wpstg-show-log-button").hide();
|
247 |
|
@@ -249,12 +247,30 @@ var WPStaging = (function ($)
|
|
249 |
|
250 |
cancelCloning();
|
251 |
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
252 |
// Cancel update cloning
|
253 |
.on("click", "#wpstg-cancel-cloning-update", function () {
|
254 |
-
if (!confirm("Are you sure you want to cancel clone updating process?"))
|
255 |
-
{
|
256 |
-
return false;
|
257 |
-
}
|
258 |
|
259 |
var $this = $(this);
|
260 |
|
@@ -337,9 +353,7 @@ var WPStaging = (function ($)
|
|
337 |
if (response.length < 1)
|
338 |
{
|
339 |
showError(
|
340 |
-
"Something went wrong! Error: No response.
|
341 |
-
"Than try again. If that does not help, " +
|
342 |
-
"<a href='https://wp-staging.com/support/' target='_blank'>open a support ticket</a> "
|
343 |
);
|
344 |
}
|
345 |
|
@@ -392,9 +406,7 @@ var WPStaging = (function ($)
|
|
392 |
|
393 |
|
394 |
showError(
|
395 |
-
"Fatal Unknown Error.
|
396 |
-
"Than try again. If that does not help, " +
|
397 |
-
"<a href='https://wp-staging.com/support/' target='_blank'>open a support ticket</a> "
|
398 |
);
|
399 |
},
|
400 |
success: function (data) {
|
@@ -406,18 +418,22 @@ var WPStaging = (function ($)
|
|
406 |
statusCode: {
|
407 |
404: function (data) {
|
408 |
showError(
|
409 |
-
"Something went wrong
|
410 |
-
"Than try again. If that does not help, " +
|
411 |
-
"<a href='https://wp-staging.com/support/' target='_blank'>open a support ticket</a> "
|
412 |
);
|
413 |
-
|
414 |
},
|
415 |
500: function () {
|
416 |
showError(
|
417 |
-
"Something went wrong! Internal server error while processing the request!
|
418 |
-
"Than try again. If that does not help, " +
|
419 |
-
"<a href='https://wp-staging.com/support/' target='_blank'>open a support ticket</a> "
|
420 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
421 |
}
|
422 |
}
|
423 |
});
|
@@ -435,8 +451,18 @@ var WPStaging = (function ($)
|
|
435 |
.on("click", ".wpstg-next-step-link", function (e) {
|
436 |
e.preventDefault();
|
437 |
|
438 |
-
var $this = $(this)
|
439 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
440 |
|
441 |
// Button is disabled
|
442 |
if ($this.attr("disabled"))
|
@@ -480,7 +506,7 @@ var WPStaging = (function ($)
|
|
480 |
{
|
481 |
showError(
|
482 |
"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.'" +
|
483 |
-
"
|
484 |
"<a href='https://wp-staging.com/support/' target='_blank'>open a support ticket</a> "
|
485 |
);
|
486 |
}
|
@@ -626,7 +652,7 @@ var WPStaging = (function ($)
|
|
626 |
}
|
627 |
|
628 |
that.data.cloneID = $("#wpstg-new-clone-id").val() || new Date().getTime().toString();
|
629 |
-
// Remove this to keep &_POST[] small otherwise mod_security will throw
|
630 |
//that.data.excludedTables = getExcludedTables();
|
631 |
that.data.includedTables = getIncludedTables();
|
632 |
that.data.includedDirectories = getIncludedDirectories();
|
@@ -655,9 +681,7 @@ var WPStaging = (function ($)
|
|
655 |
if (response.length < 1)
|
656 |
{
|
657 |
showError(
|
658 |
-
"Something went wrong! No response.
|
659 |
-
"Then try again. If that does not help, " +
|
660 |
-
"<a href='https://wp-staging.com/support/' target='_blank'>open a support ticket</a> "
|
661 |
);
|
662 |
}
|
663 |
|
@@ -722,9 +746,7 @@ var WPStaging = (function ($)
|
|
722 |
// Error
|
723 |
if ("undefined" !== typeof response.error && "undefined" !== typeof response.message) {
|
724 |
showError(
|
725 |
-
"Something went wrong! Error:" + response.message + ".
|
726 |
-
"Than try again. If that does not help, " +
|
727 |
-
"<a href='https://wp-staging.com/support/' target='_blank'>open a support ticket</a> "
|
728 |
);
|
729 |
console.log(response.message);
|
730 |
}
|
@@ -838,6 +860,7 @@ var WPStaging = (function ($)
|
|
838 |
);
|
839 |
};
|
840 |
|
|
|
841 |
/**
|
842 |
* Scroll the window log to bottom
|
843 |
* @returns void
|
@@ -974,6 +997,8 @@ var WPStaging = (function ($)
|
|
974 |
console.log("Starting cloning process...");
|
975 |
|
976 |
cache.get("#wpstg-loader").show();
|
|
|
|
|
977 |
|
978 |
// Clone Database
|
979 |
setTimeout(function () {
|
@@ -1025,9 +1050,7 @@ var WPStaging = (function ($)
|
|
1025 |
if (false === response)
|
1026 |
{
|
1027 |
showError(
|
1028 |
-
"Something went wrong! Error: No response. <br/><br/>
|
1029 |
-
"Then try again. If that does not help, " +
|
1030 |
-
"<a href='https://wp-staging.com/support/' target='_blank'>open a support ticket</a> "
|
1031 |
);
|
1032 |
cache.get("#wpstg-loader").hide();
|
1033 |
cache.get(".wpstg-loader").hide();
|
@@ -1038,9 +1061,7 @@ var WPStaging = (function ($)
|
|
1038 |
if ("undefined" !== typeof (response.error) && response.error) {
|
1039 |
console.log(response.message);
|
1040 |
showError(
|
1041 |
-
"Something went wrong! Error:" + response.message + ".
|
1042 |
-
"Then try again. If that does not help, " +
|
1043 |
-
"<a href='https://wp-staging.com/support/' target='_blank'>open a support ticket</a> "
|
1044 |
);
|
1045 |
|
1046 |
return;
|
@@ -1102,6 +1123,7 @@ var WPStaging = (function ($)
|
|
1102 |
cache.get("#wpstg_staging_name").html(that.data.cloneID);
|
1103 |
cache.get("#wpstg-finished-result").show();
|
1104 |
cache.get("#wpstg-cancel-cloning").hide();
|
|
|
1105 |
cache.get("#wpstg-cancel-cloning-update").prop("disabled", true);
|
1106 |
|
1107 |
var $link1 = cache.get("#wpstg-clone-url-1");
|
49 |
{
|
50 |
cache.get("#wpstg-try-again").css("display", "inline-block");
|
51 |
cache.get("#wpstg-cancel-cloning").text("Reset");
|
52 |
+
cache.get("#wpstg-resume-cloning").show();
|
53 |
+
//cache.get("#wpstg-cloning-result").text("Fail");
|
54 |
+
//cache.get("#wpstg-processing-status").text("Process Failed");
|
55 |
cache.get("#wpstg-error-wrapper").show();
|
56 |
+
cache.get("#wpstg-error-details").show().html(message);
|
|
|
|
|
57 |
cache.get("#wpstg-removing-clone").removeClass("loading");
|
58 |
cache.get("#wpstg-loader").hide();
|
59 |
};
|
240 |
that.isCancelled = true;
|
241 |
that.progressBar = 0;
|
242 |
|
|
|
|
|
243 |
$("#wpstg-processing-status").text("Please wait...this can take up a while.");
|
244 |
$("#wpstg-loader, #wpstg-show-log-button").hide();
|
245 |
|
247 |
|
248 |
cancelCloning();
|
249 |
})
|
250 |
+
// Resume cloning
|
251 |
+
.on("click", "#wpstg-resume-cloning", function () {
|
252 |
+
|
253 |
+
var $this = $(this);
|
254 |
+
|
255 |
+
$("#wpstg-try-again, #wpstg-home-link").hide();
|
256 |
+
|
257 |
+
that.isCancelled = false;
|
258 |
+
//that.progressBar = 0;
|
259 |
+
|
260 |
+
$("#wpstg-processing-status").text("Try to resume cloning process...");
|
261 |
+
$("#wpstg-error-details").hide();
|
262 |
+
$("#wpstg-loader").show();
|
263 |
+
|
264 |
+
$this.parent().append(ajaxSpinner);
|
265 |
+
|
266 |
+
that.startCloning();
|
267 |
+
})
|
268 |
// Cancel update cloning
|
269 |
.on("click", "#wpstg-cancel-cloning-update", function () {
|
270 |
+
// if (!confirm("Are you sure you want to cancel clone updating process?"))
|
271 |
+
// {
|
272 |
+
// return false;
|
273 |
+
// }
|
274 |
|
275 |
var $this = $(this);
|
276 |
|
353 |
if (response.length < 1)
|
354 |
{
|
355 |
showError(
|
356 |
+
"Something went wrong! Error: No response. Please try the <a href='https://wp-staging.com/docs/wp-staging-settings-for-small-servers/' target='_blank'>WP Staging Small Server Settings</a> or submit an error report."
|
|
|
|
|
357 |
);
|
358 |
}
|
359 |
|
406 |
|
407 |
|
408 |
showError(
|
409 |
+
"Fatal Unknown Error. Please try the <a href='https://wp-staging.com/docs/wp-staging-settings-for-small-servers/' target='_blank'>WP Staging Small Server Settings</a> or submit an error report."
|
|
|
|
|
410 |
);
|
411 |
},
|
412 |
success: function (data) {
|
418 |
statusCode: {
|
419 |
404: function (data) {
|
420 |
showError(
|
421 |
+
"Something went wrong! can't find ajax request URL! Please try the <a href='https://wp-staging.com/docs/wp-staging-settings-for-small-servers/' target='_blank'>WP Staging Small Server Settings</a> or submit an error report."
|
|
|
|
|
422 |
);
|
423 |
+
|
424 |
},
|
425 |
500: function () {
|
426 |
showError(
|
427 |
+
"Something went wrong! Internal server error while processing the request! Please try the <a href='https://wp-staging.com/docs/wp-staging-settings-for-small-servers/' target='_blank'>WP Staging Small Server Settings</a> or submit an error report."
|
|
|
|
|
428 |
);
|
429 |
+
},
|
430 |
+
504: function () {
|
431 |
+
showError("It looks like your server is rate limiting ajax requests. Please try to resume after a minute. If this still not works try the <a href='https://wp-staging.com/docs/wp-staging-settings-for-small-servers/' target='_blank'>WP Staging Small Server Settings</a> or submit an error report.\n\ ");
|
432 |
+
var obj = new Object();
|
433 |
+
obj.status = false;
|
434 |
+
obj.error = 'custom error';
|
435 |
+
return JSON.stringify(obj);
|
436 |
+
|
437 |
}
|
438 |
}
|
439 |
});
|
451 |
.on("click", ".wpstg-next-step-link", function (e) {
|
452 |
e.preventDefault();
|
453 |
|
454 |
+
var $this = $(this);
|
455 |
+
var isScan = false;
|
456 |
+
|
457 |
+
if ($this.data("action") === "wpstg_update") {
|
458 |
+
// Update Clone - confirmed
|
459 |
+
if (!confirm("Are you sure you want to update the staging site with data from the live site? \n\nMake sure to exclude all the tables and folders which you do not want to overwrite first! \n\nDo not necessarily cancel the updating process! This can break your staging site."))
|
460 |
+
{
|
461 |
+
return false;
|
462 |
+
}
|
463 |
+
|
464 |
+
}
|
465 |
+
|
466 |
|
467 |
// Button is disabled
|
468 |
if ($this.attr("disabled"))
|
506 |
{
|
507 |
showError(
|
508 |
"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.'" +
|
509 |
+
"and try again. If that does not help, " +
|
510 |
"<a href='https://wp-staging.com/support/' target='_blank'>open a support ticket</a> "
|
511 |
);
|
512 |
}
|
652 |
}
|
653 |
|
654 |
that.data.cloneID = $("#wpstg-new-clone-id").val() || new Date().getTime().toString();
|
655 |
+
// Remove this to keep &_POST[] small otherwise mod_security will throw error 404
|
656 |
//that.data.excludedTables = getExcludedTables();
|
657 |
that.data.includedTables = getIncludedTables();
|
658 |
that.data.includedDirectories = getIncludedDirectories();
|
681 |
if (response.length < 1)
|
682 |
{
|
683 |
showError(
|
684 |
+
"Something went wrong! No response. Please try the <a href='https://wp-staging.com/docs/wp-staging-settings-for-small-servers/' target='_blank'>WP Staging Small Server Settings</a> or submit an error report."
|
|
|
|
|
685 |
);
|
686 |
}
|
687 |
|
746 |
// Error
|
747 |
if ("undefined" !== typeof response.error && "undefined" !== typeof response.message) {
|
748 |
showError(
|
749 |
+
"Something went wrong! Error:" + response.message + ". Please try the <a href='https://wp-staging.com/docs/wp-staging-settings-for-small-servers/' target='_blank'>WP Staging Small Server Settings</a> or submit an error report."
|
|
|
|
|
750 |
);
|
751 |
console.log(response.message);
|
752 |
}
|
860 |
);
|
861 |
};
|
862 |
|
863 |
+
|
864 |
/**
|
865 |
* Scroll the window log to bottom
|
866 |
* @returns void
|
997 |
console.log("Starting cloning process...");
|
998 |
|
999 |
cache.get("#wpstg-loader").show();
|
1000 |
+
cache.get("#wpstg-cancel-cloning").text('Cancel');
|
1001 |
+
cache.get("#wpstg-resume-cloning").hide();
|
1002 |
|
1003 |
// Clone Database
|
1004 |
setTimeout(function () {
|
1050 |
if (false === response)
|
1051 |
{
|
1052 |
showError(
|
1053 |
+
"Something went wrong! Error: No response. <br/><br/> Please try the <a href='https://wp-staging.com/docs/wp-staging-settings-for-small-servers/' target='_blank'>WP Staging Small Server Settings</a> or submit an error report."
|
|
|
|
|
1054 |
);
|
1055 |
cache.get("#wpstg-loader").hide();
|
1056 |
cache.get(".wpstg-loader").hide();
|
1061 |
if ("undefined" !== typeof (response.error) && response.error) {
|
1062 |
console.log(response.message);
|
1063 |
showError(
|
1064 |
+
"Something went wrong! Error:" + response.message + ". Please try the <a href='https://wp-staging.com/docs/wp-staging-settings-for-small-servers/' target='_blank'>WP Staging Small Server Settings</a> or submit an error report."
|
|
|
|
|
1065 |
);
|
1066 |
|
1067 |
return;
|
1123 |
cache.get("#wpstg_staging_name").html(that.data.cloneID);
|
1124 |
cache.get("#wpstg-finished-result").show();
|
1125 |
cache.get("#wpstg-cancel-cloning").hide();
|
1126 |
+
cache.get("#wpstg-resume-cloning").hide();
|
1127 |
cache.get("#wpstg-cancel-cloning-update").prop("disabled", true);
|
1128 |
|
1129 |
var $link1 = cache.get("#wpstg-clone-url-1");
|
apps/Backend/views/_includes/messages/beta.php
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<div class="wpstg_beta_notice error" style="box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);">
|
2 |
<p>
|
3 |
WP Staging is well tested and we did a lot to catch every possible error but
|
4 |
we can not handle all possible combinations of server, plugins and themes. <br>
|
1 |
+
<div class="wpstg_beta_notice wpstg-error" style="box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);">
|
2 |
<p>
|
3 |
WP Staging is well tested and we did a lot to catch every possible error but
|
4 |
we can not handle all possible combinations of server, plugins and themes. <br>
|
apps/Backend/views/_includes/messages/cache-directory-permission-problem.php
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<div class="error">
|
2 |
<p>
|
3 |
<strong>WP Staging Folder Permission error: </strong> <?php echo "{$varsDirectory}cache"?> is not write and/or readable.
|
4 |
<br>
|
1 |
+
<div class="wpstg-error">
|
2 |
<p>
|
3 |
<strong>WP Staging Folder Permission error: </strong> <?php echo "{$varsDirectory}cache"?> is not write and/or readable.
|
4 |
<br>
|
apps/Backend/views/_includes/messages/logs-directory-permission-problem.php
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<div class="error">
|
2 |
<p>
|
3 |
<strong>WP Staging Folder Permission error: </strong> <?php echo "{$varsDirectory}logs"?> is not write and/or readable.
|
4 |
<br>
|
1 |
+
<div class="wpstg-error">
|
2 |
<p>
|
3 |
<strong>WP Staging Folder Permission error: </strong> <?php echo "{$varsDirectory}logs"?> is not write and/or readable.
|
4 |
<br>
|
apps/Backend/views/_includes/messages/staging-directory-permission-problem.php
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<div class="error">
|
2 |
<p>
|
3 |
<strong>
|
4 |
<?php echo sprintf(__('WP Staging Folder Permission error:</strong>
|
1 |
+
<div class="wpstg-error">
|
2 |
<p>
|
3 |
<strong>
|
4 |
<?php echo sprintf(__('WP Staging Folder Permission error:</strong>
|
apps/Backend/views/_includes/messages/uploads-cache-directory-permission-problem.php
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<div class="error">
|
2 |
<p>
|
3 |
<strong>WP Staging Folder Permission error: </strong>
|
4 |
<?php echo \WPStaging\WPStaging::getContentDir()?>
|
1 |
+
<div class="wpstg-error">
|
2 |
<p>
|
3 |
<strong>WP Staging Folder Permission error: </strong>
|
4 |
<?php echo \WPStaging\WPStaging::getContentDir()?>
|
apps/Backend/views/_includes/messages/vars-directory-permission-problem.php
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<div class="error">
|
2 |
<p>
|
3 |
<strong>WP Staging Folder Permission error: </strong> <?php echo "{$varsDirectory}"?> is not write and/or readable.
|
4 |
<br>
|
1 |
+
<div class="wpstg-error">
|
2 |
<p>
|
3 |
<strong>WP Staging Folder Permission error: </strong> <?php echo "{$varsDirectory}"?> is not write and/or readable.
|
4 |
<br>
|
apps/Backend/views/_includes/messages/wp-version-compatible-message.php
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
<div class="error">
|
2 |
<p>
|
3 |
<?php
|
4 |
echo sprintf( __(
|
1 |
+
<div class="wpstg-error">
|
2 |
<p>
|
3 |
<?php
|
4 |
echo sprintf( __(
|
apps/Backend/views/_includes/messages/wrong-scheme.php
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div class="wpstg-error">
|
2 |
+
<p>
|
3 |
+
<strong><?php _e( 'WP Staging HTTP/HTTPS Scheme Error:', 'wp-staging' ); ?></strong>
|
4 |
+
<?php echo sprintf(__( 'Go to <a href="%s" target="_blank">Settings > General</a> and make sure that WordPress Address (URL) and Site Address (URL) do both contain the same http / https scheme.', 'wp-staging' ), admin_url() . 'options-general.php'); ?>
|
5 |
+
<br>
|
6 |
+
<?php _e( 'Otherwise your staging site will not be reachable after creation.', 'wp-staging' ); ?></p>
|
7 |
+
</div>
|
apps/Backend/views/clone/ajax/start.php
CHANGED
@@ -17,6 +17,10 @@
|
|
17 |
<?php echo __("Cancel", "wp-staging")?>
|
18 |
</button>
|
19 |
|
|
|
|
|
|
|
|
|
20 |
<button type="button" id="wpstg-show-log-button" class="button" data-clone="<?php echo $cloning->getOptions()->clone?>" style="margin-top: 5px;display:none;">
|
21 |
<?php _e('Display working log', 'wp-staging')?>
|
22 |
</button>
|
17 |
<?php echo __("Cancel", "wp-staging")?>
|
18 |
</button>
|
19 |
|
20 |
+
<button type="button" id="wpstg-resume-cloning" class="wpstg-link-btn button-primary">
|
21 |
+
<?php echo __("Resume", "wp-staging")?>
|
22 |
+
</button>
|
23 |
+
|
24 |
<button type="button" id="wpstg-show-log-button" class="button" data-clone="<?php echo $cloning->getOptions()->clone?>" style="margin-top: 5px;display:none;">
|
25 |
<?php _e('Display working log', 'wp-staging')?>
|
26 |
</button>
|
apps/Backend/views/welcome/welcome.php
CHANGED
@@ -8,8 +8,9 @@
|
|
8 |
<li><strong>Authentication</strong> - <?php _e( 'Staging Site is available to authenticated users only', 'wp-staging' ); ?></li>
|
9 |
<li><strong>High Performance</strong> - <?php _e( 'Cloning process is fast and does not slow down website loading', 'wp-staging' ); ?></li>
|
10 |
<li><strong>Secure</strong> - <?php _e( 'WP Staging is coded well for protection of your data', 'wp-staging' ); ?></li>
|
|
|
11 |
<a href="http://wp-staging.com/?utm_source=wpstg&utm_medium=addon_page&utm_term=click-wpstaging-pro&utm_campaign=wpstaging" target="_blank" class="wpstg-button green">Buy WP Staging Pro</a>
|
12 |
<a href="<?php echo admin_url(); ?>admin.php?page=wpstg_clone" target="_self" style="margin-left:30px;">Skip - Start Cloning</a>
|
13 |
-
<div class="wpstg-footer"> <?php _e( 'Comes with our 30-day
|
14 |
</div>
|
15 |
</div>
|
8 |
<li><strong>Authentication</strong> - <?php _e( 'Staging Site is available to authenticated users only', 'wp-staging' ); ?></li>
|
9 |
<li><strong>High Performance</strong> - <?php _e( 'Cloning process is fast and does not slow down website loading', 'wp-staging' ); ?></li>
|
10 |
<li><strong>Secure</strong> - <?php _e( 'WP Staging is coded well for protection of your data', 'wp-staging' ); ?></li>
|
11 |
+
<li><strong>Multisites</strong> - <?php _e( 'WP Staging Pro allows to clone and push Multisites, (main site & sub sites)', 'wp-staging' ); ?></li>
|
12 |
<a href="http://wp-staging.com/?utm_source=wpstg&utm_medium=addon_page&utm_term=click-wpstaging-pro&utm_campaign=wpstaging" target="_blank" class="wpstg-button green">Buy WP Staging Pro</a>
|
13 |
<a href="<?php echo admin_url(); ?>admin.php?page=wpstg_clone" target="_self" style="margin-left:30px;">Skip - Start Cloning</a>
|
14 |
+
<div class="wpstg-footer"> <?php _e( 'Comes with our 30-day money back guarantee * You need to give us chance to resolve your issue first.', 'wp-staging' ); ?></div>
|
15 |
</div>
|
16 |
</div>
|
apps/Core/Utils/Cache.php
CHANGED
@@ -1,10 +1,10 @@
|
|
1 |
<?php
|
|
|
2 |
namespace WPStaging\Utils;
|
3 |
|
4 |
// No Direct Access
|
5 |
-
if
|
6 |
-
|
7 |
-
die;
|
8 |
}
|
9 |
|
10 |
use WPStaging\WPStaging;
|
@@ -13,206 +13,189 @@ use WPStaging\WPStaging;
|
|
13 |
* Class Cache
|
14 |
* @package WPStaging\Utils
|
15 |
*/
|
16 |
-
class Cache
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
197 |
-
|
198 |
-
|
199 |
-
|
200 |
-
|
201 |
-
{
|
202 |
-
return $this->cacheExtension;
|
203 |
-
}
|
204 |
-
|
205 |
-
|
206 |
-
/**
|
207 |
-
* Throw a errror message via json and stop further execution
|
208 |
-
* @param string $message
|
209 |
-
*/
|
210 |
-
protected function returnException($message = ''){
|
211 |
-
wp_die( json_encode(array(
|
212 |
-
'job' => isset($this->options->currentJob) ? $this->options->currentJob : '',
|
213 |
-
'status' => false,
|
214 |
-
'message' => $message,
|
215 |
-
'error' => true
|
216 |
-
)));
|
217 |
}
|
218 |
-
}
|
1 |
<?php
|
2 |
+
|
3 |
namespace WPStaging\Utils;
|
4 |
|
5 |
// No Direct Access
|
6 |
+
if( !defined( "WPINC" ) ) {
|
7 |
+
die;
|
|
|
8 |
}
|
9 |
|
10 |
use WPStaging\WPStaging;
|
13 |
* Class Cache
|
14 |
* @package WPStaging\Utils
|
15 |
*/
|
16 |
+
class Cache {
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Cache directory (full path)
|
20 |
+
* @var string
|
21 |
+
*/
|
22 |
+
private $cacheDir;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Cache file extension
|
26 |
+
* @var string
|
27 |
+
*/
|
28 |
+
private $cacheExtension = "cache";
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Lifetime of cache files in seconds
|
32 |
+
* @var int
|
33 |
+
*/
|
34 |
+
private $lifetime = 2592000; // 30 days
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Cache constructor.
|
38 |
+
* @param null|int $lifetime
|
39 |
+
* @param null|string $cacheDir
|
40 |
+
* @param null|string $cacheExtension
|
41 |
+
* @throws \Exception
|
42 |
+
*/
|
43 |
+
|
44 |
+
public function __construct( $lifetime = null, $cacheDir = null, $cacheExtension = null ) {
|
45 |
+
// Set lifetime
|
46 |
+
$lifetime = ( int ) $lifetime;
|
47 |
+
if( $lifetime > 0 ) {
|
48 |
+
$this->lifetime = $lifetime;
|
49 |
+
}
|
50 |
+
|
51 |
+
// Set cache directory
|
52 |
+
if( !empty( $cacheDir ) && is_dir( $cacheDir ) ) {
|
53 |
+
$this->cacheDir = $cacheDir;
|
54 |
+
}
|
55 |
+
// Set default
|
56 |
+
else {
|
57 |
+
|
58 |
+
$this->cacheDir = \WPStaging\WPStaging::getContentDir();
|
59 |
+
}
|
60 |
+
|
61 |
+
// Set cache extension
|
62 |
+
if( !empty( $cacheExtension ) ) {
|
63 |
+
$this->cacheExtension = $cacheExtension;
|
64 |
+
}
|
65 |
+
|
66 |
+
// If cache directory doesn't exists, create it
|
67 |
+
if( !is_dir( $this->cacheDir ) && !@mkdir( $this->cacheDir, 0775, true ) ) {
|
68 |
+
throw new \Exception( "Failed to create cache directory " . $this->cacheDir . '! Make sure folder permission is 755 and owner is correct. Should be www-data or similar.' );
|
69 |
+
}
|
70 |
+
}
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Get cache
|
74 |
+
* @param string $cacheFileName
|
75 |
+
* @param mixed $defaultValue
|
76 |
+
* @param null|int $lifetime
|
77 |
+
* @return mixed|null
|
78 |
+
*/
|
79 |
+
public function get( $cacheFileName, $defaultValue = null, $lifetime = null ) {
|
80 |
+
// Check if file is valid
|
81 |
+
if( false === ($cacheFile = $this->isValid( $cacheFileName, true, $lifetime )) ) {
|
82 |
+
return $defaultValue;
|
83 |
+
}
|
84 |
+
|
85 |
+
return @unserialize( file_get_contents( $cacheFile ) );
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Saves value to given cache file
|
90 |
+
* @param string $cacheFileName
|
91 |
+
* @param mixed $value
|
92 |
+
* @return bool
|
93 |
+
* @throws \Exception
|
94 |
+
*/
|
95 |
+
public function save( $cacheFileName, $value ) {
|
96 |
+
$cacheFile = $this->cacheDir . $cacheFileName . '.' . $this->cacheExtension;
|
97 |
+
|
98 |
+
// Attempt to delete cache file if it exists
|
99 |
+
if( is_file( $cacheFile ) && !@unlink( $cacheFile ) ) {
|
100 |
+
$this->returnException( "Can't delete existing cache file" );
|
101 |
+
throw new \Exception( "Can't delete existing cache file" );
|
102 |
+
}
|
103 |
+
|
104 |
+
try {
|
105 |
+
// Save it to file
|
106 |
+
if( !file_put_contents( $cacheFile, @serialize( $value ) ) ) {
|
107 |
+
$this->returnException( " Can't save data to: " . $cacheFile . " Disk quota exceeded or not enough free disk space left" );
|
108 |
+
return false;
|
109 |
+
}
|
110 |
+
} catch ( Exception $e ) {
|
111 |
+
$this->returnException( " Can't save data to: " . $cacheFile . " Error: " . $e );
|
112 |
+
return false;
|
113 |
+
}
|
114 |
+
return true;
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Checks if file is valid or not
|
119 |
+
* @param $cacheFileName
|
120 |
+
* @param bool $deleteFileIfInvalid
|
121 |
+
* @param null|int $lifetime
|
122 |
+
* @return string|bool
|
123 |
+
* @throws \Exception
|
124 |
+
*/
|
125 |
+
public function isValid( $cacheFileName, $deleteFileIfInvalid = false, $lifetime = null ) {
|
126 |
+
// Lifetime
|
127 |
+
$lifetime = ( int ) $lifetime;
|
128 |
+
if( -1 > $lifetime || 0 == $lifetime ) {
|
129 |
+
$lifetime = $this->lifetime;
|
130 |
+
}
|
131 |
+
|
132 |
+
// Get full path of the given cache file
|
133 |
+
$cacheFile = $this->cacheDir . $cacheFileName . '.' . $this->cacheExtension;
|
134 |
+
|
135 |
+
// File doesn't exist
|
136 |
+
if( !is_file( $cacheFile ) ) {
|
137 |
+
return false;
|
138 |
+
}
|
139 |
+
|
140 |
+
// As long as file exists, don't check lifetime
|
141 |
+
if( -1 == $lifetime ) {
|
142 |
+
return $cacheFile;
|
143 |
+
}
|
144 |
+
|
145 |
+
// Time is up, file is invalid
|
146 |
+
if( time() - filemtime( $cacheFile ) >= $lifetime ) {
|
147 |
+
|
148 |
+
// Attempt to delete the file
|
149 |
+
if( $deleteFileIfInvalid === true && !@unlink( $cacheFile ) ) {
|
150 |
+
throw new \Exception( "Attempting to delete invalid cache file has failed!" );
|
151 |
+
}
|
152 |
+
|
153 |
+
// No need to delete the file, return
|
154 |
+
return false;
|
155 |
+
}
|
156 |
+
|
157 |
+
return $cacheFile;
|
158 |
+
}
|
159 |
+
|
160 |
+
/**
|
161 |
+
* Delete a cache file
|
162 |
+
* @param string $cacheFileName
|
163 |
+
* @return bool
|
164 |
+
* @throws \Exception
|
165 |
+
*/
|
166 |
+
public function delete( $cacheFileName ) {
|
167 |
+
if( false !== ($cacheFile = $this->isValid( $cacheFileName, true )) && false === @unlink( $cacheFile ) ) {
|
168 |
+
throw new \Exception( "Couldn't delete cache: {$cacheFileName}. Full Path: {$cacheFile}" );
|
169 |
+
}
|
170 |
+
|
171 |
+
return true;
|
172 |
+
}
|
173 |
+
|
174 |
+
/**
|
175 |
+
* @return string
|
176 |
+
*/
|
177 |
+
public function getCacheDir() {
|
178 |
+
return $this->cacheDir;
|
179 |
+
}
|
180 |
+
|
181 |
+
/**
|
182 |
+
* @return string
|
183 |
+
*/
|
184 |
+
public function getCacheExtension() {
|
185 |
+
return $this->cacheExtension;
|
186 |
+
}
|
187 |
+
|
188 |
+
/**
|
189 |
+
* Throw a errror message via json and stop further execution
|
190 |
+
* @param string $message
|
191 |
+
*/
|
192 |
+
protected function returnException( $message = '' ) {
|
193 |
+
wp_die( json_encode( array(
|
194 |
+
'job' => isset( $this->options->currentJob ) ? $this->options->currentJob : '',
|
195 |
+
'status' => false,
|
196 |
+
'message' => $message,
|
197 |
+
'error' => true
|
198 |
+
) ) );
|
199 |
+
}
|
200 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
201 |
}
|
|
apps/Core/Utils/Multisite.php
CHANGED
@@ -12,15 +12,48 @@ if( !defined( "WPINC" ) ) {
|
|
12 |
class Multisite {
|
13 |
|
14 |
/**
|
15 |
-
*
|
16 |
-
* @
|
17 |
*/
|
18 |
-
|
|
|
|
|
19 |
$helper = new Helper();
|
|
|
|
|
20 |
|
21 |
-
|
22 |
-
|
|
|
|
|
|
|
|
|
23 |
return $result['scheme'] . "://" . $result['host'];
|
24 |
}
|
25 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
}
|
12 |
class Multisite {
|
13 |
|
14 |
/**
|
15 |
+
*
|
16 |
+
* @var object
|
17 |
*/
|
18 |
+
private $url;
|
19 |
+
|
20 |
+
public function __construct() {
|
21 |
$helper = new Helper();
|
22 |
+
$this->url = $helper->get_home_url();
|
23 |
+
}
|
24 |
|
25 |
+
/**
|
26 |
+
* Get multisite main site domain e.g. https://blog.domain.com or https://domain.com
|
27 |
+
* @return string
|
28 |
+
*/
|
29 |
+
public function getHomeDomain() {
|
30 |
+
$result = parse_url( $this->url );
|
31 |
return $result['scheme'] . "://" . $result['host'];
|
32 |
}
|
33 |
|
34 |
+
/**
|
35 |
+
* Return domain without scheme e.g. blog.domain.com or domain.com
|
36 |
+
* @param string $str
|
37 |
+
* @return string
|
38 |
+
*/
|
39 |
+
public function getHomeDomainWithoutScheme() {
|
40 |
+
return preg_replace( '#^https?://#', '', rtrim( $this->getHomeDomain(), '/' ) );
|
41 |
+
}
|
42 |
+
/**
|
43 |
+
* Get home url e.g. blog.domain.com
|
44 |
+
* @return type
|
45 |
+
*/
|
46 |
+
public function getHomeUrl() {
|
47 |
+
return $this->url;
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Return url without scheme e.g. blog.domain.com/site1 or domain.com/site1
|
52 |
+
* @param string $str
|
53 |
+
* @return string
|
54 |
+
*/
|
55 |
+
public function getHomeUrlWithoutScheme() {
|
56 |
+
return preg_replace( '#^https?://#', '', rtrim( $this->url, '/' ) );
|
57 |
+
}
|
58 |
+
|
59 |
}
|
apps/Core/Utils/requirements-check.php
ADDED
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class Wpstg_Requirements_Check {
|
4 |
+
|
5 |
+
private $title = '';
|
6 |
+
private $php = '5.2.4';
|
7 |
+
private $wp = '3.8';
|
8 |
+
private $file;
|
9 |
+
|
10 |
+
public function __construct( $args ) {
|
11 |
+
foreach ( array('title', 'php', 'wp', 'file') as $setting ) {
|
12 |
+
if( isset( $args[$setting] ) ) {
|
13 |
+
$this->$setting = $args[$setting];
|
14 |
+
}
|
15 |
+
}
|
16 |
+
}
|
17 |
+
|
18 |
+
public function passes() {
|
19 |
+
$passes = $this->php_passes() && $this->wp_passes();
|
20 |
+
if( !$passes ) {
|
21 |
+
add_action( 'admin_notices', array($this, 'deactivate') );
|
22 |
+
}
|
23 |
+
return $passes;
|
24 |
+
}
|
25 |
+
|
26 |
+
public function deactivate() {
|
27 |
+
if( isset( $this->file ) ) {
|
28 |
+
deactivate_plugins( plugin_basename( $this->file ) );
|
29 |
+
}
|
30 |
+
}
|
31 |
+
|
32 |
+
private function php_passes() {
|
33 |
+
if( $this->__php_at_least( $this->php ) ) {
|
34 |
+
return true;
|
35 |
+
} else {
|
36 |
+
add_action( 'admin_notices', array($this, 'php_version_notice') );
|
37 |
+
return false;
|
38 |
+
}
|
39 |
+
}
|
40 |
+
|
41 |
+
private static function __php_at_least( $min_version ) {
|
42 |
+
return version_compare( phpversion(), $min_version, '>=' );
|
43 |
+
}
|
44 |
+
|
45 |
+
public function php_version_notice() {
|
46 |
+
echo '<div class="error">';
|
47 |
+
echo "<p>The “" . esc_html( $this->title ) . "” plugin cannot run on PHP versions older than " . $this->php . '. Please contact your host and ask them to upgrade.</p>';
|
48 |
+
echo '</div>';
|
49 |
+
}
|
50 |
+
|
51 |
+
private function wp_passes() {
|
52 |
+
if( $this->__wp_at_least( $this->wp ) ) {
|
53 |
+
return true;
|
54 |
+
} else {
|
55 |
+
add_action( 'admin_notices', array($this, 'wp_version_notice') );
|
56 |
+
return false;
|
57 |
+
}
|
58 |
+
}
|
59 |
+
|
60 |
+
private static function __wp_at_least( $min_version ) {
|
61 |
+
return version_compare( get_bloginfo( 'version' ), $min_version, '>=' );
|
62 |
+
}
|
63 |
+
|
64 |
+
public function wp_version_notice() {
|
65 |
+
echo '<div class="error">';
|
66 |
+
echo "<p>The “" . esc_html( $this->title ) . "” plugin cannot run on WordPress versions older than " . $this->wp . '. Please update WordPress.</p>';
|
67 |
+
echo '</div>';
|
68 |
+
}
|
69 |
+
|
70 |
+
}
|
apps/Core/WPStaging.php
CHANGED
@@ -29,7 +29,7 @@ final class WPStaging {
|
|
29 |
/**
|
30 |
* Plugin version
|
31 |
*/
|
32 |
-
const VERSION = "2.3.
|
33 |
|
34 |
/**
|
35 |
* Plugin name
|
@@ -375,12 +375,12 @@ final class WPStaging {
|
|
375 |
break;
|
376 |
|
377 |
case "low":
|
378 |
-
$cpuLoad =
|
379 |
break;
|
380 |
|
381 |
case "default":
|
382 |
default:
|
383 |
-
$cpuLoad =
|
384 |
}
|
385 |
|
386 |
return $cpuLoad;
|
29 |
/**
|
30 |
* Plugin version
|
31 |
*/
|
32 |
+
const VERSION = "2.3.7";
|
33 |
|
34 |
/**
|
35 |
* Plugin name
|
375 |
break;
|
376 |
|
377 |
case "low":
|
378 |
+
$cpuLoad = 0;
|
379 |
break;
|
380 |
|
381 |
case "default":
|
382 |
default:
|
383 |
+
$cpuLoad = 0;
|
384 |
}
|
385 |
|
386 |
return $cpuLoad;
|
install.php
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WPStaging;
|
4 |
+
|
5 |
+
use WPStaging\WPStaging;
|
6 |
+
use WPStaging\Backend\Optimizer\Optimizer;
|
7 |
+
use WPStaging\Cron\Cron;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* Install Function
|
11 |
+
*
|
12 |
+
*/
|
13 |
+
// Exit if accessed directly
|
14 |
+
if( !defined( 'ABSPATH' ) )
|
15 |
+
exit;
|
16 |
+
|
17 |
+
/*
|
18 |
+
* Install Multisite
|
19 |
+
* check first if multisite is enabled
|
20 |
+
* @since 2.1.1
|
21 |
+
*
|
22 |
+
*/
|
23 |
+
|
24 |
+
|
25 |
+
class Install {
|
26 |
+
|
27 |
+
public function __construct() {
|
28 |
+
register_activation_hook( __DIR__ . DIRECTORY_SEPARATOR . WPSTG_PLUGIN_SLUG . '.php', array($this, 'activation') );
|
29 |
+
}
|
30 |
+
|
31 |
+
public static function activation() {
|
32 |
+
// Register cron job.
|
33 |
+
$cron = new \WPStaging\Cron\Cron;
|
34 |
+
$cron->schedule_event();
|
35 |
+
|
36 |
+
// Install Optimizer
|
37 |
+
$optimizer = new Optimizer();
|
38 |
+
$optimizer->installOptimizer();
|
39 |
+
|
40 |
+
// Add the transient to redirect for class Welcome (not for multisites)
|
41 |
+
set_transient( 'wpstg_activation_redirect', true, 3600 );
|
42 |
+
}
|
43 |
+
|
44 |
+
}
|
45 |
+
|
46 |
+
new Install();
|
languages/wp-staging-it_1.mo
ADDED
Binary file
|
languages/wp-staging-it_1.po
ADDED
@@ -0,0 +1,418 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Translation of Plugins - WP Staging – DB & File Duplicator & Migration - Stable Readme (latest release) in Italian
|
2 |
+
# This file is distributed under the same license as the Plugins - WP Staging – DB & File Duplicator & Migration - Stable Readme (latest release) package.
|
3 |
+
msgid ""
|
4 |
+
msgstr ""
|
5 |
+
"PO-Revision-Date: 2015-12-01 15:35:13+0000\n"
|
6 |
+
"MIME-Version: 1.0\n"
|
7 |
+
"Content-Type: text/plain; charset=UTF-8\n"
|
8 |
+
"Content-Transfer-Encoding: 8bit\n"
|
9 |
+
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
10 |
+
"X-Generator: GlotPress/2.4.0-alpha\n"
|
11 |
+
"Language: it\n"
|
12 |
+
"Project-Id-Version: Plugins - WP Staging – DB & File Duplicator & Migration - Stable Readme (latest release)\n"
|
13 |
+
|
14 |
+
#. Short description.
|
15 |
+
msgid "A duplicator plugin! Clone, duplicate and migrate live sites to independent staging and development sites that are available only to administrators."
|
16 |
+
msgstr ""
|
17 |
+
|
18 |
+
#. Plugin name.
|
19 |
+
msgid "WP Staging - DB & File Duplicator & Migration"
|
20 |
+
msgstr ""
|
21 |
+
|
22 |
+
#. Found in changelog list item.
|
23 |
+
msgid "Fix: Missing http(s) scheme after cloning multisites results in not working clones"
|
24 |
+
msgstr ""
|
25 |
+
|
26 |
+
#. Found in changelog list item.
|
27 |
+
msgid "New: Support for Windows Azure cloud servers"
|
28 |
+
msgstr ""
|
29 |
+
|
30 |
+
#. Found in changelog list item.
|
31 |
+
msgid "Fix: Do not search & replace mail addresses"
|
32 |
+
msgstr ""
|
33 |
+
|
34 |
+
#. Found in changelog list item.
|
35 |
+
msgid "Fix: Remove term 'Error' from login page"
|
36 |
+
msgstr ""
|
37 |
+
|
38 |
+
#. Found in changelog list item.
|
39 |
+
msgid "New: Login options not needed any more - removed"
|
40 |
+
msgstr ""
|
41 |
+
|
42 |
+
#. Found in changelog list item.
|
43 |
+
msgid "New: Detect if wp-config.php has been moved one folder level up"
|
44 |
+
msgstr ""
|
45 |
+
|
46 |
+
#. Found in changelog list item.
|
47 |
+
msgid "New: Better error reporting"
|
48 |
+
msgstr ""
|
49 |
+
|
50 |
+
#. Found in changelog list item.
|
51 |
+
msgid "New: Compatible up to WordPress 4.9.8"
|
52 |
+
msgstr ""
|
53 |
+
|
54 |
+
#. Found in changelog list item.
|
55 |
+
msgid "New: Setting to specify the maximum allowed file size to copy"
|
56 |
+
msgstr ""
|
57 |
+
|
58 |
+
#. Found in changelog list item.
|
59 |
+
msgid "Fix: Search & replace path not correct if scheme http/https is not identical in wp-config and db wp_options"
|
60 |
+
msgstr ""
|
61 |
+
|
62 |
+
#. Found in changelog list item.
|
63 |
+
msgid "Fix: Creating a new clone resets the custom wp staging user settings. E.g. ignores authentication setting"
|
64 |
+
msgstr ""
|
65 |
+
|
66 |
+
#. Found in changelog list item.
|
67 |
+
msgid "Tweak: Remove certain debugging notices from the default log window"
|
68 |
+
msgstr ""
|
69 |
+
|
70 |
+
#. Found in changelog list item.
|
71 |
+
msgid "Tweaks: remove term \"error\" from several log entries"
|
72 |
+
msgstr ""
|
73 |
+
|
74 |
+
#. Found in changelog list item.
|
75 |
+
msgid "Fix: Search & Replace not working if serialized object contains __PHP_Incomplete_Class_Name"
|
76 |
+
msgstr ""
|
77 |
+
|
78 |
+
#. Found in changelog list item.
|
79 |
+
msgid "Fix: Skip search & replace for objects where key is null"
|
80 |
+
msgstr ""
|
81 |
+
|
82 |
+
#. Found in changelog list item.
|
83 |
+
msgid "Fix: Parameter must be an array or an object that implements Callable"
|
84 |
+
msgstr ""
|
85 |
+
|
86 |
+
#. Found in changelog list item.
|
87 |
+
msgid "Fix: wp-config.php not copied when previous clone updating process has been failed"
|
88 |
+
msgstr ""
|
89 |
+
|
90 |
+
#. Found in changelog list item.
|
91 |
+
msgid "Fix: Undefined object $this->tables"
|
92 |
+
msgstr ""
|
93 |
+
|
94 |
+
#. Found in changelog list item.
|
95 |
+
msgid "Fix: Can not open upload folder in file selection menu"
|
96 |
+
msgstr ""
|
97 |
+
|
98 |
+
#. Found in changelog list item.
|
99 |
+
msgid "Fix: Progress bar not shown as intented for clone updating process"
|
100 |
+
msgstr ""
|
101 |
+
|
102 |
+
#. Found in changelog list item.
|
103 |
+
msgid "Fix: If cloning update process is interupted it may happen that staging site is not available any longer. (Updating the clone does not copy index.php to staging site again)"
|
104 |
+
msgstr ""
|
105 |
+
|
106 |
+
#. Found in changelog list item.
|
107 |
+
msgid "Fix: Progress bar for step 'database' is not filling up to 100%"
|
108 |
+
msgstr ""
|
109 |
+
|
110 |
+
#. Found in changelog list item.
|
111 |
+
msgid "New: Use the new progress bar for clone updating process"
|
112 |
+
msgstr ""
|
113 |
+
|
114 |
+
#. Found in changelog list item.
|
115 |
+
msgid "New: Add multisite informations in system info log"
|
116 |
+
msgstr ""
|
117 |
+
|
118 |
+
#. Found in changelog list item.
|
119 |
+
msgid "New: Option to allow adjustment of the allowed maximum size of files that are going to be copied while cloning."
|
120 |
+
msgstr ""
|
121 |
+
|
122 |
+
#. Found in changelog list item.
|
123 |
+
msgid "Security: Do not allow to create a new staging site into a subfolder which already exists"
|
124 |
+
msgstr ""
|
125 |
+
|
126 |
+
#. Found in changelog list item.
|
127 |
+
msgid "Fix: Missing trailingslash results to wrong absolute paths in database after Search & Replace operation "
|
128 |
+
msgstr ""
|
129 |
+
|
130 |
+
#. Found in changelog list item.
|
131 |
+
msgid "New: Compatible to WordPress 4.9.6"
|
132 |
+
msgstr ""
|
133 |
+
|
134 |
+
#. Found in changelog list item.
|
135 |
+
msgid "New: Add new setting which allow to specify the search & replace processing query limit"
|
136 |
+
msgstr ""
|
137 |
+
|
138 |
+
#. Found in changelog list item.
|
139 |
+
msgid "New: Supports search & replace for revslider image slider and several visual editors which are using non default serialized data"
|
140 |
+
msgstr ""
|
141 |
+
|
142 |
+
#. Found in changelog list item.
|
143 |
+
msgid "New: Add filter 'wpstg_fiter_search_replace_rows' to exclude certain tables from search & replace"
|
144 |
+
msgstr ""
|
145 |
+
|
146 |
+
#. Found in changelog list item.
|
147 |
+
msgid "New: Add datetime timestamp internally to clone. (Used in WP Staging pro)"
|
148 |
+
msgstr ""
|
149 |
+
|
150 |
+
#. Found in changelog list item.
|
151 |
+
msgid "New: Support for custom upload folder. For instance, if upload folder has been renamed and removed outsite wp-content folder"
|
152 |
+
msgstr ""
|
153 |
+
|
154 |
+
#. Found in changelog list item.
|
155 |
+
msgid "New: Exclude tables for plugin wp_mail_smtp"
|
156 |
+
msgstr ""
|
157 |
+
|
158 |
+
#. Found in changelog list item.
|
159 |
+
msgid "New: Add filter 'wpstg_filter_options_replace' to exclude certain tables from updating while cloning"
|
160 |
+
msgstr ""
|
161 |
+
|
162 |
+
#. Found in changelog list item.
|
163 |
+
msgid "Fix: WP_SITEURL & WP_HOME not replaced if constant contains php generated string"
|
164 |
+
msgstr ""
|
165 |
+
|
166 |
+
#. Found in changelog list item.
|
167 |
+
msgid "Fix: Serialize replace is not working properly for serialized strings"
|
168 |
+
msgstr ""
|
169 |
+
|
170 |
+
#. Found in faq list item.
|
171 |
+
msgid ""
|
172 |
+
"I can not login to the staging site\n"
|
173 |
+
"If you are using a security plugin like All In One WP Security & Firewall you need to install latest version of WP Staging. \n"
|
174 |
+
"Go to WP Staging > Settings and add the slug to the custom login page which you set up in All In One WP Security & Firewall plugin."
|
175 |
+
msgstr ""
|
176 |
+
|
177 |
+
#. Found in installation list item, faq list item.
|
178 |
+
msgid "Upload and install it via the WordPress plugin backend wp-admin > plugins > add new > uploads"
|
179 |
+
msgstr ""
|
180 |
+
|
181 |
+
#. Found in installation list item, faq list item.
|
182 |
+
msgid "Download the file \"wp-staging.zip\":"
|
183 |
+
msgstr ""
|
184 |
+
|
185 |
+
#. Found in description paragraph.
|
186 |
+
msgid ""
|
187 |
+
"Permalinks are disabled on the staging site because the staging site is cloned into a subfolder and permalinks are not working on all systems\n"
|
188 |
+
"without doing changes to the .htaccess (Apache server) or nginx.conf (Nginx Server).\n"
|
189 |
+
"<a href=\"https://wp-staging.com/docs/activate-permalinks-staging-site/\" title=\"activate permalinks on staging site\">Read here</a> how to activate permalinks on the staging site."
|
190 |
+
msgstr ""
|
191 |
+
|
192 |
+
#. Found in description list item.
|
193 |
+
msgid "New: Compatible to All In One WP Security & Firewall"
|
194 |
+
msgstr ""
|
195 |
+
|
196 |
+
#. Found in description paragraph.
|
197 |
+
msgid "Note: WordPress 5.0 will be shipped with a new visual editor called Gutenberg. Use WP Staging to check if Gutenberg editor is working as intended on your website and that all used plugins are compatible with that new editor."
|
198 |
+
msgstr ""
|
199 |
+
|
200 |
+
#. Found in changelog paragraph.
|
201 |
+
msgid "Complete changelog: <a href=\"https://wp-staging.com/changelog.txt\">https://wp-staging.com/changelog.txt</a>"
|
202 |
+
msgstr ""
|
203 |
+
|
204 |
+
#. Found in description paragraph.
|
205 |
+
msgid "https://wp-staging.com"
|
206 |
+
msgstr ""
|
207 |
+
|
208 |
+
#. Found in description paragraph.
|
209 |
+
msgid ""
|
210 |
+
"<strong>This cloning and staging plugin is well tested and work in progress. <br /><br />\n"
|
211 |
+
"If you find any issue, please open a <a href=\"https://wp-staging.com/support/\" title=\"support ticket\">support ticket</a>.\n"
|
212 |
+
"</strong>\n"
|
213 |
+
"<br /><br />\n"
|
214 |
+
"<strong>Note: </strong> For pushing & migrating plugins and theme files to live site, check out the pro version <a href=\"https://wp-staging.com/\" title=\"WP Staging Pro\">https://wp-staging.com/</a>\n"
|
215 |
+
"<br /><br />"
|
216 |
+
msgstr ""
|
217 |
+
|
218 |
+
#. Found in faq header.
|
219 |
+
msgid "Installation Instructions"
|
220 |
+
msgstr ""
|
221 |
+
|
222 |
+
#. Found in description list item.
|
223 |
+
msgid ""
|
224 |
+
"WordPress duplicating process on windows server (not tested but will probably work) \n"
|
225 |
+
"Edit: Duplication on windows server seems to be working well: <a href=\"https://wordpress.org/support/topic/wont-copy-files?replies=5\" title=\"Read more\">Read more</a> "
|
226 |
+
msgstr ""
|
227 |
+
|
228 |
+
#. Found in description list item.
|
229 |
+
msgid ""
|
230 |
+
"<strong>Safe: </strong> Access to staging site is granted for administrators only.\n"
|
231 |
+
"<br /><br />\n"
|
232 |
+
"<strong>More safe:</strong> \n"
|
233 |
+
"<br />"
|
234 |
+
msgstr ""
|
235 |
+
|
236 |
+
#. Found in description paragraph.
|
237 |
+
msgid "[youtube https://www.youtube.com/watch?v=Ye3fC6cdB3A]"
|
238 |
+
msgstr ""
|
239 |
+
|
240 |
+
#. Found in description header.
|
241 |
+
msgid "Official Site"
|
242 |
+
msgstr ""
|
243 |
+
|
244 |
+
#. Found in installation list item, faq list item.
|
245 |
+
msgid "Activate the plugin through the 'Plugins' menu in WordPress."
|
246 |
+
msgstr "Attivare il plugin tramite il menu 'Plugin' di WordPress"
|
247 |
+
|
248 |
+
#. Found in description paragraph.
|
249 |
+
msgid ""
|
250 |
+
"Install it via the admin dashboard and to 'Plugins', click 'Add New' and search the plugins for 'Staging'. Install the plugin with 'Install Now'.\n"
|
251 |
+
"After installation goto the settings page 'Staging' and do your adjustments there."
|
252 |
+
msgstr ""
|
253 |
+
|
254 |
+
#. Found in description paragraph.
|
255 |
+
msgid ""
|
256 |
+
"This plugin has been done in hundreds of hours to work on even the smallest shared webhosting package but i am limited in testing this only on a handful of different server so i need your help:\n"
|
257 |
+
"Please open a <a href=\"https://wordpress.org/support/plugin/wp-staging/\" title=\"support request\">support request</a> and describe your problem exactely. In wp-content/wp-staging/logs you find extended logfiles. Have a look at them and let me know the error-thrown lines."
|
258 |
+
msgstr ""
|
259 |
+
|
260 |
+
#. Found in description paragraph.
|
261 |
+
msgid ""
|
262 |
+
"So, if you have created a local or webhosted development site and you need to migrate this site the first time to your production domain than you are doing nothing wrong with using\n"
|
263 |
+
"the Duplicator plugin! If you need all you latest production data like posts, updated plugins, theme data and styles in a testing environment than i recommend to use WP Staging instead!"
|
264 |
+
msgstr ""
|
265 |
+
|
266 |
+
#. Found in description paragraph.
|
267 |
+
msgid ""
|
268 |
+
"At first, i love the <a href=\"https://wordpress.org/plugins/duplicator/\" title=\"Duplicator plugin\">Duplicator plugin</a>. Duplicator is a great tool for migrating from development site to production one or from production site to development one. \n"
|
269 |
+
"The downside is that Duplicator needs adjustments, manually interventions and prerequirements for this. Duplicator also needs some skills to be able to create a development / staging site, where WP Staging does not need more than a click from you.\n"
|
270 |
+
"However, Duplicator is best placed to be a tool for first-time creation of your production site. This is something where it is very handy and powerful."
|
271 |
+
msgstr ""
|
272 |
+
|
273 |
+
#. Found in description paragraph.
|
274 |
+
msgid ""
|
275 |
+
"If you want to migrate your local database to a already existing production site you can use a tool like WP Migrate DB.\n"
|
276 |
+
"WP Staging is only for creating a staging site with latest data from your production site. So it goes the opposite way of WP Migrate DB.\n"
|
277 |
+
"Both tools are excellent cooperating eachother."
|
278 |
+
msgstr ""
|
279 |
+
|
280 |
+
#. Found in description paragraph.
|
281 |
+
msgid "This is were WP Staging steps in... Site cloning and staging site creation simplified!"
|
282 |
+
msgstr ""
|
283 |
+
|
284 |
+
#. Found in description paragraph.
|
285 |
+
msgid ""
|
286 |
+
"Nope! If your local hardware and software environment is not a 100% exact clone of your production server there is NO guarantee that every aspect \n"
|
287 |
+
"of your local copy is working on your live website exactely as you would expect it. \n"
|
288 |
+
"There are some obvious things like differences in the config of php and the server you are running but even such non obvious settings like the amount of ram or the \n"
|
289 |
+
"the cpu performance can lead to unexpected results on your production website. \n"
|
290 |
+
"There are dozens of other possible cause of failure which can not be handled well when you are testing your changes on a local staging platform."
|
291 |
+
msgstr ""
|
292 |
+
|
293 |
+
#. Found in description paragraph.
|
294 |
+
msgid "<strong> I think its time to change this, so i created \"WP Staging\" for WordPress migration of staging sites</strong>"
|
295 |
+
msgstr ""
|
296 |
+
|
297 |
+
#. Found in description paragraph.
|
298 |
+
msgid ""
|
299 |
+
"Some people are also afraid of installing plugins updates because they follow the rule \"never touch a running system\" with having in mind that untested updates are increasing the risk of breaking their site.\n"
|
300 |
+
"I totally understand this and i am guilty as well here, but unfortunately this leads to one of the main reasons why WordPress installations are often outdated, not updated at all and unsecure due to this non-update behavior."
|
301 |
+
msgstr ""
|
302 |
+
|
303 |
+
#. Found in description paragraph.
|
304 |
+
msgid ""
|
305 |
+
"Testing a plugin update before installing it in live environment isn´t done very often by most user because existing staging solutions are too complex and need a lot of time to create a \n"
|
306 |
+
"up-to-date copy of your website."
|
307 |
+
msgstr ""
|
308 |
+
|
309 |
+
#. Found in description paragraph.
|
310 |
+
msgid ""
|
311 |
+
"Plugin updates and theme customizations should be tested on a staging platform first. Its recommended to have the staging platform on the same server where the production website is located.\n"
|
312 |
+
"When you run a plugin update or plan to install a new one, it is a necessary task to check first the modifications on a clone of your production website.\n"
|
313 |
+
"This makes sure that any modifications is working on your website without throwing unexpected errors or preventing your site from loading. (Better known as the wordpress blank page error)"
|
314 |
+
msgstr ""
|
315 |
+
|
316 |
+
#. Found in description paragraph.
|
317 |
+
msgid "<strong>Change your workflow of updating themes and plugins data:</strong>"
|
318 |
+
msgstr ""
|
319 |
+
|
320 |
+
#. Found in description paragraph.
|
321 |
+
msgid "WP Staging helps you to prevent your website from being broken or unavailable because of installing untested plugin updates!"
|
322 |
+
msgstr ""
|
323 |
+
|
324 |
+
#. Found in description paragraph.
|
325 |
+
msgid "<em>* Time of creation depends on size of your database and file size</em>"
|
326 |
+
msgstr ""
|
327 |
+
|
328 |
+
#. Found in description list item.
|
329 |
+
msgid "Everything running as expected? You are on the save side for migration of all these modifications to your production site!"
|
330 |
+
msgstr ""
|
331 |
+
|
332 |
+
#. Found in description list item.
|
333 |
+
msgid "Test everything on your staging site first"
|
334 |
+
msgstr ""
|
335 |
+
|
336 |
+
#. Found in description list item.
|
337 |
+
msgid "Customize theme, configuration and plugins or install new plugins"
|
338 |
+
msgstr ""
|
339 |
+
|
340 |
+
#. Found in description list item.
|
341 |
+
msgid "Use WP Staging for migration of a production website to a clone site for staging purposes"
|
342 |
+
msgstr ""
|
343 |
+
|
344 |
+
#. Found in description list item.
|
345 |
+
msgid "Wordpress migration of wordpress multisites (not tested)"
|
346 |
+
msgstr ""
|
347 |
+
|
348 |
+
#. Found in description list item.
|
349 |
+
msgid "Extensive logging if duplication or migration process should fail."
|
350 |
+
msgstr ""
|
351 |
+
|
352 |
+
#. Found in description list item.
|
353 |
+
msgid "Admin bar reflects that you are working on a staging site"
|
354 |
+
msgstr ""
|
355 |
+
|
356 |
+
#. Found in description list item.
|
357 |
+
msgid "<strong>Fast: </strong> Migration process lasts only a few seconds or minutes, depending on the site's size and server I/O power"
|
358 |
+
msgstr ""
|
359 |
+
|
360 |
+
#. Found in description list item.
|
361 |
+
msgid "<strong>Easy: </strong> Staging migration applicable for everyone. No configuration needed!"
|
362 |
+
msgstr ""
|
363 |
+
|
364 |
+
#. Found in description header.
|
365 |
+
msgid "How to install and setup?"
|
366 |
+
msgstr ""
|
367 |
+
|
368 |
+
#. Found in description header.
|
369 |
+
msgid "Important"
|
370 |
+
msgstr "Wichtig"
|
371 |
+
|
372 |
+
#. Found in description header.
|
373 |
+
msgid "I need you feedback"
|
374 |
+
msgstr ""
|
375 |
+
|
376 |
+
#. Found in description header.
|
377 |
+
msgid "What are the benefits compared to a plugin like Duplicator?"
|
378 |
+
msgstr ""
|
379 |
+
|
380 |
+
#. Found in description header.
|
381 |
+
msgid "I just want to migrate the database from one installation to another"
|
382 |
+
msgstr ""
|
383 |
+
|
384 |
+
#. Found in description header.
|
385 |
+
msgid " Can´t i just use my local wordpress development copy for testing like xampp / lampp? "
|
386 |
+
msgstr ""
|
387 |
+
|
388 |
+
#. Found in description header.
|
389 |
+
msgid " Why should i use a staging website? "
|
390 |
+
msgstr ""
|
391 |
+
|
392 |
+
#. Found in description header.
|
393 |
+
msgid "What does not work or is not tested when running wordpress migration?"
|
394 |
+
msgstr ""
|
395 |
+
|
396 |
+
#. Found in description header.
|
397 |
+
msgid "Main Features"
|
398 |
+
msgstr ""
|
399 |
+
|
400 |
+
#. Found in description header.
|
401 |
+
msgid " WP Staging for WordPress Migration "
|
402 |
+
msgstr ""
|
403 |
+
|
404 |
+
#. Screenshot description.
|
405 |
+
msgid "Finish!"
|
406 |
+
msgstr ""
|
407 |
+
|
408 |
+
#. Screenshot description.
|
409 |
+
msgid "Step 3. Wordpress Staging site creation in progress"
|
410 |
+
msgstr ""
|
411 |
+
|
412 |
+
#. Screenshot description.
|
413 |
+
msgid "Step 2. Scanning your website for files and database tables"
|
414 |
+
msgstr ""
|
415 |
+
|
416 |
+
#. Screenshot description.
|
417 |
+
msgid "Step 1. Create new WordPress staging site"
|
418 |
+
msgstr ""
|
readme.txt
CHANGED
@@ -9,7 +9,7 @@ License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
|
9 |
Tags: staging, duplication, cloning, clone, migration, sandbox, test site, testing, backup, post, admin, administration, duplicate posts
|
10 |
Requires at least: 3.6+
|
11 |
Tested up to: 4.9
|
12 |
-
Stable tag: 2.3.
|
13 |
Requires PHP: 5.3
|
14 |
|
15 |
A duplicator plugin! Clone, duplicate and migrate live sites to independent staging and development sites that are available only to administrators.
|
@@ -146,6 +146,18 @@ https://wp-staging.com
|
|
146 |
|
147 |
== Changelog ==
|
148 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
149 |
= 2.3.6 =
|
150 |
* Fix: Add version number to css and js files to prevent caching issues
|
151 |
* Fix: Wrong text domain in a few language strings
|
@@ -182,6 +194,6 @@ Complete changelog: [https://wp-staging.com/wp-staging-changelog](https://wp-sta
|
|
182 |
|
183 |
== Upgrade Notice ==
|
184 |
|
185 |
-
= 2.3.
|
186 |
* New: Compatible to WordPress 4.9.8. Important fixes!
|
187 |
|
9 |
Tags: staging, duplication, cloning, clone, migration, sandbox, test site, testing, backup, post, admin, administration, duplicate posts
|
10 |
Requires at least: 3.6+
|
11 |
Tested up to: 4.9
|
12 |
+
Stable tag: 2.3.7
|
13 |
Requires PHP: 5.3
|
14 |
|
15 |
A duplicator plugin! Clone, duplicate and migrate live sites to independent staging and development sites that are available only to administrators.
|
146 |
|
147 |
== Changelog ==
|
148 |
|
149 |
+
= 2.3.7 =
|
150 |
+
* New: Increase cloning performance
|
151 |
+
* New: Show admin notice if php version and wordpress version do not meet requirements.
|
152 |
+
* New: Show error if there is not enough free diskspace
|
153 |
+
* New: Add resume function in case the cloning process interrupts
|
154 |
+
* New: Add italian translation
|
155 |
+
* New: Better looking admin notices
|
156 |
+
* Fix: Different scheme of siteurl and home leads to non available staging site. Show admin notice to ask user to fix that first before creating a staging site
|
157 |
+
* Fix: WP Staging welcome screen shown when any plugin is activated
|
158 |
+
* Fix: Lower default settings to 10000, cpu load low. File copy limit to 50
|
159 |
+
|
160 |
+
|
161 |
= 2.3.6 =
|
162 |
* Fix: Add version number to css and js files to prevent caching issues
|
163 |
* Fix: Wrong text domain in a few language strings
|
194 |
|
195 |
== Upgrade Notice ==
|
196 |
|
197 |
+
= 2.3.7 =
|
198 |
* New: Compatible to WordPress 4.9.8. Important fixes!
|
199 |
|
wp-staging.php
CHANGED
@@ -7,7 +7,7 @@
|
|
7 |
* Author: WP-Staging
|
8 |
* Author URI: https://wp-staging.com
|
9 |
* Contributors: ReneHermi, ilgityildirim
|
10 |
-
* Version: 2.3.
|
11 |
* Text Domain: wp-staging
|
12 |
* Domain Path: /languages/
|
13 |
|
@@ -29,63 +29,92 @@
|
|
29 |
* @category Core
|
30 |
* @author René Hermenau, Ilgıt Yıldırım
|
31 |
*/
|
32 |
-
|
33 |
// No Direct Access
|
34 |
-
if
|
35 |
-
|
36 |
-
|
|
|
|
|
|
|
|
|
37 |
}
|
38 |
|
39 |
-
//
|
40 |
if( !defined( 'WPSTG_PLUGIN_DIR' ) ) {
|
41 |
-
define( 'WPSTG_PLUGIN_DIR', plugin_dir_path(
|
42 |
}
|
43 |
-
|
|
|
44 |
if( !defined( 'WPSTG_PLUGIN_URL' ) ) {
|
45 |
-
define( 'WPSTG_PLUGIN_URL', plugin_dir_url(
|
46 |
}
|
47 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
|
49 |
/**
|
50 |
* Fix nonce check
|
51 |
-
* https://core.trac.wordpress.org/ticket/41617#ticket
|
52 |
* @param int $seconds
|
53 |
* @return int
|
54 |
*/
|
55 |
-
function wpstg_overwrite_nonce($seconds){
|
56 |
-
|
57 |
-
|
58 |
-
|
|
|
59 |
|
60 |
/**
|
61 |
* Path to main WP Staging class
|
62 |
* Make sure to not redeclare class in case free version has been installed previosly
|
63 |
*/
|
64 |
-
if
|
65 |
-
require_once plugin_dir_path(__FILE__) . "apps/Core/WPStaging.php";
|
66 |
}
|
67 |
|
68 |
-
$
|
69 |
|
70 |
-
|
71 |
-
* Load a few important WP globals into WPStaging class to make them available via dependancy injection
|
72 |
-
*/
|
73 |
|
|
|
|
|
|
|
74 |
// Wordpress DB Object
|
75 |
-
if
|
76 |
-
|
77 |
-
|
78 |
-
}
|
79 |
|
80 |
// WordPress Filter Object
|
81 |
-
if
|
82 |
-
{
|
83 |
-
|
84 |
-
|
85 |
-
|
|
|
|
|
|
|
|
|
|
|
86 |
}
|
87 |
|
88 |
/**
|
89 |
-
*
|
90 |
*/
|
91 |
-
|
|
|
|
7 |
* Author: WP-Staging
|
8 |
* Author URI: https://wp-staging.com
|
9 |
* Contributors: ReneHermi, ilgityildirim
|
10 |
+
* Version: 2.3.7
|
11 |
* Text Domain: wp-staging
|
12 |
* Domain Path: /languages/
|
13 |
|
29 |
* @category Core
|
30 |
* @author René Hermenau, Ilgıt Yıldırım
|
31 |
*/
|
|
|
32 |
// No Direct Access
|
33 |
+
if( !defined( "WPINC" ) ) {
|
34 |
+
die;
|
35 |
+
}
|
36 |
+
|
37 |
+
// Slug
|
38 |
+
if( !defined( 'WPSTG_PLUGIN_SLUG' ) ) {
|
39 |
+
define( 'WPSTG_PLUGIN_SLUG', 'wp-staging' );
|
40 |
}
|
41 |
|
42 |
+
// Folder Path
|
43 |
if( !defined( 'WPSTG_PLUGIN_DIR' ) ) {
|
44 |
+
define( 'WPSTG_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
|
45 |
}
|
46 |
+
|
47 |
+
// Folder URL
|
48 |
if( !defined( 'WPSTG_PLUGIN_URL' ) ) {
|
49 |
+
define( 'WPSTG_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
|
50 |
}
|
51 |
|
52 |
+
// Version
|
53 |
+
if( !defined( 'WPSTGPRO_VERSION' ) ) {
|
54 |
+
define( 'WPSTGPRO_VERSION', '2.3.7' );
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Check if system fullfils all requirements
|
59 |
+
*/
|
60 |
+
if( !class_exists( 'Wpstg_Requirements_Check' ) ) {
|
61 |
+
include( dirname( __FILE__ ) . '/apps/Core/Utils/requirements-check.php' );
|
62 |
+
}
|
63 |
+
$plugin_requirements = new Wpstg_Requirements_Check( array(
|
64 |
+
'title' => 'WP STAGING',
|
65 |
+
'php' => '5.3',
|
66 |
+
'wp' => '3.0',
|
67 |
+
'file' => __FILE__,
|
68 |
+
) );
|
69 |
|
70 |
/**
|
71 |
* Fix nonce check
|
72 |
+
* Bug: https://core.trac.wordpress.org/ticket/41617#ticket
|
73 |
* @param int $seconds
|
74 |
* @return int
|
75 |
*/
|
76 |
+
function wpstg_overwrite_nonce( $seconds ) {
|
77 |
+
return 86400;
|
78 |
+
}
|
79 |
+
|
80 |
+
add_filter( 'nonce_life', 'wpstg_overwrite_nonce', 99999 );
|
81 |
|
82 |
/**
|
83 |
* Path to main WP Staging class
|
84 |
* Make sure to not redeclare class in case free version has been installed previosly
|
85 |
*/
|
86 |
+
if( !class_exists( 'WPStaging\WPStaging' ) ) {
|
87 |
+
require_once plugin_dir_path( __FILE__ ) . "apps/Core/WPStaging.php";
|
88 |
}
|
89 |
|
90 |
+
if( $plugin_requirements->passes() ) {
|
91 |
|
92 |
+
$wpStaging = \WPStaging\WPStaging::getInstance();
|
|
|
|
|
93 |
|
94 |
+
/**
|
95 |
+
* Load a few important WP globals into WPStaging class to make them available via dependancy injection
|
96 |
+
*/
|
97 |
// Wordpress DB Object
|
98 |
+
if( isset( $wpdb ) ) {
|
99 |
+
$wpStaging->set( "wpdb", $wpdb );
|
100 |
+
}
|
|
|
101 |
|
102 |
// WordPress Filter Object
|
103 |
+
if( isset( $wp_filter ) ) {
|
104 |
+
$wpStaging->set( "wp_filter", function() use(&$wp_filter) {
|
105 |
+
return $wp_filter;
|
106 |
+
} );
|
107 |
+
}
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Inititalize WPStaging
|
111 |
+
*/
|
112 |
+
$wpStaging->run();
|
113 |
}
|
114 |
|
115 |
/**
|
116 |
+
* Installation Hooks
|
117 |
*/
|
118 |
+
if( !class_exists( 'WPStaging\Install' ) ) {
|
119 |
+
require_once plugin_dir_path( __FILE__ ) . "/install.php";
|
120 |
+
}
|