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

Version Description

  • Fix: If there is a damaged backup in backup folder, automated backup does not work any longer #1707
  • Fix: Support UNC paths like //servername/path Unix or \servername\path DOS/Windows #1698
  • Fix: Remove prefixed vendor namespace from the Normalizer class in the idn-intl polyfill #1720
  • Fix: Handle SSL related errors and catch other exceptions while making remote request to refresh Google token #1718
  • Fix: Backup does not restore theme if theme does not have a style.css #1719
  • Fix: Missing exception in Backup Extractor.php #1724
  • Enh: List damaged backup files in the UI and mark them #1710
  • Enh: Remove message "backup metadata not found" in debug log #1710
  • Enh: Clean up debug messages #1722
  • Enh: Add missing escaping of POST output #1705
Download this release

Release Info

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

Code changes from version 2.9.11 to 2.9.12

Backend/Modules/Jobs/Directories.php CHANGED
@@ -6,6 +6,7 @@ use Exception;
6
  use WPStaging\Core\WPStaging;
7
  use WPStaging\Framework\Adapter\Directory;
8
  use WPStaging\Framework\CloningProcess\ExcludedPlugins;
 
9
  use WPStaging\Framework\Filesystem\Filters\ExcludeFilter;
10
  use WPStaging\Framework\Traits\FileScanToCacheTrait;
11
  use WPStaging\Framework\Utils\SlashMode;
@@ -15,6 +16,7 @@ use WPStaging\Framework\Utils\WpDefaultDirectories;
15
  /**
16
  * Class Files
17
  * @package WPStaging\Backend\Modules\Directories
 
18
  */
19
  class Directories extends JobExecutable
20
  {
@@ -47,6 +49,16 @@ class Directories extends JobExecutable
47
  */
48
  private $strUtils;
49
 
 
 
 
 
 
 
 
 
 
 
50
  /**
51
  * Initialize
52
  */
@@ -55,6 +67,8 @@ class Directories extends JobExecutable
55
  $this->filename = $this->cache->getCacheDir() . "files_to_copy." . $this->cache->getCacheExtension();
56
  $this->wpDirectories = new WpDefaultDirectories();
57
  $this->strUtils = new Strings();
 
 
58
  }
59
 
60
  /**
@@ -126,20 +140,22 @@ class Directories extends JobExecutable
126
  return true;
127
  }
128
 
 
 
 
129
  // Skip it
130
  if (!is_dir($directory)) {
131
- $this->log("Skipping: {$directory} does not exist.");
132
  return true;
133
  }
134
 
135
  // Skip it
136
  if ($this->isDirectoryExcluded($directory)) {
137
- $this->log("Skipping: {$directory}");
138
  return true;
139
  }
140
 
141
- $relativeDirectory = str_replace($this->strUtils->sanitizeDirectorySeparator(ABSPATH), '', $directory);
142
- $this->log("Scanning " . $relativeDirectory . " and its sub-directories and files");
143
 
144
  // open file handle
145
  $files = $this->open($this->filename, 'a');
@@ -175,16 +191,20 @@ class Directories extends JobExecutable
175
  private function getWpContentFiles()
176
  {
177
  $directory = WP_CONTENT_DIR;
 
 
 
 
178
  // Skip it
179
  if ($this->isDirectoryExcluded($directory)) {
180
- $this->log("Skip " . $directory);
181
  return true;
182
  }
 
183
  // open file handle
184
  $files = $this->open($this->filename, 'a');
185
 
186
- $relativeDirectory = str_replace(ABSPATH, '', $directory);
187
- $this->log("Scanning " . $relativeDirectory . " for other directories");
188
 
189
  $excludePaths = [
190
  $this->wpDirectories->getRelativeWpContentPath(SlashMode::BOTH_SLASHES) . 'cache',
@@ -217,16 +237,20 @@ class Directories extends JobExecutable
217
  private function getWpIncludesFiles()
218
  {
219
  $directory = ABSPATH . 'wp-includes';
 
 
 
 
220
  // Skip it
221
  if ($this->isDirectoryExcluded($directory)) {
222
- $this->log("Skip " . $directory);
223
  return true;
224
  }
 
225
  // open file handle
226
  $files = $this->open($this->filename, 'a');
227
 
228
- $relativeDirectory = str_replace(ABSPATH, '', $directory);
229
- $this->log("Scanning " . $relativeDirectory . " for its sub-directories and files");
230
 
231
  try {
232
  $this->options->totalFiles += $this->scanToCacheFile($files, $directory, true);
@@ -247,16 +271,20 @@ class Directories extends JobExecutable
247
  private function getWpAdminFiles()
248
  {
249
  $directory = ABSPATH . 'wp-admin';
 
 
 
 
250
  // Skip it
251
  if ($this->isDirectoryExcluded($directory)) {
252
- $this->log("Skip " . $directory);
253
  return true;
254
  }
 
255
  // open file handle
256
  $files = $this->open($this->filename, 'a');
257
 
258
- $relativeDirectory = str_replace(ABSPATH, '', $directory);
259
- $this->log("Scanning " . $relativeDirectory . " for its sub-directories and files");
260
 
261
  try {
262
  $this->options->totalFiles += $this->scanToCacheFile($files, $directory, true);
6
  use WPStaging\Core\WPStaging;
7
  use WPStaging\Framework\Adapter\Directory;
8
  use WPStaging\Framework\CloningProcess\ExcludedPlugins;
9
+ use WPStaging\Framework\Filesystem\Filesystem;
10
  use WPStaging\Framework\Filesystem\Filters\ExcludeFilter;
11
  use WPStaging\Framework\Traits\FileScanToCacheTrait;
12
  use WPStaging\Framework\Utils\SlashMode;
16
  /**
17
  * Class Files
18
  * @package WPStaging\Backend\Modules\Directories
19
+ * @todo DRY this class and WPStaging\Backend\Pro\Modules\Directories class
20
  */
21
  class Directories extends JobExecutable
22
  {
49
  */
50
  private $strUtils;
51
 
52
+ /**
53
+ * @var Filesystem
54
+ */
55
+ private $filesystem;
56
+
57
+ /**
58
+ * @var string
59
+ */
60
+ private $rootPath;
61
+
62
  /**
63
  * Initialize
64
  */
67
  $this->filename = $this->cache->getCacheDir() . "files_to_copy." . $this->cache->getCacheExtension();
68
  $this->wpDirectories = new WpDefaultDirectories();
69
  $this->strUtils = new Strings();
70
+ $this->filesystem = WPStaging::make(Filesystem::class);
71
+ $this->rootPath = $this->filesystem->normalizePath(ABSPATH, true);
72
  }
73
 
