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

Version Description

  • New: Compatible to WordPress 5.2
  • New: Allow adding file .wp-staging to root of website to determine if it's a staging or production website
  • New: Add extended data about a staging site in list overview of staging sites
  • New: Show unfinished or interrupted clones and allow deletion of them
  • Tweak: Move admin notices templates to views/notices
  • Fix: Rating notice appears again after using review later button
  • Fix: Can not find staging site when staging site has been created with old version of wp staging
  • Fix: Do not search & replace over incomplete classes in database to prevent warnings
Download this release

Release Info

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

Code changes from version 2.5.5 to 2.5.6

Files changed (27) hide show
  1. apps/Backend/Administrator.php +7 -6
  2. apps/Backend/Modules/Jobs/Cloning.php +64 -11
  3. apps/Backend/Modules/Jobs/Finish.php +3 -1
  4. apps/Backend/Modules/Jobs/Multisite/Finish.php +11 -35
  5. apps/Backend/Modules/Jobs/ProcessLock.php +61 -61
  6. apps/Backend/Modules/Jobs/SearchReplace.php +27 -21
  7. apps/Backend/Modules/Jobs/Updating.php +0 -9
  8. apps/Backend/Modules/SystemInfo.php +1 -1
  9. apps/Backend/Notices/Notices.php +31 -17
  10. apps/Backend/public/js/wpstg-admin-rating.js +7 -7
  11. apps/Backend/views/clone/ajax/single-overview.php +16 -7
  12. apps/Backend/views/{_includes/messages → notices}/beta.php +0 -0
  13. apps/Backend/views/{_includes/messages → notices}/cache-directory-permission-problem.php +0 -0
  14. apps/Backend/views/{_includes/messages → notices}/logs-directory-permission-problem.php +0 -0
  15. apps/Backend/views/{_includes/messages → notices}/poll.php +0 -0
  16. apps/Backend/views/{_includes/messages → notices}/rating.php +0 -0
  17. apps/Backend/views/{_includes/messages → notices}/staging-directory-permission-problem.php +0 -0
  18. apps/Backend/views/{_includes/messages → notices}/transient.php +0 -0
  19. apps/Backend/views/{_includes/messages → notices}/uploads-cache-directory-permission-problem.php +0 -0
  20. apps/Backend/views/{_includes/messages → notices}/vars-directory-permission-problem.php +0 -0
  21. apps/Backend/views/{_includes/messages → notices}/wp-version-compatible-message.php +0 -0
  22. apps/Backend/views/{_includes/messages → notices}/wrong-scheme.php +0 -0
  23. apps/Core/Utils/functions.php +28 -13
  24. apps/Core/WPStaging.php +5 -5
  25. apps/Frontend/Frontend.php +3 -2
  26. readme.txt +18 -4
  27. wp-staging.php +2 -2
