Version Description
- New: Support up to WordPress 5.9.1
- New: Add filter wpstg.frontend.showLoginForm to allow third party plugin disabling login form for the staging site #1577
- New: Add labels to distinguish between network and single site clones on multisite
- Fix: Handle issue when showing staging sites in System Info #1560
- Fix: Fix Rows Generator for zero or negative values for Primary Key Index #1584
- Fix: Set option "Keep permalinks" on the staging site when updating a staging site if "keep permalinks" is active on the production site initially #1562
- Fix: Updating an existing multisite clone converted the clone to a single site #1565 #1589
Download this release
Release Info
Developer | ReneHermi |
Plugin | WP Staging – DB & File Duplicator & Migration |
Version | 2.9.6 |
Comparing to | |
See all releases |
Code changes from version 2.9.5 to 2.9.6
- Backend/Modules/Jobs/SearchReplace.php +5 -3
- Backend/Modules/Jobs/Updating.php +2 -0
- Backend/Modules/SystemInfo.php +14 -11
- Backend/views/backup/listing-single-backup.php +1 -1
- Backend/views/clone/ajax/single-overview.php +5 -0
- Core/DTO/Settings.php +16 -0
- Framework/CloningProcess/Data/CloningService.php +1 -1
- Framework/CloningProcess/Data/UpdateStagingOptionsTable.php +8 -0
- Framework/CloningProcess/Data/UpdateWpConfigConstants.php +4 -4
- Framework/Traits/DbRowsGeneratorTrait.php +14 -9
- Frontend/Frontend.php +6 -1
- constantsFree.php +2 -2
- opcacheBootstrap.php +1 -1
- readme.txt +11 -2
- wp-staging.php +1 -1
Backend/Modules/Jobs/SearchReplace.php
CHANGED
@@ -333,6 +333,7 @@ class SearchReplace extends CloningProcess
|
|
333 |
if (defined('WPSTG_DISABLE_SEARCH_REPLACE_GENERATOR') && WPSTG_DISABLE_SEARCH_REPLACE_GENERATOR) {
|
334 |
$data = $this->stagingDb->get_results("SELECT * FROM $table LIMIT $offset, $limit", ARRAY_A);
|
335 |
} else {
|
|
|
336 |
$data = $this->rowsGenerator($table, $offset, $limit, $this->stagingDb);
|
337 |
}
|
338 |
|
@@ -550,7 +551,7 @@ class SearchReplace extends CloningProcess
|
|
550 |
protected function finishStep()
|
551 |
{
|
552 |
// This job is not finished yet
|
553 |
-
if ($this->options->job->total > $this->options->job->start) {
|
554 |
return false;
|
555 |
}
|
556 |
|
@@ -579,9 +580,10 @@ class SearchReplace extends CloningProcess
|
|
579 |
$this->processed = absint($processed);
|
580 |
|
581 |
// If it is a numeric primary key table execution,
|
582 |
-
//
|
583 |
if ($this->executeNumericPrimaryKeyQuery && $this->lastFetchedPrimaryKeyValue !== false) {
|
584 |
-
$this->options->job->
|
|
|
585 |
return;
|
586 |
}
|
587 |
|
333 |
if (defined('WPSTG_DISABLE_SEARCH_REPLACE_GENERATOR') && WPSTG_DISABLE_SEARCH_REPLACE_GENERATOR) {
|
334 |
$data = $this->stagingDb->get_results("SELECT * FROM $table LIMIT $offset, $limit", ARRAY_A);
|
335 |
} else {
|
336 |
+
$this->lastFetchedPrimaryKeyValue = property_exists($this->options->job, 'lastProcessedId') ? $this->options->job->lastProcessedId : false;
|
337 |
$data = $this->rowsGenerator($table, $offset, $limit, $this->stagingDb);
|
338 |
}
|
339 |
|
551 |
protected function finishStep()
|
552 |
{
|
553 |
// This job is not finished yet
|
554 |
+
if (!$this->noResultRows && ($this->options->job->total > $this->options->job->start)) {
|
555 |
return false;
|
556 |
}
|
557 |
|
580 |
$this->processed = absint($processed);
|
581 |
|
582 |
// If it is a numeric primary key table execution,
|
583 |
+
// Save the last processed primary key value for the next request
|
584 |
if ($this->executeNumericPrimaryKeyQuery && $this->lastFetchedPrimaryKeyValue !== false) {
|
585 |
+
$this->options->job->lastProcessedId = $this->lastFetchedPrimaryKeyValue;
|
586 |
+
$this->options->job->start += $this->processed;
|
587 |
return;
|
588 |
}
|
589 |
|
Backend/Modules/Jobs/Updating.php
CHANGED
@@ -135,6 +135,8 @@ class Updating extends Job
|
|
135 |
$this->options->uploadsSymlinked = isset($this->options->existingClones[strtolower($this->options->clone)]['uploadsSymlinked']) ? $this->options->existingClones[strtolower($this->options->clone)]['uploadsSymlinked'] : false;
|
136 |
$this->options->prefix = $this->options->existingClones[$this->options->clone]['prefix'];
|
137 |
$this->options->emailsAllowed = $this->options->existingClones[$this->options->clone]['emailsAllowed'];
|
|
|
|
|
138 |
//$this->options->prefix = $this->getStagingPrefix();
|
139 |
$helper = new Helper();
|
140 |
$this->options->homeHostname = $helper->getHomeUrlWithoutScheme();
|
135 |
$this->options->uploadsSymlinked = isset($this->options->existingClones[strtolower($this->options->clone)]['uploadsSymlinked']) ? $this->options->existingClones[strtolower($this->options->clone)]['uploadsSymlinked'] : false;
|
136 |
$this->options->prefix = $this->options->existingClones[$this->options->clone]['prefix'];
|
137 |
$this->options->emailsAllowed = $this->options->existingClones[$this->options->clone]['emailsAllowed'];
|
138 |
+
$this->options->networkClone = isset($this->options->existingClones[strtolower($this->options->clone)]['networkClone']) ? $this->options->existingClones[$this->options->clone]['networkClone'] : false;
|
139 |
+
$this->options->networkClone = filter_var($this->options->networkClone, FILTER_VALIDATE_BOOLEAN);
|
140 |
//$this->options->prefix = $this->getStagingPrefix();
|
141 |
$helper = new Helper();
|
142 |
$this->options->homeHostname = $helper->getHomeUrlWithoutScheme();
|
Backend/Modules/SystemInfo.php
CHANGED
@@ -183,17 +183,20 @@ class SystemInfo
|
|
183 |
// old name wpstg_existing_clones_beta
|
184 |
// New name since version 4.0.3 wpstg_staging_sites
|
185 |
$stagingSites = get_option(Sites::STAGING_SITES_OPTION, []);
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
195 |
-
|
196 |
-
|
|
|
|
|
|
|
197 |
}
|
198 |
|
199 |
$output .= $this->info(Sites::STAGING_SITES_OPTION . ": ", serialize(get_option(Sites::STAGING_SITES_OPTION, [])));
|
183 |
// old name wpstg_existing_clones_beta
|
184 |
// New name since version 4.0.3 wpstg_staging_sites
|
185 |
$stagingSites = get_option(Sites::STAGING_SITES_OPTION, []);
|
186 |
+
// make sure $stagingSites is an array
|
187 |
+
if (is_array($stagingSites)) {
|
188 |
+
foreach ($stagingSites as $key => $clone) {
|
189 |
+
$path = !empty($clone['path']) ? $clone['path'] : 'undefined';
|
190 |
+
|
191 |
+
$output .= $this->info("Number:", isset($clone['number']) ? $clone['number'] : 'undefined');
|
192 |
+
$output .= $this->info("directoryName:", isset($clone['directoryName']) ? $clone['directoryName'] : 'undefined');
|
193 |
+
$output .= $this->info("Path:", $path);
|
194 |
+
$output .= $this->info("URL:", isset($clone['url']) ? $clone['url'] : 'undefined');
|
195 |
+
$output .= $this->info("DB Prefix:", isset($clone['prefix']) ? $clone['prefix'] : 'undefined');
|
196 |
+
$output .= $this->info("DB Prefix wp-config.php:", $this->getStagingPrefix($clone));
|
197 |
+
$output .= $this->info("WP Staging Version:", isset($clone['version']) ? $clone['version'] : 'undefined');
|
198 |
+
$output .= $this->info("WP Version:", $this->getStagingWpVersion($path)) . PHP_EOL . PHP_EOL;
|
199 |
+
}
|
200 |
}
|
201 |
|
202 |
$output .= $this->info(Sites::STAGING_SITES_OPTION . ": ", serialize(get_option(Sites::STAGING_SITES_OPTION, [])));
|
Backend/views/backup/listing-single-backup.php
CHANGED
@@ -36,7 +36,7 @@ if (defined('WPSTG_DOWNLOAD_BACKUP_USING_PHP') && WPSTG_DOWNLOAD_BACKUP_USING_PH
|
|
36 |
<?php echo esc_html($name); ?>
|
37 |
</span>
|
38 |
<div class="wpstg-clone-labels">
|
39 |
-
<span class="wpstg-clone-label"><?php echo $backup->type === 'single' ? 'Single Site' : 'Multisite' ?></span>
|
40 |
</div>
|
41 |
<div class="wpstg-clone-actions">
|
42 |
<div class="wpstg-dropdown wpstg-action-dropdown">
|
36 |
<?php echo esc_html($name); ?>
|
37 |
</span>
|
38 |
<div class="wpstg-clone-labels">
|
39 |
+
<span class="wpstg-clone-label"><?php echo $backup->type === 'single' ? __('Single Site', 'wp-staging') : __('Multisite', 'wp-staging') ?></span>
|
40 |
</div>
|
41 |
<div class="wpstg-clone-actions">
|
42 |
<div class="wpstg-dropdown wpstg-action-dropdown">
|
Backend/views/clone/ajax/single-overview.php
CHANGED
@@ -26,6 +26,11 @@
|
|
26 |
<a href="<?php echo $urlLogin ?>" class="wpstg-clone-title" target="_blank">
|
27 |
<?php echo isset($data["cloneName"]) ? $data["cloneName"] : $data["directoryName"]; ?>
|
28 |
</a>
|
|
|
|
|
|
|
|
|
|
|
29 |
<div class="wpstg-clone-actions">
|
30 |
<div class="wpstg-dropdown wpstg-action-dropdown">
|
31 |
<a href="#" class="wpstg-dropdown-toggler transparent">
|
26 |
<a href="<?php echo $urlLogin ?>" class="wpstg-clone-title" target="_blank">
|
27 |
<?php echo isset($data["cloneName"]) ? $data["cloneName"] : $data["directoryName"]; ?>
|
28 |
</a>
|
29 |
+
<?php if (is_multisite()) { ?>
|
30 |
+
<div class="wpstg-clone-labels">
|
31 |
+
<span class="wpstg-clone-label"><?php echo $data['networkClone'] ? __('Network', 'wp-staging') : __('Site', 'wp-staging') ?></span>
|
32 |
+
</div>
|
33 |
+
<?php } ?>
|
34 |
<div class="wpstg-clone-actions">
|
35 |
<div class="wpstg-dropdown wpstg-action-dropdown">
|
36 |
<a href="#" class="wpstg-dropdown-toggler transparent">
|
Core/DTO/Settings.php
CHANGED
@@ -153,6 +153,22 @@ class Settings
|
|
153 |
$this->queryLimit = $queryLimit;
|
154 |
}
|
155 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
156 |
/**
|
157 |
* @return int
|
158 |
*/
|
153 |
$this->queryLimit = $queryLimit;
|
154 |
}
|
155 |
|
156 |
+
/**
|
157 |
+
* @return int
|
158 |
+
*/
|
159 |
+
public function getQuerySRLimit()
|
160 |
+
{
|
161 |
+
return $this->querySRLimit;
|
162 |
+
}
|
163 |
+
|
164 |
+
/**
|
165 |
+
* @param int $querySRLimit
|
166 |
+
*/
|
167 |
+
public function setQuerySRLimit($querySRLimit)
|
168 |
+
{
|
169 |
+
$this->querySRLimit = $querySRLimit;
|
170 |
+
}
|
171 |
+
|
172 |
/**
|
173 |
* @return int
|
174 |
*/
|
Framework/CloningProcess/Data/CloningService.php
CHANGED
@@ -94,7 +94,7 @@ abstract class CloningService
|
|
94 |
}
|
95 |
|
96 |
/**
|
97 |
-
*
|
98 |
*
|
99 |
* @return boolean
|
100 |
*/
|
94 |
}
|
95 |
|
96 |
/**
|
97 |
+
* Is the current clone network?
|
98 |
*
|
99 |
* @return boolean
|
100 |
*/
|
Framework/CloningProcess/Data/UpdateStagingOptionsTable.php
CHANGED
@@ -78,6 +78,14 @@ class UpdateStagingOptionsTable extends DBCloningService
|
|
78 |
if (!$this->keepPermalinks()) {
|
79 |
$updateOrInsert['rewrite_rules'] = null;
|
80 |
$updateOrInsert['permalink_structure'] = ' ';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
81 |
}
|
82 |
|
83 |
$freemiusHelper = new FreemiusScript();
|
78 |
if (!$this->keepPermalinks()) {
|
79 |
$updateOrInsert['rewrite_rules'] = null;
|
80 |
$updateOrInsert['permalink_structure'] = ' ';
|
81 |
+
} else {
|
82 |
+
/**
|
83 |
+
* if staging site is created with keep permalinks setting off,
|
84 |
+
* The below code make sure permalinks settings are kept during update,
|
85 |
+
* when later production site has keep permalinks setting on,
|
86 |
+
* without the need to also keep permalinks setting on staging site too.
|
87 |
+
*/
|
88 |
+
$updateOrInsert['wpstg_rmpermalinks_executed'] = 'true';
|
89 |
}
|
90 |
|
91 |
$freemiusHelper = new FreemiusScript();
|
Framework/CloningProcess/Data/UpdateWpConfigConstants.php
CHANGED
@@ -35,13 +35,13 @@ class UpdateWpConfigConstants extends FileCloningService
|
|
35 |
$replaceOrAdd['DB_NAME'] = sprintf("'%s'", $this->escapeSingleQuotes($this->dto->getExternalDatabaseName()));
|
36 |
}
|
37 |
|
|
|
38 |
if ($this->isNetworkClone()) {
|
39 |
$replaceOrAdd['DOMAIN_CURRENT_SITE'] = sprintf("'%s'", $this->escapeSingleQuotes($this->dto->getStagingSiteDomain()));
|
40 |
$replaceOrAdd['PATH_CURRENT_SITE'] = sprintf("'%s'", trailingslashit($this->escapeSingleQuotes($this->dto->getStagingSitePath())));
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
if (!$this->isNetworkClone()) {
|
45 |
//It's OK to attempt replacing multi-site constants even in single-site jobs as they will not be present in a single-site wp-config.php
|
46 |
$replaceOrSkip["WP_ALLOW_MULTISITE"] = 'false';
|
47 |
$replaceOrSkip["MULTISITE"] = 'false';
|
35 |
$replaceOrAdd['DB_NAME'] = sprintf("'%s'", $this->escapeSingleQuotes($this->dto->getExternalDatabaseName()));
|
36 |
}
|
37 |
|
38 |
+
$replaceOrSkip = [];
|
39 |
if ($this->isNetworkClone()) {
|
40 |
$replaceOrAdd['DOMAIN_CURRENT_SITE'] = sprintf("'%s'", $this->escapeSingleQuotes($this->dto->getStagingSiteDomain()));
|
41 |
$replaceOrAdd['PATH_CURRENT_SITE'] = sprintf("'%s'", trailingslashit($this->escapeSingleQuotes($this->dto->getStagingSitePath())));
|
42 |
+
$replaceOrSkip["WP_ALLOW_MULTISITE"] = 'true';
|
43 |
+
$replaceOrSkip["MULTISITE"] = 'true';
|
44 |
+
} else {
|
|
|
45 |
//It's OK to attempt replacing multi-site constants even in single-site jobs as they will not be present in a single-site wp-config.php
|
46 |
$replaceOrSkip["WP_ALLOW_MULTISITE"] = 'false';
|
47 |
$replaceOrSkip["MULTISITE"] = 'false';
|
Framework/Traits/DbRowsGeneratorTrait.php
CHANGED
@@ -31,6 +31,9 @@ trait DbRowsGeneratorTrait
|
|
31 |
/** @var string */
|
32 |
public $numericPrimaryKey = null;
|
33 |
|
|
|
|
|
|
|
34 |
/**
|
35 |
* Used by unit tests
|
36 |
* @var bool
|
@@ -147,11 +150,6 @@ trait DbRowsGeneratorTrait
|
|
147 |
$batchSize = ceil($batchSize);
|
148 |
$lastFetch = false;
|
149 |
|
150 |
-
$this->lastFetchedPrimaryKeyValue = false;
|
151 |
-
if (!empty($numericPrimaryKey)) {
|
152 |
-
$this->lastFetchedPrimaryKeyValue = $offset;
|
153 |
-
}
|
154 |
-
|
155 |
do {
|
156 |
if (count($rows) === 0) {
|
157 |
if ($lastFetch) {
|
@@ -160,10 +158,15 @@ trait DbRowsGeneratorTrait
|
|
160 |
|
161 |
// Optimal! We have a Primary Key so it doesn't get slower on large offsets.
|
162 |
if (!empty($numericPrimaryKey)) {
|
|
|
|
|
|
|
|
|
|
|
163 |
$query = <<<SQL
|
164 |
SELECT *
|
165 |
FROM `{$table}`
|
166 |
-
|
167 |
ORDER BY `{$numericPrimaryKey}` ASC
|
168 |
LIMIT 0, {$batchSize}
|
169 |
SQL;
|
@@ -171,6 +174,7 @@ SQL;
|
|
171 |
$query = "SELECT * FROM `{$table}` LIMIT {$offset}, {$batchSize}";
|
172 |
}
|
173 |
|
|
|
174 |
$rows = $db->get_results($query, ARRAY_A);
|
175 |
|
176 |
// Call to mysql_free_result
|
@@ -181,7 +185,8 @@ SQL;
|
|
181 |
}
|
182 |
|
183 |
// We're done here.
|
184 |
-
if (empty($rows)) {
|
|
|
185 |
break;
|
186 |
}
|
187 |
|
@@ -202,9 +207,9 @@ SQL;
|
|
202 |
break;
|
203 |
}
|
204 |
|
205 |
-
// save the last fetched primary key
|
206 |
if (!empty($numericPrimaryKey)) {
|
207 |
-
$this->lastFetchedPrimaryKeyValue = $row[$
|
208 |
}
|
209 |
|
210 |
yield $row;
|
31 |
/** @var string */
|
32 |
public $numericPrimaryKey = null;
|
33 |
|
34 |
+
/** @var bool */
|
35 |
+
public $noResultRows = false;
|
36 |
+
|
37 |
/**
|
38 |
* Used by unit tests
|
39 |
* @var bool
|
150 |
$batchSize = ceil($batchSize);
|
151 |
$lastFetch = false;
|
152 |
|
|
|
|
|
|
|
|
|
|
|
153 |
do {
|
154 |
if (count($rows) === 0) {
|
155 |
if ($lastFetch) {
|
158 |
|
159 |
// Optimal! We have a Primary Key so it doesn't get slower on large offsets.
|
160 |
if (!empty($numericPrimaryKey)) {
|
161 |
+
$whereCondition = '';
|
162 |
+
if ($this->lastFetchedPrimaryKeyValue !== false) {
|
163 |
+
$whereCondition = "WHERE `{$numericPrimaryKey}` > {$this->lastFetchedPrimaryKeyValue}";
|
164 |
+
}
|
165 |
+
|
166 |
$query = <<<SQL
|
167 |
SELECT *
|
168 |
FROM `{$table}`
|
169 |
+
{$whereCondition}
|
170 |
ORDER BY `{$numericPrimaryKey}` ASC
|
171 |
LIMIT 0, {$batchSize}
|
172 |
SQL;
|
174 |
$query = "SELECT * FROM `{$table}` LIMIT {$offset}, {$batchSize}";
|
175 |
}
|
176 |
|
177 |
+
$this->noResultRows = false;
|
178 |
$rows = $db->get_results($query, ARRAY_A);
|
179 |
|
180 |
// Call to mysql_free_result
|
185 |
}
|
186 |
|
187 |
// We're done here.
|
188 |
+
if (empty($rows) || count($rows) === 0) {
|
189 |
+
$this->noResultRows = true;
|
190 |
break;
|
191 |
}
|
192 |
|
207 |
break;
|
208 |
}
|
209 |
|
210 |
+
// save the last fetched primary key for next requests
|
211 |
if (!empty($numericPrimaryKey)) {
|
212 |
+
$this->lastFetchedPrimaryKeyValue = $row[$numericPrimaryKey];
|
213 |
}
|
214 |
|
215 |
yield $row;
|
Frontend/Frontend.php
CHANGED
@@ -90,7 +90,12 @@ class Frontend
|
|
90 |
{
|
91 |
$this->accessDenied = false;
|
92 |
|
93 |
-
//
|
|
|
|
|
|
|
|
|
|
|
94 |
if ((new Rest())->isRestUrl()) {
|
95 |
return false;
|
96 |
}
|
90 |
{
|
91 |
$this->accessDenied = false;
|
92 |
|
93 |
+
// Don't show login form if showLoginForm filter is set to false. Used by Real Cookie Banner plugin
|
94 |
+
if (apply_filters('wpstg.frontend.showLoginForm', false)) {
|
95 |
+
return false;
|
96 |
+
}
|
97 |
+
|
98 |
+
// Don't show login form for rest requests
|
99 |
if ((new Rest())->isRestUrl()) {
|
100 |
return false;
|
101 |
}
|
constantsFree.php
CHANGED
@@ -2,10 +2,10 @@
|
|
2 |
|
3 |
// WP STAGING version number
|
4 |
if (!defined('WPSTG_VERSION')) {
|
5 |
-
define('WPSTG_VERSION', '2.9.
|
6 |
}
|
7 |
|
8 |
// Compatible up to WordPress Version
|
9 |
if (!defined('WPSTG_COMPATIBLE')) {
|
10 |
-
define('WPSTG_COMPATIBLE', '5.
|
11 |
}
|
2 |
|
3 |
// WP STAGING version number
|
4 |
if (!defined('WPSTG_VERSION')) {
|
5 |
+
define('WPSTG_VERSION', '2.9.6');
|
6 |
}
|
7 |
|
8 |
// Compatible up to WordPress Version
|
9 |
if (!defined('WPSTG_COMPATIBLE')) {
|
10 |
+
define('WPSTG_COMPATIBLE', '5.9.1');
|
11 |
}
|
opcacheBootstrap.php
CHANGED
@@ -45,7 +45,7 @@ if (!$canInvalidate) {
|
|
45 |
*
|
46 |
* We use the "Version" from the headers of the main file of the plugin to compare.
|
47 |
*/
|
48 |
-
$runtimeVersionDifferentFromBuildVersion = get_file_data($pluginFilePath, ['Version' => 'Version'])['Version'] !== '2.9.
|
49 |
$lastCheckHappenedAfterInterval = current_time('timestamp') > (int)get_site_transient('wpstg.bootstrap.opcache.lastCleared') + 5 * MINUTE_IN_SECONDS;
|
50 |
|
51 |
$shouldClearOpCache = apply_filters('wpstg.bootstrap.opcache.shouldClear', $runtimeVersionDifferentFromBuildVersion && $lastCheckHappenedAfterInterval);
|
45 |
*
|
46 |
* We use the "Version" from the headers of the main file of the plugin to compare.
|
47 |
*/
|
48 |
+
$runtimeVersionDifferentFromBuildVersion = get_file_data($pluginFilePath, ['Version' => 'Version'])['Version'] !== '2.9.6';
|
49 |
$lastCheckHappenedAfterInterval = current_time('timestamp') > (int)get_site_transient('wpstg.bootstrap.opcache.lastCleared') + 5 * MINUTE_IN_SECONDS;
|
50 |
|
51 |
$shouldClearOpCache = apply_filters('wpstg.bootstrap.opcache.shouldClear', $runtimeVersionDifferentFromBuildVersion && $lastCheckHappenedAfterInterval);
|
readme.txt
CHANGED
@@ -8,8 +8,8 @@ License: GPLv2 or later
|
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
Tags: backup, cloud backup, database backup, restore, wordpress backup
|
10 |
Requires at least: 3.6+
|
11 |
-
Tested up to: 5.
|
12 |
-
Stable tag: 2.9.
|
13 |
Requires PHP: 5.6
|
14 |
|
15 |
Backup & Duplicator Plugin - Clone, move, duplicate & migrate websites to staging, backup, and development sites for authorized users only.
|
@@ -193,6 +193,15 @@ https://wp-staging.com
|
|
193 |
|
194 |
== Changelog ==
|
195 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
196 |
= 2.9.5 =
|
197 |
* New: Create backups and restore of multisites (PRO) #1458
|
198 |
* Fix: Force AnalyticsSender to convert wpstg_settings to array before usage #1559
|
8 |
License URI: http://www.gnu.org/licenses/gpl-2.0.html
|
9 |
Tags: backup, cloud backup, database backup, restore, wordpress backup
|
10 |
Requires at least: 3.6+
|
11 |
+
Tested up to: 5.9
|
12 |
+
Stable tag: 2.9.6
|
13 |
Requires PHP: 5.6
|
14 |
|
15 |
Backup & Duplicator Plugin - Clone, move, duplicate & migrate websites to staging, backup, and development sites for authorized users only.
|
193 |
|
194 |
== Changelog ==
|
195 |
|
196 |
+
= 2.9.6 =
|
197 |
+
* New: Support up to WordPress 5.9.1
|
198 |
+
* New: Add filter wpstg.frontend.showLoginForm to allow third party plugin disabling login form for the staging site #1577
|
199 |
+
* New: Add labels to distinguish between network and single site clones on multisite
|
200 |
+
* Fix: Handle issue when showing staging sites in System Info #1560
|
201 |
+
* Fix: Fix Rows Generator for zero or negative values for Primary Key Index #1584
|
202 |
+
* Fix: Set option "Keep permalinks" on the staging site when updating a staging site if "keep permalinks" is active on the production site initially #1562
|
203 |
+
* Fix: Updating an existing multisite clone converted the clone to a single site #1565 #1589
|
204 |
+
|
205 |
= 2.9.5 =
|
206 |
* New: Create backups and restore of multisites (PRO) #1458
|
207 |
* Fix: Force AnalyticsSender to convert wpstg_settings to array before usage #1559
|
wp-staging.php
CHANGED
@@ -7,7 +7,7 @@
|
|
7 |
* Author: WP-STAGING
|
8 |
* Author URI: https://wp-staging.com
|
9 |
* Contributors: ReneHermi
|
10 |
-
* Version: 2.9.
|
11 |
* Text Domain: wp-staging
|
12 |
* Domain Path: /languages/
|
13 |
*
|
7 |
* Author: WP-STAGING
|
8 |
* Author URI: https://wp-staging.com
|
9 |
* Contributors: ReneHermi
|
10 |
+
* Version: 2.9.6
|
11 |
* Text Domain: wp-staging
|
12 |
* Domain Path: /languages/
|
13 |
*
|