Version Description
- New: Add filter 'wpstg_filter_options_replace' to exclude certain tables from updating while cloning
- New: Exclude tables for plugin wp_mail_smtp
- New: Support for custom upload folder. For instance, if upload folder has been renamed and removed outsite wp-content folder
- New: Add datetime timestamp internally to clone. (Used in WP Staging pro)
- New: Add filter 'wpstg_fiter_search_replace_rows' to exclude certain tables from search & replace
- New: Supports search & replace for revslider image slider and several visual editors which are using non default serialized data
- New: Add new setting which allow to specify the search & replace processing query limit
- New: Compatible to WordPress 4.9.6
Download this release
Release Info
Developer | ReneHermi |
Plugin | WP Staging – DB & File Duplicator & Migration |
Version | 2.2.8 |
Comparing to | |
See all releases |
Code changes from version 2.2.7 to 2.2.8
- apps/Backend/Modules/Jobs/Data.php +23 -5
- apps/Backend/Modules/Jobs/Directories.php +7 -3
- apps/Backend/Modules/Jobs/Finish.php +4 -1
- apps/Backend/Modules/Jobs/Job.php +2 -0
- apps/Backend/Modules/Jobs/Scan.php +25 -5
- apps/Backend/Modules/Jobs/SearchReplace.php +50 -20
- apps/Backend/Modules/Views/Forms/Settings.php +14 -0
- apps/Backend/views/settings/index.php +23 -0
- apps/Core/WPStaging.php +2 -2
- readme.txt +15 -4
- wp-staging.php +1 -1
apps/Backend/Modules/Jobs/Data.php
CHANGED
@@ -283,7 +283,7 @@ class Data extends JobExecutable {
|
|
283 |
}
|
284 |
|
285 |
/**
|
286 |
-
* Update Table Prefix in
|
287 |
* @return bool
|
288 |
*/
|
289 |
protected function step4() {
|
@@ -305,17 +305,35 @@ class Data extends JobExecutable {
|
|
305 |
return false;
|
306 |
}
|
307 |
|
308 |
-
$this->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
309 |
|
310 |
$resultUserMeta = $this->db->query(
|
311 |
$this->db->prepare(
|
312 |
-
"UPDATE {$this->prefix}options SET option_name= replace(option_name, %s, %s) WHERE option_name LIKE %s", $this->db->prefix, $this->prefix, $this->db->prefix . "_%"
|
313 |
)
|
314 |
);
|
315 |
|
316 |
if( !$resultUserMeta ) {
|
317 |
-
$this->log( "Preparing Data Step4: Failed to update db
|
318 |
-
$this->returnException( "Data Crunching Step 4: Failed to update db
|
319 |
return false;
|
320 |
}
|
321 |
|
283 |
}
|
284 |
|
285 |
/**
|
286 |
+
* Update Table Prefix in wp_usermeta and wp_options
|
287 |
* @return bool
|
288 |
*/
|
289 |
protected function step4() {
|
305 |
return false;
|
306 |
}
|
307 |
|
308 |
+
if( false === $this->isTable( $this->prefix . 'options' ) ) {
|
309 |
+
return true;
|
310 |
+
}
|
311 |
+
|
312 |
+
$this->log( "Updating db option_names in {$this->prefix}options. Error: {$this->db->last_error}" );
|
313 |
+
|
314 |
+
// Filter the rows below. Do not update them!
|
315 |
+
$filters = array(
|
316 |
+
'wp_mail_smtp',
|
317 |
+
'wp_mail_smtp_version',
|
318 |
+
'wp_mail_smtp_debug',
|
319 |
+
);
|
320 |
+
|
321 |
+
$filters = apply_filters('wpstg_filter_options_replace', $filters);
|
322 |
+
|
323 |
+
$where = "";
|
324 |
+
foreach($filters as $filter){
|
325 |
+
$where .= " AND option_name <> '" . $filter . "'";
|
326 |
+
}
|
327 |
|
328 |
$resultUserMeta = $this->db->query(
|
329 |
$this->db->prepare(
|
330 |
+
"UPDATE IGNORE {$this->prefix}options SET option_name= replace(option_name, %s, %s) WHERE option_name LIKE %s" . $where, $this->db->prefix, $this->prefix, $this->db->prefix . "_%"
|
331 |
)
|
332 |
);
|
333 |
|
334 |
if( !$resultUserMeta ) {
|
335 |
+
$this->log( "Preparing Data Step4: Failed to update db option_names in {$this->prefix}options. Error: {$this->db->last_error}", Logger::TYPE_ERROR );
|
336 |
+
$this->returnException( "Data Crunching Step 4: Failed to update db option_names in {$this->prefix}options. Error: {$this->db->last_error}" );
|
337 |
return false;
|
338 |
}
|
339 |
|
apps/Backend/Modules/Jobs/Directories.php
CHANGED
@@ -68,6 +68,8 @@ class Directories extends JobExecutable {
|
|
68 |
return ( object ) $this->response;
|
69 |
}
|
70 |
|
|
|
|
|
71 |
/**
|
72 |
* Step 0
|
73 |
* Get WP Root files
|
@@ -125,7 +127,8 @@ class Directories extends JobExecutable {
|
|
125 |
'cache',
|
126 |
'wps-hide-login',
|
127 |
'node_modules',
|
128 |
-
'nbproject'
|
|
|
129 |
);
|
130 |
|
131 |
try {
|
@@ -284,7 +287,7 @@ class Directories extends JobExecutable {
|
|
284 |
|
285 |
try {
|
286 |
|
287 |
-
// Iterate over
|
288 |
$iterator = new \WPStaging\Iterators\RecursiveDirectoryIterator( $folder );
|
289 |
|
290 |
// Exclude new line file names
|
@@ -313,7 +316,8 @@ class Directories extends JobExecutable {
|
|
313 |
// Write path line
|
314 |
foreach ( $iterator as $item ) {
|
315 |
if( $item->isFile() ) {
|
316 |
-
if( $this->write( $files, $strings->getLastElemAfterString( '/', $folder ) . DIRECTORY_SEPARATOR . $iterator->getSubPathName() . PHP_EOL ) ) {
|
|
|
317 |
$this->options->totalFiles++;
|
318 |
// Add current file size
|
319 |
$this->options->totalFileSize += $iterator->getSize();
|
68 |
return ( object ) $this->response;
|
69 |
}
|
70 |
|
71 |
+
|
72 |
+
|
73 |
/**
|
74 |
* Step 0
|
75 |
* Get WP Root files
|
127 |
'cache',
|
128 |
'wps-hide-login',
|
129 |
'node_modules',
|
130 |
+
'nbproject',
|
131 |
+
'.idea'
|
132 |
);
|
133 |
|
134 |
try {
|
287 |
|
288 |
try {
|
289 |
|
290 |
+
// Iterate over extra directory
|
291 |
$iterator = new \WPStaging\Iterators\RecursiveDirectoryIterator( $folder );
|
292 |
|
293 |
// Exclude new line file names
|
316 |
// Write path line
|
317 |
foreach ( $iterator as $item ) {
|
318 |
if( $item->isFile() ) {
|
319 |
+
//if( $this->write( $files, $strings->getLastElemAfterString( '/', $folder ) . DIRECTORY_SEPARATOR . $iterator->getSubPathName() . PHP_EOL ) ) {
|
320 |
+
if( $this->write( $files, str_replace( ABSPATH, '', $folder ) . DIRECTORY_SEPARATOR . $iterator->getSubPathName() . PHP_EOL ) ) {
|
321 |
$this->options->totalFiles++;
|
322 |
// Add current file size
|
323 |
$this->options->totalFileSize += $iterator->getSize();
|
apps/Backend/Modules/Jobs/Finish.php
CHANGED
@@ -78,7 +78,9 @@ class Finish extends Job
|
|
78 |
// Clone data already exists
|
79 |
if (isset($this->options->existingClones[$this->options->clone]))
|
80 |
{
|
81 |
-
|
|
|
|
|
82 |
return true;
|
83 |
}
|
84 |
|
@@ -96,6 +98,7 @@ class Finish extends Job
|
|
96 |
"version" => \WPStaging\WPStaging::VERSION,
|
97 |
"status" => false,
|
98 |
"prefix" => $this->options->prefix,
|
|
|
99 |
);
|
100 |
|
101 |
if (false === update_option("wpstg_existing_clones_beta", $this->options->existingClones))
|
78 |
// Clone data already exists
|
79 |
if (isset($this->options->existingClones[$this->options->clone]))
|
80 |
{
|
81 |
+
$this->options->existingClones[$this->options->clone]['datetime'] = time();
|
82 |
+
update_option("wpstg_existing_clones_beta", $this->options->existingClones);
|
83 |
+
$this->log("Finish: The job finished!");
|
84 |
return true;
|
85 |
}
|
86 |
|
98 |
"version" => \WPStaging\WPStaging::VERSION,
|
99 |
"status" => false,
|
100 |
"prefix" => $this->options->prefix,
|
101 |
+
"datetime" => time()
|
102 |
);
|
103 |
|
104 |
if (false === update_option("wpstg_existing_clones_beta", $this->options->existingClones))
|
apps/Backend/Modules/Jobs/Job.php
CHANGED
@@ -126,6 +126,7 @@ abstract class Job implements JobInterface
|
|
126 |
// check default options
|
127 |
if ( !isset($this->settings) ||
|
128 |
!isset($this->settings->queryLimit) ||
|
|
|
129 |
!isset($this->settings->batchSize) ||
|
130 |
!isset($this->settings->cpuLoad) ||
|
131 |
!isset($this->settings->fileLimit)
|
@@ -176,6 +177,7 @@ abstract class Job implements JobInterface
|
|
176 |
*/
|
177 |
protected function setDefaultSettings(){
|
178 |
$this->settings->queryLimit = "5000";
|
|
|
179 |
$this->settings->fileLimit = "1";
|
180 |
$this->settings->batchSize = "2";
|
181 |
$this->settings->cpuLoad = 'medium';
|
126 |
// check default options
|
127 |
if ( !isset($this->settings) ||
|
128 |
!isset($this->settings->queryLimit) ||
|
129 |
+
!isset($this->settings->querySRLimit) ||
|
130 |
!isset($this->settings->batchSize) ||
|
131 |
!isset($this->settings->cpuLoad) ||
|
132 |
!isset($this->settings->fileLimit)
|
177 |
*/
|
178 |
protected function setDefaultSettings(){
|
179 |
$this->settings->queryLimit = "5000";
|
180 |
+
$this->settings->querySRLimit = "5000";
|
181 |
$this->settings->fileLimit = "1";
|
182 |
$this->settings->batchSize = "2";
|
183 |
$this->settings->cpuLoad = 'medium';
|
apps/Backend/Modules/Jobs/Scan.php
CHANGED
@@ -45,6 +45,7 @@ class Scan extends Job
|
|
45 |
$this->prefix = $this->db->prefix;
|
46 |
|
47 |
|
|
|
48 |
}
|
49 |
|
50 |
/**
|
@@ -89,8 +90,6 @@ class Scan extends Job
|
|
89 |
// Delete previous cached files
|
90 |
$this->cache->delete("files_to_copy");
|
91 |
$this->cache->delete("clone_options");
|
92 |
-
//$this->cache->delete("files_to_verify");
|
93 |
-
//$this->cache->delete("files_verified");
|
94 |
|
95 |
// Save options
|
96 |
$this->saveOptions();
|
@@ -98,6 +97,25 @@ class Scan extends Job
|
|
98 |
return $this;
|
99 |
}
|
100 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
101 |
/**
|
102 |
* Format bytes into human readable form
|
103 |
* @param int $bytes
|
@@ -301,8 +319,11 @@ class Scan extends Job
|
|
301 |
// Gather Themes
|
302 |
$this->getSubDirectories(WP_CONTENT_DIR . DIRECTORY_SEPARATOR . "themes");
|
303 |
|
304 |
-
// Gather Uploads
|
305 |
-
|
|
|
|
|
|
|
306 |
}
|
307 |
|
308 |
/**
|
@@ -360,7 +381,6 @@ class Scan extends Job
|
|
360 |
$directoryArray = explode(DIRECTORY_SEPARATOR, $path);
|
361 |
$total = is_array($directoryArray) || $directoryArray instanceof Countable ? count($directoryArray) : 0;
|
362 |
|
363 |
-
|
364 |
if ($total < 1)
|
365 |
{
|
366 |
return;
|
45 |
$this->prefix = $this->db->prefix;
|
46 |
|
47 |
|
48 |
+
|
49 |
}
|
50 |
|
51 |
/**
|
90 |
// Delete previous cached files
|
91 |
$this->cache->delete("files_to_copy");
|
92 |
$this->cache->delete("clone_options");
|
|
|
|
|
93 |
|
94 |
// Save options
|
95 |
$this->saveOptions();
|
97 |
return $this;
|
98 |
}
|
99 |
|
100 |
+
/**
|
101 |
+
* Get relative WP uploads path
|
102 |
+
* @return string
|
103 |
+
*/
|
104 |
+
protected function getUploadDir(){
|
105 |
+
$uploads = wp_upload_dir();
|
106 |
+
return $uploads['basedir'];
|
107 |
+
}
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Get WP media folder
|
111 |
+
*
|
112 |
+
* @return string
|
113 |
+
*/
|
114 |
+
// protected function getUploadFolder(){
|
115 |
+
// $uploads = wp_upload_dir();
|
116 |
+
// return wp_basedir($uploads['baseurl']);
|
117 |
+
// }
|
118 |
+
|
119 |
/**
|
120 |
* Format bytes into human readable form
|
121 |
* @param int $bytes
|
319 |
// Gather Themes
|
320 |
$this->getSubDirectories(WP_CONTENT_DIR . DIRECTORY_SEPARATOR . "themes");
|
321 |
|
322 |
+
// Gather Default Uploads Folder
|
323 |
+
//$this->getSubDirectories(WP_CONTENT_DIR . DIRECTORY_SEPARATOR . "uploads");
|
324 |
+
|
325 |
+
// Gather Custom Uploads Folder if there is one
|
326 |
+
//$this->getSubDirectories( $this->getUploadDir() );
|
327 |
}
|
328 |
|
329 |
/**
|
381 |
$directoryArray = explode(DIRECTORY_SEPARATOR, $path);
|
382 |
$total = is_array($directoryArray) || $directoryArray instanceof Countable ? count($directoryArray) : 0;
|
383 |
|
|
|
384 |
if ($total < 1)
|
385 |
{
|
386 |
return;
|
apps/Backend/Modules/Jobs/SearchReplace.php
CHANGED
@@ -27,14 +27,12 @@ class SearchReplace extends JobExecutable {
|
|
27 |
*/
|
28 |
public $db;
|
29 |
|
30 |
-
|
31 |
/**
|
32 |
*
|
33 |
* @var string
|
34 |
*/
|
35 |
private $homeUrl;
|
36 |
|
37 |
-
|
38 |
/**
|
39 |
* The prefix of the new database tables which are used for the live site after updating tables
|
40 |
* @var string
|
@@ -55,7 +53,7 @@ class SearchReplace extends JobExecutable {
|
|
55 |
|
56 |
public function start() {
|
57 |
// Skip job. Nothing to do
|
58 |
-
if
|
59 |
$this->prepareResponse( true, false );
|
60 |
}
|
61 |
|
@@ -167,7 +165,7 @@ class SearchReplace extends JobExecutable {
|
|
167 |
* @param string $old
|
168 |
*/
|
169 |
private function startReplace( $new ) {
|
170 |
-
$rows = $this->options->job->start + $this->settings->
|
171 |
$this->log(
|
172 |
"DB Processing: Table {$new} {$this->options->job->start} to {$rows} records"
|
173 |
);
|
@@ -176,7 +174,7 @@ class SearchReplace extends JobExecutable {
|
|
176 |
$this->searchReplace( $new, $rows, array() );
|
177 |
|
178 |
// Set new offset
|
179 |
-
$this->options->job->start += $this->settings->
|
180 |
}
|
181 |
|
182 |
/**
|
@@ -187,7 +185,7 @@ class SearchReplace extends JobExecutable {
|
|
187 |
private function get_pages_in_table( $table ) {
|
188 |
$table = esc_sql( $table );
|
189 |
$rows = $this->db->get_var( "SELECT COUNT(*) FROM $table" );
|
190 |
-
$pages = ceil( $rows / $this->settings->
|
191 |
return absint( $pages );
|
192 |
}
|
193 |
|
@@ -231,31 +229,35 @@ class SearchReplace extends JobExecutable {
|
|
231 |
|
232 |
// Load up the default settings for this chunk.
|
233 |
$table = esc_sql( $table );
|
234 |
-
$current_page = $this->options->job->start + $this->settings->
|
235 |
$pages = $this->get_pages_in_table( $table );
|
236 |
//$done = false;
|
237 |
|
238 |
|
239 |
if( $this->isSubDir() ) {
|
240 |
-
//$homeUrl = rtrim($this->homeUrl, "/") . $this->getSubDir() . $this->options->cloneDirectoryName;
|
241 |
// Search URL example.com/staging and root path to staging site /var/www/htdocs/staging
|
242 |
$args['search_for'] = array(
|
243 |
-
|
244 |
-
|
|
|
|
|
245 |
);
|
246 |
|
247 |
$args['replace_with'] = array(
|
248 |
rtrim( $this->homeUrl, "/" ) . $this->getSubDir() . '/' . $this->options->cloneDirectoryName,
|
249 |
-
rtrim( ABSPATH, '/' ) . '/' . $this->options->cloneDirectoryName
|
|
|
250 |
);
|
251 |
} else {
|
252 |
$args['search_for'] = array(
|
253 |
rtrim( $this->homeUrl, '/' ),
|
254 |
-
ABSPATH
|
|
|
255 |
);
|
256 |
$args['replace_with'] = array(
|
257 |
rtrim( $this->homeUrl, '/' ) . '/' . $this->options->cloneDirectoryName,
|
258 |
-
|
|
|
259 |
);
|
260 |
}
|
261 |
|
@@ -279,16 +281,34 @@ class SearchReplace extends JobExecutable {
|
|
279 |
list( $primary_key, $columns ) = $this->get_columns( $table );
|
280 |
|
281 |
// Bail out early if there isn't a primary key.
|
282 |
-
|
283 |
-
|
284 |
-
|
|
|
|
|
|
|
|
|
285 |
|
286 |
$current_row = 0;
|
287 |
$start = $this->options->job->start;
|
288 |
-
$end = $this->settings->
|
289 |
|
290 |
// Grab the content of the table.
|
291 |
$data = $this->db->get_results( "SELECT * FROM $table LIMIT $start, $end", ARRAY_A );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
292 |
|
293 |
// Loop through the data.
|
294 |
foreach ( $data as $row ) {
|
@@ -297,6 +317,16 @@ class SearchReplace extends JobExecutable {
|
|
297 |
$where_sql = array();
|
298 |
$upd = false;
|
299 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
300 |
foreach ( $columns as $column ) {
|
301 |
|
302 |
$dataRow = $row[$column];
|
@@ -363,10 +393,10 @@ class SearchReplace extends JobExecutable {
|
|
363 |
}
|
364 |
} // end row loop
|
365 |
unset( $row );
|
|
|
|
|
|
|
366 |
|
367 |
-
// if( $current_page >= $pages - 1 ) {
|
368 |
-
// $done = true;
|
369 |
-
// }
|
370 |
|
371 |
// DB Flush
|
372 |
$this->db->flush();
|
27 |
*/
|
28 |
public $db;
|
29 |
|
|
|
30 |
/**
|
31 |
*
|
32 |
* @var string
|
33 |
*/
|
34 |
private $homeUrl;
|
35 |
|
|
|
36 |
/**
|
37 |
* The prefix of the new database tables which are used for the live site after updating tables
|
38 |
* @var string
|
53 |
|
54 |
public function start() {
|
55 |
// Skip job. Nothing to do
|
56 |
+
if( $this->options->totalSteps === 0 ) {
|
57 |
$this->prepareResponse( true, false );
|
58 |
}
|
59 |
|
165 |
* @param string $old
|
166 |
*/
|
167 |
private function startReplace( $new ) {
|
168 |
+
$rows = $this->options->job->start + $this->settings->querySRLimit;
|
169 |
$this->log(
|
170 |
"DB Processing: Table {$new} {$this->options->job->start} to {$rows} records"
|
171 |
);
|
174 |
$this->searchReplace( $new, $rows, array() );
|
175 |
|
176 |
// Set new offset
|
177 |
+
$this->options->job->start += $this->settings->querySRLimit;
|
178 |
}
|
179 |
|
180 |
/**
|
185 |
private function get_pages_in_table( $table ) {
|
186 |
$table = esc_sql( $table );
|
187 |
$rows = $this->db->get_var( "SELECT COUNT(*) FROM $table" );
|
188 |
+
$pages = ceil( $rows / $this->settings->querySRLimit );
|
189 |
return absint( $pages );
|
190 |
}
|
191 |
|
229 |
|
230 |
// Load up the default settings for this chunk.
|
231 |
$table = esc_sql( $table );
|
232 |
+
$current_page = $this->options->job->start + $this->settings->querySRLimit;
|
233 |
$pages = $this->get_pages_in_table( $table );
|
234 |
//$done = false;
|
235 |
|
236 |
|
237 |
if( $this->isSubDir() ) {
|
|
|
238 |
// Search URL example.com/staging and root path to staging site /var/www/htdocs/staging
|
239 |
$args['search_for'] = array(
|
240 |
+
rtrim( $this->homeUrl, "/" ) . $this->getSubDir(),
|
241 |
+
ABSPATH,
|
242 |
+
str_replace('/', '\/', rtrim( $this->homeUrl, '/' )) . str_replace('/', '\/', $this->getSubDir()) // // Used by revslider and several visual editors
|
243 |
+
|
244 |
);
|
245 |
|
246 |
$args['replace_with'] = array(
|
247 |
rtrim( $this->homeUrl, "/" ) . $this->getSubDir() . '/' . $this->options->cloneDirectoryName,
|
248 |
+
rtrim( ABSPATH, '/' ) . '/' . $this->options->cloneDirectoryName,
|
249 |
+
str_replace('/', '\/', rtrim( $this->homeUrl, "/" )) . str_replace('/', '\/', $this->getSubDir()) . '\/' . $this->options->cloneDirectoryName, // Used by revslider and several visual editors
|
250 |
);
|
251 |
} else {
|
252 |
$args['search_for'] = array(
|
253 |
rtrim( $this->homeUrl, '/' ),
|
254 |
+
ABSPATH,
|
255 |
+
str_replace('/', '\/' , rtrim( $this->homeUrl, '/' ))
|
256 |
);
|
257 |
$args['replace_with'] = array(
|
258 |
rtrim( $this->homeUrl, '/' ) . '/' . $this->options->cloneDirectoryName,
|
259 |
+
rtrim( ABSPATH, '/' ) . '/' . $this->options->cloneDirectoryName,
|
260 |
+
str_replace('/', '\/', rtrim( $this->homeUrl, '/' )) . '\/' . $this->options->cloneDirectoryName,
|
261 |
);
|
262 |
}
|
263 |
|
281 |
list( $primary_key, $columns ) = $this->get_columns( $table );
|
282 |
|
283 |
// Bail out early if there isn't a primary key.
|
284 |
+
// We commented this to search & replace through tables which have no primary keys like wp_revslider_slides
|
285 |
+
// @todo test this carefully. If it causes (performance) issues we need to activate it again!
|
286 |
+
// @since 2.4.4
|
287 |
+
|
288 |
+
// if( null === $primary_key ) {
|
289 |
+
// return false;
|
290 |
+
// }
|
291 |
|
292 |
$current_row = 0;
|
293 |
$start = $this->options->job->start;
|
294 |
+
$end = $this->settings->querySRLimit;
|
295 |
|
296 |
// Grab the content of the table.
|
297 |
$data = $this->db->get_results( "SELECT * FROM $table LIMIT $start, $end", ARRAY_A );
|
298 |
+
|
299 |
+
// Filter certain rows (of other plugins)
|
300 |
+
$filter = array(
|
301 |
+
'Admin_custome_login_Slidshow',
|
302 |
+
'Admin_custome_login_Social',
|
303 |
+
'Admin_custome_login_logo',
|
304 |
+
'Admin_custome_login_text',
|
305 |
+
'Admin_custome_login_login',
|
306 |
+
'Admin_custome_login_top',
|
307 |
+
'Admin_custome_login_dashboard',
|
308 |
+
'Admin_custome_login_Version',
|
309 |
+
);
|
310 |
+
|
311 |
+
apply_filters('wpstg_fiter_search_replace_rows', $filter);
|
312 |
|
313 |
// Loop through the data.
|
314 |
foreach ( $data as $row ) {
|
317 |
$where_sql = array();
|
318 |
$upd = false;
|
319 |
|
320 |
+
// Skip rows below
|
321 |
+
if (isset($row['option_name']) && in_array($row['option_name'], $filter)){
|
322 |
+
continue;
|
323 |
+
}
|
324 |
+
|
325 |
+
// Skip rows with transients (They can store huge data and we need to save memory)
|
326 |
+
if( isset( $row['option_name'] ) && strpos( $row['option_name'], '_transient' ) === 0 ) {
|
327 |
+
continue;
|
328 |
+
}
|
329 |
+
|
330 |
foreach ( $columns as $column ) {
|
331 |
|
332 |
$dataRow = $row[$column];
|
393 |
}
|
394 |
} // end row loop
|
395 |
unset( $row );
|
396 |
+
unset( $update_sql );
|
397 |
+
unset( $where_sql );
|
398 |
+
unset( $sql );
|
399 |
|
|
|
|
|
|
|
400 |
|
401 |
// DB Flush
|
402 |
$this->db->flush();
|
apps/Backend/Modules/Views/Forms/Settings.php
CHANGED
@@ -61,6 +61,20 @@ class Settings {
|
|
61 |
$element->setLabel( "DB Copy Query Limit" )
|
62 |
->setDefault( isset( $settings->queryLimit ) ? $settings->queryLimit : 5000 )
|
63 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
64 |
|
65 |
$options = array('1' => '1', '10' => '10', '50' => '50', '250' => '250', '500' => '500', '1000' => '1000');
|
66 |
// DB Copy Query Limit
|
61 |
$element->setLabel( "DB Copy Query Limit" )
|
62 |
->setDefault( isset( $settings->queryLimit ) ? $settings->queryLimit : 5000 )
|
63 |
);
|
64 |
+
// DB Search & Replace Query Limit
|
65 |
+
$element = new Numerical(
|
66 |
+
"wpstg_settings[querySRLimit]", array(
|
67 |
+
"class" => "medium-text",
|
68 |
+
"step" => 1,
|
69 |
+
"max" => 999999,
|
70 |
+
"min" => 0
|
71 |
+
)
|
72 |
+
);
|
73 |
+
|
74 |
+
$this->form["general"]->add(
|
75 |
+
$element->setLabel( "DB Search & Replace Limit" )
|
76 |
+
->setDefault( isset( $settings->querySRLimit ) ? $settings->querySRLimit : 5000 )
|
77 |
+
);
|
78 |
|
79 |
$options = array('1' => '1', '10' => '10', '50' => '50', '250' => '250', '500' => '500', '1000' => '1000');
|
80 |
// DB Copy Query Limit
|
apps/Backend/views/settings/index.php
CHANGED
@@ -106,6 +106,25 @@
|
|
106 |
<?php echo $form->render( "wpstg_settings[queryLimit]" ) ?>
|
107 |
</td>
|
108 |
</tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
109 |
|
110 |
<tr class="row">
|
111 |
<td class="row th">
|
@@ -118,6 +137,10 @@
|
|
118 |
The higher the value the faster the file copy process.
|
119 |
To find out the highest possible values try a high value like 500 or more. If you get timeout issues, lower it
|
120 |
until you get no more errors during copying process.
|
|
|
|
|
|
|
|
|
121 |
<br>
|
122 |
<strong> Default: 1 </strong>
|
123 |
</span>
|
106 |
<?php echo $form->render( "wpstg_settings[queryLimit]" ) ?>
|
107 |
</td>
|
108 |
</tr>
|
109 |
+
<tr class="row">
|
110 |
+
<td class="row th">
|
111 |
+
<div class="col-title">
|
112 |
+
<?php
|
113 |
+
echo $form->label("wpstg_settings[querySRLimit]")
|
114 |
+
?>
|
115 |
+
<span class="description">
|
116 |
+
Number of DB rows, that will be processed within one ajax request.
|
117 |
+
The higher the value the faster the database search & replace process.
|
118 |
+
This is a high memory consumptive process. If you get timeouts lower this value!
|
119 |
+
<br>
|
120 |
+
<strong> Default: 5000 </strong>
|
121 |
+
</span>
|
122 |
+
</div>
|
123 |
+
</td>
|
124 |
+
<td>
|
125 |
+
<?php echo $form->render("wpstg_settings[querySRLimit]")?>
|
126 |
+
</td>
|
127 |
+
</tr>
|
128 |
|
129 |
<tr class="row">
|
130 |
<td class="row th">
|
137 |
The higher the value the faster the file copy process.
|
138 |
To find out the highest possible values try a high value like 500 or more. If you get timeout issues, lower it
|
139 |
until you get no more errors during copying process.
|
140 |
+
<br>
|
141 |
+
<br>
|
142 |
+
<strong>Important:</strong> If CPU Load Priority is Low try a file copy limit value of 10 or higher. Otherwise file copying process takes a lot of time.
|
143 |
+
<br>
|
144 |
<br>
|
145 |
<strong> Default: 1 </strong>
|
146 |
</span>
|
apps/Core/WPStaging.php
CHANGED
@@ -29,7 +29,7 @@ final class WPStaging {
|
|
29 |
/**
|
30 |
* Plugin version
|
31 |
*/
|
32 |
-
const VERSION = "2.2.
|
33 |
|
34 |
/**
|
35 |
* Plugin name
|
@@ -44,7 +44,7 @@ final class WPStaging {
|
|
44 |
/**
|
45 |
* Compatible WP Version
|
46 |
*/
|
47 |
-
const WP_COMPATIBLE = "4.9.
|
48 |
|
49 |
/**
|
50 |
* Slug: Either wp-staging or wp-staging-pro
|
29 |
/**
|
30 |
* Plugin version
|
31 |
*/
|
32 |
+
const VERSION = "2.2.8";
|
33 |
|
34 |
/**
|
35 |
* Plugin name
|
44 |
/**
|
45 |
* Compatible WP Version
|
46 |
*/
|
47 |
+
const WP_COMPATIBLE = "4.9.6";
|
48 |
|
49 |
/**
|
50 |
* Slug: Either wp-staging or wp-staging-pro
|
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.2.
|
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,17 @@ https://wp-staging.com
|
|
146 |
|
147 |
== Changelog ==
|
148 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
149 |
= 2.2.7 =
|
150 |
* Fix: Serialize replace is not working properly for serialized strings
|
151 |
* Fix: WP_SITEURL & WP_HOME not replaced if constant contains php generated string
|
@@ -247,6 +258,6 @@ Complete changelog: [https://wp-staging.com/changelog.txt](https://wp-staging.co
|
|
247 |
|
248 |
== Upgrade Notice ==
|
249 |
|
250 |
-
= 2.2.
|
251 |
-
*
|
252 |
-
|
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.2.8
|
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.2.8 =
|
150 |
+
* New: Add filter 'wpstg_filter_options_replace' to exclude certain tables from updating while cloning
|
151 |
+
* New: Exclude tables for plugin wp_mail_smtp
|
152 |
+
* New: Support for custom upload folder. For instance, if upload folder has been renamed and removed outsite wp-content folder
|
153 |
+
* New: Add datetime timestamp internally to clone. (Used in WP Staging pro)
|
154 |
+
* New: Add filter 'wpstg_fiter_search_replace_rows' to exclude certain tables from search & replace
|
155 |
+
* New: Supports search & replace for revslider image slider and several visual editors which are using non default serialized data
|
156 |
+
* New: Add new setting which allow to specify the search & replace processing query limit
|
157 |
+
* New: Compatible to WordPress 4.9.6
|
158 |
+
|
159 |
+
|
160 |
= 2.2.7 =
|
161 |
* Fix: Serialize replace is not working properly for serialized strings
|
162 |
* Fix: WP_SITEURL & WP_HOME not replaced if constant contains php generated string
|
258 |
|
259 |
== Upgrade Notice ==
|
260 |
|
261 |
+
= 2.2.8 =
|
262 |
+
* New: Compatible to WordPress 4.9.6
|
263 |
+
|
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.2.
|
11 |
* Text Domain: wpstg
|
12 |
* Domain Path: /languages/
|
13 |
|
7 |
* Author: WP-Staging
|
8 |
* Author URI: https://wp-staging.com
|
9 |
* Contributors: ReneHermi, ilgityildirim
|
10 |
+
* Version: 2.2.8
|
11 |
* Text Domain: wpstg
|
12 |
* Domain Path: /languages/
|
13 |
|