apps/Backend/Administrator.php CHANGED
@@ -238,8 +238,8 @@ class Administrator extends InjectionAware {
238
public function getToolsPage() {
239
// Tabs
240
$tabs = new Tabs( array(
241
- "system_info" => __( "System Info", "wp-staging" ),
242
- "import_export" => __( "Import/Export", "wp-staging" )
243
) );
244
245
$this->di->set( "tabs", $tabs );
@@ -636,8 +636,8 @@ class Administrator extends InjectionAware {
636
* @return mixed bool | json
637
*/
638
public function ajaxHideLaterRating() {
639
- if( false !== update_option( 'wpstg_rating', date( 'Y-m-d' ) )
640
- ) {
641
wp_send_json( true );
642
}
643
return wp_send_json( false );
@@ -695,7 +695,7 @@ class Administrator extends InjectionAware {
695
}
696
697
/**
698
- * Ajax Start Pushing. Needs wp quads pro
699
*/
700
public function ajaxPushProcessing() {
701
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
@@ -792,7 +792,8 @@ class Administrator extends InjectionAware {
792
// }
793
$db->select( $database );
794
if( !$db->ready ) {
795
- echo json_encode( array('errors' => "Error: Can't select {$database} [" . print_r( $db->error, true ) . "] Either it does not exist or you don't have privileges to access it. ") );
796
exit;
797
}
798
echo json_encode( array('success' => 'true') );
238
public function getToolsPage() {
239
// Tabs
240
$tabs = new Tabs( array(
241
+ "import_export" => __( "Import/Export", "wp-staging" ),
242
+ "system_info" => __( "System Info", "wp-staging" )
243
) );
244
245
$this->di->set( "tabs", $tabs );
636
* @return mixed bool | json
637
*/
638
public function ajaxHideLaterRating() {
639
+ $date = date('Y-m-d', strtotime(date('Y-m-d'). ' + 7 days'));
640
+ if( false !== update_option( 'wpstg_rating',$date )) {
641
wp_send_json( true );
642
}
643
return wp_send_json( false );
695
}
696
697
/**
698
+ * Ajax Start Pushing. Needs WP Staging Pro
699
*/
700
public function ajaxPushProcessing() {
701
check_ajax_referer( "wpstg_ajax_nonce", "nonce" );
792
// }
793
$db->select( $database );
794
if( !$db->ready ) {
795
+ $error = isset($db->error->errors['db_select_fail']) ? $db->error->errors['db_select_fail'] : "Error: Can't select {database} Either it does not exist or you don't have privileges to access it.";
796
+ echo json_encode( array('errors' => $error ) );
797
exit;
798
}
799
echo json_encode( array('success' => 'true') );
apps/Backend/Modules/Jobs/Cloning.php CHANGED
@@ -49,7 +49,8 @@ class Cloning extends Job {
49
'desktop.ini',
50
'.gitignore',
51
'.log',
52
- 'web.config' // Important: Windows IIS configuartion file. Must not be in the staging site!
53
);
54
$this->options->excludedFilesFullPath = array(
55
'wp-content' . DIRECTORY_SEPARATOR . 'db.php',
@@ -74,7 +75,7 @@ class Cloning extends Job {
74
// Get data and increment it
75
elseif( !empty( $this->options->existingClones ) ) {
76
$this->options->cloneNumber = count( $this->options->existingClones ) + 1;
77
- $this->options->prefix = $this->setStagingPrefix();
78
}
79
80
// Included Tables
@@ -86,7 +87,7 @@ class Cloning extends Job {
86
87
// Excluded Directories
88
if( isset( $_POST["excludedDirectories"] ) && is_array( $_POST["excludedDirectories"] ) ) {
89
- $this->options->excludedDirectories = wpstg_urldecode($_POST["excludedDirectories"]);
90
}
91
92
// Excluded Directories TOTAL
@@ -99,18 +100,18 @@ class Cloning extends Job {
99
\WPStaging\WPStaging::getWPpath() . 'wp-content' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'wp-spamshield',
100
);
101
102
- $this->options->excludedDirectories = array_merge( $excludedDirectories, wpstg_urldecode($this->options->excludedDirectories ));
103
104
array_unshift( $this->options->directoriesToCopy, \WPStaging\WPStaging::getWPpath() );
105
106
// Included Directories
107
if( isset( $_POST["includedDirectories"] ) && is_array( $_POST["includedDirectories"] ) ) {
108
- $this->options->includedDirectories = wpstg_urldecode($_POST["includedDirectories"]);
109
}
110
111
// Extra Directories
112
if( isset( $_POST["extraDirectories"] ) && !empty( $_POST["extraDirectories"] ) ) {
113
- $this->options->extraDirectories = wpstg_urldecode($_POST["extraDirectories"]);
114
}
115
116
// Directories to Copy
@@ -137,11 +138,11 @@ class Cloning extends Job {
137
}
138
$this->options->databasePrefix = '';
139
if( isset( $_POST["databasePrefix"] ) && !empty( $_POST["databasePrefix"] ) ) {
140
- $this->options->databasePrefix = $this->sanitizePrefix( $_POST["databasePrefix"] );
141
}
142
$this->options->cloneDir = '';
143
if( isset( $_POST["cloneDir"] ) && !empty( $_POST["cloneDir"] ) ) {
144
- $this->options->cloneDir = wpstg_urldecode(trailingslashit( $_POST["cloneDir"] ));
145
}
146
$this->options->cloneHostname = '';
147
if( isset( $_POST["cloneHostname"] ) && !empty( $_POST["cloneHostname"] ) ) {
@@ -157,9 +158,61 @@ class Cloning extends Job {
157
// Process lock state
158
$this->options->isRunning = true;
159
160
return $this->saveOptions();
161
}
162
163
/**
164
* Return target hostname
165
* @return string
@@ -187,7 +240,7 @@ class Cloning extends Job {
187
*/
188
private function getDestinationDir() {
189
// No custom clone dir or clone dir equals abspath of main wordpress site
190
- if( empty( $this->options->cloneDir ) || $this->options->cloneDir == (string)\WPStaging\WPStaging::getWPpath()) {
191
return trailingslashit( \WPStaging\WPStaging::getWPpath() . $this->options->cloneDirectoryName );
192
}
193
return trailingslashit( $this->options->cloneDir );
@@ -224,7 +277,7 @@ class Cloning extends Job {
224
225
// Prefix does not exist. We can use it
226
if( !$tables ) {
227
- return $this->options->prefix;
228
}
229
}
230
$this->returnException( "Fatal Error: Can not create staging prefix. '{$this->options->prefix}' already exists! Stopping for security reasons. Contact support@wp-staging.com" );
@@ -251,7 +304,7 @@ class Cloning extends Job {
251
* Start the cloning job
252
*/
253
public function start() {
254
- if( !property_exists($this->options, 'currentJob') || null === $this->options->currentJob ) {
255
$this->log( "Cloning job finished" );
256
return true;
257
}
49
'desktop.ini',
50
'.gitignore',
51
'.log',
52
+ 'web.config', // Important: Windows IIS configuration file. Must not be in the staging site!
53
+ '.wp-staging' // Determines if a site is a staging site
54
);
55
$this->options->excludedFilesFullPath = array(
56
'wp-content' . DIRECTORY_SEPARATOR . 'db.php',
75
// Get data and increment it
76
elseif( !empty( $this->options->existingClones ) ) {
77
$this->options->cloneNumber = count( $this->options->existingClones ) + 1;
78
+ //$this->options->prefix = $this->setStagingPrefix();
79
}
80
81
// Included Tables
87
88
// Excluded Directories
89
if( isset( $_POST["excludedDirectories"] ) && is_array( $_POST["excludedDirectories"] ) ) {
90
+ $this->options->excludedDirectories = wpstg_urldecode( $_POST["excludedDirectories"] );
91
}
92
93
// Excluded Directories TOTAL
100
\WPStaging\WPStaging::getWPpath() . 'wp-content' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'wp-spamshield',
101
);
102
103
+ $this->options->excludedDirectories = array_merge( $excludedDirectories, wpstg_urldecode( $this->options->excludedDirectories ) );
104
105
array_unshift( $this->options->directoriesToCopy, \WPStaging\WPStaging::getWPpath() );
106
107
// Included Directories
108
if( isset( $_POST["includedDirectories"] ) && is_array( $_POST["includedDirectories"] ) ) {
109
+ $this->options->includedDirectories = wpstg_urldecode( $_POST["includedDirectories"] );
110
}
111
112
// Extra Directories
113
if( isset( $_POST["extraDirectories"] ) && !empty( $_POST["extraDirectories"] ) ) {
114
+ $this->options->extraDirectories = wpstg_urldecode( $_POST["extraDirectories"] );
115
}
116
117
// Directories to Copy
138
}
139
$this->options->databasePrefix = '';
140
if( isset( $_POST["databasePrefix"] ) && !empty( $_POST["databasePrefix"] ) ) {
141
+ $this->options->databasePrefix = strtolower( $this->sanitizePrefix( $_POST["databasePrefix"] ) );
142
}
143
$this->options->cloneDir = '';
144
if( isset( $_POST["cloneDir"] ) && !empty( $_POST["cloneDir"] ) ) {
145
+ $this->options->cloneDir = wpstg_urldecode( trailingslashit( $_POST["cloneDir"] ) );
146
}
147
$this->options->cloneHostname = '';
148
if( isset( $_POST["cloneHostname"] ) && !empty( $_POST["cloneHostname"] ) ) {
158
// Process lock state
159
$this->options->isRunning = true;
160
161
+
162
+ // Save Clone data
163
+ $this->saveClone();
164
+
165
return $this->saveOptions();
166
}
167
168
+ /**
169
+ * Save clone data initially
170
+ * @return boolean
171
+ */
172
+ private function saveClone(){
173
+ // Save new clone data
174
+ $this->log( "Cloning: {$this->options->clone}'s clone job's data is not in database, generating data" );
175
+
176
+ $this->options->existingClones[$this->options->clone] = array(
177
+ "directoryName" => $this->options->cloneDirectoryName,
178
+ "path" => trailingslashit( $this->options->destinationDir ),
179
+ "url" => $this->getDestinationUrl(),
180
+ "number" => $this->options->cloneNumber,
181
+ "version" => \WPStaging\WPStaging::VERSION,
182
+ //"status" => false,
183
+ "status" => "unfinished or broken",
184
+ "prefix" => $this->options->prefix,
185
+ "datetime" => time(),
186
+ "databaseUser" => $this->options->databaseUser,
187
+ "databasePassword" => $this->options->databasePassword,
188
+ "databaseDatabase" => $this->options->databaseDatabase,
189
+ "databaseServer" => $this->options->databaseServer,
190
+ "databasePrefix" => $this->options->databasePrefix
191
+ );
192
+
193
+ if( false === update_option( "wpstg_existing_clones_beta", $this->options->existingClones ) ) {
194
+ $this->log( "Cloning: Failed to save {$this->options->clone}'s clone job data to database'" );
195
+ return false;
196
+ }
197
+
198
+ return true;
199
+ }
200
+
201
+
202
+ /**
203
+ * Get destination Hostname depending on wheather WP has been installed in sub dir or not
204
+ * @return type
205
+ */
206
+ private function getDestinationUrl() {
207
+
208
+ if( !empty( $this->options->cloneHostname ) ) {
209
+ return $this->options->cloneHostname;
210
+ }
211
+
212
+ return trailingslashit( get_site_url() ) . $this->options->cloneDirectoryName;
213
+ }
214
+
215
+
216
/**
217
* Return target hostname
218
* @return string
240
*/
241
private function getDestinationDir() {
242
// No custom clone dir or clone dir equals abspath of main wordpress site
243
+ if( empty( $this->options->cloneDir ) || $this->options->cloneDir == ( string ) \WPStaging\WPStaging::getWPpath() ) {
244
return trailingslashit( \WPStaging\WPStaging::getWPpath() . $this->options->cloneDirectoryName );
245
}
246
return trailingslashit( $this->options->cloneDir );
277
278
// Prefix does not exist. We can use it
279
if( !$tables ) {
280
+ return strtolower( $this->options->prefix );
281
}
282
}
283
$this->returnException( "Fatal Error: Can not create staging prefix. '{$this->options->prefix}' already exists! Stopping for security reasons. Contact support@wp-staging.com" );
304
* Start the cloning job
305
*/
306
public function start() {
307
+ if( !property_exists( $this->options, 'currentJob' ) || null === $this->options->currentJob ) {
308
$this->log( "Cloning job finished" );
309
return true;
310
}
apps/Backend/Modules/Jobs/Finish.php CHANGED
@@ -74,6 +74,7 @@ class Finish extends Job {
74
// Clone data already exists
75
if( isset( $this->options->existingClones[$this->options->clone] ) ) {
76
$this->options->existingClones[$this->options->clone]['datetime'] = time();
77
update_option( "wpstg_existing_clones_beta", $this->options->existingClones );
78
$this->log( "Finish: The job finished!" );
79
return true;
@@ -91,7 +92,8 @@ class Finish extends Job {
91
"url" => $this->getDestinationUrl(),
92
"number" => $this->options->cloneNumber,
93
"version" => \WPStaging\WPStaging::VERSION,
94
- "status" => false,
95
"prefix" => $this->options->prefix,
96
"datetime" => time(),
97
"databaseUser" => $this->options->databaseUser,
74
// Clone data already exists
75
if( isset( $this->options->existingClones[$this->options->clone] ) ) {
76
$this->options->existingClones[$this->options->clone]['datetime'] = time();
77
+ $this->options->existingClones[$this->options->clone]['status'] = 'finished';
78
update_option( "wpstg_existing_clones_beta", $this->options->existingClones );
79
$this->log( "Finish: The job finished!" );
80
return true;
92
"url" => $this->getDestinationUrl(),
93
"number" => $this->options->cloneNumber,
94
"version" => \WPStaging\WPStaging::VERSION,
95
+ //"status" => false,
96
+ "status" => "finished",
97
"prefix" => $this->options->prefix,
98
"datetime" => time(),
99
"databaseUser" => $this->options->databaseUser,
apps/Backend/Modules/Jobs/Multisite/Finish.php CHANGED
@@ -32,6 +32,8 @@ class Finish extends Job {
32
// Prepare clone records & save scanned directories for delete job later
33
$this->prepareCloneDataRecords();
34
35
$multisite = new Multisite;
36
37
@@ -79,6 +81,7 @@ class Finish extends Job {
79
if( isset( $this->options->existingClones[$this->options->clone] ) ) {
80
$this->options->existingClones[$this->options->clone]['datetime'] = time();
81
$this->options->existingClones[$this->options->clone]['url'] = $this->getDestinationUrl();
82
update_option( "wpstg_existing_clones_beta", $this->options->existingClones );
83
$this->log( "Finish: The job finished!" );
84
return true;
@@ -96,7 +99,7 @@ class Finish extends Job {
96
"url" => $this->getDestinationUrl(),
97
"number" => $this->options->cloneNumber,
98
"version" => \WPStaging\WPStaging::VERSION,
99
- "status" => false,
100
"prefix" => $this->options->prefix,
101
"datetime" => time(),
102
"databaseUser" => $this->options->databaseUser,
@@ -114,7 +117,6 @@ class Finish extends Job {
114
return true;
115
}
116
117
-
118
/**
119
* Get destination Hostname depending on wheather WP has been installed in sub dir or not
120
* @return type
@@ -125,39 +127,13 @@ class Finish extends Job {
125
return $this->options->cloneHostname;
126
}
127
128
- return trailingslashit( $this->multisiteHomeDomain ) . $this->options->cloneDirectoryName;
129
- }
130
131
- /**
132
- * Check if WP is installed in subdir
133
- * @return boolean
134
- */
135
- // private function isSubDir() {
136
- // // Compare names without scheme to bypass cases where siteurl and home have different schemes http / https
137
- // // This is happening much more often than you would expect
138
- // $siteurl = preg_replace( '#^https?://#', '', rtrim( get_option( 'siteurl' ), '/' ) );
139
- // $home = preg_replace( '#^https?://#', '', rtrim( get_option( 'home' ), '/' ) );
140
- //
141
- // if( $home !== $siteurl ) {
142
- // return true;
143
- // }
144
- // return false;
145
- // }
146
-
147
- /**
148
- * Get the install sub directory if WP is installed in sub directory
149
- * @return string
150
- */
151
- // private function getSubDir() {
152
- // $home = get_option( 'home' );
153
- // $siteurl = get_option( 'siteurl' );
154
- //
155
- // if( empty( $home ) || empty( $siteurl ) ) {
156
- // return '';
157
- // }
158
- //
159
- // $dir = str_replace( $home, '', $siteurl );
160
- // return str_replace( '/', '', $dir );
161
- // }
162
163
}
32
// Prepare clone records & save scanned directories for delete job later
33
$this->prepareCloneDataRecords();
34
35
+ $this->options->isRunning = false;
36
+
37
$multisite = new Multisite;
38
39
81
if( isset( $this->options->existingClones[$this->options->clone] ) ) {
82
$this->options->existingClones[$this->options->clone]['datetime'] = time();
83
$this->options->existingClones[$this->options->clone]['url'] = $this->getDestinationUrl();
84
+ $this->options->existingClones[$this->options->clone]['status'] = 'finished';
85
update_option( "wpstg_existing_clones_beta", $this->options->existingClones );
86
$this->log( "Finish: The job finished!" );
87
return true;
99
"url" => $this->getDestinationUrl(),
100
"number" => $this->options->cloneNumber,
101
"version" => \WPStaging\WPStaging::VERSION,
102
+ "status" => "finished",
103
"prefix" => $this->options->prefix,
104
"datetime" => time(),
105
"databaseUser" => $this->options->databaseUser,
117
return true;
118
}
119
120
/**
121
* Get destination Hostname depending on wheather WP has been installed in sub dir or not
122
* @return type
127
return $this->options->cloneHostname;
128
}
129
130
+ //return trailingslashit( $this->multisiteHomeDomain ) . $this->options->cloneDirectoryName;
131
+ // Get the path to the main multisite without appending and trailingslash e.g. wordpress
132
+ $multisitePath = defined( 'PATH_CURRENT_SITE') ? PATH_CURRENT_SITE : '/';
133
+ return rtrim( $this->multisiteHomeDomain, '/\\' ) . $multisitePath . $this->options->cloneDirectoryName;
134
+ //$multisitePath = defined( 'PATH_CURRENT_SITE' ) ? str_replace( '/', '', PATH_CURRENT_SITE ) : '';
135
136
+ //return trailingslashit( $this->multisiteHomeDomain ) . $multisitePath . '/' . $this->options->cloneDirectoryName;
137
+ }
138
139
}
apps/Backend/Modules/Jobs/ProcessLock.php CHANGED
@@ -1,61 +1,61 @@
1
- <?php
2
-
3
- namespace WPStaging\Backend\Modules\Jobs;
4
-
5
- use WPStaging\WPStaging;
6
-
7
- //use WPStaging\Utils\Cache;
8
-
9
- /**
10
- * Class Cloning
11
- * @package WPStaging\Backend\Modules\Jobs
12
- */
13
- class ProcessLock extends JobExecutable {
14
-
15
- /**
16
- * Check if any process is already running
17
- * @return boolean
18
- */
19
- public function isRunning() {
20
- // Another process is running
21
- if( isset( $this->options->isRunning ) ) {
22
-
23
- $this->log( "Another process is running" );
24
-
25
- $message = __( 'Hold on, another WP Staging process is already running...', 'wp-staging' );
26
-
27
- require_once WPSTG_PLUGIN_DIR . "apps/Backend/views/clone/ajax/process-lock.php";
28
-
29
- wp_die();
30
- }
31
- // No other process running
32
-
33
- return false;
34
- }
35
-
36
- /**
37
- * remove process lock value
38
- */
39
- public function restart() {
40
- unset( $this->options->isRunning );
41
- $this->cache->delete( "clone_options" );
42
- $this->cache->delete( "files_to_copy" );
43
- }
44
-
45
- /**
46
- * abstract
47
- * @return void
48
- */
49
- protected function calculateTotalSteps() {
50
-
51
- }
52
-
53
- /**
54
- * abstract
55
- * @return bool
56
- */
57
- protected function execute() {
58
-
59
- }
60
-
61
- }
1
+ <?php
2
+
3
+ namespace WPStaging\Backend\Modules\Jobs;
4
+
5
+ use WPStaging\WPStaging;
6
+
7
+ //use WPStaging\Utils\Cache;
8
+
9
+ /**
10
+ * Class Cloning
11
+ * @package WPStaging\Backend\Modules\Jobs
12
+ */
13
+ class ProcessLock extends JobExecutable {
14
+
15
+ /**
16
+ * Check if any process is already running
17
+ * @return boolean
18
+ */
19
+ public function isRunning() {
20
+ // Another process is running
21
+ if( isset( $this->options->isRunning ) ) {
22
+
23
+ $this->log( "Another process is running" );
24
+
25
+ $message = __( 'Hold on, another WP Staging process is already running...', 'wp-staging' );
26
+
27
+ require_once WPSTG_PLUGIN_DIR . "apps/Backend/views/clone/ajax/process-lock.php";
28
+
29
+ wp_die();
30
+ }
31
+ // No other process running
32
+
33
+ return false;
34
+ }
35
+
36
+ /**
37
+ * remove process lock value
38
+ */
39
+ public function restart() {
40
+ unset( $this->options->isRunning );
41
+ $this->cache->delete( "clone_options" );
42
+ $this->cache->delete( "files_to_copy" );
43
+ }
44
+
45
+ /**
46
+ * abstract
47
+ * @return void
48
+ */
49
+ protected function calculateTotalSteps() {
50
+
51
+ }
52
+
53
+ /**
54
+ * abstract
55
+ * @return bool
56
+ */
57
+ protected function execute() {
58
+
59
+ }
60
+
61
+ }
apps/Backend/Modules/Jobs/SearchReplace.php CHANGED
@@ -514,6 +514,12 @@ class SearchReplace extends JobExecutable {
514
$data = $tmp;
515
unset( $tmp );
516
} elseif( is_object( $data ) ) {
517
$tmp = $data;
518
$props = get_object_vars( $data );
519
foreach ( $props as $key => $value ) {
@@ -548,27 +554,27 @@ class SearchReplace extends JobExecutable {
548
* Can not use is_object alone because in php 7.2 it's returning true even though object is __PHP_Incomplete_Class_Name
549
* @return boolean
550
*/
551
- // private function isValidObject($data){
552
- // if( !is_object( $data ) || gettype( $data ) != 'object' ) {
553
- // return false;
554
- // }
555
- //
556
- // $invalid_class_props = get_object_vars( $data );
557
- //
558
- // if (!isset($invalid_class_props['__PHP_Incomplete_Class_Name'])){
559
- // // Assume it must be an valid object
560
- // return true;
561
- // }
562
- //
563
- // $invalid_object_class = $invalid_class_props['__PHP_Incomplete_Class_Name'];
564
- //
565
- // if( !empty( $invalid_object_class ) ) {
566
- // return false;
567
- // }
568
- //
569
- // // Assume it must be an valid object
570
- // return true;
571
- // }
572
573
/**
574
* Mimics the mysql_real_escape_string function. Adapted from a post by 'feedr' on php.net.
514
$data = $tmp;
515
unset( $tmp );
516
} elseif( is_object( $data ) ) {
517
+
518
+ // Is no valid or is incomplete object
519
+ if (!$this->isValidObject($data)){
520
+ return $data;
521
+ }
522
+
523
$tmp = $data;
524
$props = get_object_vars( $data );
525
foreach ( $props as $key => $value ) {
554
* Can not use is_object alone because in php 7.2 it's returning true even though object is __PHP_Incomplete_Class_Name
555
* @return boolean
556
*/
557
+ private function isValidObject($data){
558
+ if( !is_object( $data ) || gettype( $data ) != 'object' ) {
559
+ return false;
560
+ }
561
+
562
+ $invalid_class_props = get_object_vars( $data );
563
+
564
+ if (!isset($invalid_class_props['__PHP_Incomplete_Class_Name'])){
565
+ // Assume it must be an valid object
566
+ return true;
567
+ }
568
+
569
+ $invalid_object_class = $invalid_class_props['__PHP_Incomplete_Class_Name'];
570
+
571
+ if( !empty( $invalid_object_class ) ) {
572
+ return false;
573
+ }
574
+
575
+ // Assume it must be an valid object
576
+ return true;
577
+ }
578
579
/**
580
* Mimics the mysql_real_escape_string function. Adapted from a post by 'feedr' on php.net.
apps/Backend/Modules/Jobs/Updating.php CHANGED
@@ -2,14 +2,7 @@
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
use WPStaging\Utils\Helper;
14
15
/**
@@ -133,8 +126,6 @@ class Updating extends Job {
133
$this->options->cloneDir = wpstg_urldecode(trailingslashit( $_POST["cloneDir"] ));
134
}
135
136
- //$this->options->destinationDir = !empty( $this->options->cloneDir ) ? trailingslashit( $this->options->cloneDir ) : trailingslashit( $this->options->existingClones[$this->options->clone]['path'] );
137
-
138
$this->options->destinationDir = $this->getDestinationDir();
139
140
$this->options->cloneHostname = '';
2
3
namespace WPStaging\Backend\Modules\Jobs;
4
5
use WPStaging\WPStaging;
6
use WPStaging\Utils\Helper;
7
8
/**
126
$this->options->cloneDir = wpstg_urldecode(trailingslashit( $_POST["cloneDir"] ));
127
}
128
129
$this->options->destinationDir = $this->getDestinationDir();
130
131
$this->options->cloneHostname = '';
apps/Backend/Modules/SystemInfo.php CHANGED
@@ -200,7 +200,7 @@ class SystemInfo extends InjectionAware {
200
$output .= $this->info( "Plugin Version:", get_option( 'wpstg_version', 'undefined' ) );
201
$output .= $this->info( "Install Date:", get_option( 'wpstg_installDate', 'undefined' ) );
202
$output .= $this->info( "Upgraded from:", get_option( 'wpstg_version_upgraded_from', 'undefined' ) );
203
- $output .= $this->info( "Is Staging Site:", get_option( 'wpstg_is_staging_site', 'undefined' ) ) . PHP_EOL . PHP_EOL;
204
205
206
return apply_filters( "wpstg_sysinfo_after_wpstaging_info", $output );
200
$output .= $this->info( "Plugin Version:", get_option( 'wpstg_version', 'undefined' ) );
201
$output .= $this->info( "Install Date:", get_option( 'wpstg_installDate', 'undefined' ) );
202
$output .= $this->info( "Upgraded from:", get_option( 'wpstg_version_upgraded_from', 'undefined' ) );
203
+ $output .= $this->info( "Is Staging Site:", wpstg_is_stagingsite() ? 'true' : 'false' ) . PHP_EOL . PHP_EOL;
204
205
206
return apply_filters( "wpstg_sysinfo_after_wpstaging_info", $output );
apps/Backend/Notices/Notices.php CHANGED
@@ -35,7 +35,7 @@ class Notices {
35
}
36
37
/**
38
- * Check whether the page is an WP QUADS admin settings page or not
39
* @return bool
40
*/
41
private function isAdminPage() {
@@ -60,33 +60,43 @@ class Notices {
60
*/
61
private function canShow( $option, $days = 10 ) {
62
63
if( empty( $option ) ) {
64
return false;
65
}
66
67
$dbOption = get_option( $option );
68
69
$now = new \DateTime( "now" );
70
71
-
72
- // Check if user clicked on "rate later" button
73
- if( "no" !== $dbOption && wpstg_validate_date( $dbOption ) ) {
74
// Get days difference
75
- $hideDate = new \DateTime( $dbOption );
76
- $difference = $now->diff( $hideDate )->days;
77
-
78
- if( $days <= $difference )
79
- return true;
80
}
81
82
83
// Show X days after installation
84
$installDate = new \DateTime( get_option( "wpstg_installDate" ) );
85
86
- // Get days difference
87
$difference = $now->diff( $installDate )->days;
88
89
- if( $days <= $difference && "no" !== $dbOption ) {
90
return true;
91
}
92
@@ -103,21 +113,25 @@ class Notices {
103
}
104
}
105
106
public function messages() {
107
108
- $viewsNoticesPath = "{$this->path}views/_includes/messages/";
109
110
// Show notice when free and pro version have been activated at the same time
111
$this->plugin_deactivated_notice();
112
113
114
- // Show rating review message on all admin pages
115
if( $this->canShow( "wpstg_rating", 7 ) && $this->getCurrentScreen() !== 'page' && $this->getCurrentScreen() !== 'post' ) {
116
require_once "{$viewsNoticesPath}rating.php";
117
}
118
119
120
- // Display messages below to admins only, only on admin panel
121
if( !current_user_can( "update_plugins" ) || !$this->isAdminPage() ) {
122
return;
123
}
@@ -148,9 +162,9 @@ class Notices {
148
delete_transient( "wp_staging_deactivated_notice_id" );
149
}
150
// Rating
151
- if( $this->canShow( "wpstg_rating", 7 ) ) {
152
- require_once "{$viewsNoticesPath}rating.php";
153
- }
154
155
// Different scheme in home and siteurl
156
if( $this->isDifferentScheme() ) {
35
}
36
37
/**
38
+ * Check whether the page is admin page or not
39
* @return bool
40
*/
41
private function isAdminPage() {
60
*/
61
private function canShow( $option, $days = 10 ) {
62
63
+ // Do not show notice
64
if( empty( $option ) ) {
65
return false;
66
}
67
68
$dbOption = get_option( $option );
69
+
70
+ // Do not show notice
71
+ if ("no" === $dbOption){
72
+ return false;
73
+ }
74
75
$now = new \DateTime( "now" );
76
77
+ // Check if user clicked on "rate later" button and if there is a valid 'later' date
78
+ if( wpstg_is_valid_date( $dbOption ) ) {
79
// Get days difference
80
+ // $hideDate = new \DateTime( $dbOption );
81
+ // $difference = $now->diff( $hideDate )->days;
82
+ //
83
+ // if( $days >= $difference )
84
+ // return true;
85
+ // Do not show before this date
86
+ $show = new \DateTime( $dbOption );
87
+ if ($now < $show){
88
+ return false;
89
+ }
90
}
91
92
93
// Show X days after installation
94
$installDate = new \DateTime( get_option( "wpstg_installDate" ) );
95
96
+ // get number of days between installation date and today
97
$difference = $now->diff( $installDate )->days;
98
99
+ if( $days <= $difference ) {
100
return true;
101
}
102
113
}
114
}
115
116
+ /**
117
+ * Load admin notices
118
+ * @return string
119
+ */
120
public function messages() {
121
122
+ $viewsNoticesPath = "{$this->path}views/notices/";
123
124
// Show notice when free and pro version have been activated at the same time
125
$this->plugin_deactivated_notice();
126
127
128
+ // Show rating review message on all admin pages except pages and posts
129
if( $this->canShow( "wpstg_rating", 7 ) && $this->getCurrentScreen() !== 'page' && $this->getCurrentScreen() !== 'post' ) {
130
require_once "{$viewsNoticesPath}rating.php";
131
}
132
133
134
+ // Display notices below to admins only, only on admin panel
135
if( !current_user_can( "update_plugins" ) || !$this->isAdminPage() ) {
136
return;
137
}
162
delete_transient( "wp_staging_deactivated_notice_id" );
163
}
164
// Rating
165
+ // if( $this->canShow( "wpstg_rating", 7 ) ) {
166
+ // require_once "{$viewsNoticesPath}rating.php";
167
+ // }
168
169
// Different scheme in home and siteurl
170
if( $this->isDifferentScheme() ) {
apps/Backend/public/js/wpstg-admin-rating.js CHANGED
@@ -1,4 +1,5 @@
1
jQuery(document).ready(function ($) {
2
$(".wpstg_hide_rating").click(function (e) {
3
e.preventDefault();
4
@@ -10,9 +11,8 @@ jQuery(document).ready(function ($) {
10
console.log(xhr.status + ' ' + xhr.statusText + '---' + textStatus);
11
console.log(textStatus);
12
13
-
14
alert(
15
- "Unknown error"
16
);
17
},
18
success: function (data) {
@@ -21,10 +21,10 @@ jQuery(document).ready(function ($) {
21
},
22
statusCode: {
23
404: function () {
24
- alert("Something went wrong; can't find ajax request URL!");
25
},
26
500: function () {
27
- alert("Something went wrong; internal server error while processing the request!");
28
}
29
}
30
});
@@ -43,7 +43,7 @@ jQuery(document).ready(function ($) {
43
44
45
alert(
46
- "Unknown error"
47
);
48
},
49
success: function (data) {
@@ -52,10 +52,10 @@ jQuery(document).ready(function ($) {
52
},
53
statusCode: {
54
404: function () {
55
- alert("Something went wrong; can't find ajax request URL!");
56
},
57
500: function () {
58
- alert("Something went wrong; internal server error while processing the request!");
59
}
60
}
61
});
1
jQuery(document).ready(function ($) {
2
+
3
$(".wpstg_hide_rating").click(function (e) {
4
e.preventDefault();
5
11
console.log(xhr.status + ' ' + xhr.statusText + '---' + textStatus);
12
console.log(textStatus);
13
14
alert(
15
+ "Unknown error. Please get in contact with us to solve it support@wp-staging.com"
16
);
17
},
18
success: function (data) {
21
},
22
statusCode: {
23
404: function () {
24
+ alert("Something went wrong; can't find ajax request URL! Please get in contact with us to solve it support@wp-staging.com");
25
},
26
500: function () {
27
+ alert("Something went wrong; internal server error while processing the request! Please get in contact with us to solve it support@wp-staging.com");
28
}
29
}
30
});
43
44
45
alert(
46
+ "Unknown error. Please get in contact with us to solve it support@wp-staging.com"
47
);
48
},
49
success: function (data) {
52
},
53
statusCode: {
54
404: function () {
55
+ alert("Something went wrong; can't find ajax request URL! Please get in contact with us to solve it support@wp-staging.com");
56
},
57
500: function () {
58
+ alert("Something went wrong; internal server error while processing the request! Please get in contact with us to solve it support@wp-staging.com");
59
}
60
}
61
});
apps/Backend/views/clone/ajax/single-overview.php CHANGED
@@ -37,16 +37,25 @@
37
38
<?php echo apply_filters("wpstg_after_stage_buttons", $html = '', $name, $data)?>
39
<div class="wpstg-staging-info">
40
- <?php
41
- $prefix = !empty ($data['prefix']) ? __("DB Prefix: <span class='wpstg-bold'>" . $data['prefix'], "wp-staging") . '</span> ' : '&nbsp;&nbsp;&nbsp;';
42
echo $prefix;
43
echo '</br>';
44
- $dbname = !empty ($data['databaseDatabase']) ? __("DB Name: <span class='wpstg-bold'>" . $data['databaseDatabase'], "wp-staging") . '</span></br> ' : '';
45
- echo $dbname;
46
- $datetime = !empty ($data['datetime']) ? __("Updated: <span>" . date("D, d M Y H:i:s T",$data['datetime']) , "wp-staging") . '</span> ' : '&nbsp;&nbsp;&nbsp;';
47
echo $datetime;
48
-
49
-
50
?>
51
</div>
52
</div>
37
38
<?php echo apply_filters("wpstg_after_stage_buttons", $html = '', $name, $data)?>
39
<div class="wpstg-staging-info">
40
+ <?php
41
+ $dbname = !empty( $data['databaseDatabase'] ) ? __( "Database: <span class='wpstg-bold'>" . $data['databaseDatabase'], "wp-staging" ) . '</span>' : 'Database: <span class="wpstg-bold">' . DB_NAME . '</span>';
42
+ $prefix = !empty( $data['prefix'] ) ? __( "Database Prefix: <span class='wpstg-bold'>" . $data['prefix'], "wp-staging" ) . '</span> ' : '';
43
+ $cloneDir = !empty( $data['path'] ) ? __( "Directory: <span class='wpstg-bold'>" . $data['path'], "wp-staging" ) . '</span> ' : 'Directory: ';
44
+ $url = !empty( $data['url'] ) ? __( "URL: <span class='wpstg-bold'>" . $data['url'], "wp-staging" ) . '</span> ' : 'URL: ';
45
+ $datetime = !empty( $data['datetime'] ) ? __( "Updated: <span>" . date( "D, d M Y H:i:s T", $data['datetime'] ), "wp-staging" ) . '</span> ' : '&nbsp;&nbsp;&nbsp;';
46
+ $status = !empty( $data['status'] ) && $data['status'] !== 'finished' ? "Status: <span class='wpstg-bold'>" . $data['status'] . "</span>" : '&nbsp;&nbsp;&nbsp;';
47
+
48
+ echo $dbname;
49
+ echo '</br>';
50
echo $prefix;
51
echo '</br>';
52
+ echo $cloneDir;
53
+ echo '</br>';
54
+ echo $url;
55
+ echo '</br>';
56
+ echo $status;
57
+ echo '</br>';
58
echo $datetime;
59
?>
60
</div>
61
</div>
apps/Backend/views/{_includes/messages → notices}/beta.php RENAMED
File without changes
apps/Backend/views/{_includes/messages → notices}/cache-directory-permission-problem.php RENAMED
File without changes
apps/Backend/views/{_includes/messages → notices}/logs-directory-permission-problem.php RENAMED
File without changes
apps/Backend/views/{_includes/messages → notices}/poll.php RENAMED
File without changes
apps/Backend/views/{_includes/messages → notices}/rating.php RENAMED
File without changes
apps/Backend/views/{_includes/messages → notices}/staging-directory-permission-problem.php RENAMED
File without changes
apps/Backend/views/{_includes/messages → notices}/transient.php RENAMED
File without changes
apps/Backend/views/{_includes/messages → notices}/uploads-cache-directory-permission-problem.php RENAMED
File without changes
apps/Backend/views/{_includes/messages → notices}/vars-directory-permission-problem.php RENAMED
File without changes
apps/Backend/views/{_includes/messages → notices}/wp-version-compatible-message.php RENAMED
File without changes
apps/Backend/views/{_includes/messages → notices}/wrong-scheme.php RENAMED
File without changes
apps/Core/Utils/functions.php CHANGED
@@ -128,7 +128,7 @@ function wpstg_replace_last_match( $needle, $replace, $haystack ) {
128
* @param type $format
129
* @return bool
130
*/
131
- function wpstg_validate_date( $date, $format = 'Y-m-d' ) {
132
$d = DateTime::createFromFormat( $format, $date );
133
// The Y ( 4 digits year ) returns TRUE for any integer with any number of digits so changing the comparison from == to === fixes the issue.
134
return $d && $d->format( $format ) === $date;
@@ -140,23 +140,38 @@ function wpstg_validate_date( $date, $format = 'Y-m-d' ) {
140
* @param miced string | array $data
141
* @return mixed string | array
142
*/
143
- function wpstg_urldecode($data){
144
- if (empty($data)){
145
return $data;
146
}
147
-
148
- if ( is_string( $data)){
149
- return urldecode($data);
150
}
151
-
152
- if( is_array( $data )){
153
$array = array();
154
- foreach ($data as $string){
155
- $array[] = urldecode($string);
156
- }
157
return $array;
158
}
159
-
160
return $data;
161
-
162
}
128
* @param type $format
129
* @return bool
130
*/
131
+ function wpstg_is_valid_date( $date, $format = 'Y-m-d' ) {
132
$d = DateTime::createFromFormat( $format, $date );
133
// The Y ( 4 digits year ) returns TRUE for any integer with any number of digits so changing the comparison from == to === fixes the issue.
134
return $d && $d->format( $format ) === $date;
140
* @param miced string | array $data
141
* @return mixed string | array
142
*/
143
+ function wpstg_urldecode( $data ) {
144
+ if( empty( $data ) ) {
145
return $data;
146
}
147
+
148
+ if( is_string( $data ) ) {
149
+ return urldecode( $data );
150
}
151
+
152
+ if( is_array( $data ) ) {
153
$array = array();
154
+ foreach ( $data as $string ) {
155
+ $array[] = urldecode( $string );
156
+ }
157
return $array;
158
}
159
+
160
return $data;
161
+ }
162
+
163
+ /**
164
+ * Check if it is a staging site
165
+ * @return bool
166
+ */
167
+ function wpstg_is_stagingsite() {
168
+ if( "true" === get_option( "wpstg_is_staging_site" ) ) {
169
+ return true;
170
+ }
171
+
172
+ if( file_exists( ABSPATH . '.wp-staging' ) ) {
173
+ return true;
174
+ }
175
+
176
+ return false;
177
}
apps/Core/WPStaging.php CHANGED
@@ -29,7 +29,7 @@ final class WPStaging {
29
/**
30
* Plugin version
31
*/
32
- const VERSION = "2.5.5";
33
34
/**
35
* Plugin name
@@ -167,7 +167,7 @@ final class WPStaging {
167
public function enqueueElements( $hook ) {
168
169
// Load this css file on frontend and backend on all pages if current site is a staging site
170
- if( $this->isStagingSite() ) {
171
wp_enqueue_style( "wpstg-admin-bar", $this->backend_url . "css/wpstg-admin-bar.css", array(), $this->getVersion() );
172
}
173
@@ -444,9 +444,9 @@ final class WPStaging {
444
* Check if it is a staging site
445
* @return bool
446
*/
447
- private function isStagingSite() {
448
- return ("true" === get_option( "wpstg_is_staging_site" ));
449
- }
450
451
/**
452
* Initialize licensing functions
29
/**
30
* Plugin version
31
*/
32
+ const VERSION = "2.5.6";
33
34
/**
35
* Plugin name
167
public function enqueueElements( $hook ) {
168
169
// Load this css file on frontend and backend on all pages if current site is a staging site
170
+ if( wpstg_is_stagingsite() ) {
171
wp_enqueue_style( "wpstg-admin-bar", $this->backend_url . "css/wpstg-admin-bar.css", array(), $this->getVersion() );
172
}
173
444
* Check if it is a staging site
445
* @return bool
446
*/
447
+ // private function isStagingSite() {
448
+ // return ("true" === get_option( "wpstg_is_staging_site" ));
449
+ // }
450
451
/**
452
* Initialize licensing functions
apps/Frontend/Frontend.php CHANGED
@@ -114,11 +114,11 @@ class Frontend extends InjectionAware {
114
*/
115
private function disableLogin() {
116
// Is not staging site
117
- if( !$this->isStagingSite() ) {
118
return false;
119
}
120
121
- // Allow access for users with certain capabilitie only
122
if( current_user_can( 'manage_options' ) ) {
123
//if( current_user_can( 'administrator' ) ) {
124
return false;
@@ -156,6 +156,7 @@ class Frontend extends InjectionAware {
156
* Reset permalink structure of the clone to default; index.php?p=123
157
*/
158
private function resetPermaLinks() {
159
if( !$this->isStagingSite() || "true" === get_option( "wpstg_rmpermalinks_executed" ) ) {
160
return;
161
}
114
*/
115
private function disableLogin() {
116
// Is not staging site
117
+ if( !wpstg_is_stagingsite() ) {
118
return false;
119
}
120
121
+ // Allow access for user role administrator in any case
122
if( current_user_can( 'manage_options' ) ) {
123
//if( current_user_can( 'administrator' ) ) {
124
return false;
156
* Reset permalink structure of the clone to default; index.php?p=123
157
*/
158
private function resetPermaLinks() {
159
+ // Do nothing
160
if( !$this->isStagingSite() || "true" === get_option( "wpstg_rmpermalinks_executed" ) ) {
161
return;
162
}
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: 5.1
12
- Stable tag: 2.5.5
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.
@@ -151,6 +151,16 @@ https://wp-staging.com
151
152
== Changelog ==
153
154
= 2.5.5 =
155
* Fix: Fatal error, undefined function wpstg_validate_data()
156
@@ -227,6 +237,10 @@ Complete changelog: [https://wp-staging.com/wp-staging-changelog](https://wp-sta
227
228
== Upgrade Notice ==
229
230
- = 2.5.4 =
231
- * Fix: WordFence firewall rule 'local file inclusion' blocks wp staging initial starting cloning sequence
232
- * Fix: Values of form Extra directories to copy are ignored
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: 5.1
12
+ Stable tag: 2.5.6
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.
151
152
== Changelog ==
153
154
+ = 2.5.6 =
155
+ * New: Compatible to WordPress 5.2
156
+ * New: Allow adding file .wp-staging to root of website to determine if it's a staging or production website
157
+ * New: Add extended data about a staging site in list overview of staging sites
158
+ * New: Show unfinished or interrupted clones and allow deletion of them
159
+ * Tweak: Move admin notices templates to views/notices
160
+ * Fix: Rating notice appears again after using review later button
161
+ * Fix: Can not find staging site when staging site has been created with old version of wp staging
162
+ * Fix: Do not search & replace over incomplete classes in database to prevent warnings
163
+
164
= 2.5.5 =
165
* Fix: Fatal error, undefined function wpstg_validate_data()
166
237
238
== Upgrade Notice ==
239
240
+ = 2.5.6 =
241
+ * New: compatible to WordPress 5.2
242
+ * New: Allow adding file .wp-staging to root of website to determine if it's a staging or production website
243
+ * Tweak: Move admin notices templates to views/notices
244
+ * Fix: Rating notice appears again immediately after using review later button
245
+ * Fix: Convert staging site table prefix to lowercase
246
+ * New: Show unfinished or interrupted clones and allow deletion of them
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.5.5
11
* Text Domain: wp-staging
12
* Domain Path: /languages/
13
@@ -51,7 +51,7 @@ if( !defined( 'WPSTG_PLUGIN_URL' ) ) {
51
52
// Version
53
if( !defined( 'WPSTG_VERSION' ) ) {
54
- define( 'WPSTG_VERSION', '2.5.5' );
55
}
56
57
// Must use version of the optimizer
7
* Author: WP-Staging
8
* Author URI: https://wp-staging.com
9
* Contributors: ReneHermi, ilgityildirim
10
+ * Version: 2.5.6
11
* Text Domain: wp-staging
12
* Domain Path: /languages/
13
51
52
// Version
53
if( !defined( 'WPSTG_VERSION' ) ) {
54
+ define( 'WPSTG_VERSION', '2.5.6' );
55
}
56
57
// Must use version of the optimizer