74
  /**
140
  return true;
141
  }
142
 
143
+ $directory = $this->filesystem->normalizePath($directory);
144
+ $relPath = str_replace($this->rootPath, '', $directory);
145
+
146
  // Skip it
147
  if (!is_dir($directory)) {
148
+ $this->log("Skipping: {$relPath} does not exist.");
149
  return true;
150
  }
151
 
152
  // Skip it
153
  if ($this->isDirectoryExcluded($directory)) {
154
+ $this->log("Skipping: {$relPath}");
155
  return true;
156
  }
157
 
158
+ $this->log("Scanning {$relPath} and its sub-directories and files");
 
159
 
160
  // open file handle
161
  $files = $this->open($this->filename, 'a');
191
  private function getWpContentFiles()
192
  {
193
  $directory = WP_CONTENT_DIR;
194
+
195
+ $directory = $this->filesystem->normalizePath($directory);
196
+ $relPath = str_replace($this->rootPath, '', $directory);
197
+
198
  // Skip it
199
  if ($this->isDirectoryExcluded($directory)) {
200
+ $this->log("Skipping {$relPath} for other files.");
201
  return true;
202
  }
203
+
204
  // open file handle
205
  $files = $this->open($this->filename, 'a');
206
 
207
+ $this->log("Scanning {$relPath} for other directories and files");
 
208
 
209
  $excludePaths = [
210
  $this->wpDirectories->getRelativeWpContentPath(SlashMode::BOTH_SLASHES) . 'cache',
237
  private function getWpIncludesFiles()
238
  {
239
  $directory = ABSPATH . 'wp-includes';
240
+
241
+ $directory = $this->filesystem->normalizePath($directory);
242
+ $relPath = str_replace($this->rootPath, '', $directory);
243
+
244
  // Skip it
245
  if ($this->isDirectoryExcluded($directory)) {
246
+ $this->log("Skipping " . $relPath);
247
  return true;
248
  }
249
+
250
  // open file handle
251
  $files = $this->open($this->filename, 'a');
252
 
253
+ $this->log("Scanning " . $relPath . " for its sub-directories and files");
 
254
 
255
  try {
256
  $this->options->totalFiles += $this->scanToCacheFile($files, $directory, true);
271
  private function getWpAdminFiles()
272
  {
273
  $directory = ABSPATH . 'wp-admin';
274
+
275
+ $directory = $this->filesystem->normalizePath($directory);
276
+ $relPath = str_replace($this->rootPath, '', $directory);
277
+
278
  // Skip it
279
  if ($this->isDirectoryExcluded($directory)) {
280
+ $this->log("Skipping " . $relPath);
281
  return true;
282
  }
283
+
284
  // open file handle
285
  $files = $this->open($this->filename, 'a');
286
 
287
+ $this->log("Scanning " . $relPath . " for its sub-directories and files");
 
288
 
289
  try {
290
  $this->options->totalFiles += $this->scanToCacheFile($files, $directory, true);
Backend/Modules/Jobs/Files.php CHANGED
@@ -44,15 +44,28 @@ class Files extends JobExecutable
44
  */
45
  private $permissions;
46
 
 
 
 
 
 
 
 
 
 
 
47
  /**
48
  * Initialization
49
  */
50
  public function initialize()
51
  {
52
-
53
  $this->permissions = new Permissions();
 
 
 
 
54
 
55
- $this->destination = $this->options->destinationDir;
56
 
57
  $filePath = $this->cache->getCacheDir() . "files_to_copy." . $this->cache->getCacheExtension();
58
 
@@ -182,7 +195,7 @@ class Files extends JobExecutable
182
  ->shouldPermissionExceptionsBypass(true)
183
  ->setRecursive(true);
184
  try {
185
- if (!$fs->delete($this->destination)) {
186
  foreach ($fs->getLogs() as $log) {
187
  $this->log($log, Logger::TYPE_WARNING);
188
  }
@@ -339,7 +352,7 @@ class Files extends JobExecutable
339
  {
340
  $file = trim(WPStaging::getWPpath() . $file);
341
 
342
- $file = wpstg_replace_windows_directory_separator($file);
343
 
344
  $directory = dirname($file);
345
 
@@ -365,13 +378,13 @@ class Files extends JobExecutable
365
  $this->log("File doesn't exist {$file}", Logger::TYPE_WARNING);
366
  return true;
367
  }
368
- // Invalid file, skipping it as if succeeded
369
- if (!is_readable($file)) {
 
370
  $this->log("Can't read file {$file}", Logger::TYPE_WARNING);
371
  return true;
372
  }
373
 
374
-
375
  // Get file size
376
  $fileSize = filesize($file);
377
 
@@ -429,20 +442,18 @@ class Files extends JobExecutable
429
  */
430
  private function getDestination($file)
431
  {
432
- $file = wpstg_replace_windows_directory_separator($file);
433
- $rootPath = wpstg_replace_windows_directory_separator(WPStaging::getWPpath());
434
- $relativePath = str_replace($rootPath, '', $file);
435
  $destinationPath = $this->destination . $relativePath;
436
  $destinationDirectory = dirname($destinationPath);
437
 
438
- $fs = new Filesystem();
439
- $isDirectoryNotCreated = !is_dir($destinationDirectory) && !$fs->mkdir($destinationDirectory) && !is_dir($destinationDirectory);
440
  if ($isDirectoryNotCreated) {
441
- $this->log("Files: Can not create directory {$destinationDirectory}." . $fs->getLogs()[0], Logger::TYPE_ERROR);
442
  return false;
443
  }
444
 
445
- return $this->sanitizeDirectorySeparator($destinationPath);
446
  }
447
 
448
  /**
@@ -503,7 +514,7 @@ class Files extends JobExecutable
503
  );
504
  }
505
 
506
- if ((new Filesystem())->isFilenameExcluded($file, $excludedFiles)) {
507
  return true;
508
  }
509
 
44
  */
45
  private $permissions;
46
 
47
+ /**
48
+ * @var Filesystem
49
+ */
50
+ private $filesystem;
51
+
52
+ /**
53
+ * @var string
54
+ */
55
+ private $rootPath;
56
+
57
  /**
58
  * Initialization
59
  */
60
  public function initialize()
61
  {
 
62
  $this->permissions = new Permissions();
63
+ /** @var Filesystem */
64
+ $this->filesystem = WPStaging::make(Filesystem::class);
65
+
66
+ $this->rootPath = $this->filesystem->normalizePath(WPStaging::getWPpath(), true);
67
 
68
+ $this->destination = $this->filesystem->normalizePath($this->options->destinationDir, true);
69
 
70
  $filePath = $this->cache->getCacheDir() . "files_to_copy." . $this->cache->getCacheExtension();
71
 
195
  ->shouldPermissionExceptionsBypass(true)
196
  ->setRecursive(true);
197
  try {
198
+ if (!$fs->delete($this->destination, false)) {
199
  foreach ($fs->getLogs() as $log) {
200
  $this->log($log, Logger::TYPE_WARNING);
201
  }
352
  {
353
  $file = trim(WPStaging::getWPpath() . $file);
354
 
355
+ $file = $this->filesystem->normalizePath($file, true);
356
 
357
  $directory = dirname($file);
358
 
378
  $this->log("File doesn't exist {$file}", Logger::TYPE_WARNING);
379
  return true;
380
  }
381
+
382
+ // If file is unreadable, skip it as if succeeded
383
+ if (!$this->filesystem->isReadableFile($file)) {
384
  $this->log("Can't read file {$file}", Logger::TYPE_WARNING);
385
  return true;
386
  }
387
 
 
388
  // Get file size
389
  $fileSize = filesize($file);
390
 
442
  */
443
  private function getDestination($file)
444
  {
445
+ $file = $this->filesystem->normalizePath($file, true);
446
+ $relativePath = str_replace($this->rootPath, '', $file);
 
447
  $destinationPath = $this->destination . $relativePath;
448
  $destinationDirectory = dirname($destinationPath);
449
 
450
+ $isDirectoryNotCreated = !is_dir($destinationDirectory) && !$this->filesystem->mkdir($destinationDirectory) && !is_dir($destinationDirectory);
 
451
  if ($isDirectoryNotCreated) {
452
+ $this->log("Files: Can not create directory {$destinationDirectory}." . $this->filesystem->getLogs()[0], Logger::TYPE_ERROR);
453
  return false;
454
  }
455
 
456
+ return $this->filesystem->normalizePath($destinationPath, true);
457
  }
458
 
459
  /**
514
  );
515
  }
516
 
517
+ if ($this->filesystem->isFilenameExcluded($file, $excludedFiles)) {
518
  return true;
519
  }
520
 
Backend/views/backup/listing-single-backup.php CHANGED
@@ -15,6 +15,7 @@ $size = $backup->size;
15
  $id = $backup->id;
16
  $automatedBackup = $backup->automatedBackup;
17
  $legacy = $backup->legacy;
 
18
 
19
  $isUnsupported = version_compare($backup->generatedOnWPStagingVersion, RestoreRequirementsCheckTask::BETA_VERSION_LIMIT, '<');
20
 
@@ -35,9 +36,11 @@ if (defined('WPSTG_DOWNLOAD_BACKUP_USING_PHP') && WPSTG_DOWNLOAD_BACKUP_USING_PH
35
  <span class="wpstg-clone-title">
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">
43
  <a href="#" class="wpstg-dropdown-toggler transparent">
@@ -45,7 +48,7 @@ if (defined('WPSTG_DOWNLOAD_BACKUP_USING_PHP') && WPSTG_DOWNLOAD_BACKUP_USING_PH
45
  <span class="wpstg-caret"></span>
46
  </a>
47
  <div class="wpstg-dropdown-menu">
48
- <?php if (!$legacy) : ?>
49
  <a href="#" class="wpstg-clone-action wpstg--backup--restore"
50
  data-filePath="<?php echo esc_attr($backup->relativePath) ?>"
51
  data-title="<?php esc_attr_e('Restore and overwrite current website according to the contents of this backup.', 'wp-staging') ?>"
@@ -58,7 +61,7 @@ if (defined('WPSTG_DOWNLOAD_BACKUP_USING_PHP') && WPSTG_DOWNLOAD_BACKUP_USING_PH
58
  title="<?php esc_attr_e('Download backup file on local system', 'wp-staging') ?>">
59
  <?php esc_html_e('Download', 'wp-staging') ?>
60
  </a>
61
- <?php if (!$legacy) : ?>
62
  <a href="#" class="wpstg--backup--edit wpstg-clone-action"
63
  data-md5="<?php echo esc_attr($backup->md5BaseName); ?>"
64
  data-name="<?php echo esc_attr($name); ?>"
@@ -82,14 +85,19 @@ if (defined('WPSTG_DOWNLOAD_BACKUP_USING_PHP') && WPSTG_DOWNLOAD_BACKUP_USING_PH
82
 
83
  <div class="wpstg-staging-info">
84
  <ul>
85
- <?php if ($isUnsupported) : ?>
 
 
 
 
 
86
  <li class="wpstg-unsupported-backup wpstg--red">
87
  <div class="wpstg-exclamation">!</div><strong><?php esc_html_e('This backup was generated on the Beta version of WP STAGING and cannot be restored with the current version.', 'wp-staging') ?></strong><br/>
88
  </li>
89
  <?php endif ?>
90
  <?php if ($createdAt) : ?>
91
  <li>
92
- <strong><?php esc_html_e('Created on:', 'wp-staging') ?></strong>
93
  <?php
94
  $date = new DateTime();
95
  $date->setTimestamp($createdAt);
@@ -109,6 +117,7 @@ if (defined('WPSTG_DOWNLOAD_BACKUP_USING_PHP') && WPSTG_DOWNLOAD_BACKUP_USING_PH
109
  <strong><?php esc_html_e('Size: ', 'wp-staging') ?></strong>
110
  <?php echo esc_html($size); ?>
111
  </li>
 
112
  <li class="single-backup-includes">
113
  <strong><?php esc_html_e('Contains: ', 'wp-staging') ?></strong>
114
  <?php
@@ -121,15 +130,16 @@ if (defined('WPSTG_DOWNLOAD_BACKUP_USING_PHP') && WPSTG_DOWNLOAD_BACKUP_USING_PH
121
  include(__DIR__ . '/modal/partials/backup-contains.php');
122
  ?>
123
  </li>
124
- <?php if ($automatedBackup) : ?>
125
  <li style="font-style: italic">
126
  <img class="wpstg--dashicons wpstg-dashicons-19 wpstg-dashicons-grey wpstg--backup-automated" src="<?php echo $urlAssets; ?>svg/vendor/dashicons/update.svg" /> <?php esc_html_e('Backup created automatically.', 'wp-staging') ?>
127
  </li>
128
- <?php endif ?>
129
- <?php if ($legacy) : ?>
130
  <li style="font-style: italic">
131
  <img class="wpstg--dashicons wpstg-dashicons-19 wpstg-dashicons-grey" src="<?php echo $urlAssets; ?>svg/vendor/dashicons/cloud-saved.svg" /> <?php esc_html_e('This database backup was generated from an existing legacy WP STAGING Database export in the .SQL format.', 'wp-staging') ?>
132
  </li>
 
133
  <?php endif ?>
134
  </ul>
135
  </div>
15
  $id = $backup->id;
16
  $automatedBackup = $backup->automatedBackup;
17
  $legacy = $backup->legacy;
18
+ $corrupt = $backup->corrupt;
19
 
20
  $isUnsupported = version_compare($backup->generatedOnWPStagingVersion, RestoreRequirementsCheckTask::BETA_VERSION_LIMIT, '<');
21
 
36
  <span class="wpstg-clone-title">
37
  <?php echo esc_html($name); ?>
38
  </span>
39
+ <?php if (!$corrupt) : ?>
40
  <div class="wpstg-clone-labels">
41
  <span class="wpstg-clone-label"><?php echo $backup->type === 'single' ? __('Single Site', 'wp-staging') : __('Multisite', 'wp-staging') ?></span>
42
  </div>
43
+ <?php endif ?>
44
  <div class="wpstg-clone-actions">
45
  <div class="wpstg-dropdown wpstg-action-dropdown">
46
  <a href="#" class="wpstg-dropdown-toggler transparent">
48
  <span class="wpstg-caret"></span>
49
  </a>
50
  <div class="wpstg-dropdown-menu">
51
+ <?php if (!$legacy && !$corrupt) : ?>
52
  <a href="#" class="wpstg-clone-action wpstg--backup--restore"
53
  data-filePath="<?php echo esc_attr($backup->relativePath) ?>"
54
  data-title="<?php esc_attr_e('Restore and overwrite current website according to the contents of this backup.', 'wp-staging') ?>"
61
  title="<?php esc_attr_e('Download backup file on local system', 'wp-staging') ?>">
62
  <?php esc_html_e('Download', 'wp-staging') ?>
63
  </a>
64
+ <?php if (!$legacy && !$corrupt) : ?>
65
  <a href="#" class="wpstg--backup--edit wpstg-clone-action"
66
  data-md5="<?php echo esc_attr($backup->md5BaseName); ?>"
67
  data-name="<?php echo esc_attr($name); ?>"
85
 
86
  <div class="wpstg-staging-info">
87
  <ul>
88
+ <?php if ($corrupt) : ?>
89
+ <li class="wpstg-corrupted-backup wpstg--red">
90
+ <div class="wpstg-exclamation">!</div><strong><?php esc_html_e('This backup file is corrupt!', 'wp-staging') ?></strong><br/>
91
+ </li>
92
+ <?php endif ?>
93
+ <?php if ($isUnsupported && !$corrupt) : ?>
94
  <li class="wpstg-unsupported-backup wpstg--red">
95
  <div class="wpstg-exclamation">!</div><strong><?php esc_html_e('This backup was generated on the Beta version of WP STAGING and cannot be restored with the current version.', 'wp-staging') ?></strong><br/>
96
  </li>
97
  <?php endif ?>
98
  <?php if ($createdAt) : ?>
99
  <li>
100
+ <strong><?php $corrupt ? esc_html_e('Last modified:', 'wp-staging') : esc_html_e('Created on:', 'wp-staging') ?></strong>
101
  <?php
102
  $date = new DateTime();
103
  $date->setTimestamp($createdAt);
117
  <strong><?php esc_html_e('Size: ', 'wp-staging') ?></strong>
118
  <?php echo esc_html($size); ?>
119
  </li>
120
+ <?php if (!$corrupt) : ?>
121
  <li class="single-backup-includes">
122
  <strong><?php esc_html_e('Contains: ', 'wp-staging') ?></strong>
123
  <?php
130
  include(__DIR__ . '/modal/partials/backup-contains.php');
131
  ?>
132
  </li>
133
+ <?php if ($automatedBackup) : ?>
134
  <li style="font-style: italic">
135
  <img class="wpstg--dashicons wpstg-dashicons-19 wpstg-dashicons-grey wpstg--backup-automated" src="<?php echo $urlAssets; ?>svg/vendor/dashicons/update.svg" /> <?php esc_html_e('Backup created automatically.', 'wp-staging') ?>
136
  </li>
137
+ <?php endif ?>
138
+ <?php if ($legacy) : ?>
139
  <li style="font-style: italic">
140
  <img class="wpstg--dashicons wpstg-dashicons-19 wpstg-dashicons-grey" src="<?php echo $urlAssets; ?>svg/vendor/dashicons/cloud-saved.svg" /> <?php esc_html_e('This database backup was generated from an existing legacy WP STAGING Database export in the .SQL format.', 'wp-staging') ?>
141
  </li>
142
+ <?php endif ?>
143
  <?php endif ?>
144
  </ul>
145
  </div>
Backend/views/backup/modal/confirm-restore.php CHANGED
@@ -2,6 +2,10 @@
2
 
3
  use WPStaging\Pro\Backup\Entity\BackupMetadata;
4
 
 
 
 
 
5
  /**
6
  * @var BackupMetadata $info
7
  */
@@ -45,15 +49,6 @@ $isDatabaseOnlyBackup = $info->getIsExportingDatabase()
45
  <span class=""><?php echo $info->getTotalFiles() ?></span>
46
  </div>
47
  <?php endif; ?>
48
- <?php if (!empty($_POST['search'])) : ?>
49
- <div class="wpstg-db-table" style="margin-top:20px;">
50
- <?php foreach ($_POST['search'] as $index => $search) : ?>
51
- <span class=""><?php echo sprintf(__('Search: %s', 'wp-staging'), $search) ?></span> <br/>
52
- <span class=""><?php echo sprintf(__('Replace: %s', 'wp-staging'), $_POST['replace'][$index]) ?></span>
53
- <hr>
54
- <?php endforeach ?>
55
- </div>
56
- <?php endif ?>
57
  <div class="wpstg-db-table" style="margin-top:5px;display:none;">
58
  <?php
59
  $backupGeneratedInVersion = $info->getVersion();
2
 
3
  use WPStaging\Pro\Backup\Entity\BackupMetadata;
4
 
5
+ if (!defined("WPINC")) {
6
+ die();
7
+ }
8
+
9
  /**
10
  * @var BackupMetadata $info
11
  */
49
  <span class=""><?php echo $info->getTotalFiles() ?></span>
50
  </div>
51
  <?php endif; ?>
 
 
 
 
 
 
 
 
 
52
  <div class="wpstg-db-table" style="margin-top:5px;display:none;">
53
  <?php
54
  $backupGeneratedInVersion = $info->getVersion();
Framework/BackgroundProcessing/Queue.php CHANGED
@@ -500,7 +500,7 @@ class Queue
500
  {
501
  if ($this->checkTable() !== self::TABLE_EXISTS) {
502
  // No actions if the table either does nto exist or has just been created.
503
- debug_log('Queue getNextAvailable: Table does not exist for getting the next available.');
504
  return null;
505
  }
506
 
@@ -514,7 +514,7 @@ class Queue
514
  $this->database->query("LOCK TABLE `$tableName` WRITE");
515
 
516
  if ($this->count($processing) > 0) {
517
- debug_log('Queue getNextAvailable: There is an action already in process. Stop!');
518
  $this->database->query("UNLOCK TABLES");
519
  return null;
520
  }
@@ -526,7 +526,7 @@ class Queue
526
 
527
  if (!$claimedId) {
528
  // This is NOT a failure: it just means the process could not lock the row.
529
- debug_log('Queue getNextAvailable returns null because claimed Id was empty. This query failed: ' . $claimIdQuery);
530
  $this->database->query("UNLOCK TABLES");
531
  return null;
532
  }
@@ -534,7 +534,7 @@ class Queue
534
  $claimedId = $this->database->fetchAssoc($claimedId);
535
 
536
  if (!is_array($claimedId) || !array_key_exists('id', $claimedId)) {
537
- debug_log('Queue getNextAvailable returns null because claimedID query does not return an array or "id" does not exist. This query failed: ' . $claimIdQuery);
538
  $this->database->query("UNLOCK TABLES");
539
  return null;
540
  }
@@ -554,7 +554,7 @@ class Queue
554
 
555
  if (!$claimed) {
556
  // This is NOT a failure: it just means the process could not lock the row.
557
- debug_log('Queue getNextAvailable returns null the process could not lock the row. This query failed: ' . $claimQuery);
558
  return null;
559
  }
560
 
@@ -857,7 +857,7 @@ class Queue
857
  public function markDanglingAs($newStatus)
858
  {
859
  if ($this->checkTable() === static::TABLE_NOT_EXIST) {
860
- debug_log('Queue markDanglingAs: The table does not exist so there is nothing to update.');
861
  return 0;
862
  }
863
 
@@ -889,7 +889,7 @@ class Queue
889
  $marked = 0;
890
  }
891
 
892
- debug_log("Marked $marked actions as dangling.");
893
 
894
  return (int)$marked;
895
  }
500
  {
501
  if ($this->checkTable() !== self::TABLE_EXISTS) {
502
  // No actions if the table either does nto exist or has just been created.
503
+ debug_log('Queue getNextAvailable: Table does not exist for getting the next available.', 'debug');
504
  return null;
505
  }
506
 
514
  $this->database->query("LOCK TABLE `$tableName` WRITE");
515
 
516
  if ($this->count($processing) > 0) {
517
+ debug_log('Queue getNextAvailable: There is an action already in process. Stop!', 'debug');
518
  $this->database->query("UNLOCK TABLES");
519
  return null;
520
  }
526
 
527
  if (!$claimedId) {
528
  // This is NOT a failure: it just means the process could not lock the row.
529
+ debug_log('Queue getNextAvailable returns null because claimed Id was empty. This query failed: ' . $claimIdQuery, 'debug');
530
  $this->database->query("UNLOCK TABLES");
531
  return null;
532
  }
534
  $claimedId = $this->database->fetchAssoc($claimedId);
535
 
536
  if (!is_array($claimedId) || !array_key_exists('id', $claimedId)) {
537
+ debug_log('Queue getNextAvailable returns null because claimedID query does not return an array or "id" does not exist. This query failed: ' . $claimIdQuery, 'debug');
538
  $this->database->query("UNLOCK TABLES");
539
  return null;
540
  }
554
 
555
  if (!$claimed) {
556
  // This is NOT a failure: it just means the process could not lock the row.
557
+ debug_log('Queue getNextAvailable returns null the process could not lock the row. This query failed: ' . $claimQuery, 'debug');
558
  return null;
559
  }
560
 
857
  public function markDanglingAs($newStatus)
858
  {
859
  if ($this->checkTable() === static::TABLE_NOT_EXIST) {
860
+ debug_log('Queue markDanglingAs: The table does not exist so there is nothing to update.', 'debug');
861
  return 0;
862
  }
863
 
889
  $marked = 0;
890
  }
891
 
892
+ debug_log("Marked $marked actions as dangling.", 'debug');
893
 
894
  return (int)$marked;
895
  }
Framework/Filesystem/DiskWriteCheck.php CHANGED
@@ -87,6 +87,11 @@ class DiskWriteCheck
87
  }
88
  }
89
 
 
 
 
 
 
90
  public function testDiskIsWriteable()
91
  {
92
  $destination = $this->directory->getPluginUploadsDirectory() . '.wpstgDiskWriteCheck';
@@ -121,7 +126,7 @@ class DiskWriteCheck
121
  $result = $this->setLowLevelDiskFullFlag();
122
 
123
  if (!$result) {
124
- \WPStaging\functions\debug_log('WPSTGAGING DiskWriteCheck failed and could not update the option in the database.');
125
  }
126
  }
127
 
87
  }
88
  }
89
 
90
+ /**
91
+ * @return bool
92
+ * @throws DiskNotWritableException
93
+ * @throws FilesystemExceptions
94
+ */
95
  public function testDiskIsWriteable()
96
  {
97
  $destination = $this->directory->getPluginUploadsDirectory() . '.wpstgDiskWriteCheck';
126
  $result = $this->setLowLevelDiskFullFlag();
127
 
128
  if (!$result) {
129
+ \WPStaging\functions\debug_log('WP STAGING DiskWriteCheck failed and could not update the option in the database.');
130
  }
131
  }
132
 
Framework/Filesystem/FileObject.php CHANGED
@@ -94,6 +94,7 @@ class FileObject extends SplFileObject
94
 
95
  /**
96
  * @return array The backup metadata array
 
97
  */
98
  public function readBackupMetadata()
99
  {
@@ -118,7 +119,6 @@ class FileObject extends SplFileObject
118
  } while ($this->valid() && !is_array($backupMetadata));
119
 
120
  if (!is_array($backupMetadata)) {
121
- \WPStaging\functions\debug_log('Could not find metadata in the backup. This file could be corrupt.');
122
  throw new RuntimeException('Could not find metadata in the backup. This file could be corrupt.');
123
  }
124
 
94
 
95
  /**
96
  * @return array The backup metadata array
97
+ * @throws RuntimeException
98
  */
99
  public function readBackupMetadata()
100
  {
119
  } while ($this->valid() && !is_array($backupMetadata));
120
 
121
  if (!is_array($backupMetadata)) {
 
122
  throw new RuntimeException('Could not find metadata in the backup. This file could be corrupt.');
123
  }
124
 
Framework/Filesystem/Filesystem.php CHANGED
@@ -2,6 +2,7 @@
2
 
3
  namespace WPStaging\Framework\Filesystem;
4
 
 
5
  use SplFileInfo;
6
  use WPStaging\Backend\Notices\Notices;
7
  use WPStaging\Core\WPStaging;
@@ -10,6 +11,8 @@ use RuntimeException;
10
  use WPStaging\Backend\Pro\Modules\Jobs\Copiers\Copier;
11
  use WPStaging\Framework\Adapter\PhpAdapter;
12
 
 
 
13
  class Filesystem extends FilterableDirectoryIterator
14
  {
15
  /** @var string|null */
@@ -173,6 +176,17 @@ class Filesystem extends FilterableDirectoryIterator
173
  {
174
  $path = $this->findPath($path);
175
 
 
 
 
 
 
 
 
 
 
 
 
176
  set_error_handler([$this, 'handleMkdirError']);
177
  $result = wp_mkdir_p($path);
178
  restore_error_handler();
@@ -304,7 +318,7 @@ class Filesystem extends FilterableDirectoryIterator
304
 
305
  // if $path is link or file, delete it and stop execution
306
  if (is_link($path) || is_file($path)) {
307
- if (!unlink($path)) {
308
  $this->log('Permission Error: Can not delete file ' . $path);
309
  return false;
310
  }
@@ -392,7 +406,7 @@ class Filesystem extends FilterableDirectoryIterator
392
 
393
  // Delete the empty directory itself and finish execution
394
  if (is_dir($path)) {
395
- if (!rmdir($path)) {
396
  $this->log('Permission Error: Can not delete directory ' . $path);
397
  }
398
  }
@@ -744,12 +758,29 @@ class Filesystem extends FilterableDirectoryIterator
744
  * This normalizes the given path in a specific way,
745
  * aiming to compare paths with precision.
746
  *
747
- * @param $path
 
748
  *
749
  * @return string
750
  */
751
- public function normalizePath($path)
752
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
753
  $path = trim($path);
754
  $path = wp_normalize_path($path);
755
  $path = trailingslashit($path);
@@ -780,12 +811,39 @@ class Filesystem extends FilterableDirectoryIterator
780
 
781
  /**
782
  * @param string $filePath The filename to check.
 
 
 
783
  *
784
  * @return bool Whether the file exists and is readable.
785
  */
786
  public function isReadableFile($filePath)
787
  {
788
- return file_exists($filePath) && is_file($filePath) && is_readable($filePath);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
789
  }
790
 
791
  /**
2
 
3
  namespace WPStaging\Framework\Filesystem;
4
 
5
+ use Exception;
6
  use SplFileInfo;
7
  use WPStaging\Backend\Notices\Notices;
8
  use WPStaging\Core\WPStaging;
11
  use WPStaging\Backend\Pro\Modules\Jobs\Copiers\Copier;
12
  use WPStaging\Framework\Adapter\PhpAdapter;
13
 
14
+ use function WPStaging\functions\debug_log;
15
+
16
  class Filesystem extends FilterableDirectoryIterator
17
  {
18
  /** @var string|null */
176
  {
177
  $path = $this->findPath($path);
178
 
179
+ /**
180
+ * For UNC Paths
181
+ * If the path starts with two forwardslashes, we need to convert them to backwardslashes to allow directory creation
182
+ * examples
183
+ * //server/path/to/dir -> \\server/path/to/dir
184
+ * //server\path\to\dir -> \\server\path\to\dir
185
+ */
186
+ if (strpos($path, '//') === 0) {
187
+ $path = '\\\\' . substr($path, 2);
188
+ }
189
+
190
  set_error_handler([$this, 'handleMkdirError']);
191
  $result = wp_mkdir_p($path);
192
  restore_error_handler();
318
 
319
  // if $path is link or file, delete it and stop execution
320
  if (is_link($path) || is_file($path)) {
321
+ if (!@unlink($path)) {
322
  $this->log('Permission Error: Can not delete file ' . $path);
323
  return false;
324
  }
406
 
407
  // Delete the empty directory itself and finish execution
408
  if (is_dir($path)) {
409
+ if (!@rmdir($path)) {
410
  $this->log('Permission Error: Can not delete directory ' . $path);
411
  }
412
  }
758
  * This normalizes the given path in a specific way,
759
  * aiming to compare paths with precision.
760
  *
761
+ * @param string $path
762
+ * @param bool $onlyNormalize. Default false
763
  *
764
  * @return string
765
  */
766
+ public function normalizePath($path, $onlyNormalize = false)
767
  {
768
+ /**
769
+ * For UNC Paths
770
+ * If the path starts with two backslashes, we need to escape them, to make a valid UNC path
771
+ * No need to escape if already escaped.
772
+ * \\server\path\to\file is treated as \server\path\to\file
773
+ * The below code make sure \\server\path\to\file is changed to \\\\server\path\to\file so that it is treated as \\server\path\to\file
774
+ * No escaping is done if path already starts with four backslashes \\\\
775
+ */
776
+ if (strpos($path, '\\') === 0 && strpos($path, '\\\\') !== 0) {
777
+ $path = '\\' . $path;
778
+ }
779
+
780
+ if ($onlyNormalize) {
781
+ return wp_normalize_path($path);
782
+ }
783
+
784
  $path = trim($path);
785
  $path = wp_normalize_path($path);
786
  $path = trailingslashit($path);
811
 
812
  /**
813
  * @param string $filePath The filename to check.
814
+ * Also compatible with Windows Network files
815
+ * @see https://bugs.php.net/bug.php?id=73543
816
+ * @see https://bugs.php.net/bug.php?id=69834
817
  *
818
  * @return bool Whether the file exists and is readable.
819
  */
820
  public function isReadableFile($filePath)
821
  {
822
+ if (is_readable($filePath)) {
823
+ return true;
824
+ }
825
+
826
+ if (!file_exists($filePath) || !is_file($filePath)) {
827
+ return false;
828
+ }
829
+
830
+ // On window or samba network file is_readable sometimes return false
831
+ // Even though files can be accessible with file_get_contents or fopen
832
+ // see links in the method docblock for more detail.
833
+ try {
834
+ $fileHandle = fopen($filePath, 'rb');
835
+ if (!is_resource($fileHandle)) {
836
+ return false;
837
+ }
838
+
839
+ if (fclose($fileHandle)) {
840
+ return true;
841
+ }
842
+ } catch (Exception $ex) {
843
+ debug_log($ex->getMessage());
844
+ }
845
+
846
+ return false;
847
  }
848
 
849
  /**
Framework/SiteInfo.php CHANGED
@@ -206,8 +206,8 @@ class SiteInfo
206
  */
207
  public function punycodeEncode($url)
208
  {
209
- // Get punycode encode if idn extension loaded
210
- if (extension_loaded('idn') && is_callable('idn_to_ascii')) {
211
  return idn_to_ascii($url, 0, INTL_IDNA_VARIANT_UTS46);
212
  }
213
 
206
  */
207
  public function punycodeEncode($url)
208
  {
209
+ // Get punycode encode if idn or intl extension loaded
210
+ if ((extension_loaded('idn') || extension_loaded('intl')) && is_callable('idn_to_ascii')) {
211
  return idn_to_ascii($url, 0, INTL_IDNA_VARIANT_UTS46);
212
  }
213
 
constantsFree.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // WP STAGING version number
4
  if (!defined('WPSTG_VERSION')) {
5
- define('WPSTG_VERSION', '2.9.11');
6
  }
7
 
8
  // Compatible up to WordPress Version
2
 
3
  // WP STAGING version number
4
  if (!defined('WPSTG_VERSION')) {
5
+ define('WPSTG_VERSION', '2.9.12');
6
  }
7
 
8
  // Compatible up to WordPress Version
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.11';
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.12';
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
@@ -1,4 +1,4 @@
1
- === Backup Duplicator & Migration - WP STAGING ===
2
 
3
  Author URL: https://wp-staging.com/backup-wordpress
4
  Plugin URL: https://wordpress.org/plugins/wp-staging
@@ -8,8 +8,8 @@ License: GPLv2 or later
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
  Tags: backup, backup plugin, database backup, wordpress backup plugin, migrate, backup wordpress, backups
10
  Requires at least: 3.6+
11
- Tested up to: 5.9.3
12
- Stable tag: 2.9.11
13
  Requires PHP: 5.6
14
 
15
  Backup & Duplicator Plugin - Clone, backup, move, duplicate & migrate websites to staging, backup, and development sites for authorized users only.
@@ -32,7 +32,7 @@ This staging and backup plugin can clone your website even if it runs on a weak
32
 
33
  [youtube https://www.youtube.com/watch?v=vkv52s36Yvg]
34
 
35
- == WP STAGING | FREE BACKUP AND CLONING WORDPRESS FEATURES ==
36
 
37
  * Clones the entire production site into a subdirectory like example.com/staging-site.
38
  * Easy to use! Create a clone / backup site by clicking one button
@@ -48,7 +48,7 @@ This staging and backup plugin can clone your website even if it runs on a weak
48
  * Every release passes thousands of unit and acceptance tests to make the plugin extremely robust, reliable and fast on an enterprise code quality level
49
  * Fast and professional support team
50
 
51
- == WP STAGING | PRO - BACKUP AND CLONING WORDPRESS FEATURES ==
52
 
53
  The backup & cloning features below are Premium. You need WP STAGING | PRO to use those features. [More about WP STAGING | PRO](https://wp-staging.com/backup-wordpress)!
54
 
@@ -259,6 +259,18 @@ please open a [support request](https://wp-staging.com/support/ "Support Request
259
 
260
  == Changelog ==
261
 
 
 
 
 
 
 
 
 
 
 
 
 
262
  = 2.9.11 =
263
  * New: Add Amazon S3 as backup cloud storage option for backup upload #1665
264
  * Fix: Fatal error due to missing BackupScheduler class in Free version #1688
@@ -543,117 +555,4 @@ WP STAGING Backup & Cloning | Full changelog:
543
  * Fix: Can not recursive scan file system if there is a symlink in root directory linking to the root directory itself. #1688
544
  * Fix: Can not download backup files. Incorrect backup download link if wp-content folder is symlinked to another folder outside the wp root folder #1697
545
  * Fix: Error on downloading backup in IIS due to section in parent web.config that overwrites the WP STAGING generated web.config in backup folder #1699
546
- * Fix: Improve punycode related code. Keep cloning even if unable to use punycode related code doesn't work due to missing extensions #1702
547
-
548
- * New: Support up to WordPress 5.9.3
549
- * New: Added upgrade routine for backup created with version 4.1.9 and 4.2.0 to fix backup metadata info #1647
550
- * Fix: Backup creation is blocked by mod_security if access tokens contain 0x string #1651
551
- * Fix: Unable to upload backup created with version 4.1.9 and 4.2.0 using WP Staging Backup Uploader #1647
552
- * Fix: Unable to import multisite backup when restoring backup into domain other than it was created on #1644
553
- * Fix: If there is an mysql error on copying a single row, it can lead to a interrupt of the whole clone job due to a browser memory exhaust error because whole sql query is written into html log element . #1654
554
-
555
- * Fix: Fatal error if another plugin uses the same google library as WP STAGING uses for the backup storage provider #1641
556
-
557
- * New: Support up to WordPress 5.9.2
558
- * New: Feature to upload backups to Google Drive (PRO) #1453
559
- * New: Add filter wpstg.frontend.showLoginForm to force disable login form for the staging / backup site access #1577
560
- * New: Option to schedule a backup without creating one (PRO) #1588
561
- * Enh: Improve backup schedules error reporting by showing cron related notice on backups page and sending schedules error report mails (PRO) #1588
562
- * Enh: Improve subdirectory WordPress install detection by adding support for idn(internationalized domain names) #1564
563
- * Enh: Change backup lock process mechanism from using database to file based lock #1561
564
- * Enh: Make files & folders exclude filters work on WordPress root directory #1606
565
- * Enh: Remove old database only backup before PUSH process (PRO) #1608
566
- * Enh: Exclude .htaccess from root directory only during cloning process #1616
567
- * Enh: Don't backup table wp_wpstg_queue table (PRO Version) #1624
568
- * Update: Bump minimist from 1.2.5 to 1.2.6 in /tests/js #1627
569
- * Update: Bump postcss from 8.2.10 to 8.2.13 in /src/assets #1547
570
- * Update: Bump mustache/mustache from 2.13.0 to 2.14.1 #1543
571
- * Update: Bump nanoid from 3.1.22 to 3.3.1 in /src/assets #1626
572
- * Fix: Correctly set multisite subsites urls with www prefix when cloning and restoring a backup (PRO) #1567
573
- * Fix: Backup error "OutOfRangeException" was never caught when insert query exceeds max allowed packet size (PRO) #1570
574
- * Fix: Add backup logic to check extended query string size against max allowed packet size which otherwise leads to a fatal error (PRO) #1570
575
- * Fix: Handle critical error if WP STAGINGS settings get corrupted. Give option to restore default settings #1602
576
- * Fix: Recreate cron jobs of existing backup plans when adding a new backup schedules (PRO) #1588
577
- * Fix: Enqueue a failed task/item again and set the queue's offset to the end of file #1609
578
- * Fix: Stop cloning if destination directory/clone name already exists #1607
579
- * Fix: Continue cloning process even if copying a table failed #1578
580
- * Fix: Don't remove freemius options if entire multisite is cloned. Prevents a fatal error. (PRO) #1629
581
- #1638
582
-
583
- * New: Add support for WordPress 5.8.3
584
- * New: Add filter for excluding files during cloning / backup #1494
585
- * New: Add filter for overwriting max execution for database backup restore #1512
586
- * New: Add filter to allow overwriting of the maximum allowed request time to make sure backup restore works for huge files. (19.000.000M database rows) #1510
587
- * Fix: If cloning a multisite subsite into external database, it does not clone / backup wp_users and wp_usermeta #1515
588
- * Fix: Skip tmp single file plugin during backup PUSH copy process #1491
589
- * Fix: Preserve table selection during PUSH and UPDATE even when all backup tables unselected #1488
590
- * Fix: Make sure maximum memory consumption during cloning or backup is never higher than 256MB #1502
591
- * Fix: Use custom implementation of wp_timezone() for backward compatibility to WordPress older than 5.3 #1505
592
- * Fix: Override FileObject::fgets to make them behave exactly from SplFileObject of PHP < 8.0.1 #1506
593
- * Tweak: Show custom uploads folder in tooltip description and explain better that changing a symlink image will also change the image on the production site. #1495
594
-
595
- * New: If cpu load setting is low make use of the file copy limit for pushing process to increase copy speed #1485
596
- * Enh: Add warning notice if WP_CRON_DISABLED is set to true as BG Processing depends upon it #1467
597
- * Fix: Add own implementation of get_current_network_id() for backward compatibility #1438
598
- * Fix: Updating or resetting staging / backup site skips all WordPress core folders #1435
599
- * Fix: Prevent 504 Gateway Timeout issue during Backup restore by force a low CPU LOAD (i.e. 10s) #1420
600
- * Fix: Wrong directory path is displayed when update/reset a staging / backup site #1447
601
- * Fix: Override SplFileObject::seek to make it consistent across all PHP version including PHP 8 #1444
602
- * Fix: Make FileObject::seek behave exactly as SplFileObject::seek from PHP < 8.0 #1480
603
- * Fix: Search Replace now works for Visual Composer / WP Bakery encoded pages #1442
604
- * Fix: Adjust CSS of the "Backup in Progress" element #1466
605
- * Fix: Clarify email sending tooltip description #1469
606
- * Fix: Adjust CSS of the loader icon #1487
607
- * Tweak: Retain WP STAGING ( backup ) options during push #1417
608
- * Tweak: Make PHP 5.6 minimum supported PHP version #1448
609
- * Tweak: Set WordPress 4.4 as minimum required WordPress version #1449
610
- * Dev: Fix Queue working in PHP 8 and Add PHP 8 unit tests in fast tests #1450
611
- * Dev: Cancel pending or running github actions fast tests if there is a new push on the same PR #1486
612
-
613
- * Fix: Update notice is shown even when using latest version #1398
614
- * Fix: Backup & cloning 100% compatible with PHP 8.0.12 #1281
615
- * Fix: Skip search replace on backup & cloning query if it's size exceed preg functions limit #1404
616
- * Fix: Skip inserting backup & cloning query if it exceeds mysql max_allowed_package. Show warning to user #1405
617
- * Fix: Make db option wpstg_staging_sites always return an array #1413
618
- * Fix: Fix dependency injection for backup notices class. Solve conflict with TranslatePress #1416
619
- * Tweak: Use php version number as tag for php docker container #1407
620
- * Tweak: Improve symlink tooltip text #1411
621
- * Tweak: Refactor WP STAGING Pro to WP STAGING | PRO in notices #1409
622
- * Tweak: Remove 16 characters limitation for the backup & CLONE NAME and keep it for CLONE DIRECTORY #1412
623
-
624
- * Enh: Refactor the wp_login action hook to work with different parameter count than the one in WordPress Core #1223
625
- * Enh: Sort new staging backup sites in descending order by creation time #1226
626
- * Enh: Warn if creating a backup in PHP 32 bit version #1231
627
- * Enh: Update the backup upload success message #1221
628
- * Enh: Show a notice if there is a new WP STAGING free version of the backup plugin #1250
629
- * Enh: Rename db option wpstg_existing_clones_beta to wpstg_staging_sites #1211
630
- * Enh: Update the warning message shown when the delete process of the staging backup site fails #1257
631
- * Enh: Allow use of REST API on staging backup sites without login #1287
632
- * Enh: Add new EDD software licensing updater for the pro version of the WP STAGING backup plugin #1294
633
- * Fix: New pro version does not recognize staging backup sites created with older free version #1293
634
- * Fix: Fix a rare issue that could happen when creating a new staging backup site or restoring a backup when there is a row with primary key with value zero #1271
635
- * Fix: Try to repair MyISAM table if it's corrupt when creating a Backup #1222
636
- * Fix: Fix an issue on backup creation that would cause a database export to loop when encountering a table with negative integers or zeros as a primary key value #1251
637
- * Fix: Lock specific tables while exporting a backup, to prevent a rare duplicated row issue #1245
638
- * Fix: If the memory exhausts during a database export using the Backup feature, lower the memory usage/speed of the export and try again automatically #1230
639
- * Fix: Prevent failure of adding database to backup from causing a loop #1231
640
- * Fix: Fix issue when old backup clones from version 1.1.6 or lower replaces the existing clones from later version when upgrading from FREE to PRO version #1233
641
- * Fix: Fix inconsistent Unselect All Tables button's action #1243
642
- * Fix: Replace undefined date with proper formatted date during backups for some warning and critical messages #1244
643
- * Fix: Split file scanning of wp-content into scanning of plugins, themes, uploads and other directories to reduce timeout issues #1247
644
- * Fix: Rename .user.ini to .user.ini.bak after cloning to reduce fatal errors on staging backup site. Also show a notice. #1255
645
- * Fix: Skip scanning the root directory if all other directories are unselected before starting a backup staging site #1256
646
- * Fix: Show correct insufficient space message instead of permission error if unable to copy or create a backup site due to insufficient space #1283
647
- * Fix: Fix showing of error when unable to count tables rows and wrap table name when fetching rows during backup #1285
648
- * Fix: Remove custom error handler that could cause errors due to notices being thrown #1292
649
- * Fix: Fix an error that would occur when PHP lacked permission to get the size of a directory when pushing a staging backup site to production #1295
650
-
651
- * Enh: Warn if creating a backup in PHP 32 bits #1231
652
- * Enh: Update the backups upload success message #1221
653
- * Fix: Fix a rare issue that could happen when creating a new staging site or restoring a backup when there is a row with primary key with value zero #1271
654
- * Fix: Try to repair MyISAM table if it's corrupt when creating a Backup #1222
655
- * Fix: FIx an issue on backup creation that would cause a database export to loop when encountering a table with negative integers or zeros as a primary key value #1251
656
- * Fix: Lock specific tables while exporting a backup, to prevent a rare duplicated row issue #1245
657
- * Fix: If the memory exhausts during a database export using the Backup feature, we now lower the memory usage/speed of the export and try again automatically #1230
658
- * Fix: Prevent failure of adding database to backup from causing a loop #1231
659
- * Fix: Replace undefined date with proper formatted date during backups log for some warning and critical messages #1244
1
+ === WP STAGING - Backup Duplicator & Migration ===
2
 
3
  Author URL: https://wp-staging.com/backup-wordpress
4
  Plugin URL: https://wordpress.org/plugins/wp-staging
8
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
  Tags: backup, backup plugin, database backup, wordpress backup plugin, migrate, backup wordpress, backups
10
  Requires at least: 3.6+
11
+ Tested up to: 5.9
12
+ Stable tag: 2.9.12
13
  Requires PHP: 5.6
14
 
15
  Backup & Duplicator Plugin - Clone, backup, move, duplicate & migrate websites to staging, backup, and development sites for authorized users only.
32
 
33
  [youtube https://www.youtube.com/watch?v=vkv52s36Yvg]
34
 
35
+ == WP STAGING FREE - BACKUP & STAGING FEATURES ==
36
 
37
  * Clones the entire production site into a subdirectory like example.com/staging-site.
38
  * Easy to use! Create a clone / backup site by clicking one button
48
  * Every release passes thousands of unit and acceptance tests to make the plugin extremely robust, reliable and fast on an enterprise code quality level
49
  * Fast and professional support team
50
 
51
+ == WP STAGING | PRO - BACKUP & STAGING FEATURES ==
52
 
53
  The backup & cloning features below are Premium. You need WP STAGING | PRO to use those features. [More about WP STAGING | PRO](https://wp-staging.com/backup-wordpress)!
54
 
259
 
260
  == Changelog ==
261
 
262
+ = 2.9.12 =
263
+ * Fix: If there is a damaged backup in backup folder, automated backup does not work any longer #1707
264
+ * Fix: Support UNC paths like //servername/path Unix or \\servername\path DOS/Windows #1698
265
+ * Fix: Remove prefixed vendor namespace from the Normalizer class in the idn-intl polyfill #1720
266
+ * Fix: Handle SSL related errors and catch other exceptions while making remote request to refresh Google token #1718
267
+ * Fix: Backup does not restore theme if theme does not have a style.css #1719
268
+ * Fix: Missing exception in Backup Extractor.php #1724
269
+ * Enh: List damaged backup files in the UI and mark them #1710
270
+ * Enh: Remove message "backup metadata not found" in debug log #1710
271
+ * Enh: Clean up debug messages #1722
272
+ * Enh: Add missing escaping of POST output #1705
273
+
274
  = 2.9.11 =
275
  * New: Add Amazon S3 as backup cloud storage option for backup upload #1665
276
  * Fix: Fatal error due to missing BackupScheduler class in Free version #1688
555
  * Fix: Can not recursive scan file system if there is a symlink in root directory linking to the root directory itself. #1688
556
  * Fix: Can not download backup files. Incorrect backup download link if wp-content folder is symlinked to another folder outside the wp root folder #1697
557
  * Fix: Error on downloading backup in IIS due to section in parent web.config that overwrites the WP STAGING generated web.config in backup folder #1699
558
+ * Fix: Improve punycode related code. Keep cloning even if unable to use punycode related code doesn't work due to missing extensions #1702
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
vendor_wpstg/autoload/vendor.php CHANGED
@@ -7,6 +7,7 @@ $baseDir = dirname($vendorDir);
7
 
8
  return array(
9
  'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
 
10
  'WPStaging\\Vendor\\AWS\\CRT\\Auth\\AwsCredentials' => $vendorDir . '/aws/aws-crt-php/src/AWS/CRT/Auth/AwsCredentials.php',
11
  'WPStaging\\Vendor\\AWS\\CRT\\Auth\\CredentialsProvider' => $vendorDir . '/aws/aws-crt-php/src/AWS/CRT/Auth/CredentialsProvider.php',
12
  'WPStaging\\Vendor\\AWS\\CRT\\Auth\\Signable' => $vendorDir . '/aws/aws-crt-php/src/AWS/CRT/Auth/Signable.php',
@@ -664,7 +665,6 @@ return array(
664
  'WPStaging\\Vendor\\Monolog\\ResettableInterface' => $vendorDir . '/monolog/monolog/src/Monolog/ResettableInterface.php',
665
  'WPStaging\\Vendor\\Monolog\\SignalHandler' => $vendorDir . '/monolog/monolog/src/Monolog/SignalHandler.php',
666
  'WPStaging\\Vendor\\Monolog\\Utils' => $vendorDir . '/monolog/monolog/src/Monolog/Utils.php',
667
- 'WPStaging\\Vendor\\Normalizer' => $vendorDir . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php',
668
  'WPStaging\\Vendor\\ParseError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/ParseError.php',
669
  'WPStaging\\Vendor\\Psr\\Cache\\CacheException' => $vendorDir . '/psr/cache/src/CacheException.php',
670
  'WPStaging\\Vendor\\Psr\\Cache\\CacheItemInterface' => $vendorDir . '/psr/cache/src/CacheItemInterface.php',
7
 
8
  return array(
9
  'Composer\\InstalledVersions' => $vendorDir . '/composer/InstalledVersions.php',
10
+ 'Normalizer' => $vendorDir . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php',
11
  'WPStaging\\Vendor\\AWS\\CRT\\Auth\\AwsCredentials' => $vendorDir . '/aws/aws-crt-php/src/AWS/CRT/Auth/AwsCredentials.php',
12
  'WPStaging\\Vendor\\AWS\\CRT\\Auth\\CredentialsProvider' => $vendorDir . '/aws/aws-crt-php/src/AWS/CRT/Auth/CredentialsProvider.php',
13
  'WPStaging\\Vendor\\AWS\\CRT\\Auth\\Signable' => $vendorDir . '/aws/aws-crt-php/src/AWS/CRT/Auth/Signable.php',
665
  'WPStaging\\Vendor\\Monolog\\ResettableInterface' => $vendorDir . '/monolog/monolog/src/Monolog/ResettableInterface.php',
666
  'WPStaging\\Vendor\\Monolog\\SignalHandler' => $vendorDir . '/monolog/monolog/src/Monolog/SignalHandler.php',
667
  'WPStaging\\Vendor\\Monolog\\Utils' => $vendorDir . '/monolog/monolog/src/Monolog/Utils.php',
 
668
  'WPStaging\\Vendor\\ParseError' => $vendorDir . '/symfony/polyfill-php70/Resources/stubs/ParseError.php',
669
  'WPStaging\\Vendor\\Psr\\Cache\\CacheException' => $vendorDir . '/psr/cache/src/CacheException.php',
670
  'WPStaging\\Vendor\\Psr\\Cache\\CacheItemInterface' => $vendorDir . '/psr/cache/src/CacheItemInterface.php',
vendor_wpstg/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- namespace WPStaging\Vendor;
4
 
5
  class Normalizer extends \WPStaging\Vendor\Symfony\Polyfill\Intl\Normalizer\Normalizer
6
  {
1
  <?php
2
 
3
+
4
 
5
  class Normalizer extends \WPStaging\Vendor\Symfony\Polyfill\Intl\Normalizer\Normalizer
6
  {
wp-staging.php CHANGED
@@ -1,32 +1,18 @@
1
  <?php
2
 
3
  /**
4
- * Plugin Name: WP STAGING
5
  * Plugin URI: https://wordpress.org/plugins/wp-staging
6
- * Description: Create a staging clone site for testing & developing
7
- * Author: WP-STAGING
8
- * Author URI: https://wp-staging.com
9
- * Contributors: ReneHermi
10
- * Version: 2.9.11
 
 
 
11
  * Text Domain: wp-staging
12
  * Domain Path: /languages/
13
- *
14
- * WP STAGING is free software: you can redistribute it and/or modify
15
- * it under the terms of the GNU General Public License as published by
16
- * the Free Software Foundation, either version 2 of the License, or
17
- * any later version.
18
- *
19
- * WP STAGING is distributed in the hope that it will be useful,
20
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22
- * GNU General Public License for more details.
23
- *
24
- * You should have received a copy of the GNU General Public License
25
- * along with Staging. If not, see <http://www.gnu.org/licenses/>.
26
- *
27
- * @package WPSTG
28
- * @category Development, Migrating, Staging
29
- * @author WP STAGING
30
  */
31
 
32
  if (!defined("WPINC")) {
@@ -34,7 +20,7 @@ if (!defined("WPINC")) {
34
  }
35
 
36
  /**
37
- * Welcome to WPSTAGING.
38
  *
39
  * If you're reading this, you are a curious person that likes
40
  * to understand how things works, and that's awesome!
1
  <?php
2
 
3
  /**
4
+ * Plugin Name: Backup Duplicator & Migration - WP STAGING
5
  * Plugin URI: https://wordpress.org/plugins/wp-staging
6
+ * Description: Backup & Duplicator Plugin - Clone, backup, move, duplicate & migrate websites to staging, backup, and development sites for authorized users only.
7
+ * Version: 2.9.12
8
+ * Requires at least: 3.6+
9
+ * Requires PHP: 5.6
10
+ * Author: WP-STAGING, wpstagingbackup
11
+ * Author URI: https://wp-staging.com/backup-wordpress
12
+ * License: GPLv2 or later
13
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.html
14
  * Text Domain: wp-staging
15
  * Domain Path: /languages/
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  */
17
 
18
  if (!defined("WPINC")) {
20
  }
21
 
22
  /**
23
+ * Welcome to WP STAGING.
24
  *
25
  * If you're reading this, you are a curious person that likes
26
  * to understand how things works, and that's awesome!