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

Version Description

  • Enh: Add Shutdownable interface to replace usages of __destruct in the code #729
  • Enh: Refactor on how the plugin keeps track of a request running time #766
  • Fix: Replace deprecated jQuery click method #730
  • Fix: Fix overlapping of sweetalert confirmation on push with sidebar #742
  • Fix: Exclude wp staging content folder during staging #741
  • Fix: Add sanitizing for path to fix comparing for Windows paths #751
  • Fix: _cerber_files tables are excluded and could not be copied Fix #770
  • Fix: Replaced jQuery assignment with an IIFE wrapper #761
  • Dev: Update php-scoper and other development dependencies #744
  • Dev: Build javascript when building the distributable version of the plugin #750
  • Dev: Internal helper CLI command to order the changelog notes according to type #749
  • Dev: Refactor Job(s) implementation to use the Resources Trait #765
  • Dev: Add internal documentation to versioning and hotfixes #780
Download this release

Release Info

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

Code changes from version 2.8.2 to 2.8.3

Backend/Modules/Jobs/Delete.php CHANGED
@@ -337,6 +337,7 @@ class Delete extends Job
337
  */
338
  public function deleteTables()
339
  {
 
340
  if ($this->isOverThreshold()) {
341
  $this->log("Deleting: Is over threshold", Logger::TYPE_INFO);
342
  return;
337
  */
338
  public function deleteTables()
339
  {
340
+
341
  if ($this->isOverThreshold()) {
342
  $this->log("Deleting: Is over threshold", Logger::TYPE_INFO);
343
  return;
Backend/Modules/Jobs/Directories.php CHANGED
@@ -3,9 +3,6 @@
3
  namespace WPStaging\Backend\Modules\Jobs;
4
 
5
  use Exception;
6
- use RecursiveIteratorIterator;
7
- use WPStaging\Core\Iterators\RecursiveDirectoryIterator;
8
- use WPStaging\Core\Iterators\RecursiveFilterExclude;
9
  use WPStaging\Core\WPStaging;
10
  use WPStaging\Framework\CloningProcess\ExcludedPlugins;
11
  use WPStaging\Framework\Traits\FileScanToCacheTrait;
@@ -279,28 +276,11 @@ class Directories extends JobExecutable
279
 
280
  // open file handle and attach data to end of file
281
  $files = $this->open($this->filename, 'a');
 
 
282
 
283
  try {
284
- // Iterate over extra directory
285
- $iterator = new RecursiveDirectoryIterator($folder);
286
-
287
- $exclude = [];
288
-
289
- $iterator = new RecursiveFilterExclude($iterator, $exclude);
290
- // Recursively iterate over content directory
291
- $iterator = new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::LEAVES_ONLY, RecursiveIteratorIterator::CATCH_GET_CHILD);
292
-
293
- $this->log("Scanning {$this->strUtil->getLastElemAfterString( '/', $folder )} for its sub-directories and files");
294
-
295
- // Write path line
296
- foreach ($iterator as $item) {
297
- if ($item->isFile()) {
298
- $path = str_replace($this->strUtil->sanitizeDirectorySeparator(ABSPATH), '', $this->strUtil->sanitizeDirectorySeparator($folder)) . DIRECTORY_SEPARATOR . $item->getSubPathname() . PHP_EOL;
299
- if ($this->write($files, $path)) {
300
- $this->options->totalFiles++;
301
- }
302
- }
303
- }
304
  } catch (Exception $e) {
305
  $this->returnException('Error: ' . $e->getMessage());
306
  }
3
  namespace WPStaging\Backend\Modules\Jobs;
4
 
5
  use Exception;
 
 
 
6
  use WPStaging\Core\WPStaging;
7
  use WPStaging\Framework\CloningProcess\ExcludedPlugins;
8
  use WPStaging\Framework\Traits\FileScanToCacheTrait;
276
 
277
  // open file handle and attach data to end of file
278
  $files = $this->open($this->filename, 'a');
279
+ $strUtil = new Strings();
280
+ $this->log("Scanning {$strUtil->getLastElemAfterString( '/', $folder )} for its sub-directories and files");
281
 
282
  try {
283
+ $this->options->totalFiles += $this->scanToCacheFile($files, $folder, true, []);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
284
  } catch (Exception $e) {
285
  $this->returnException('Error: ' . $e->getMessage());
286
  }
Backend/Modules/Jobs/Files.php CHANGED
@@ -154,7 +154,9 @@ class Files extends JobExecutable
154
 
155
  // Finished or path does not exist
156
  if (empty($this->destination) || !is_dir($this->destination)) {
157
- error_log('Destination is not a directory: ' . $this->destination);
 
 
158
  $this->log(sprintf(__('Fail! Destination is not a directory! %s', 'wp-staging'), $this->destination));
159
  return true;
160
  }
154
 
155
  // Finished or path does not exist
156
  if (empty($this->destination) || !is_dir($this->destination)) {
157
+ if (defined('WPSTG_DEBUG') && WPSTG_DEBUG) {
158
+ error_log('Destination is not a directory: ' . $this->destination);
159
+ }
160
  $this->log(sprintf(__('Fail! Destination is not a directory! %s', 'wp-staging'), $this->destination));
161
  return true;
162
  }
Backend/Modules/Jobs/Job.php CHANGED
@@ -7,25 +7,23 @@ if (!defined("WPINC")) {
7
  die;
8
  }
9
 
10
- use WPStaging\Core\Utils\Logger;
11
- use WPStaging\Core\WPStaging;
12
- use WPStaging\Core\Utils\Cache;
13
- use WPStaging\Core\thirdParty\thirdPartyCompatibility;
14
- use WPStaging\Framework\Utils\Strings;
15
- use WPStaging\Framework\Utils\WpDefaultDirectories;
16
- use DateTime;
17
  use DateInterval;
 
18
  use Exception;
 
 
 
 
 
 
19
 
20
  /**
21
  * Class Job
22
  * @package WPStaging\Backend\Modules\Jobs
23
  */
24
- abstract class Job
25
  {
26
-
27
- const EXECUTION_TIME_RATIO = 0.8;
28
- const MAX_MEMORY_RATIO = 1;
29
 
30
  /**
31
  * @var Cache
@@ -52,38 +50,6 @@ abstract class Job
52
  */
53
  protected $settings;
54
 
55
- /**
56
- * System total maximum memory consumption
57
- * @var int
58
- */
59
- protected $maxMemoryLimit;
60
-
61
- /**
62
- * Script maximum memory consumption
63
- * @var int
64
- */
65
- protected $memoryLimit;
66
-
67
- /**
68
- * @var int
69
- */
70
- protected $maxExecutionTime;
71
-
72
- /**
73
- * @var int
74
- */
75
- protected $executionLimit;
76
-
77
- /**
78
- * @var int
79
- */
80
- protected $totalRecursion;
81
-
82
- /**
83
- * @var int
84
- */
85
- protected $maxRecursionLimit;
86
-
87
  /**
88
  * Multisite home domain without scheme
89
  * @var string
@@ -96,25 +62,14 @@ abstract class Job
96
  */
97
  protected $thirdParty;
98
 
99
- /**
100
- * @var int
101
- */
102
- protected $start;
103
-
104
  /**
105
  * Job constructor.
106
  * @throws Exception
107
  */
108
  public function __construct()
109
  {
110
- $this->start = $this->time();
111
-
112
- $this->maxMemoryLimit = $this->getMemoryInBytes(@ini_get("memory_limit"));
113
-
114
  $this->thirdParty = new thirdPartyCompatibility();
115
 
116
- $this->maxExecutionTime = 10;
117
-
118
  // Services
119
  $this->cache = new Cache(-1, WPStaging::getContentDir());
120
  $this->logger = WPStaging::getInstance()->get("logger");
@@ -146,39 +101,19 @@ abstract class Job
146
  $this->setDefaultSettings();
147
  }
148
 
149
- // Set limits accordingly to CPU LIMITS
150
- $this->setLimits();
151
-
152
- $this->maxRecursionLimit = (int)ini_get("xdebug.max_nesting_level");
153
-
154
- /*
155
- * This is needed to make sure that maxRecursionLimit = -1
156
- * if xdebug is not used in production env.
157
- * For using xdebug, maxRecursionLimit must be larger
158
- * otherwise xdebug is throwing an error 500 while debugging
159
- */
160
- if ($this->maxRecursionLimit < 1) {
161
- $this->maxRecursionLimit = -1;
162
- } else {
163
- $this->maxRecursionLimit = $this->maxRecursionLimit - 50; // just to make sure
164
- }
165
-
166
  if (method_exists($this, "initialize")) {
167
  $this->initialize();
168
  }
169
  }
170
 
171
- /**
172
- * Job destructor
173
- */
174
- public function __destruct()
175
  {
176
  // Commit logs
177
  if ($this->logger instanceof Logger) {
178
  $this->logger->commit();
179
  } else {
180
  if (defined('WPSTG_DEBUG') && WPSTG_DEBUG) {
181
- error_log('Tried to commit log, but $this->logger was not a logger. May be a __destruct problem.');
182
  }
183
  }
184
  }
@@ -205,35 +140,6 @@ abstract class Job
205
  update_option('wpstg_settings', $this->settings);
206
  }
207
 
208
- /**
209
- * Set limits accordingly to
210
- */
211
- protected function setLimits()
212
- {
213
- if (!isset($this->settings->cpuLoad)) {
214
- $this->settings->cpuLoad = "low";
215
- }
216
-
217
- $memoryLimit = self::MAX_MEMORY_RATIO;
218
- $timeLimit = self::EXECUTION_TIME_RATIO;
219
-
220
- switch ($this->settings->cpuLoad) {
221
- case "medium":
222
- $timeLimit = $timeLimit / 2;
223
- break;
224
- case "low":
225
- $timeLimit = $timeLimit / 4;
226
- break;
227
-
228
- case "fast":
229
- default:
230
- break;
231
- }
232
-
233
- $this->memoryLimit = $this->maxMemoryLimit * $memoryLimit;
234
- $this->executionLimit = $this->maxExecutionTime * $timeLimit;
235
- }
236
-
237
  /**
238
  * Save options
239
  * @param null|array|object $options
@@ -262,56 +168,6 @@ abstract class Job
262
  return $this->options;
263
  }
264
 
265
- /**
266
- * @param string $memory
267
- * @return int
268
- */
269
- protected function getMemoryInBytes($memory)
270
- {
271
- // Handle unlimited ones
272
- if ((int)$memory < 1) {
273
- // 128 MB default value
274
- return (int)134217728;
275
- }
276
-
277
- $bytes = (int)$memory; // grab only the number
278
- $size = trim(str_replace($bytes, null, strtolower($memory))); // strip away number and lower-case it
279
- // Actual calculation
280
- switch ($size) {
281
- case 'k':
282
- $bytes *= 1024;
283
- break;
284
- case 'm':
285
- $bytes *= (1024 * 1024);
286
- break;
287
- case 'g':
288
- $bytes *= (1024 * 1024 * 1024);
289
- break;
290
- }
291
-
292
- return $bytes;
293
- }
294
-
295
- /**
296
- * Format bytes into ini_set favorable form
297
- * @param int $bytes
298
- * @return string
299
- */
300
- protected function formatBytes($bytes)
301
- {
302
- if ((int)$bytes < 1) {
303
- return '';
304
- }
305
-
306
- $units = ['B', 'K', 'M', 'G']; // G since PHP 5.1.x so we are good!
307
-
308
- $bytes = (int)$bytes;
309
- $base = log($bytes) / log(1000);
310
- $pow = pow(1000, $base - floor($base));
311
-
312
- return round($pow, 0) . $units[(int)floor($base)];
313
- }
314
-
315
  /**
316
  * Get current time in seconds
317
  * @return float
@@ -330,38 +186,50 @@ abstract class Job
330
  public function isOverThreshold()
331
  {
332
  // Check if the memory is over threshold
333
- $usedMemory = (int)@memory_get_usage(true);
 
 
 
 
 
 
 
 
 
 
 
 
334
 
335
- $this->debugLog('Used Memory: ' . $this->formatBytes($usedMemory) . ' Max Memory Limit: ' . $this->formatBytes($this->maxMemoryLimit) . ' Max Script Memory Limit: ' . $this->formatBytes($this->memoryLimit), Logger::TYPE_DEBUG);
 
 
 
 
 
 
 
 
 
336
 
337
- if ($usedMemory >= $this->memoryLimit) {
338
- $this->log('Used Memory: ' . $this->formatBytes($usedMemory) . ' Memory Limit: ' . $this->formatBytes($this->maxMemoryLimit) . ' Max Script memory limit: ' . $this->formatBytes($this->memoryLimit), Logger::TYPE_ERROR);
339
- return true;
340
- }
341
-
342
- if ($this->isRecursionLimit()) {
343
  return true;
344
  }
345
 
346
  // Check if execution time is over threshold
347
- $time = round($this->time() - $this->start, 4);
348
- if ($time >= $this->executionLimit) {
349
- $this->debugLog('RESET TIME: current time: ' . $time . ', Start Time: ' . $this->start . ', exec time limit: ' . $this->executionLimit);
 
 
 
 
 
 
350
  return true;
351
  }
352
 
353
  return false;
354
  }
355
 
356
- /**
357
- * Checks if calls are over recursion limit
358
- * @return bool
359
- */
360
- protected function isRecursionLimit()
361
- {
362
- return ($this->maxRecursionLimit > 0 && $this->totalRecursion >= $this->maxRecursionLimit);
363
- }
364
-
365
  /**
366
  * @param string $msg
367
  * @param string $type
7
  die;
8
  }
9
 
 
 
 
 
 
 
 
10
  use DateInterval;
11
+ use DateTime;
12
  use Exception;
13
+ use WPStaging\Core\thirdParty\thirdPartyCompatibility;
14
+ use WPStaging\Core\Utils\Cache;
15
+ use WPStaging\Core\Utils\Logger;
16
+ use WPStaging\Core\WPStaging;
17
+ use WPStaging\Framework\Interfaces\ShutdownableInterface;
18
+ use WPStaging\Framework\Traits\ResourceTrait;
19
 
20
  /**
21
  * Class Job
22
  * @package WPStaging\Backend\Modules\Jobs
23
  */
24
+ abstract class Job implements ShutdownableInterface
25
  {
26
+ use ResourceTrait;
 
 
27
 
28
  /**
29
  * @var Cache
50
  */
51
  protected $settings;
52
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  /**
54
  * Multisite home domain without scheme
55
  * @var string
62
  */
63
  protected $thirdParty;
64
 
 
 
 
 
 
65
  /**
66
  * Job constructor.
67
  * @throws Exception
68
  */
69
  public function __construct()
70
  {
 
 
 
 
71
  $this->thirdParty = new thirdPartyCompatibility();
72
 
 
 
73
  // Services
74
  $this->cache = new Cache(-1, WPStaging::getContentDir());
75
  $this->logger = WPStaging::getInstance()->get("logger");
101
  $this->setDefaultSettings();
102
  }
103
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
104
  if (method_exists($this, "initialize")) {
105
  $this->initialize();
106
  }
107
  }
108
 
109
+ public function onWpShutdown()
 
 
 
110
  {
111
  // Commit logs
112
  if ($this->logger instanceof Logger) {
113
  $this->logger->commit();
114
  } else {
115
  if (defined('WPSTG_DEBUG') && WPSTG_DEBUG) {
116
+ error_log('Tried to commit log, but $this->logger was not a logger.');
117
  }
118
  }
119
  }
140
  update_option('wpstg_settings', $this->settings);
141
  }
142
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
143
  /**
144
  * Save options
145
  * @param null|array|object $options
168
  return $this->options;
169
  }
170
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
171
  /**
172
  * Get current time in seconds
173
  * @return float
186
  public function isOverThreshold()
187
  {
188
  // Check if the memory is over threshold
189
+ $usedMemory = $this->getMemoryPeakUsage(true);
190
+ $maxMemoryLimit = $this->getMaxMemoryLimit();
191
+ $scriptMemoryLimit = $this->getScriptMemoryLimit();
192
+
193
+ $this->debugLog(
194
+ sprintf(
195
+ "Used Memory: %s Max Memory Limit: %s Max Script Memory Limit: %s",
196
+ size_format($usedMemory),
197
+ size_format($maxMemoryLimit),
198
+ size_format($scriptMemoryLimit)
199
+ ),
200
+ Logger::TYPE_DEBUG
201
+ );
202
 
203
+ if ($this->isMemoryLimit()) {
204
+ $this->log(
205
+ sprintf(
206
+ "Used Memory: %s Memory Limit: %s Max Script memory limit: %s",
207
+ size_format($usedMemory),
208
+ size_format($maxMemoryLimit),
209
+ size_format($scriptMemoryLimit)
210
+ ),
211
+ Logger::TYPE_ERROR
212
+ );
213
 
 
 
 
 
 
 
214
  return true;
215
  }
216
 
217
  // Check if execution time is over threshold
218
+ if ($this->isTimeLimit()) {
219
+ $this->debugLog(
220
+ sprintf(
221
+ "RESET TIME: current time: %s, Start Time: %d, exec time limit: %s",
222
+ $this->getRunningTime(),
223
+ WPStaging::getInstance()->getStartTime(),
224
+ $this->findExecutionTimeLimit()
225
+ )
226
+ );
227
  return true;
228
  }
229
 
230
  return false;
231
  }
232
 
 
 
 
 
 
 
 
 
 
233
  /**
234
  * @param string $msg
235
  * @param string $type
Backend/Modules/Jobs/JobExecutable.php CHANGED
@@ -75,7 +75,6 @@ abstract class JobExecutable extends Job
75
  "step" => $this->options->currentStep,
76
  "job" => $this->options->currentJob,
77
  "last_msg" => $this->logger->getLastLogMsg(),
78
- "running_time" => $this->time() - time(),
79
  "job_done" => $status
80
  ];
81
  }
75
  "step" => $this->options->currentStep,
76
  "job" => $this->options->currentJob,
77
  "last_msg" => $this->logger->getLastLogMsg(),
 
78
  "job_done" => $status
79
  ];
80
  }
Backend/Modules/Jobs/SearchReplace.php CHANGED
@@ -2,11 +2,6 @@
2
 
3
  namespace WPStaging\Backend\Modules\Jobs;
4
 
5
- // No Direct Access
6
- if (!defined("WPINC")) {
7
- die;
8
- }
9
-
10
  use WPStaging\Core\Utils\Helper;
11
  use WPStaging\Core\Utils\Logger;
12
  use WPStaging\Core\Utils\Multisite;
@@ -15,7 +10,13 @@ use WPStaging\Framework\Traits\DbRowsGeneratorTrait;
15
  use WPStaging\Framework\Utils\Strings;
16
 
17
  /**
18
- * Class Database
 
 
 
 
 
 
19
  * @package WPStaging\Backend\Modules\Jobs
20
  */
21
  class SearchReplace extends CloningProcess
@@ -235,12 +236,25 @@ class SearchReplace extends CloningProcess
235
  private function startReplace($table)
236
  {
237
  $rows = $this->options->job->start + $this->settings->querySRLimit;
 
 
 
 
 
 
 
 
 
238
  $this->log(
239
  "DB Search & Replace: Table {$table} {$this->options->job->start} to {$rows} records"
240
  );
241
 
242
  // Search & Replace
243
  $this->searchReplace($table, []);
 
 
 
 
244
  }
245
 
246
  /**
@@ -253,8 +267,8 @@ class SearchReplace extends CloningProcess
253
  protected function get_columns($table)
254
  {
255
  $primary_key = null;
256
- $columns = [];
257
- $fields = $this->stagingDb->get_results('DESCRIBE ' . $table);
258
 
259
  if (empty($fields)) {
260
  // Either there was an error or the table has no columns.
@@ -280,11 +294,6 @@ class SearchReplace extends CloningProcess
280
  */
281
  private function searchReplace($table, $args)
282
  {
283
- if ($this->thirdParty->isSearchReplaceExcluded($table)) {
284
- $this->log("DB Search & Replace: Skip {$table}", Logger::TYPE_INFO);
285
- return true;
286
- }
287
-
288
  $table = esc_sql($table);
289
 
290
  $args['search_for'] = $this->searchReplaceService->generateHostnamePatterns($this->sourceHostname);
@@ -315,11 +324,33 @@ class SearchReplace extends CloningProcess
315
 
316
  list($primary_key, $columns) = $primaryKeyAndColumns;
317
 
 
 
 
 
318
  $currentRow = 0;
319
  $offset = $this->options->job->start;
320
  $limit = $this->settings->querySRLimit;
321
 
322
- $data = $this->rowsGenerator($table, $offset, $limit, $this->stagingDb);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
323
 
324
  // Filter certain rows (of other plugins)
325
  $filter = $this->searchReplaceService->excludedStrings();
@@ -328,6 +359,20 @@ class SearchReplace extends CloningProcess
328
 
329
  $processed = 0;
330
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
331
  // Go through the table rows
332
  foreach ($data as $row) {
333
  $processed++;
@@ -401,9 +446,30 @@ class SearchReplace extends CloningProcess
401
  }
402
  }
403
  } // end row loop
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
404
  unset($row,$updateSql,$whereSql,$sql,$currentRow);
405
 
406
- $this->updateJobStart($processed);
 
 
 
 
 
407
 
408
  // DB Flush
409
  $this->stagingDb->flush();
@@ -426,18 +492,18 @@ class SearchReplace extends CloningProcess
426
 
427
  /**
428
  * Start Job
429
- * @param string $new
430
- * @param string $old
431
  * @return bool
432
  */
433
- private function startJob($new, $old)
434
  {
435
- if ($this->isExcludedTable($new)) {
436
  return false;
437
  }
438
 
439
  // Table does not exist
440
- $result = $this->productionDb->query("SHOW TABLES LIKE '{$old}'");
441
  if (!$result || $result === 0) {
442
  return false;
443
  }
@@ -451,7 +517,7 @@ class SearchReplace extends CloningProcess
451
  return !($this->options->job->failedAttempts > $this->maxFailedAttempts);
452
  }
453
 
454
- $this->options->job->total = (int)$this->productionDb->get_var("SELECT COUNT(1) FROM {$old}");
455
  $this->options->job->failedAttempts = 0;
456
 
457
  if ($this->options->job->total == 0) {
@@ -470,8 +536,14 @@ class SearchReplace extends CloningProcess
470
  private function isExcludedTable($table)
471
  {
472
  $excludedCustomTables = apply_filters('wpstg_clone_searchreplace_tables_exclude', []);
 
473
  $excludedDefaultTables = ['blogs'];
474
 
 
 
 
 
 
475
  $tables = array_merge($excludedCustomTables, $excludedDefaultTables);
476
 
477
  $excludedAllTables = [];
@@ -480,6 +552,7 @@ class SearchReplace extends CloningProcess
480
  }
481
 
482
  if (in_array($table, $excludedAllTables)) {
 
483
  return true;
484
  }
485
  return false;
@@ -539,14 +612,43 @@ class SearchReplace extends CloningProcess
539
  *
540
  * If nothing was processed, then the job start will be ticked by 1.
541
  *
542
- * @param int $processed The number of actually processed rows in this run.
543
- t
 
 
544
  * @return void The method does not return any value.
545
  */
546
- protected function updateJobStart($processed)
547
  {
548
  $this->processed = absint($processed);
549
- $this->options->job->start += max($processed, 1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
550
  }
551
 
552
  /**
@@ -559,4 +661,11 @@ class SearchReplace extends CloningProcess
559
  {
560
  return $this->processed;
561
  }
 
 
 
 
 
 
 
562
  }
2
 
3
  namespace WPStaging\Backend\Modules\Jobs;
4
 
 
 
 
 
 
5
  use WPStaging\Core\Utils\Helper;
6
  use WPStaging\Core\Utils\Logger;
7
  use WPStaging\Core\Utils\Multisite;
10
  use WPStaging\Framework\Utils\Strings;
11
 
12
  /**
13
+ * Class SearchReplace
14
+ *
15
+ * Used for CLONING
16
+ * @see \WPStaging\Backend\Pro\Modules\Jobs\SearchReplace Used for PUSHING
17
+ *
18
+ * @todo Unify those
19
+ *
20
  * @package WPStaging\Backend\Modules\Jobs
21
  */
22
  class SearchReplace extends CloningProcess
236
  private function startReplace($table)
237
  {
238
  $rows = $this->options->job->start + $this->settings->querySRLimit;
239
+
240
+ if ((int)$this->settings->querySRLimit <= 1) {
241
+ $this->logDebug(sprintf('%s - $this->settings->querySRLimit is too low. Typeof: %s. JSON Encoded Value: %s', __METHOD__, gettype($this->settings->querySRLimit), wp_json_encode($this->settings->querySRLimit)));
242
+ }
243
+
244
+ if ((int)$rows <= 1) {
245
+ $this->logDebug(sprintf('%s - $rows is too low.', __METHOD__));
246
+ }
247
+
248
  $this->log(
249
  "DB Search & Replace: Table {$table} {$this->options->job->start} to {$rows} records"
250
  );
251
 
252
  // Search & Replace
253
  $this->searchReplace($table, []);
254
+
255
+ if (defined('WPSTG_DISABLE_SEARCH_REPLACE_GENERATOR') && WPSTG_DISABLE_SEARCH_REPLACE_GENERATOR) {
256
+ $this->options->job->start += $this->settings->querySRLimit;
257
+ }
258
  }
259
 
260
  /**
267
  protected function get_columns($table)
268
  {
269
  $primary_key = null;
270
+ $columns = [];
271
+ $fields = $this->stagingDb->get_results('DESCRIBE ' . $table);
272
 
273
  if (empty($fields)) {
274
  // Either there was an error or the table has no columns.
294
  */
295
  private function searchReplace($table, $args)
296
  {
 
 
 
 
 
297
  $table = esc_sql($table);
298
 
299
  $args['search_for'] = $this->searchReplaceService->generateHostnamePatterns($this->sourceHostname);
324
 
325
  list($primary_key, $columns) = $primaryKeyAndColumns;
326
 
327
+ if ($this->options->job->current != $table) {
328
+ $this->logDebug(sprintf('We are using the LIMITS of a table different than the table we are parsing now. Table being parsed: %s. Table that we are using "start" from: %s. Start: %s', $table, $this->options->job->current, $this->options->job->start));
329
+ }
330
+
331
  $currentRow = 0;
332
  $offset = $this->options->job->start;
333
  $limit = $this->settings->querySRLimit;
334
 
335
+ /// DEBUG
336
+ $this->logDebug(
337
+ sprintf(
338
+ 'SearchReplace-beforeRowsGenerator: max-memory-limit=%s; script-memory-limit=%s; memory-usage=%s; execution-time-limit=%s; running-time=%s; is-threshold=%s',
339
+ $this->getMaxMemoryLimit(),
340
+ $this->getScriptMemoryLimit(),
341
+ $this->getMemoryUsage(),
342
+ $this->findExecutionTimeLimit(),
343
+ $this->getRunningTime(),
344
+ ($this->isThreshold() ? 'yes' : 'no')
345
+ )
346
+ );
347
+ /// DEBUG
348
+
349
+ if (defined('WPSTG_DISABLE_SEARCH_REPLACE_GENERATOR') && WPSTG_DISABLE_SEARCH_REPLACE_GENERATOR) {
350
+ $data = $this->stagingDb->get_results("SELECT * FROM $table LIMIT $offset, $limit", ARRAY_A);
351
+ } else {
352
+ $data = $this->rowsGenerator($table, $offset, $limit, $this->stagingDb);
353
+ }
354
 
355
  // Filter certain rows (of other plugins)
356
  $filter = $this->searchReplaceService->excludedStrings();
359
 
360
  $processed = 0;
361
 
362
+ /// DEBUG
363
+ $this->logDebug(
364
+ sprintf(
365
+ 'SearchReplace-beforeRowProcessing: max-memory-limit=%s; script-memory-limit=%s; memory-usage=%s; execution-time-limit=%s; running-time=%s; is-threshold=%s',
366
+ $this->getMaxMemoryLimit(),
367
+ $this->getScriptMemoryLimit(),
368
+ $this->getMemoryUsage(),
369
+ $this->findExecutionTimeLimit(),
370
+ $this->getRunningTime(),
371
+ ($this->isThreshold() ? 'yes' : 'no')
372
+ )
373
+ );
374
+ /// DEBUG
375
+
376
  // Go through the table rows
377
  foreach ($data as $row) {
378
  $processed++;
446
  }
447
  }
448
  } // end row loop
449
+
450
+ /// DEBUG
451
+ $this->logDebug(
452
+ sprintf(
453
+ 'SearchReplace-afterRowsProcessing: processed=%s; max-memory-limit=%s; script-memory-limit=%s; memory-usage=%s; execution-time-limit=%s; running-time=%s; is-threshold=%s',
454
+ $processed,
455
+ $this->getMaxMemoryLimit(),
456
+ $this->getScriptMemoryLimit(),
457
+ $this->getMemoryUsage(),
458
+ $this->findExecutionTimeLimit(),
459
+ $this->getRunningTime(),
460
+ ($this->isThreshold() ? 'yes' : 'no')
461
+ )
462
+ );
463
+ /// DEBUG
464
+
465
  unset($row,$updateSql,$whereSql,$sql,$currentRow);
466
 
467
+ if (
468
+ !defined('WPSTG_DISABLE_SEARCH_REPLACE_GENERATOR') ||
469
+ defined('WPSTG_DISABLE_SEARCH_REPLACE_GENERATOR') && !WPSTG_DISABLE_SEARCH_REPLACE_GENERATOR
470
+ ) {
471
+ $this->updateJobStart($processed, $this->stagingDb, $table);
472
+ }
473
 
474
  // DB Flush
475
  $this->stagingDb->flush();
492
 
493
  /**
494
  * Start Job
495
+ * @param string $newTableName
496
+ * @param string $oldTableName
497
  * @return bool
498
  */
499
+ private function startJob($newTableName, $oldTableName)
500
  {
501
+ if ($this->isExcludedTable($newTableName)) {
502
  return false;
503
  }
504
 
505
  // Table does not exist
506
+ $result = $this->productionDb->query("SHOW TABLES LIKE '{$oldTableName}'");
507
  if (!$result || $result === 0) {
508
  return false;
509
  }
517
  return !($this->options->job->failedAttempts > $this->maxFailedAttempts);
518
  }
519
 
520
+ $this->options->job->total = (int)$this->productionDb->get_var("SELECT COUNT(1) FROM {$oldTableName}");
521
  $this->options->job->failedAttempts = 0;
522
 
523
  if ($this->options->job->total == 0) {
536
  private function isExcludedTable($table)
537
  {
538
  $excludedCustomTables = apply_filters('wpstg_clone_searchreplace_tables_exclude', []);
539
+
540
  $excludedDefaultTables = ['blogs'];
541
 
542
+ // @todo remove isSearchReplaceExcluded() if SearchReplace() is made DRY and provide a simple list of excluded table names
543
+ if ($this->thirdParty->isSearchReplaceExcluded($table)) {
544
+ $excludedDefaultTables[] = str_replace($this->options->prefix, '', $table);
545
+ }
546
+
547
  $tables = array_merge($excludedCustomTables, $excludedDefaultTables);
548
 
549
  $excludedAllTables = [];
552
  }
553
 
554
  if (in_array($table, $excludedAllTables)) {
555
+ $this->log("DB Search & Replace: Table {$table} excluded by WP STAGING", Logger::TYPE_INFO);
556
  return true;
557
  }
558
  return false;
612
  *
613
  * If nothing was processed, then the job start will be ticked by 1.
614
  *
615
+ * @param int $processed The number of actually processed rows in this run.
616
+ * @param \wpdb $db The wpdb instance being used to process.
617
+ * @param string $table The table being processed.
618
+ *
619
  * @return void The method does not return any value.
620
  */
621
+ protected function updateJobStart($processed, \wpdb $db, $table)
622
  {
623
  $this->processed = absint($processed);
624
+
625
+ // We make sure to increment the offset at least in 1 to avoid infinite loops.
626
+ $minimumProcessed = 1;
627
+
628
+ /*
629
+ * There are some scenarios where we couldn't process any rows in this request.
630
+ * The exact causes of this is still under investigation, but to mitigate this
631
+ * effect, we will smartly set the offset for the next job based on some context.
632
+ */
633
+ if ($this->processed === 0) {
634
+ $this->logDebug('SEARCH_REPLACE: Processed is zero');
635
+
636
+ $totalRowsInTable = $db->get_var("SELECT COUNT(*) FROM $table");
637
+
638
+ if (is_numeric($totalRowsInTable)) {
639
+ $this->logDebug("SEARCH_REPLACE: Rows count is numeric: $totalRowsInTable");
640
+ // Skip 1% of the current table on each iteration, with a minimum of 1 and a maximum of the query limit.
641
+ $minimumProcessed = min(max((int)$totalRowsInTable / 100, 1), $this->settings->querySRLimit);
642
+ } else {
643
+ $this->logDebug(sprintf("SEARCH_REPLACE: Rows count is not numeric. Type: %s. Json encoded value: %s", gettype($totalRowsInTable), wp_json_encode($totalRowsInTable)));
644
+ // Unexpected result from query. Set the offset to the limit.
645
+ $minimumProcessed = $this->settings->querySRLimit;
646
+ }
647
+
648
+ $this->logDebug("SEARCH_REPLACE: Minimum processed is: $minimumProcessed");
649
+ }
650
+
651
+ $this->options->job->start += max($processed, $minimumProcessed);
652
  }
653
 
654
  /**
661
  {
662
  return $this->processed;
663
  }
664
+
665
+ protected function logDebug($message)
666
+ {
667
+ if (defined('WPSTG_DEBUG') && WPSTG_DEBUG) {
668
+ error_log($message);
669
+ }
670
+ }
671
  }
Core/Utils/Logger.php CHANGED
@@ -11,6 +11,7 @@ namespace WPStaging\Core\Utils;
11
 
12
  use WPStaging\Core\WPStaging;
13
  use WPStaging\Framework\Filesystem\Filesystem;
 
14
  use WPStaging\Vendor\Psr\Log\LoggerInterface;
15
  use WPStaging\Vendor\Psr\Log\LogLevel;
16
 
@@ -18,7 +19,7 @@ use WPStaging\Vendor\Psr\Log\LogLevel;
18
  * Class Logger
19
  * @package WPStaging\Core\Utils
20
  */
21
- class Logger implements LoggerInterface
22
  {
23
  const TYPE_ERROR = "ERROR";
24
 
@@ -87,7 +88,7 @@ class Logger implements LoggerInterface
87
  (new Filesystem())->mkdir($this->logDir);
88
  }
89
 
90
- public function __destruct()
91
  {
92
  $this->commit();
93
  }
11
 
12
  use WPStaging\Core\WPStaging;
13
  use WPStaging\Framework\Filesystem\Filesystem;
14
+ use WPStaging\Framework\Interfaces\ShutdownableInterface;
15
  use WPStaging\Vendor\Psr\Log\LoggerInterface;
16
  use WPStaging\Vendor\Psr\Log\LogLevel;
17
 
19
  * Class Logger
20
  * @package WPStaging\Core\Utils
21
  */
22
+ class Logger implements LoggerInterface, ShutdownableInterface
23
  {
24
  const TYPE_ERROR = "ERROR";
25
 
88
  (new Filesystem())->mkdir($this->logDir);
89
  }
90
 
91
+ public function onWpShutdown()
92
  {
93
  $this->commit();
94
  }
Core/WPStaging.php CHANGED
@@ -37,6 +37,11 @@ final class WPStaging
37
  */
38
  private $isBootstrapped = false;
39
 
 
 
 
 
 
40
  /**
41
  * WPStaging constructor.
42
  */
@@ -49,6 +54,8 @@ final class WPStaging
49
  {
50
  $this->isBootstrapped = true;
51
 
 
 
52
  // Todo: Move this to a common service Provider for both Free and Pro. Do not register anything else here.
53
  $this->container->bind(LoggerInterface::class, Logger::class);
54
 
@@ -65,6 +72,11 @@ final class WPStaging
65
  $this->preventDirectoryListing();
66
  }
67
 
 
 
 
 
 
68
  /**
69
  * Initialize cron jobs
70
  */
37
  */
38
  private $isBootstrapped = false;
39
 
40
+ /**
41
+ * @var int The microtime where the Container was bootstraped. Used to identify the time where the application started running.
42
+ */
43
+ private $startTime;
44
+
45
  /**
46
  * WPStaging constructor.
47
  */
54
  {
55
  $this->isBootstrapped = true;
56
 
57
+ $this->startTime = microtime(true);
58
+
59
  // Todo: Move this to a common service Provider for both Free and Pro. Do not register anything else here.
60
  $this->container->bind(LoggerInterface::class, Logger::class);
61
 
72
  $this->preventDirectoryListing();
73
  }
74
 
75
+ public function getStartTime()
76
+ {
77
+ return $this->startTime;
78
+ }
79
+
80
  /**
81
  * Initialize cron jobs
82
  */
Core/thirdParty/thirdPartyCompatibility.php CHANGED
@@ -5,7 +5,9 @@ namespace WPStaging\Core\thirdParty;
5
  /**
6
  * Methods to use for third party plugin compatibility
7
  *
8
- * @author IronMan
 
 
9
  */
10
  class thirdPartyCompatibility {
11
 
@@ -17,6 +19,7 @@ class thirdPartyCompatibility {
17
  public function isSearchReplaceExcluded( $table ) {
18
  $excludedTables = [
19
  '_cerber_files', // Cerber Security Plugin
 
20
  ];
21
 
22
  $excludedTables = apply_filters( 'wpstg_searchreplace_excl_tables', $excludedTables );
5
  /**
6
  * Methods to use for third party plugin compatibility
7
  *
8
+ * @todo remove this method when src/Backend/Modules/Jobs/SearchReplace.php and
9
+ * src/Backend/Pro/Modules/Jobs/SearchReplace.php are made DRY
10
+ *
11
  */
12
  class thirdPartyCompatibility {
13
 
19
  public function isSearchReplaceExcluded( $table ) {
20
  $excludedTables = [
21
  '_cerber_files', // Cerber Security Plugin
22
+ '_cerber_sets', // Cerber Security Plugin
23
  ];
24
 
25
  $excludedTables = apply_filters( 'wpstg_searchreplace_excl_tables', $excludedTables );
Framework/DI/Container.php CHANGED
@@ -2,6 +2,8 @@
2
 
3
  namespace WPStaging\Framework\DI;
4
 
 
 
5
  class Container extends \WPStaging\Vendor\tad_DI52_Container
6
  {
7
  /**
@@ -31,10 +33,38 @@ class Container extends \WPStaging\Vendor\tad_DI52_Container
31
  }
32
  }
33
 
34
- public function offsetUnset($offset)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  {
36
- parent::offsetUnset($offset);
37
- unset($this->reflections[$offset]);
 
 
 
 
 
 
38
  }
39
 
40
  /**
2
 
3
  namespace WPStaging\Framework\DI;
4
 
5
+ use WPStaging\Framework\Interfaces\ShutdownableInterface;
6
+
7
  class Container extends \WPStaging\Vendor\tad_DI52_Container
8
  {
9
  /**
33
  }
34
  }
35
 
36
+ /**
37
+ * Allows to enqueue the ShutdownableInterface hook
38
+ * on classes resolved by the DI container, such as
39
+ * dependencies injected in the __construct.
40
+ */
41
+ protected function resolve($classOrInterface)
42
+ {
43
+ $instance = parent::resolve($classOrInterface);
44
+ if (is_object($instance) && $instance instanceof ShutdownableInterface) {
45
+ if (!has_action('shutdown', [$instance, 'onWpShutdown'])) {
46
+ add_action('shutdown', [$instance, 'onWpShutdown']);
47
+ }
48
+ }
49
+
50
+ return $instance;
51
+ }
52
+
53
+ /**
54
+ * Allows to enqueue the ShutdownableInterface hook
55
+ * on classes requested directly by the application
56
+ * to the container.
57
+ */
58
+ public function make($classOrInterface)
59
  {
60
+ $instance = parent::make($classOrInterface);
61
+ if (is_object($instance) && $instance instanceof ShutdownableInterface) {
62
+ if (!has_action('shutdown', [$instance, 'onWpShutdown'])) {
63
+ add_action('shutdown', [$instance, 'onWpShutdown']);
64
+ }
65
+ }
66
+
67
+ return $instance;
68
  }
69
 
70
  /**
Framework/Filesystem/DirectoryScannerControl.php CHANGED
@@ -7,6 +7,7 @@
7
  namespace WPStaging\Framework\Filesystem;
8
 
9
  use RuntimeException;
 
10
  use WPStaging\Pro\Backup\Task\Tasks\JobExport\DirectoryScannerTask;
11
  use WPStaging\Framework\Adapter\Directory;
12
  use WPStaging\Framework\Queue\FinishedQueueException;
@@ -21,7 +22,7 @@ use WPStaging\Framework\Utils\Cache\BufferedCache;
21
  *
22
  * @package WPStaging\Framework\Filesystem
23
  */
24
- class DirectoryScannerControl
25
  {
26
  const DATA_CACHE_FILE = 'filesystem_scanner_directory_data';
27
  const QUEUE_CACHE_FILE = 'directory_scanner';
@@ -53,7 +54,7 @@ class DirectoryScannerControl
53
  $this->directory = $directory;
54
  }
55
 
56
- public function __destruct()
57
  {
58
  if ($this->newQueueItems && $this->queue) {
59
  $this->queue->pushAsArray($this->newQueueItems);
7
  namespace WPStaging\Framework\Filesystem;
8
 
9
  use RuntimeException;
10
+ use WPStaging\Framework\Interfaces\ShutdownableInterface;
11
  use WPStaging\Pro\Backup\Task\Tasks\JobExport\DirectoryScannerTask;
12
  use WPStaging\Framework\Adapter\Directory;
13
  use WPStaging\Framework\Queue\FinishedQueueException;
22
  *
23
  * @package WPStaging\Framework\Filesystem
24
  */
25
+ class DirectoryScannerControl implements ShutdownableInterface
26
  {
27
  const DATA_CACHE_FILE = 'filesystem_scanner_directory_data';
28
  const QUEUE_CACHE_FILE = 'directory_scanner';
54
  $this->directory = $directory;
55
  }
56
 
57
+ public function onWpShutdown()
58
  {
59
  if ($this->newQueueItems && $this->queue) {
60
  $this->queue->pushAsArray($this->newQueueItems);
Framework/Filesystem/FileScannerControl.php CHANGED
@@ -7,13 +7,14 @@
7
  namespace WPStaging\Framework\Filesystem;
8
 
9
  use RuntimeException;
 
10
  use WPStaging\Framework\Queue\FinishedQueueException;
11
  use WPStaging\Framework\Queue\Queue;
12
  use WPStaging\Framework\Queue\Storage\BufferedCacheStorage;
13
  use WPStaging\Framework\Utils\Cache\BufferedCache;
14
  use WPStaging\Vendor\Psr\Log\LoggerInterface;
15
 
16
- class FileScannerControl
17
  {
18
  const DATA_CACHE_FILE = 'filesystem_scanner_file_data';
19
  const QUEUE_CACHE_FILE = 'file_scanner';
@@ -41,7 +42,7 @@ class FileScannerControl
41
  $this->scanner = $scanner;
42
  }
43
 
44
- public function __destruct()
45
  {
46
  if ($this->newQueueItems && $this->queue) {
47
  $this->queue->pushAsArray($this->newQueueItems);
7
  namespace WPStaging\Framework\Filesystem;
8
 
9
  use RuntimeException;
10
+ use WPStaging\Framework\Interfaces\ShutdownableInterface;
11
  use WPStaging\Framework\Queue\FinishedQueueException;
12
  use WPStaging\Framework\Queue\Queue;
13
  use WPStaging\Framework\Queue\Storage\BufferedCacheStorage;
14
  use WPStaging\Framework\Utils\Cache\BufferedCache;
15
  use WPStaging\Vendor\Psr\Log\LoggerInterface;
16
 
17
+ class FileScannerControl implements ShutdownableInterface
18
  {
19
  const DATA_CACHE_FILE = 'filesystem_scanner_file_data';
20
  const QUEUE_CACHE_FILE = 'file_scanner';
42
  $this->scanner = $scanner;
43
  }
44
 
45
+ public function onWpShutdown()
46
  {
47
  if ($this->newQueueItems && $this->queue) {
48
  $this->queue->pushAsArray($this->newQueueItems);
Framework/Interfaces/ShutdownableInterface.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WPStaging\Framework\Interfaces;
4
+
5
+ /**
6
+ * Interface ShutdownableInterface
7
+ *
8
+ * @see \WPStaging\Framework\DI\Container::make
9
+ *
10
+ * @package WPStaging\Framework\Interfaces
11
+ */
12
+ interface ShutdownableInterface
13
+ {
14
+ /**
15
+ * This code will be hooked to the "shutdown" WordPress action.
16
+ *
17
+ * @return void
18
+ */
19
+ public function onWpShutdown();
20
+ }
Framework/Queue/Storage/BufferedCacheStorage.php CHANGED
@@ -5,13 +5,14 @@
5
 
6
  namespace WPStaging\Framework\Queue\Storage;
7
 
 
8
  use WPStaging\Framework\Utils\Cache\AbstractCache;
9
  use WPStaging\Framework\Utils\Cache\BufferedCache;
10
 
11
  // This does not use $items like other cache
12
  // $items are to append to the end of the cache when it is destructed
13
  // Buffered Cache does not read entire file, it read the file partially
14
- class BufferedCacheStorage implements StorageInterface
15
  {
16
  const FILE_PREFIX = 'queue_';
17
 
@@ -36,7 +37,7 @@ class BufferedCacheStorage implements StorageInterface
36
  $this->items = [];
37
  }
38
 
39
- public function __destruct()
40
  {
41
  if (!$this->commited) {
42
  $this->commit();
5
 
6
  namespace WPStaging\Framework\Queue\Storage;
7
 
8
+ use WPStaging\Framework\Interfaces\ShutdownableInterface;
9
  use WPStaging\Framework\Utils\Cache\AbstractCache;
10
  use WPStaging\Framework\Utils\Cache\BufferedCache;
11
 
12
  // This does not use $items like other cache
13
  // $items are to append to the end of the cache when it is destructed
14
  // Buffered Cache does not read entire file, it read the file partially
15
+ class BufferedCacheStorage implements StorageInterface, ShutdownableInterface
16
  {
17
  const FILE_PREFIX = 'queue_';
18
 
37
  $this->items = [];
38
  }
39
 
40
+ public function onWpShutdown()
41
  {
42
  if (!$this->commited) {
43
  $this->commit();
Framework/Queue/Storage/CacheStorage.php CHANGED
@@ -5,10 +5,11 @@
5
 
6
  namespace WPStaging\Framework\Queue\Storage;
7
 
 
8
  use WPStaging\Framework\Utils\Cache\AbstractCache;
9
  use WPStaging\Framework\Utils\Cache\Cache;
10
 
11
- class CacheStorage implements StorageInterface
12
  {
13
  /** @var string */
14
  private $key;
@@ -26,7 +27,7 @@ class CacheStorage implements StorageInterface
26
  $this->cache = $cache;
27
  }
28
 
29
- public function __destruct()
30
  {
31
  if (!$this->commited) {
32
  $this->commit();
5
 
6
  namespace WPStaging\Framework\Queue\Storage;
7
 
8
+ use WPStaging\Framework\Interfaces\ShutdownableInterface;
9
  use WPStaging\Framework\Utils\Cache\AbstractCache;
10
  use WPStaging\Framework\Utils\Cache\Cache;
11
 
12
+ class CacheStorage implements StorageInterface, ShutdownableInterface
13
  {
14
  /** @var string */
15
  private $key;
27
  $this->cache = $cache;
28
  }
29
 
30
+ public function onWpShutdown()
31
  {
32
  if (!$this->commited) {
33
  $this->commit();
Framework/Traits/DbRowsGeneratorTrait.php CHANGED
@@ -38,13 +38,29 @@ trait DbRowsGeneratorTrait
38
  */
39
  protected function rowsGenerator($table, $offset, $limit, \wpdb $db = null)
40
  {
41
- $this->initiateStartTime();
 
 
 
 
 
 
 
 
 
 
 
 
 
42
 
43
  if (null === $db) {
44
  global $wpdb;
45
  $db = $wpdb;
46
  }
47
 
 
 
 
48
  // Sets the execution time limit to either a detected value below 10s and above 1s, or a safe 10s value.
49
  $this->setTimeLimit(min(10, max((int)$this->findExecutionTimeLimit(), 1)));
50
 
@@ -60,13 +76,27 @@ trait DbRowsGeneratorTrait
60
  break;
61
  }
62
 
 
 
63
  $rows = $db->get_results("SELECT * FROM {$table} LIMIT {$offset}, {$batchSize}", ARRAY_A);
64
 
65
- if (null === $rows) {
 
 
 
 
 
 
66
  // We're done here.
67
  break;
68
  }
69
 
 
 
 
 
 
 
70
  $offset += $batchSize;
71
  // If we got less than the batch size, then this is the last fetch.
72
  $lastFetch = count($rows) < $batchSize;
@@ -85,5 +115,7 @@ trait DbRowsGeneratorTrait
85
  // It's actually processed when the caller code returns the control to the Generator.
86
  $processed++;
87
  } while (!$this->isThreshold() && $processed < $limit);
 
 
88
  }
89
  }
38
  */
39
  protected function rowsGenerator($table, $offset, $limit, \wpdb $db = null)
40
  {
41
+ if (defined('WPSTG_DEBUG') && WPSTG_DEBUG) {
42
+ error_log(
43
+ sprintf(
44
+ 'DbRowsGeneratorTrait: max-memory-limit=%s; script-memory-limit=%s; memory-usage=%s; execution-time-limit=%s; running-time=%s; is-threshold=%s',
45
+ $this->getMaxMemoryLimit(),
46
+ $this->getScriptMemoryLimit(),
47
+ $this->getMemoryUsage(),
48
+ $this->findExecutionTimeLimit(),
49
+ $this->getRunningTime(),
50
+ ($this->isThreshold() ? 'yes' : 'no')
51
+ )
52
+ );
53
+ }
54
+
55
 
56
  if (null === $db) {
57
  global $wpdb;
58
  $db = $wpdb;
59
  }
60
 
61
+ $suppressErrorsOriginal = $db->suppress_errors;
62
+ $db->suppress_errors(false);
63
+
64
  // Sets the execution time limit to either a detected value below 10s and above 1s, or a safe 10s value.
65
  $this->setTimeLimit(min(10, max((int)$this->findExecutionTimeLimit(), 1)));
66
 
76
  break;
77
  }
78
 
79
+ $batchSize = ceil($batchSize);
80
+
81
  $rows = $db->get_results("SELECT * FROM {$table} LIMIT {$offset}, {$batchSize}", ARRAY_A);
82
 
83
+ if (!empty($db->last_error)) {
84
+ if (defined('WPSTG_DEBUG') && WPSTG_DEBUG) {
85
+ error_log($db->last_error);
86
+ }
87
+ }
88
+
89
+ if (empty($rows)) {
90
  // We're done here.
91
  break;
92
  }
93
 
94
+ if (!is_array($rows)) {
95
+ if (defined('WPSTG_DEBUG') && WPSTG_DEBUG) {
96
+ error_log(sprintf('$rows is not an array. Actual type: %s', gettype($rows)));
97
+ }
98
+ }
99
+
100
  $offset += $batchSize;
101
  // If we got less than the batch size, then this is the last fetch.
102
  $lastFetch = count($rows) < $batchSize;
115
  // It's actually processed when the caller code returns the control to the Generator.
116
  $processed++;
117
  } while (!$this->isThreshold() && $processed < $limit);
118
+
119
+ $db->suppress_errors($suppressErrorsOriginal);
120
  }
121
  }
Framework/Traits/ResourceTrait.php CHANGED
@@ -9,8 +9,8 @@ trait ResourceTrait
9
  /** @var int|null */
10
  protected $timeLimit;
11
 
12
- private static $default_max_execution_time_in_seconds = 30;
13
- private static $execution_time_gap_in_seconds = 5;
14
 
15
  /**
16
  * @return bool
@@ -28,18 +28,14 @@ trait ResourceTrait
28
  /**
29
  * Overriding this filter to return true allows someone to ignore memory limits.
30
  */
31
- $ignoreTimeLimit = (bool)apply_filters('wpstg.resources.ignoreMemoryLimit', false);
32
 
33
- if ($ignoreTimeLimit) {
34
  return false;
35
  }
36
 
37
- $limit = wp_convert_hr_to_bytes(ini_get('memory_limit'));
38
 
39
- if (!is_int($limit) || $limit < 64000000) {
40
- $limit = 64000000;
41
- }
42
- $allowed = $limit - 1024;
43
  return $allowed <= $this->getMemoryUsage();
44
  }
45
 
@@ -63,6 +59,7 @@ trait ResourceTrait
63
  if ($this->timeLimit !== null) {
64
  $timeLimit = $this->timeLimit;
65
  }
 
66
  return $timeLimit <= $this->getRunningTime();
67
  }
68
  // TODO Recursion for xDebug? Recursion is bad idea will cause more resource usage, need to avoid it.
@@ -72,12 +69,20 @@ trait ResourceTrait
72
  */
73
  public function findExecutionTimeLimit()
74
  {
75
- $executionTime = (int) ini_get('max_execution_time');
 
 
76
  // TODO don't overwrite when CLI / SAPI and / or add setting to not overwrite for devs
77
- if (!$executionTime || $executionTime > static::$default_max_execution_time_in_seconds) {
78
- $executionTime = static::$default_max_execution_time_in_seconds;
79
  }
80
- return $executionTime - static::$execution_time_gap_in_seconds;
 
 
 
 
 
 
81
  }
82
 
83
  /**
@@ -113,4 +118,77 @@ trait ResourceTrait
113
  {
114
  $this->timeLimit = $timeLimit;
115
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
  }
9
  /** @var int|null */
10
  protected $timeLimit;
11
 
12
+ public static $defaultMaxExecutionTimeInSeconds = 30;
13
+ public static $executionTimeGapInSeconds = 5;
14
 
15
  /**
16
  * @return bool
28
  /**
29
  * Overriding this filter to return true allows someone to ignore memory limits.
30
  */
31
+ $ignoreMemoryLimit = (bool)apply_filters('wpstg.resources.ignoreMemoryLimit', false);
32
 
33
+ if ($ignoreMemoryLimit) {
34
  return false;
35
  }
36
 
37
+ $allowed = $this->getScriptMemoryLimit();
38
 
 
 
 
 
39
  return $allowed <= $this->getMemoryUsage();
40
  }
41
 
59
  if ($this->timeLimit !== null) {
60
  $timeLimit = $this->timeLimit;
61
  }
62
+
63
  return $timeLimit <= $this->getRunningTime();
64
  }
65
  // TODO Recursion for xDebug? Recursion is bad idea will cause more resource usage, need to avoid it.
69
  */
70
  public function findExecutionTimeLimit()
71
  {
72
+ $phpMaxExecutionTime = $this->getPhpMaxExecutionTime();
73
+ $cpuBoundMaxExecutionTime = $this->getCpuBoundMaxExecutionTime();
74
+
75
  // TODO don't overwrite when CLI / SAPI and / or add setting to not overwrite for devs
76
+ if (!$cpuBoundMaxExecutionTime || $cpuBoundMaxExecutionTime > static::$defaultMaxExecutionTimeInSeconds) {
77
+ $cpuBoundMaxExecutionTime = static::$defaultMaxExecutionTimeInSeconds;
78
  }
79
+
80
+ if ($phpMaxExecutionTime > 0) {
81
+ // Never go over PHP own execution time limit, if set.
82
+ $cpuBoundMaxExecutionTime = min($phpMaxExecutionTime, $cpuBoundMaxExecutionTime);
83
+ }
84
+
85
+ return $cpuBoundMaxExecutionTime - static::$executionTimeGapInSeconds;
86
  }
87
 
88
  /**
118
  {
119
  $this->timeLimit = $timeLimit;
120
  }
121
+
122
+ /**
123
+ * Returns the current PHP memory limit in bytes..
124
+ *
125
+ * @return int The current memory limit in bytes.
126
+ */
127
+ private function getMaxMemoryLimit()
128
+ {
129
+ $limit = wp_convert_hr_to_bytes(ini_get('memory_limit'));
130
+
131
+ if (!is_int($limit) || $limit < 64000000) {
132
+ $limit = 64000000;
133
+ }
134
+
135
+ return $limit;
136
+ }
137
+
138
+ /**
139
+ * Returns the actual script memory limit.
140
+ *
141
+ * @return int The script memory limit, by definition less then
142
+ * the maximum memory limit.
143
+ */
144
+ private function getScriptMemoryLimit()
145
+ {
146
+ $limit = $this->getMaxMemoryLimit();
147
+
148
+ return $limit - 1024;
149
+ }
150
+
151
+ /**
152
+ * Returns the max execution time value as bound by the "CPU Load" setting.
153
+ *
154
+ * @param string|null $cpuLoadSetting Either a specific CPU Load setting to
155
+ * return the max execution time for, or
156
+ * `null` to read the current CPU Load
157
+ * value from the Settings.
158
+ * @return int The max execution time as bound by the CPU Load setting.
159
+ */
160
+ protected function getCpuBoundMaxExecutionTime($cpuLoadSetting = null)
161
+ {
162
+ $settings = json_decode(json_encode(get_option('wpstg_settings', [])));
163
+ if ($cpuLoadSetting === null) {
164
+ $cpuLoadSetting = isset($settings->cpuLoad) ? $settings->cpuLoad : 'medium';
165
+ }
166
+ $execution_gap = static::$executionTimeGapInSeconds;
167
+
168
+ switch ($cpuLoadSetting) {
169
+ case 'low':
170
+ $cpuBoundMaxExecutionTime = 10 + $execution_gap;
171
+ break;
172
+ case 'medium':
173
+ default:
174
+ $cpuBoundMaxExecutionTime = 20 + $execution_gap;
175
+ break;
176
+ case 'high':
177
+ $cpuBoundMaxExecutionTime = 25 + $execution_gap;
178
+ break;
179
+ }
180
+
181
+ return $cpuBoundMaxExecutionTime;
182
+ }
183
+
184
+ /**
185
+ * Returns the max execution time as set in PHP ini settings.
186
+ *
187
+ * @return int The PHP max execution time in seconds. Note that `0` and `-1` would
188
+ * both indicate there is no time limit set.
189
+ */
190
+ private function getPhpMaxExecutionTime()
191
+ {
192
+ return (int)ini_get('max_execution_time');
193
+ }
194
  }
Framework/Traits/TimerTrait.php CHANGED
@@ -2,29 +2,15 @@
2
 
3
  namespace WPStaging\Framework\Traits;
4
 
 
 
5
  trait TimerTrait
6
  {
7
- /** @var float */
8
- protected $startTime;
9
-
10
- protected function initiateStartTime()
11
- {
12
- $this->startTime = microtime(true);
13
- }
14
-
15
  /**
16
  * @return float
17
  */
18
  protected function getRunningTime()
19
  {
20
- if ($this->startTime === null) {
21
- throw new \LogicException(
22
- sprintf(
23
- 'You must call the "%s::initiateStartTime" method before trying to get the current run time.',
24
- __TRAIT__
25
- )
26
- );
27
- }
28
- return microtime(true) - $this->startTime;
29
  }
30
  }
2
 
3
  namespace WPStaging\Framework\Traits;
4
 
5
+ use WPStaging\Core\WPStaging;
6
+
7
  trait TimerTrait
8
  {
 
 
 
 
 
 
 
 
9
  /**
10
  * @return float
11
  */
12
  protected function getRunningTime()
13
  {
14
+ return microtime(true) - WPStaging::getInstance()->getStartTime();
 
 
 
 
 
 
 
 
15
  }
16
  }
assets/js/dist/wpstg-legacy-database.js CHANGED
@@ -10,1566 +10,1567 @@ function _asyncToGenerator(fn) { return function () { var self = this, args = ar
10
 
11
  function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
12
 
13
- window.addEventListener('database-backups-tab', function () {
14
- WPStagingLegacyDatabase.init();
15
- });
16
- var $ = jQuery;
17
- var WPStagingLegacyDatabase = {
18
- type: null,
19
- isCancelled: false,
20
- processInfo: {
21
- title: null,
22
- interval: null
23
- },
24
- cache: {
25
- elements: [],
26
- get: function get(selector) {
27
- // It is already cached!
28
- if ($.inArray(selector, this.elements) !== -1) {
29
- return this.elements[selector];
30
- } // Create cache and return
31
-
32
-
33
- this.elements[selector] = $(selector);
34
- return this.elements[selector];
35
  },
36
- refresh: function refresh(selector) {
37
- selector.elements[selector] = $(selector);
38
- }
39
- },
40
- init: function init() {
41
- WPStagingLegacyDatabase.fetchListing();
42
- this.create();
43
- this["delete"]();
44
- this.restore();
45
- this.edit(); // noinspection JSIgnoredPromiseFromCall
46
-
47
- $('body').off('change', '#wpstg--backups--filter').on('change', '#wpstg--backups--filter', function () {
48
- var $records = $('#wpstg-existing-database-backups').find('> div[id][data-type].wpstg-backup');
49
-
50
- if (this.value === '') {
51
- $records.show();
52
- } else if (this.value === 'database') {
53
- $records.filter('[data-type="site"]').hide();
54
- $records.filter('[data-type="database"]').show();
55
- } else if (this.value === 'site') {
56
- $records.filter('[data-type="database"]').hide();
57
- $records.filter('[data-type="site"]').show();
58
- }
59
- }).on('click', '.wpstg--backup--download', function () {
60
- var url = this.getAttribute('data-url');
61
 
62
- if (url.length > 0) {
63
- window.location.href = url;
64
- return;
65
- }
66
 
67
- WPStagingLegacyDatabase.downloadModal({
68
- titleExport: this.getAttribute('data-title-export'),
69
- title: this.getAttribute('data-title'),
70
- id: this.getAttribute('data-id'),
71
- btnTxtCancel: this.getAttribute('data-btn-cancel-txt'),
72
- btnTxtConfirm: this.getAttribute('data-btn-download-txt')
73
- });
74
- }).off('click', '#wpstg-import-backup').on('click', '#wpstg-import-backup', function () {
75
- WPStagingLegacyDatabase.importModal();
76
- }) // Import
77
- .off('click', '.wpstg--backup--import--choose-option').on('click', '.wpstg--backup--import--choose-option', function () {
78
- var $parent = $(this).parent();
79
-
80
- if (!$parent.hasClass('wpstg--show-options')) {
81
- $parent.addClass('wpstg--show-options');
82
- $(this).text($(this).attr('data-txtChoose'));
83
- } else {
84
- $parent.removeClass('wpstg--show-options');
85
- $(this).text($(this).attr('data-txtOther'));
86
- }
87
- }).off('click', '.wpstg--modal--backup--import--search-replace--new').on('click', '.wpstg--modal--backup--import--search-replace--new', function (e) {
88
- e.preventDefault();
89
- var $container = $(Swal.getContainer()).find('.wpstg--modal--backup--import--search-replace--input--container');
90
- var total = $container.find('.wpstg--modal--backup--import--search-replace--input-group').length;
91
- $container.append(WPStagingLegacyDatabase.modal["import"].searchReplaceForm.replace(/{i}/g, total));
92
- }).off('input', '.wpstg--backup--import--search').on('input', '.wpstg--backup--import--search', function () {
93
- var index = parseInt(this.getAttribute('data-index'));
94
-
95
- if (!isNaN(index)) {
96
- WPStagingLegacyDatabase.modal["import"].data.search[index] = this.value;
97
  }
98
- }).off('input', '.wpstg--backup--import--replace').on('input', '.wpstg--backup--import--replace', function () {
99
- var index = parseInt(this.getAttribute('data-index'));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
100
 
101
- if (!isNaN(index)) {
102
- WPStagingLegacyDatabase.modal["import"].data.replace[index] = this.value;
103
- }
104
- }) // Other Options
105
- .off('click', '.wpstg--backup--import--option[data-option]').on('click', '.wpstg--backup--import--option[data-option]', function () {
106
- var option = this.getAttribute('data-option');
107
 
108
- if (option === 'file') {
109
- $('input[type="file"][name="wpstg--backup--import--upload--file"]').trigger('click');
110
- return;
111
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
 
113
- if (option === 'upload') {
114
- WPStagingLegacyDatabase.modal["import"].containerFilesystem.hide();
115
- WPStagingLegacyDatabase.modal["import"].containerUpload.show();
116
- $('.wpstg--backup--import--choose-option').trigger('click');
117
- $('.wpstg--modal--backup--import--search-replace--wrapper').show();
118
- }
119
 
120
- if (option !== 'filesystem') {
121
- return;
122
- }
 
123
 
124
- WPStagingLegacyDatabase.modal["import"].containerUpload.hide();
125
- var $containerFilesystem = WPStagingLegacyDatabase.modal["import"].containerFilesystem;
126
- $containerFilesystem.show();
127
- fetch(ajaxurl + "?action=wpstg--backups--import--file-list&_=" + Math.random() + "&accessToken=" + wpstg.accessToken + "&nonce=" + wpstg.nonce).then(WPStagingLegacyDatabase.handleFetchErrors).then(function (res) {
128
- return res.json();
129
- }).then(function (res) {
130
- var $ul = $('.wpstg--modal--backup--import--filesystem ul');
131
- $ul.empty();
132
 
133
- if (!res || WPStagingLegacyDatabase.isEmpty(res)) {
134
- $ul.append("<span id=\"wpstg--backups--import--file-list-empty\">No import file found! Upload an import file to the folder above.</span><br />");
135
- $('.wpstg--modal--backup--import--search-replace--wrapper').hide();
136
  return;
137
  }
138
 
139
- $ul.append("<span id=\"wpstg--backups--import--file-list\">Select file to import:</span><br />");
140
- res.forEach(function (file, index) {
141
- // var checked = (index === 0) ? 'checked' : '';
142
- $ul.append("<li><label><input name=\"backup_import_file\" type=\"radio\" value=\"" + file.fullPath + "\">" + file.name + " <br /> " + file.size + "</label></li>");
143
- }); // $('.wpstg--modal--actions .swal2-confirm').prop('disabled', false);
 
 
 
144
 
145
- return res;
146
- })["catch"](function (e) {
147
- return WPStagingLegacyDatabase.showAjaxFatalError(e, '', 'Submit an error report.');
148
- });
149
- }).off('change', 'input[type="file"][name="wpstg--backup--import--upload--file"]').on('change', 'input[type="file"][name="wpstg--backup--import--upload--file"]', function () {
150
- WPStagingLegacyDatabase.modal["import"].setFile(this.files[0] || null);
151
- $('.wpstg--backup--import--choose-option').trigger('click');
152
- }).off('change', 'input[type="radio"][name="backup_import_file"]').on('change', 'input[type="radio"][name="backup_import_file"]', function () {
153
- $('.wpstg--modal--actions .swal2-confirm').prop('disabled', false);
154
- WPStagingLegacyDatabase.modal["import"].data.file = this.value;
155
- }) // Drag & Drop
156
- .on('drag dragstart dragend dragover dragenter dragleave drop', '.wpstg--modal--backup--import--upload--container', function (e) {
157
- e.preventDefault();
158
- e.stopPropagation();
159
- }).on('dragover dragenter', '.wpstg--modal--backup--import--upload--container', function () {
160
- $(this).addClass('wpstg--has-dragover');
161
- }).on('dragleave dragend drop', '.wpstg--modal--backup--import--upload--container', function () {
162
- $(this).removeClass('wpstg--has-dragover');
163
- }).on('drop', '.wpstg--modal--backup--import--upload--container', function (e) {
164
- WPStagingLegacyDatabase.modal["import"].setFile(e.originalEvent.dataTransfer.files[0] || null);
165
- });
166
- },
167
- create: function create() {
168
- var createBackup = function createBackup(data) {
169
- WPStagingLegacyDatabase.resetErrors();
170
-
171
- if (WPStagingLegacyDatabase.isCancelled) {
172
- // Swal.close();
173
- return;
174
- }
175
 
176
- var reset = data['reset'];
177
- delete data['reset'];
178
- var requestData = Object.assign({}, data);
179
- var useResponseTitle = true;
180
-
181
- if (data.type === 'database') {
182
- WPStagingLegacyDatabase.type = data.type; // Only send to back-end what BE is expecting to receive.
183
- // Prevent error: Trying to hydrate DTO with value that does not exist.
184
-
185
- delete requestData['includedDirectories'];
186
- delete requestData['wpContentDir'];
187
- delete requestData['availableDirectories'];
188
- delete requestData['wpStagingDir'];
189
- delete requestData['exportDatabase'];
190
- delete requestData['includeOtherFilesInWpContent'];
191
- requestData = WPStagingLegacyDatabase.requestData('tasks.backup.database.create', _extends({}, requestData, {
192
- type: 'manual'
193
- }));
194
- } else if (data.type === 'site') {
195
- WPStagingLegacyDatabase.type = data.type; // Only send to back-end what BE is expecting to receive.
196
- // Prevent error: Trying to hydrate DTO with value that does not exist.
197
-
198
- delete requestData['type'];
199
- requestData = WPStagingLegacyDatabase.requestData('jobs.backup.site.create', requestData);
200
- useResponseTitle = false;
201
- requestData.jobs.backup.site.create.directories = [data.wpContentDir];
202
- requestData.jobs.backup.site.create.excludedDirectories = data.availableDirectories.split('|').filter(function (item) {
203
- return !data.includedDirectories.includes(item);
204
- }).map(function (item) {
205
- return item;
206
- });
207
- requestData.jobs.backup.site.create.includeOtherFilesInWpContent = [data.includeOtherFilesInWpContent]; // Do not exclude the wp-content/uploads/wp-staging using regex by default
208
- // This folder is excluded by PHP without REGEX.
209
- // requestData.jobs.backup.site.create.excludedDirectories.push(`#${data.wpStagingDir}*#`);
210
- // delete requestData.jobs.backup.site.create.includedDirectories;
211
-
212
- delete requestData.jobs.backup.site.create.wpContentDir;
213
- delete requestData.jobs.backup.site.create.wpStagingDir;
214
- delete requestData.jobs.backup.site.create.availableDirectories;
215
- } else {
216
- WPStagingLegacyDatabase.type = null;
217
- Swal.close();
218
- WPStagingLegacyDatabase.showError('Invalid Backup Type');
219
- return;
220
- }
221
 
222
- WPStagingLegacyDatabase.timer.start();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
223
 
224
- var statusStop = function statusStop() {
225
- console.log('Status: Stop');
226
- clearInterval(WPStagingLegacyDatabase.processInfo.interval);
227
- WPStagingLegacyDatabase.processInfo.interval = null;
228
- };
229
 
230
- var status = function status() {
231
- if (WPStagingLegacyDatabase.processInfo.interval !== null) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
232
  return;
233
  }
234
 
235
- console.log('Status: Start');
236
- WPStagingLegacyDatabase.processInfo.interval = setInterval(function () {
237
- if (true === WPStagingLegacyDatabase.isCancelled) {
238
- statusStop();
239
- return;
240
- }
 
241
 
242
- if (WPStagingLegacyDatabase.status.hasResponse === false) {
 
243
  return;
244
  }
245
 
246
- WPStagingLegacyDatabase.status.hasResponse = false;
247
- fetch(ajaxurl + "?action=wpstg--backups--status&accessToken=" + wpstg.accessToken + "&nonce=" + wpstg.nonce).then(function (res) {
248
- return res.json();
249
- }).then(function (res) {
250
- WPStagingLegacyDatabase.status.hasResponse = true;
251
-
252
- if (typeof res === 'undefined') {
253
  statusStop();
 
254
  }
255
 
256
- if (WPStagingLegacyDatabase.processInfo.title === res.currentStatusTitle) {
257
  return;
258
  }
259
 
260
- WPStagingLegacyDatabase.processInfo.title = res.currentStatusTitle;
261
- var $container = $(Swal.getContainer());
262
- $container.find('.wpstg--modal--process--title').text(res.currentStatusTitle);
263
- $container.find('.wpstg--modal--process--percent').text('0');
264
- })["catch"](function (e) {
265
- WPStagingLegacyDatabase.status.hasResponse = true;
266
- WPStagingLegacyDatabase.showAjaxFatalError(e, '', 'Submit an error report.');
267
- });
268
- }, 5000);
269
- };
270
 
271
- WPStaging.ajax({
272
- action: 'wpstg--backups--database-legacy-create',
273
- accessToken: wpstg.accessToken,
274
- nonce: wpstg.nonce,
275
- reset: reset,
276
- wpstg: requestData
277
- }, function (response) {
278
- if (typeof response === 'undefined') {
279
- setTimeout(function () {
280
- createBackup(data);
281
- }, wpstg.delayReq);
282
- return;
283
- }
284
-
285
- WPStagingLegacyDatabase.processResponse(response, useResponseTitle);
286
 
287
- if (!useResponseTitle && !WPStagingLegacyDatabase.processInfo.interval) {
288
- status();
289
- }
290
 
291
- if (response.status === false) {
292
- createBackup(data);
293
- } else if (response.status === true) {
294
- $('#wpstg--progress--status').text('Backup successfully created!');
295
- WPStagingLegacyDatabase.type = null;
 
 
 
 
 
296
 
297
- if (WPStagingLegacyDatabase.messages.shouldWarn()) {
298
- // noinspection JSIgnoredPromiseFromCall
299
- WPStagingLegacyDatabase.fetchListing();
300
- WPStagingLegacyDatabase.logsModal();
 
 
 
 
 
 
 
301
  return;
302
  }
303
 
304
- statusStop();
305
- Swal.close();
306
- WPStagingLegacyDatabase.fetchListing().then(function () {
307
- if (!response.backupId) {
308
- WPStagingLegacyDatabase.showError('Failed to get backup ID from response');
309
- return;
310
- } // TODO RPoC
311
 
 
 
 
312
 
313
- var $el = $(".wpstg--backup--download[data-id=\"" + response.backupId + "\"]");
314
- WPStagingLegacyDatabase.downloadModal({
315
- id: $el.data('id'),
316
- url: $el.data('url'),
317
- title: $el.data('title'),
318
- titleExport: $el.data('title-export'),
319
- btnTxtCancel: $el.data('btn-cancel-txt'),
320
- btnTxtConfirm: $el.data('btn-download-txt')
321
- });
322
- $('.wpstg--modal--download--logs--wrapper').show();
323
- var $logsContainer = $('.wpstg--modal--process--logs');
324
- WPStagingLegacyDatabase.messages.data.all.forEach(function (message) {
325
- var msgClass = "wpstg--modal--process--msg--" + message.type.toLowerCase();
326
- $logsContainer.append("<p class=\"" + msgClass + "\">[" + message.type + "] - [" + message.date + "] - " + message.message + "</p>");
327
- });
328
- });
329
- } else {
330
- setTimeout(function () {
331
  createBackup(data);
332
- }, wpstg.delayReq);
333
- }
334
- }, 'json', false, 0, // Don't retry upon failure
335
- 1.25);
336
- };
 
 
 
 
 
337
 
338
- var $body = $('body');
339
- $body.off('click', 'input[name="backup_type"]').on('click', 'input[name="backup_type"]', function () {
340
- var advancedOptions = $('.wpstg-advanced-options');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
341
 
342
- if (this.value === 'database') {
343
- advancedOptions.hide();
344
- return;
345
- }
346
 
347
- advancedOptions.show();
348
- }).off('click', '.wpstg--tab--toggle').on('click', '.wpstg--tab--toggle', function () {
349
- var $target = $($(this).attr('data-target'));
350
- $target.toggle();
351
 
352
- if ($target.is(':visible')) {
353
- $(this).find('span').text('');
354
- } else {
355
- $(this).find('span').text('►');
356
- }
357
- }).off('change', '[name="includedDirectories\[\]"], [type="checkbox"][name="export_database"]').on('change', '[type="checkbox"][name="includedDirectories\[\]"], [type="checkbox"][name="export_database"]', function () {
358
- var totalDirs = $('[type="checkbox"][name="includedDirectories\[\]"]:checked').length;
359
- var isExportDatabase = $('[type="checkbox"][name="export_database"]:checked').length === 1;
360
 
361
- if (totalDirs < 1 && !isExportDatabase) {
362
- $('.swal2-confirm').prop('disabled', true);
363
- } else {
364
- $('.swal2-confirm').prop('disabled', false);
365
- }
366
- }); // Add backup name and notes
367
-
368
- $('#wpstg--tab--database-backups').off('click', '#wpstg-new-database-backup').on('click', '#wpstg-new-database-backup', /*#__PURE__*/function () {
369
- var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(e) {
370
- var $newBackupModal, html, btnTxt, _yield$Swal$fire, formValues;
371
-
372
- return regeneratorRuntime.wrap(function _callee$(_context) {
373
- while (1) {
374
- switch (_context.prev = _context.next) {
375
- case 0:
376
- WPStagingLegacyDatabase.resetErrors();
377
- e.preventDefault();
378
- WPStagingLegacyDatabase.isCancelled = false;
379
-
380
- if (!WPStagingLegacyDatabase.modal.create.html || !WPStagingLegacyDatabase.modal.create.confirmBtnTxt) {
381
- $newBackupModal = $('#wpstg--modal--database--new');
382
- html = $newBackupModal.html();
383
- btnTxt = $newBackupModal.attr('data-confirmButtonText');
384
- WPStagingLegacyDatabase.modal.create.html = html || null;
385
- WPStagingLegacyDatabase.modal.create.confirmBtnTxt = btnTxt || null;
386
- $newBackupModal.remove();
387
- }
388
 
389
- _context.next = 6;
390
- return Swal.fire({
391
- title: '',
392
- html: WPStagingLegacyDatabase.modal.create.html,
393
- focusConfirm: false,
394
- confirmButtonText: WPStagingLegacyDatabase.modal.create.confirmBtnTxt,
395
- showCancelButton: true,
396
- preConfirm: function preConfirm() {
397
- var container = Swal.getContainer();
398
- return {
399
- type: 'database',
400
- name: container.querySelector('input[name="backup_name"]').value || null,
401
- notes: container.querySelector('textarea[name="backup_note"]').value || null,
402
- includedDirectories: Array.from(container.querySelectorAll('input[name="includedDirectories\\[\\]"]:checked') || []).map(function (i) {
403
- return i.value;
404
- }),
405
- wpContentDir: container.querySelector('input[name="wpContentDir"]').value || null,
406
- availableDirectories: container.querySelector('input[name="availableDirectories"]').value || null,
407
- wpStagingDir: container.querySelector('input[name="wpStagingDir"]').value || null,
408
- exportDatabase: container.querySelector('input[name="export_database"]:checked') !== null,
409
- includeOtherFilesInWpContent: container.querySelector('input[name="includeOtherFilesInWpContent"]:checked') !== null
410
- };
 
 
 
 
411
  }
412
- });
413
 
414
- case 6:
415
- _yield$Swal$fire = _context.sent;
416
- formValues = _yield$Swal$fire.value;
417
-
418
- if (formValues) {
419
- _context.next = 10;
420
- break;
421
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
422
 
423
- return _context.abrupt("return");
424
 
425
- case 10:
426
- formValues.reset = true;
427
- WPStagingLegacyDatabase.process({
428
- execute: function execute() {
429
- WPStagingLegacyDatabase.messages.reset();
430
- createBackup(formValues);
431
- }
432
- });
433
 
434
- case 12:
435
- case "end":
436
- return _context.stop();
 
437
  }
438
- }
439
- }, _callee);
440
- }));
441
 
442
- return function (_x) {
443
- return _ref.apply(this, arguments);
444
- };
445
- }());
446
- },
447
- isEmpty: function isEmpty(obj) {
448
- for (var prop in obj) {
449
- if (obj.hasOwnProperty(prop)) {
450
- return false;
 
451
  }
452
- }
453
 
454
- return true;
455
- },
456
- isLoading: function isLoading(_isLoading) {
457
- if (!_isLoading || _isLoading === false) {
458
- WPStagingLegacyDatabase.cache.get('.wpstg-loader').hide();
459
- } else {
460
- WPStagingLegacyDatabase.cache.get('.wpstg-loader').show();
461
- }
462
- },
463
- showAjaxFatalError: function showAjaxFatalError(response, prependMessage, appendMessage) {
464
- prependMessage = prependMessage ? prependMessage + '<br/><br/>' : 'Something went wrong! <br/><br/>';
465
- appendMessage = appendMessage ? appendMessage + '<br/><br/>' : '<br/><br/>Please try the <a href=\'https://wp-staging.com/docs/wp-staging-settings-for-small-servers/\' target=\'_blank\'>WP Staging Small Server Settings</a> or submit an error report and contact us.';
466
-
467
- if (response === false) {
468
- showError(prependMessage + ' Error: No response.' + appendMessage);
469
- window.removeEventListener('beforeunload', WPStaging.warnIfClosingDuringProcess);
470
- return;
471
- }
472
 
473
- if (typeof response.error !== 'undefined' && response.error) {
474
- console.error(response.message);
475
- showError(prependMessage + ' Error: ' + response.message + appendMessage);
476
- window.removeEventListener('beforeunload', WPStaging.warnIfClosingDuringProcess);
477
- return;
478
- }
479
- },
480
- handleFetchErrors: function handleFetchErrors(response) {
481
- if (!response.ok) {
482
- showError('Error: ' + response.status + ' - ' + response.statusText + '. Please try again or contact support.');
483
- }
484
 
485
- return response;
486
- },
487
- showError: function showError(message) {
488
- WPStagingLegacyDatabase.cache.get('#wpstg-try-again').css('display', 'inline-block');
489
- WPStagingLegacyDatabase.cache.get('#wpstg-cancel-cloning').text('Reset');
490
- WPStagingLegacyDatabase.cache.get('#wpstg-resume-cloning').show();
491
- WPStagingLegacyDatabase.cache.get('#wpstg-error-wrapper').show();
492
- WPStagingLegacyDatabase.cache.get('#wpstg-error-details').show().html(message);
493
- WPStagingLegacyDatabase.cache.get('#wpstg-removing-clone').removeClass('loading');
494
- WPStagingLegacyDatabase.cache.get('.wpstg-loader').hide();
495
- $('.wpstg--modal--process--generic-problem').show().html(message);
496
- },
497
- resetErrors: function resetErrors() {
498
- WPStagingLegacyDatabase.cache.get('#wpstg-error-details').hide().html('');
499
- },
500
-
501
- /**
502
- * Ajax Requests
503
- * @param {Object} data
504
- * @param {Function} callback
505
- * @param {string} dataType
506
- * @param {bool} showErrors
507
- * @param {int} tryCount
508
- * @param {float} incrementRatio
509
- */
510
- ajax: function ajax(data, callback, dataType, showErrors, tryCount, incrementRatio) {
511
- if (incrementRatio === void 0) {
512
- incrementRatio = null;
513
- }
514
 
515
- if ('undefined' === typeof dataType) {
516
- dataType = 'json';
517
- }
 
 
 
 
 
 
 
 
 
 
 
 
518
 
519
- if (false !== showErrors) {
520
- showErrors = true;
521
- }
 
 
 
 
 
 
 
 
 
 
522
 
523
- tryCount = 'undefined' === typeof tryCount ? 0 : tryCount;
524
- var retryLimit = 10;
525
- var retryTimeout = 10000 * tryCount;
526
- incrementRatio = parseInt(incrementRatio);
527
 
528
- if (!isNaN(incrementRatio)) {
529
- retryTimeout *= incrementRatio;
530
- }
531
 
532
- $.ajax({
533
- url: ajaxurl + '?action=wpstg_processing&_=' + Date.now() / 1000,
534
- type: 'POST',
535
- dataType: dataType,
536
- cache: false,
537
- data: data,
538
- error: function error(xhr, textStatus, errorThrown) {
539
- console.log(xhr.status + ' ' + xhr.statusText + '---' + textStatus); // try again after 10 seconds
540
 
541
- tryCount++;
 
 
542
 
543
- if (tryCount <= retryLimit) {
544
- setTimeout(function () {
545
- WPStagingLegacyDatabase.ajax(data, callback, dataType, showErrors, tryCount, incrementRatio);
546
- return;
547
- }, retryTimeout);
548
- } else {
549
- var errorCode = 'undefined' === typeof xhr.status ? 'Unknown' : xhr.status;
550
- WPStagingLegacyDatabase.showError('Fatal Error: ' + errorCode + ' Please try the <a href=\'https://wp-staging.com/docs/wp-staging-settings-for-small-servers/\' target=\'_blank\'>WP Staging Small Server Settings</a> or submit an error report and contact us.');
551
- }
552
- },
553
- success: function success(data) {
554
- if ('function' === typeof callback) {
555
- callback(data);
556
- }
557
- },
558
- statusCode: {
559
- 404: function _() {
560
- if (tryCount >= retryLimit) {
561
- WPStagingLegacyDatabase.showError('Error 404 - Can\'t find ajax request URL! Please try the <a href=\'https://wp-staging.com/docs/wp-staging-settings-for-small-servers/\' target=\'_blank\'>WP Staging Small Server Settings</a> or submit an error report and contact us.');
562
  }
563
  },
564
- 500: function _() {
565
- if (tryCount >= retryLimit) {
566
- WPStagingLegacyDatabase.showError('Fatal Error 500 - Internal server error while processing the request! Please try the <a href=\'https://wp-staging.com/docs/wp-staging-settings-for-small-servers/\' target=\'_blank\'>WP Staging Small Server Settings</a> or submit an error report and contact us.');
567
  }
568
  },
569
- 504: function _() {
570
- if (tryCount > retryLimit) {
571
- WPStagingLegacyDatabase.showError('Error 504 - It looks like your server is rate limiting ajax requests. Please try to resume after a minute. If this still not works try the <a href=\'https://wp-staging.com/docs/wp-staging-settings-for-small-servers/\' target=\'_blank\'>WP Staging Small Server Settings</a> or submit an error report and contact us.\n\ ');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
572
  }
573
- },
574
- 502: function _() {
575
- if (tryCount >= retryLimit) {
576
- WPStagingLegacyDatabase.showError('Error 502 - It looks like your server is rate limiting ajax requests. Please try to resume after a minute. If this still not works try the <a href=\'https://wp-staging.com/docs/wp-staging-settings-for-small-servers/\' target=\'_blank\'>WP Staging Small Server Settings</a> or submit an error report and contact us.\n\ ');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
577
  }
578
- },
579
- 503: function _() {
580
- if (tryCount >= retryLimit) {
581
- WPStagingLegacyDatabase.showError('Error 503 - It looks like your server is rate limiting ajax requests. Please try to resume after a minute. If this still not works try the <a href=\'https://wp-staging.com/docs/wp-staging-settings-for-small-servers/\' target=\'_blank\'>WP Staging Small Server Settings</a> or submit an error report and contact us.\n\ ');
 
 
 
 
582
  }
583
- },
584
- 429: function _() {
585
- if (tryCount >= retryLimit) {
586
- WPStagingLegacyDatabase.showError('Error 429 - It looks like your server is rate limiting ajax requests. Please try to resume after a minute. If this still not works try the <a href=\'https://wp-staging.com/docs/wp-staging-settings-for-small-servers/\' target=\'_blank\'>WP Staging Small Server Settings</a> or submit an error report and contact us.\n\ ');
 
 
 
 
 
 
 
587
  }
588
  },
589
- 403: function _() {
590
- if (tryCount >= retryLimit) {
591
- WPStagingLegacyDatabase.showError('Refresh page or login again! The process should be finished successfully. \n\ ');
592
- }
 
593
  }
594
  }
595
- });
596
- },
597
- modal: {
598
- create: {
599
- html: null,
600
- confirmBtnTxt: null
601
- },
602
- process: {
603
- html: null,
604
- cancelBtnTxt: null,
605
- modal: null
606
  },
607
- download: {
608
- html: null
609
- },
610
- "import": {
611
- html: null,
612
- btnTxtNext: null,
613
- btnTxtConfirm: null,
614
- btnTxtCancel: null,
615
- searchReplaceForm: null,
616
- file: null,
617
- containerUpload: null,
618
- containerFilesystem: null,
619
- setFile: function setFile(file, upload) {
620
- if (upload === void 0) {
621
- upload = true;
 
 
 
 
 
 
622
  }
623
 
624
- var toUnit = function toUnit(bytes) {
625
- var i = Math.floor(Math.log(bytes) / Math.log(1024));
626
- return (bytes / Math.pow(1024, i)).toFixed(2) * 1 + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i];
627
- };
628
-
629
- if (!file) {
 
630
  return;
631
  }
632
 
633
- WPStagingLegacyDatabase.modal["import"].file = file;
634
- WPStagingLegacyDatabase.modal["import"].data.file = file.name;
635
- console.log("File " + file.name);
636
- $('.wpstg--backup--import--selected-file').html(file.name + " <br /> (" + toUnit(file.size) + ")").show();
637
- $('.wpstg--drag').hide();
638
- $('.wpstg--drag-or-upload').show();
639
 
640
- if (upload) {
641
- $('.wpstg--modal--actions .swal2-confirm').prop('disabled', true);
642
- WPStagingLegacyDatabase.upload.start();
643
  }
644
- },
645
- baseDirectory: null,
646
- data: {
647
- file: null,
648
- search: [],
649
- replace: []
650
- }
651
- }
652
- },
653
- messages: {
654
- WARNING: 'warning',
655
- ERROR: 'error',
656
- INFO: 'info',
657
- DEBUG: 'debug',
658
- CRITICAL: 'critical',
659
- data: {
660
- all: [],
661
- // TODO RPoC
662
- info: [],
663
- error: [],
664
- critical: [],
665
- warning: [],
666
- debug: []
667
- },
668
- shouldWarn: function shouldWarn() {
669
- return WPStagingLegacyDatabase.messages.data.error.length > 0 || WPStagingLegacyDatabase.messages.data.critical.length > 0;
670
- },
671
- countByType: function countByType(type) {
672
- if (type === void 0) {
673
- type = WPStagingLegacyDatabase.messages.ERROR;
674
- }
675
-
676
- return WPStagingLegacyDatabase.messages.data[type].length;
677
- },
678
- addMessage: function addMessage(message) {
679
- if (Array.isArray(message)) {
680
- message.forEach(function (item) {
681
- WPStagingLegacyDatabase.messages.addMessage(item);
682
- });
683
- return;
684
- }
685
 
686
- var type = message.type.toLowerCase() || 'info';
687
 
688
- if (!WPStagingLegacyDatabase.messages.data[type]) {
689
- WPStagingLegacyDatabase.messages.data[type] = [];
 
 
 
 
 
 
 
 
 
690
  }
691
-
692
- WPStagingLegacyDatabase.messages.data.all.push(message); // TODO RPoC
693
-
694
- WPStagingLegacyDatabase.messages.data[type].push(message);
695
  },
696
- reset: function reset() {
697
- WPStagingLegacyDatabase.messages.data = {
698
- all: [],
699
- info: [],
700
- error: [],
701
- critical: [],
702
- warning: [],
703
- debug: []
704
- };
705
- }
706
- },
707
- timer: {
708
- totalSeconds: 0,
709
- interval: null,
710
- start: function start() {
711
- if (null !== WPStagingLegacyDatabase.timer.interval) {
712
- return;
713
- }
714
 
715
- var prettify = function prettify(seconds) {
716
- console.log("Process running for " + seconds + " seconds"); // If potentially anything can exceed 24h execution time than that;
717
- // const _seconds = parseInt(seconds, 10)
718
- // const hours = Math.floor(_seconds / 3600)
719
- // const minutes = Math.floor(_seconds / 60) % 60
720
- // seconds = _seconds % 60
721
- //
722
- // return [hours, minutes, seconds]
723
- // .map(v => v < 10 ? '0' + v : v)
724
- // .filter((v,i) => v !== '00' || i > 0)
725
- // .join(':')
726
- // ;
727
- // Are we sure we won't create anything that exceeds 24h execution time? If not then this;
728
-
729
- return "" + new Date(seconds * 1000).toISOString().substr(11, 8);
730
- };
731
 
732
- WPStagingLegacyDatabase.timer.interval = setInterval(function () {
733
- $('.wpstg--modal--process--elapsed-time').text(prettify(WPStagingLegacyDatabase.timer.totalSeconds));
734
- WPStagingLegacyDatabase.timer.totalSeconds++;
735
- }, 1000);
736
- },
737
- stop: function stop() {
738
- WPStagingLegacyDatabase.timer.totalSeconds = 0;
739
 
740
- if (WPStagingLegacyDatabase.timer.interval) {
741
- clearInterval(WPStagingLegacyDatabase.timer.interval);
742
- WPStagingLegacyDatabase.timer.interval = null;
743
- }
744
- }
745
- },
746
- upload: {
747
- reader: null,
748
- file: null,
749
- iop: 1000 * 1024,
750
- uploadInfo: function uploadInfo(isShow) {
751
- var $containerUpload = $('.wpstg--modal--import--upload--process');
752
- var $containerUploader = $('.wpstg--uploader');
753
-
754
- if (isShow) {
755
- $containerUpload.css('display', 'flex');
756
- $containerUploader.hide();
757
- return;
758
  }
759
-
760
- $containerUploader.css('display', 'flex');
761
- $containerUpload.hide();
762
  },
763
- start: function start() {
764
- console.log("file " + WPStagingLegacyDatabase.modal["import"].data.file);
765
- WPStagingLegacyDatabase.upload.reader = new FileReader();
766
- WPStagingLegacyDatabase.upload.file = WPStagingLegacyDatabase.modal["import"].file;
767
- WPStagingLegacyDatabase.upload.uploadInfo(true);
768
- WPStagingLegacyDatabase.upload.sendChunk();
769
- },
770
- sendChunk: function sendChunk(startsAt) {
771
- if (startsAt === void 0) {
772
- startsAt = 0;
773
- }
774
-
775
- if (!WPStagingLegacyDatabase.upload.file) {
776
- return;
777
- }
778
 
779
- var isReset = startsAt < 1;
780
- var endsAt = startsAt + WPStagingLegacyDatabase.upload.iop + 1;
781
- var blob = WPStagingLegacyDatabase.upload.file.slice(startsAt, endsAt);
 
 
 
 
 
 
 
 
 
 
 
782
 
783
- WPStagingLegacyDatabase.upload.reader.onloadend = function (event) {
784
- if (event.target.readyState !== FileReader.DONE) {
785
  return;
786
  }
787
 
788
- var body = new FormData();
789
- body.append('accessToken', wpstg.accessToken);
790
- body.append('nonce', wpstg.nonce);
791
- body.append('data', event.target.result);
792
- body.append('filename', WPStagingLegacyDatabase.upload.file.name);
793
- body.append('reset', isReset ? '1' : '0');
794
- fetch(ajaxurl + "?action=wpstg--backups--import--file-upload", {
795
- method: 'POST',
796
- body: body
797
- }).then(WPStagingLegacyDatabase.handleFetchErrors).then(function (res) {
798
- return res.json();
799
- }).then(function (res) {
800
- WPStagingLegacyDatabase.showAjaxFatalError(res, '', 'Submit an error report.');
801
- var writtenBytes = startsAt + WPStagingLegacyDatabase.upload.iop;
802
- var percent = Math.floor(writtenBytes / WPStagingLegacyDatabase.upload.file.size * 100);
803
 
804
- if (endsAt >= WPStagingLegacyDatabase.upload.file.size) {
805
- WPStagingLegacyDatabase.upload.uploadInfo(false);
806
- WPStagingLegacyDatabase.isLoading(false);
807
- $('.wpstg--modal--actions .swal2-confirm').prop('disabled', false);
808
  return;
809
  }
810
 
811
- $('.wpstg--modal--import--upload--progress--title > span').text(percent);
812
- $('.wpstg--modal--import--upload--progress').css('width', percent + "%");
813
- WPStagingLegacyDatabase.upload.sendChunk(endsAt);
814
- })["catch"](function (e) {
815
- return WPStagingLegacyDatabase.showAjaxFatalError(e, '', 'Submit an error report.');
816
- });
817
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
818
 
819
- WPStagingLegacyDatabase.upload.reader.readAsDataURL(blob);
820
- }
821
- },
822
- status: {
823
- hasResponse: null,
824
- reTryAfter: 5000
825
- },
826
- fetchListing: function fetchListing(isResetErrors) {
827
- if (isResetErrors === void 0) {
828
- isResetErrors = true;
829
- }
830
 
831
- WPStagingLegacyDatabase.isLoading(true);
832
 
833
- if (isResetErrors) {
834
- WPStagingLegacyDatabase.resetErrors();
835
- }
836
 
837
- return fetch(ajaxurl + "?action=wpstg--backups--database-legacy-listing&_=" + Math.random() + "&accessToken=" + wpstg.accessToken + "&nonce=" + wpstg.nonce).then(WPStagingLegacyDatabase.handleFetchErrors).then(function (res) {
838
- return res.json();
839
- }).then(function (res) {
840
- WPStagingLegacyDatabase.showAjaxFatalError(res, '', 'Submit an error report.');
841
- WPStagingLegacyDatabase.cache.get('#wpstg--tab--database-backups').html(res);
842
- WPStagingLegacyDatabase.isLoading(false);
843
- return res;
844
- })["catch"](function (e) {
845
- return WPStagingLegacyDatabase.showAjaxFatalError(e, '', 'Submit an error report.');
846
- });
847
- },
848
- "delete": function _delete() {
849
- $('#wpstg--tab--database-backups').off('click', '.wpstg-delete-backup[data-id]').on('click', '.wpstg-delete-backup[data-id]', function (e) {
850
- e.preventDefault();
851
- WPStagingLegacyDatabase.resetErrors();
852
- WPStagingLegacyDatabase.isLoading(true);
853
- WPStagingLegacyDatabase.cache.get('#wpstg-existing-database-backups').hide();
854
- var id = this.getAttribute('data-id');
855
- WPStagingLegacyDatabase.ajax({
856
- action: 'wpstg--backups--database-legacy-delete-confirm',
857
- id: id,
858
- accessToken: wpstg.accessToken,
859
- nonce: wpstg.nonce
860
- }, function (response) {
861
- WPStagingLegacyDatabase.showAjaxFatalError(response, '', ' Please submit an error report by using the REPORT ISSUE button.');
862
  WPStagingLegacyDatabase.isLoading(false);
863
- WPStagingLegacyDatabase.cache.get('#wpstg-delete-confirmation').html(response);
 
 
864
  });
865
- }) // Delete final confirmation page
866
- .off('click', '#wpstg-delete-backup').on('click', '#wpstg-delete-backup', function (e) {
867
- e.preventDefault();
868
- WPStagingLegacyDatabase.resetErrors();
869
- WPStagingLegacyDatabase.isLoading(true);
870
- var id = this.getAttribute('data-id');
871
- WPStagingLegacyDatabase.ajax({
872
- action: 'wpstg--backups--database-legacy-delete',
873
- id: id,
874
- accessToken: wpstg.accessToken,
875
- nonce: wpstg.nonce
876
- }, function (response) {
877
- WPStagingLegacyDatabase.showAjaxFatalError(response, '', ' Please submit an error report by using the REPORT ISSUE button.'); // noinspection JSIgnoredPromiseFromCall
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
878
 
879
- WPStagingLegacyDatabase.fetchListing();
880
- WPStagingLegacyDatabase.isLoading(false);
881
- });
882
- }).off('click', '#wpstg-cancel-backup-delete').on('click', '#wpstg-cancel-backup-delete', function (e) {
883
- e.preventDefault();
884
- WPStagingLegacyDatabase.isLoading(false); // noinspection JSIgnoredPromiseFromCall
885
 
886
- WPStagingLegacyDatabase.fetchListing();
887
- }); // Force delete if backup tables do not exist
888
- // TODO This is bloated, no need extra ID, use existing one?
889
 
890
- $('#wpstg-error-wrapper').off('click', '#wpstg-backup-force-delete').on('click', '#wpstg-backup-force-delete', function (e) {
891
- e.preventDefault();
892
- WPStagingLegacyDatabase.resetErrors();
893
- WPStagingLegacyDatabase.isLoading(true);
894
- var id = this.getAttribute('data-id');
895
 
896
- if (!confirm('Do you want to delete this backup ' + id + ' from the listed backups?')) {
897
- WPStagingLegacyDatabase.isLoading(false);
898
- return false;
899
- }
900
 
901
- WPStagingLegacyDatabase.ajax({
902
- action: 'wpstg--backups--database-legacy-delete',
903
- id: id,
904
- accessToken: wpstg.accessToken,
905
- nonce: wpstg.nonce
906
- }, function (response) {
907
- WPStagingLegacyDatabase.showAjaxFatalError(response, '', ' Please submit an error report by using the REPORT ISSUE button.'); // noinspection JSIgnoredPromiseFromCall
908
 
909
- WPStagingLegacyDatabase.fetchListing();
910
- WPStagingLegacyDatabase.isLoading(false);
 
911
  });
912
- });
913
- },
914
- restore: function restore() {
915
- var restoreBackup = function restoreBackup(prefix, reset) {
916
- WPStagingLegacyDatabase.isLoading(true);
917
- WPStagingLegacyDatabase.resetErrors();
918
 
919
- if (typeof reset === 'undefined') {
920
- reset = false;
921
- }
922
 
923
- WPStaging.ajax({
924
- action: 'wpstg--backups--database-legacy-restore',
925
- accessToken: wpstg.accessToken,
926
- nonce: wpstg.nonce,
927
- wpstg: {
928
- tasks: {
929
- backup: {
930
- database: {
931
- create: {
932
- source: prefix,
933
- reset: reset
 
934
  }
935
  }
936
  }
937
  }
938
- }
939
- }, function (response) {
940
- if (typeof response === 'undefined') {
941
- setTimeout(function () {
942
- restoreBackup(prefix);
943
- }, wpstg.delayReq);
944
- return;
945
- }
946
-
947
- WPStagingLegacyDatabase.processResponse(response);
948
 
949
- if (response.status === false || response.job_done === false) {
950
- restoreBackup(prefix);
951
- } else if (response.status === true && response.job_done === true) {
952
- WPStagingLegacyDatabase.isLoading(false);
953
- $('.wpstg--modal--process--title').text('Backup successfully restored');
954
- setTimeout(function () {
955
- Swal.close(); // noinspection JSIgnoredPromiseFromCall
956
 
957
- alert('Backup successfully restored. You might have to log-in again to WordPress.');
958
- WPStagingLegacyDatabase.fetchListing();
959
- }, 1000);
960
- } else {
961
- setTimeout(function () {
962
  restoreBackup(prefix);
963
- }, wpstg.delayReq);
964
- }
965
- }, 'json', false, 0, 1.25);
966
- };
967
-
968
- $('#wpstg--tab--database-backups').off('click', '.wpstg--backup--restore[data-id]').on('click', '.wpstg--backup--restore[data-id]', function (e) {
969
- e.preventDefault();
970
- WPStagingLegacyDatabase.resetErrors();
971
- WPStagingLegacyDatabase.ajax({
972
- action: 'wpstg--backups--database-legacy-restore-confirm',
973
- accessToken: wpstg.accessToken,
974
- nonce: wpstg.nonce,
975
- id: $(this).data('id')
976
- }, function (data) {
977
- WPStagingLegacyDatabase.cache.get('#wpstg--tab--database-backups').html(data);
978
- });
979
- }).off('click', '#wpstg--backup--restore--cancel').on('click', '#wpstg--backup--restore--cancel', function (e) {
980
- WPStagingLegacyDatabase.resetErrors();
981
- e.preventDefault(); // noinspection JSIgnoredPromiseFromCall
982
 
983
- WPStagingLegacyDatabase.fetchListing();
984
- }).off('click', '#wpstg--backup--restore[data-id]').on('click', '#wpstg--backup--restore[data-id]', function (e) {
985
- e.preventDefault();
986
- WPStagingLegacyDatabase.resetErrors();
987
- var id = this.getAttribute('data-id');
988
- WPStagingLegacyDatabase.process({
989
- execute: function execute() {
990
- WPStagingLegacyDatabase.messages.reset();
991
- restoreBackup(id, true);
992
- },
993
- isShowCancelButton: false
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
994
  });
995
- });
996
- },
997
- // Edit backups name and notes
998
- edit: function edit() {
999
- $('#wpstg--tab--database-backups').off('click', '.wpstg--backup--edit[data-id]').on('click', '.wpstg--backup--edit[data-id]', /*#__PURE__*/function () {
1000
- var _ref2 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(e) {
1001
- var name, notes, _yield$Swal$fire2, formValues;
1002
-
1003
- return regeneratorRuntime.wrap(function _callee2$(_context2) {
1004
- while (1) {
1005
- switch (_context2.prev = _context2.next) {
1006
- case 0:
1007
- e.preventDefault();
1008
- name = $(this).data('name');
1009
- notes = $(this).data('notes');
1010
- _context2.next = 5;
1011
- return Swal.fire({
1012
- title: '',
1013
- html: "\n <label id=\"wpstg-backup-edit-name\">Backup Name</label>\n <input id=\"wpstg-backup-edit-name-input\" class=\"swal2-input\" value=\"" + name + "\">\n <label>Additional Notes</label>\n <textarea id=\"wpstg-backup-edit-notes-textarea\" class=\"swal2-textarea\">" + notes + "</textarea>\n ",
1014
- focusConfirm: false,
1015
- confirmButtonText: 'Update Backup',
1016
- showCancelButton: true,
1017
- preConfirm: function preConfirm() {
1018
- return {
1019
- name: document.getElementById('wpstg-backup-edit-name-input').value || null,
1020
- notes: document.getElementById('wpstg-backup-edit-notes-textarea').value || null
1021
- };
 
 
 
 
 
 
 
 
 
1022
  }
1023
- });
1024
 
1025
- case 5:
1026
- _yield$Swal$fire2 = _context2.sent;
1027
- formValues = _yield$Swal$fire2.value;
1028
-
1029
- if (formValues) {
1030
- _context2.next = 9;
1031
- break;
1032
- }
1033
-
1034
- return _context2.abrupt("return");
1035
-
1036
- case 9:
1037
- WPStagingLegacyDatabase.ajax({
1038
- action: 'wpstg--backups--database-legacy-edit',
1039
- accessToken: wpstg.accessToken,
1040
- nonce: wpstg.nonce,
1041
- id: $(this).data('id'),
1042
- name: formValues.name,
1043
- notes: formValues.notes
1044
- }, function (response) {
1045
- WPStagingLegacyDatabase.showAjaxFatalError(response, '', 'Submit an error report.'); // noinspection JSIgnoredPromiseFromCall
1046
-
1047
- WPStagingLegacyDatabase.fetchListing();
1048
- });
1049
-
1050
- case 10:
1051
- case "end":
1052
- return _context2.stop();
1053
  }
1054
- }
1055
- }, _callee2, this);
1056
- }));
1057
 
1058
- return function (_x2) {
1059
- return _ref2.apply(this, arguments);
1060
- };
1061
- }());
1062
- },
1063
- cancel: function cancel() {
1064
- WPStagingLegacyDatabase.timer.stop();
1065
- WPStagingLegacyDatabase.isCancelled = true;
1066
- Swal.close();
1067
- setTimeout(function () {
1068
- return WPStagingLegacyDatabase.ajax({
1069
- action: 'wpstg--backups--cancel',
1070
- accessToken: wpstg.accessToken,
1071
- nonce: wpstg.nonce,
1072
- type: WPStagingLegacyDatabase.type
1073
- }, function (response) {
1074
- WPStagingLegacyDatabase.showAjaxFatalError(response, '', 'Submit an error report.');
1075
- });
1076
- }, 500);
1077
- },
1078
-
1079
- /**
1080
- * If process.execute exists, process.data and process.onResponse is not used
1081
- * process = { data: {}, onResponse: (resp) => {}, onAfterClose: () => {}, execute: () => {}, isShowCancelButton: bool }
1082
- * @param {object} process
1083
- */
1084
- process: function process(_process) {
1085
- if (typeof _process.execute !== 'function' && (!_process.data || !_process.onResponse)) {
1086
  Swal.close();
1087
- WPStagingLegacyDatabase.showError('process.data and / or process.onResponse is not set');
1088
- return;
1089
- } // TODO move to backend and get the contents as xhr response?
1090
-
1091
-
1092
- if (!WPStagingLegacyDatabase.modal.process.html || !WPStagingLegacyDatabase.modal.process.cancelBtnTxt) {
1093
- var $modal = $('#wpstg--modal--backup--process');
1094
- var html = $modal.html();
1095
- var btnTxt = $modal.attr('data-cancelButtonText');
1096
- WPStagingLegacyDatabase.modal.process.html = html || null;
1097
- WPStagingLegacyDatabase.modal.process.cancelBtnTxt = btnTxt || null;
1098
- $modal.remove();
1099
- }
 
 
 
 
 
 
 
 
 
 
1100
 
1101
- $('body').off('click', '.wpstg--modal--process--logs--tail').on('click', '.wpstg--modal--process--logs--tail', function (e) {
1102
- e.preventDefault();
1103
- var container = Swal.getContainer();
1104
- var $logs = $(container).find('.wpstg--modal--process--logs');
1105
- $logs.toggle();
1106
 
1107
- if ($logs.is(':visible')) {
1108
- container.childNodes[0].style.width = '100%';
1109
- container.style['z-index'] = 9999;
1110
- } else {
1111
- container.childNodes[0].style.width = '600px';
 
 
1112
  }
1113
- });
1114
- _process.isShowCancelButton = false !== _process.isShowCancelButton;
1115
- WPStagingLegacyDatabase.modal.process.modal = Swal.mixin({
1116
- customClass: {
1117
- cancelButton: 'wpstg--btn--cancel wpstg-blue-primary wpstg-link-btn',
1118
- content: 'wpstg--process--content'
1119
- },
1120
- buttonsStyling: false
1121
- }).fire({
1122
- html: WPStagingLegacyDatabase.modal.process.html,
1123
- cancelButtonText: WPStagingLegacyDatabase.modal.process.cancelBtnTxt,
1124
- showCancelButton: _process.isShowCancelButton,
1125
- showConfirmButton: false,
1126
- allowOutsideClick: false,
1127
- allowEscapeKey: false,
1128
- width: 600,
1129
- onRender: function onRender() {
1130
- var _btnCancel = Swal.getContainer().getElementsByClassName('swal2-cancel wpstg--btn--cancel')[0];
1131
-
1132
- var btnCancel = _btnCancel.cloneNode(true);
1133
-
1134
- _btnCancel.parentNode.replaceChild(btnCancel, _btnCancel);
1135
-
1136
- btnCancel.addEventListener('click', function (e) {
1137
- if (confirm('Are You Sure? This will cancel the process!')) {
1138
- Swal.close();
1139
- }
1140
- });
1141
-
1142
- if (typeof _process.execute === 'function') {
1143
- _process.execute();
1144
 
1145
- return;
1146
- }
 
 
 
1147
 
1148
- if (!_process.data || !_process.onResponse) {
1149
- Swal.close();
1150
- WPStagingLegacyDatabase.showError('process.data and / or process.onResponse is not set');
1151
- return;
 
1152
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1153
 
1154
- WPStagingLegacyDatabase.ajax(_process.data, _process.onResponse);
1155
- },
1156
- onAfterClose: function onAfterClose() {
1157
- return typeof _process.onAfterClose === 'function' && _process.onAfterClose();
1158
- },
1159
- onClose: function onClose() {
1160
- console.log('cancelled');
1161
- WPStagingLegacyDatabase.cancel();
1162
- }
1163
- });
1164
- },
1165
- processResponse: function processResponse(response, useTitle) {
1166
- if (response === null) {
1167
- Swal.close();
1168
- WPStagingLegacyDatabase.showError('Invalid Response; null');
1169
- throw new Error("Invalid Response; " + response);
1170
- }
1171
-
1172
- var $container = $(Swal.getContainer());
1173
 
1174
- var title = function title() {
1175
- if ((response.title || response.statusTitle) && useTitle === true) {
1176
- $container.find('.wpstg--modal--process--title').text(response.title || response.statusTitle);
1177
- }
1178
- };
1179
 
1180
- var percentage = function percentage() {
1181
- if (response.percentage) {
1182
- $container.find('.wpstg--modal--process--percent').text(response.percentage);
1183
- }
1184
- };
1185
 
1186
- var logs = function logs() {
1187
- if (!response.messages) {
1188
- return;
1189
- }
1190
 
1191
- var $logsContainer = $container.find('.wpstg--modal--process--logs');
1192
- var stoppingTypes = [WPStagingLegacyDatabase.messages.ERROR, WPStagingLegacyDatabase.messages.CRITICAL];
1193
 
1194
- var appendMessage = function appendMessage(message) {
1195
- if (Array.isArray(message)) {
1196
- for (var _iterator = _createForOfIteratorHelperLoose(message), _step; !(_step = _iterator()).done;) {
1197
- var item = _step.value;
1198
- appendMessage(item);
1199
  }
1200
 
1201
- return;
 
 
 
 
 
 
 
1202
  }
 
 
 
 
 
 
 
 
1203
 
1204
- var msgClass = "wpstg--modal--process--msg--" + message.type.toLowerCase();
1205
- $logsContainer.append("<p class=\"" + msgClass + "\">[" + message.type + "] - [" + message.date + "] - " + message.message + "</p>");
1206
 
1207
- if (stoppingTypes.includes(message.type.toLowerCase())) {
1208
- WPStagingLegacyDatabase.cancel();
1209
- setTimeout(WPStagingLegacyDatabase.logsModal, 500);
1210
  }
1211
  };
1212
 
1213
- for (var _iterator2 = _createForOfIteratorHelperLoose(response.messages), _step2; !(_step2 = _iterator2()).done;) {
1214
- var message = _step2.value;
 
 
 
1215
 
1216
- if (!message) {
1217
- continue;
 
1218
  }
1219
 
1220
- WPStagingLegacyDatabase.messages.addMessage(message);
1221
- appendMessage(message);
1222
- }
1223
 
1224
- if ($logsContainer.is(':visible')) {
1225
- $logsContainer.scrollTop($logsContainer[0].scrollHeight);
1226
- }
 
 
 
1227
 
1228
- if (!WPStagingLegacyDatabase.messages.shouldWarn()) {
1229
- return;
1230
- }
 
 
1231
 
1232
- var $btnShowLogs = $container.find('.wpstg--modal--process--logs--tail');
1233
- $btnShowLogs.html($btnShowLogs.attr('data-txt-bad'));
1234
- $btnShowLogs.find('.wpstg--modal--logs--critical-count').text(WPStagingLegacyDatabase.messages.countByType(WPStagingLegacyDatabase.messages.CRITICAL));
1235
- $btnShowLogs.find('.wpstg--modal--logs--error-count').text(WPStagingLegacyDatabase.messages.countByType(WPStagingLegacyDatabase.messages.ERROR));
1236
- $btnShowLogs.find('.wpstg--modal--logs--warning-count').text(WPStagingLegacyDatabase.messages.countByType(WPStagingLegacyDatabase.messages.WARNING));
1237
- };
1238
 
1239
- title();
1240
- percentage();
1241
- logs();
1242
 
1243
- if (response.status === true && response.job_done === true) {
1244
- WPStagingLegacyDatabase.timer.stop();
1245
- WPStagingLegacyDatabase.isCancelled = true;
1246
- }
1247
- },
1248
- requestData: function requestData(notation, data) {
1249
- var obj = {};
1250
- var keys = notation.split('.');
1251
- var lastIndex = keys.length - 1;
1252
- keys.reduce(function (accumulated, current, index) {
1253
- return accumulated[current] = index >= lastIndex ? data : {};
1254
- }, obj);
1255
- return obj;
1256
- },
1257
- logsModal: function logsModal() {
1258
- Swal.fire({
1259
- html: "<div class=\"wpstg--modal--error--logs\" style=\"display:block\"></div><div class=\"wpstg--modal--process--logs\" style=\"display:block\"></div>",
1260
- width: '95%',
1261
- onRender: function onRender() {
1262
- var $container = $(Swal.getContainer());
1263
- $container[0].style['z-index'] = 9999;
1264
- var $logsContainer = $container.find('.wpstg--modal--process--logs');
1265
- var $errorContainer = $container.find('.wpstg--modal--error--logs');
1266
- var $translations = $('#wpstg--js--translations');
1267
- var messages = WPStagingLegacyDatabase.messages;
1268
- var title = $translations.attr('data-modal-logs-title').replace('{critical}', messages.countByType(messages.CRITICAL)).replace('{errors}', messages.countByType(messages.ERROR)).replace('{warnings}', messages.countByType(messages.WARNING));
1269
- $errorContainer.before("<h3>" + title + "</h3>");
1270
- var warnings = [WPStagingLegacyDatabase.messages.CRITICAL, WPStagingLegacyDatabase.messages.ERROR, WPStagingLegacyDatabase.messages.WARNING];
1271
 
1272
  if (!WPStagingLegacyDatabase.messages.shouldWarn()) {
1273
- $errorContainer.hide();
1274
  }
1275
 
1276
- for (var _iterator3 = _createForOfIteratorHelperLoose(messages.data.all), _step3; !(_step3 = _iterator3()).done;) {
1277
- var message = _step3.value;
1278
- var msgClass = "wpstg--modal--process--msg--" + message.type.toLowerCase(); // TODO RPoC
 
 
 
1279
 
1280
- if (warnings.includes(message.type)) {
1281
- $errorContainer.append("<p class=\"" + msgClass + "\">[" + message.type + "] - [" + message.date + "] - " + message.message + "</p>");
1282
- }
1283
 
1284
- $logsContainer.append("<p class=\"" + msgClass + "\">[" + message.type + "] - [" + message.date + "] - " + message.message + "</p>");
1285
- }
1286
- },
1287
- onOpen: function onOpen(container) {
1288
- var $logsContainer = $(container).find('.wpstg--modal--process--logs');
1289
- $logsContainer.scrollTop($logsContainer[0].scrollHeight);
1290
  }
1291
- });
1292
- },
1293
- downloadModal: function downloadModal(_ref3) {
1294
- var _ref3$title = _ref3.title,
1295
- title = _ref3$title === void 0 ? null : _ref3$title,
1296
- _ref3$titleExport = _ref3.titleExport,
1297
- titleExport = _ref3$titleExport === void 0 ? null : _ref3$titleExport,
1298
- _ref3$id = _ref3.id,
1299
- id = _ref3$id === void 0 ? null : _ref3$id,
1300
- _ref3$url = _ref3.url,
1301
- url = _ref3$url === void 0 ? null : _ref3$url,
1302
- _ref3$btnTxtCancel = _ref3.btnTxtCancel,
1303
- btnTxtCancel = _ref3$btnTxtCancel === void 0 ? 'Cancel' : _ref3$btnTxtCancel,
1304
- _ref3$btnTxtConfirm = _ref3.btnTxtConfirm,
1305
- btnTxtConfirm = _ref3$btnTxtConfirm === void 0 ? 'Download' : _ref3$btnTxtConfirm;
1306
-
1307
- if (null === WPStagingLegacyDatabase.modal.download.html) {
1308
- var $el = $('#wpstg--modal--backup--download');
1309
- WPStagingLegacyDatabase.modal.download.html = $el.html();
1310
- $el.remove();
1311
- }
1312
-
1313
- var exportModal = function exportModal() {
1314
- return Swal.fire({
1315
- html: "<h2>" + titleExport + "</h2><span class=\"wpstg-loader\"></span>",
1316
- showCancelButton: false,
1317
- showConfirmButton: false,
1318
  onRender: function onRender() {
1319
- WPStagingLegacyDatabase.ajax({
1320
- action: 'wpstg--backups--database-legacy-export',
1321
- accessToken: wpstg.accessToken,
1322
- nonce: wpstg.nonce,
1323
- id: id
1324
- }, function (response) {
1325
- console.log(response);
1326
-
1327
- if (!response || !response.success || !response.data || response.data.length < 1) {
1328
- return;
 
 
 
 
 
 
 
 
 
 
1329
  }
1330
 
1331
- var a = document.createElement('a');
1332
- a.style.display = 'none';
1333
- a.href = response.data;
1334
- document.body.appendChild(a);
1335
- a.click();
1336
- document.body.removeChild(a);
1337
- Swal.close();
1338
- });
1339
  }
1340
  });
1341
- };
1342
-
1343
- Swal.mixin({
1344
- customClass: {
1345
- cancelButton: 'wpstg--btn--cancel wpstg-blue-primary wpstg-link-btn',
1346
- confirmButton: 'wpstg--btn--confirm wpstg-blue-primary wpstg-button wpstg-link-btn',
1347
- actions: 'wpstg--modal--actions'
1348
- },
1349
- buttonsStyling: false
1350
- }).fire({
1351
- icon: 'success',
1352
- html: WPStagingLegacyDatabase.modal.download.html.replace('{title}', title).replace('{btnTxtLog}', 'Show Logs'),
1353
- cancelButtonText: btnTxtCancel,
1354
- confirmButtonText: btnTxtConfirm,
1355
- showCancelButton: true,
1356
- showConfirmButton: true
1357
- }).then(function (isConfirm) {
1358
- if (!isConfirm || !isConfirm.value) {
1359
- return;
1360
- }
1361
-
1362
- if (url && url.length > 0) {
1363
- window.location.href = url;
1364
- return;
1365
  }
1366
 
1367
- exportModal();
1368
- });
1369
- },
1370
- importModal: function importModal() {
1371
- var restoreSiteBackup = function restoreSiteBackup(data) {
1372
- WPStagingLegacyDatabase.resetErrors();
 
 
 
 
 
 
 
 
 
 
 
1373
 
1374
- if (WPStagingLegacyDatabase.isCancelled) {
1375
- console.log('cancelled'); // Swal.close();
 
 
 
 
 
 
 
 
 
1376
 
1377
- return;
1378
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1379
 
1380
- var reset = data['reset'];
1381
- delete data['reset'];
1382
- data['mergeMediaFiles'] = 1; // always merge for uploads / media
 
1383
 
1384
- var requestData = Object.assign({}, data);
1385
- requestData = WPStagingLegacyDatabase.requestData('jobs.backup.site.restore', _extends({}, WPStagingLegacyDatabase.modal["import"].data));
1386
- WPStagingLegacyDatabase.timer.start();
 
 
 
1387
 
1388
- var statusStop = function statusStop() {
1389
- console.log('Status: Stop');
1390
- clearInterval(WPStagingLegacyDatabase.processInfo.interval);
1391
- WPStagingLegacyDatabase.processInfo.interval = null;
1392
- };
1393
 
1394
- var status = function status() {
1395
- if (WPStagingLegacyDatabase.processInfo.interval !== null) {
1396
  return;
1397
  }
1398
 
1399
- console.log('Status: Start');
1400
- WPStagingLegacyDatabase.processInfo.interval = setInterval(function () {
1401
- if (true === WPStagingLegacyDatabase.isCancelled) {
1402
- statusStop();
1403
- return;
1404
- }
1405
 
1406
- if (WPStagingLegacyDatabase.status.hasResponse === false) {
 
 
 
 
 
 
 
 
 
 
 
1407
  return;
1408
  }
1409
 
1410
- WPStagingLegacyDatabase.status.hasResponse = false;
1411
- fetch(ajaxurl + "?action=wpstg--backups--status&process=restore&accessToken=" + wpstg.accessToken + "&nonce=" + wpstg.nonce).then(function (res) {
1412
- return res.json();
1413
- }).then(function (res) {
1414
- WPStagingLegacyDatabase.status.hasResponse = true;
1415
-
1416
- if (typeof res === 'undefined') {
1417
  statusStop();
 
1418
  }
1419
 
1420
- if (WPStagingLegacyDatabase.processInfo.title === res.currentStatusTitle) {
1421
  return;
1422
  }
1423
 
1424
- WPStagingLegacyDatabase.processInfo.title = res.currentStatusTitle;
1425
- var $container = $(Swal.getContainer());
1426
- $container.find('.wpstg--modal--process--title').text(res.currentStatusTitle);
1427
- $container.find('.wpstg--modal--process--percent').text('0');
1428
- })["catch"](function (e) {
1429
- WPStagingLegacyDatabase.status.hasResponse = true;
1430
- WPStagingLegacyDatabase.showAjaxFatalError(e, '', 'Submit an error report.');
1431
- });
1432
- }, 5000);
1433
- };
1434
-
1435
- WPStaging.ajax({
1436
- action: 'wpstg--backups--database-legacy-restore',
1437
- accessToken: wpstg.accessToken,
1438
- nonce: wpstg.nonce,
1439
- reset: reset,
1440
- wpstg: requestData
1441
- }, function (response) {
1442
- if (typeof response === 'undefined') {
1443
- setTimeout(function () {
1444
- restoreSiteBackup(data);
1445
- }, wpstg.delayReq);
1446
- return;
1447
- }
1448
 
1449
- WPStagingLegacyDatabase.processResponse(response, true);
 
 
1450
 
1451
- if (!WPStagingLegacyDatabase.processInfo.interval) {
1452
- status();
1453
- }
1454
 
1455
- if (response.status === false) {
1456
- restoreSiteBackup(data);
1457
- } else if (response.status === true) {
1458
- $('#wpstg--progress--status').text('Backup successfully restored!');
1459
- WPStagingLegacyDatabase.type = null;
 
 
 
 
 
1460
 
1461
- if (WPStagingLegacyDatabase.messages.shouldWarn()) {
1462
- // noinspection JSIgnoredPromiseFromCall
1463
- WPStagingLegacyDatabase.fetchListing();
1464
- WPStagingLegacyDatabase.logsModal();
 
 
 
 
 
 
 
1465
  return;
1466
  }
1467
 
1468
- statusStop();
1469
- var logEntries = $('.wpstg--modal--process--logs').get(1).innerHTML;
1470
- var html = '<div class="wpstg--modal--process--logs">' + logEntries + '</div>';
1471
- var issueFound = html.includes('wpstg--modal--process--msg--warning') || html.includes('wpstg--modal--process--msg--error') ? 'Issues(s) found! ' : '';
1472
- console.log('errors found: ' + issueFound); // var errorMessage = html.includes('wpstg--modal--process--msg--error') ? 'Errors(s) found! ' : '';
1473
- // var Message = warningMessage + errorMessage;
1474
- // Swal.close();
1475
 
1476
- Swal.fire({
1477
- icon: 'success',
1478
- title: 'Finished',
1479
- html: 'System restored from backup. <br/><span class="wpstg--modal--process--msg-found">' + issueFound + '</span><button class="wpstg--modal--process--logs--tail" data-txt-bad="">Show Logs</button><br/>' + html
1480
- }); // noinspection JSIgnoredPromiseFromCall
1481
 
1482
- WPStagingLegacyDatabase.fetchListing();
1483
- } else {
1484
- setTimeout(function () {
1485
  restoreSiteBackup(data);
1486
- }, wpstg.delayReq);
1487
- }
1488
- }, 'json', false, 0, // Don't retry upon failure
1489
- 1.25);
1490
- };
1491
-
1492
- if (!WPStagingLegacyDatabase.modal["import"].html) {
1493
- var $modal = $('#wpstg--modal--backup--import'); // Search & Replace Form
1494
-
1495
- var $form = $modal.find('.wpstg--modal--backup--import--search-replace--input--container');
1496
- WPStagingLegacyDatabase.modal["import"].searchReplaceForm = $form.html();
1497
- $form.find('.wpstg--modal--backup--import--search-replace--input-group').remove();
1498
- $form.html(WPStagingLegacyDatabase.modal["import"].searchReplaceForm.replace(/{i}/g, 0));
1499
- WPStagingLegacyDatabase.modal["import"].html = $modal.html();
1500
- WPStagingLegacyDatabase.modal["import"].baseDirectory = $modal.attr('data-baseDirectory');
1501
- WPStagingLegacyDatabase.modal["import"].btnTxtNext = $modal.attr('data-nextButtonText');
1502
- WPStagingLegacyDatabase.modal["import"].btnTxtConfirm = $modal.attr('data-confirmButtonText');
1503
- WPStagingLegacyDatabase.modal["import"].btnTxtCancel = $modal.attr('data-cancelButtonText');
1504
- $modal.remove();
1505
- }
1506
 
1507
- WPStagingLegacyDatabase.modal["import"].data.search = [];
1508
- WPStagingLegacyDatabase.modal["import"].data.replace = [];
1509
- var $btnConfirm = null;
1510
- Swal.mixin({
1511
- customClass: {
1512
- confirmButton: 'wpstg--btn--confirm wpstg-blue-primary wpstg-button wpstg-link-btn',
1513
- cancelButton: 'wpstg--btn--cancel wpstg-blue-primary wpstg-link-btn',
1514
- actions: 'wpstg--modal--actions'
1515
- },
1516
- buttonsStyling: false // progressSteps: ['1', '2']
1517
-
1518
- }).queue([{
1519
- html: WPStagingLegacyDatabase.modal["import"].html,
1520
- confirmButtonText: WPStagingLegacyDatabase.modal["import"].btnTxtNext,
1521
- showCancelButton: false,
1522
- showConfirmButton: true,
1523
- showLoaderOnConfirm: true,
1524
- width: 650,
1525
- onRender: function onRender() {
1526
- $btnConfirm = $('.wpstg--modal--actions .swal2-confirm');
1527
- $btnConfirm.prop('disabled', true);
1528
- WPStagingLegacyDatabase.modal["import"].containerUpload = $('.wpstg--modal--backup--import--upload');
1529
- WPStagingLegacyDatabase.modal["import"].containerFilesystem = $('.wpstg--modal--backup--import--filesystem');
1530
- },
1531
- preConfirm: function preConfirm() {
1532
- var body = new FormData();
1533
- body.append('accessToken', wpstg.accessToken);
1534
- body.append('nonce', wpstg.nonce);
1535
- body.append('filePath', WPStagingLegacyDatabase.modal["import"].data.file);
1536
- WPStagingLegacyDatabase.modal["import"].data.search.forEach(function (item, index) {
1537
- body.append("search[" + index + "]", item);
1538
- });
1539
- WPStagingLegacyDatabase.modal["import"].data.replace.forEach(function (item, index) {
1540
- body.append("replace[" + index + "]", item);
1541
- });
1542
- return fetch(ajaxurl + "?action=wpstg--backups--import--file-info", {
1543
- method: 'POST',
1544
- body: body
1545
- }).then(WPStagingLegacyDatabase.handleFetchErrors).then(function (res) {
1546
- return res.json();
1547
- }).then(function (html) {
1548
- return Swal.insertQueueStep({
1549
- html: html,
1550
- confirmButtonText: WPStagingLegacyDatabase.modal["import"].btnTxtConfirm,
1551
- cancelButtonText: WPStagingLegacyDatabase.modal["import"].btnTxtCancel,
1552
- showCancelButton: true
1553
- });
1554
- })["catch"](function (e) {
1555
- return WPStagingLegacyDatabase.showAjaxFatalError(e, '', 'Submit an error report.');
1556
- });
1557
- }
1558
- }]).then(function (res) {
1559
- if (!res || !res.value || !res.value[1] || res.value[1] !== true) {
1560
- return;
1561
  }
1562
 
1563
- WPStagingLegacyDatabase.isCancelled = false;
1564
- var data = WPStagingLegacyDatabase.modal["import"].data;
1565
- data['file'] = WPStagingLegacyDatabase.modal["import"].baseDirectory + data['file'];
1566
- data['reset'] = true;
1567
- WPStagingLegacyDatabase.process({
1568
- execute: function execute() {
1569
- WPStagingLegacyDatabase.messages.reset();
1570
- restoreSiteBackup(data);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1571
  }
 
 
 
 
 
 
 
 
 
 
 
1572
  });
1573
- });
1574
- }
1575
- };
10
 
11
  function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
12
 
13
+ (function ($) {
14
+ window.addEventListener('database-backups-tab', function () {
15
+ WPStagingLegacyDatabase.init();
16
+ });
17
+ var WPStagingLegacyDatabase = {
18
+ type: null,
19
+ isCancelled: false,
20
+ processInfo: {
21
+ title: null,
22
+ interval: null
 
 
 
 
 
 
 
 
 
 
 
 
23
  },
24
+ cache: {
25
+ elements: [],
26
+ get: function get(selector) {
27
+ // It is already cached!
28
+ if ($.inArray(selector, this.elements) !== -1) {
29
+ return this.elements[selector];
30
+ } // Create cache and return
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
 
 
 
 
 
32
 
33
+ this.elements[selector] = $(selector);
34
+ return this.elements[selector];
35
+ },
36
+ refresh: function refresh(selector) {
37
+ selector.elements[selector] = $(selector);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  }
39
+ },
40
+ init: function init() {
41
+ WPStagingLegacyDatabase.fetchListing();
42
+ this.create();
43
+ this["delete"]();
44
+ this.restore();
45
+ this.edit(); // noinspection JSIgnoredPromiseFromCall
46
+
47
+ $('body').off('change', '#wpstg--backups--filter').on('change', '#wpstg--backups--filter', function () {
48
+ var $records = $('#wpstg-existing-database-backups').find('> div[id][data-type].wpstg-backup');
49
+
50
+ if (this.value === '') {
51
+ $records.show();
52
+ } else if (this.value === 'database') {
53
+ $records.filter('[data-type="site"]').hide();
54
+ $records.filter('[data-type="database"]').show();
55
+ } else if (this.value === 'site') {
56
+ $records.filter('[data-type="database"]').hide();
57
+ $records.filter('[data-type="site"]').show();
58
+ }
59
+ }).on('click', '.wpstg--backup--download', function () {
60
+ var url = this.getAttribute('data-url');
61
 
62
+ if (url.length > 0) {
63
+ window.location.href = url;
64
+ return;
65
+ }
 
 
66
 
67
+ WPStagingLegacyDatabase.downloadModal({
68
+ titleExport: this.getAttribute('data-title-export'),
69
+ title: this.getAttribute('data-title'),
70
+ id: this.getAttribute('data-id'),
71
+ btnTxtCancel: this.getAttribute('data-btn-cancel-txt'),
72
+ btnTxtConfirm: this.getAttribute('data-btn-download-txt')
73
+ });
74
+ }).off('click', '#wpstg-import-backup').on('click', '#wpstg-import-backup', function () {
75
+ WPStagingLegacyDatabase.importModal();
76
+ }) // Import
77
+ .off('click', '.wpstg--backup--import--choose-option').on('click', '.wpstg--backup--import--choose-option', function () {
78
+ var $parent = $(this).parent();
79
+
80
+ if (!$parent.hasClass('wpstg--show-options')) {
81
+ $parent.addClass('wpstg--show-options');
82
+ $(this).text($(this).attr('data-txtChoose'));
83
+ } else {
84
+ $parent.removeClass('wpstg--show-options');
85
+ $(this).text($(this).attr('data-txtOther'));
86
+ }
87
+ }).off('click', '.wpstg--modal--backup--import--search-replace--new').on('click', '.wpstg--modal--backup--import--search-replace--new', function (e) {
88
+ e.preventDefault();
89
+ var $container = $(Swal.getContainer()).find('.wpstg--modal--backup--import--search-replace--input--container');
90
+ var total = $container.find('.wpstg--modal--backup--import--search-replace--input-group').length;
91
+ $container.append(WPStagingLegacyDatabase.modal["import"].searchReplaceForm.replace(/{i}/g, total));
92
+ }).off('input', '.wpstg--backup--import--search').on('input', '.wpstg--backup--import--search', function () {
93
+ var index = parseInt(this.getAttribute('data-index'));
94
+
95
+ if (!isNaN(index)) {
96
+ WPStagingLegacyDatabase.modal["import"].data.search[index] = this.value;
97
+ }
98
+ }).off('input', '.wpstg--backup--import--replace').on('input', '.wpstg--backup--import--replace', function () {
99
+ var index = parseInt(this.getAttribute('data-index'));
100
 
101
+ if (!isNaN(index)) {
102
+ WPStagingLegacyDatabase.modal["import"].data.replace[index] = this.value;
103
+ }
104
+ }) // Other Options
105
+ .off('click', '.wpstg--backup--import--option[data-option]').on('click', '.wpstg--backup--import--option[data-option]', function () {
106
+ var option = this.getAttribute('data-option');
107
 
108
+ if (option === 'file') {
109
+ $('input[type="file"][name="wpstg--backup--import--upload--file"]').click();
110
+ return;
111
+ }
112
 
113
+ if (option === 'upload') {
114
+ WPStagingLegacyDatabase.modal["import"].containerFilesystem.hide();
115
+ WPStagingLegacyDatabase.modal["import"].containerUpload.show();
116
+ $('.wpstg--backup--import--choose-option').click();
117
+ $('.wpstg--modal--backup--import--search-replace--wrapper').show();
118
+ }
 
 
119
 
120
+ if (option !== 'filesystem') {
 
 
121
  return;
122
  }
123
 
124
+ WPStagingLegacyDatabase.modal["import"].containerUpload.hide();
125
+ var $containerFilesystem = WPStagingLegacyDatabase.modal["import"].containerFilesystem;
126
+ $containerFilesystem.show();
127
+ fetch(ajaxurl + "?action=wpstg--backups--import--file-list&_=" + Math.random() + "&accessToken=" + wpstg.accessToken + "&nonce=" + wpstg.nonce).then(WPStagingLegacyDatabase.handleFetchErrors).then(function (res) {
128
+ return res.json();
129
+ }).then(function (res) {
130
+ var $ul = $('.wpstg--modal--backup--import--filesystem ul');
131
+ $ul.empty();
132
 
133
+ if (!res || WPStagingLegacyDatabase.isEmpty(res)) {
134
+ $ul.append("<span id=\"wpstg--backups--import--file-list-empty\">No import file found! Upload an import file to the folder above.</span><br />");
135
+ $('.wpstg--modal--backup--import--search-replace--wrapper').hide();
136
+ return;
137
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
138
 
139
+ $ul.append("<span id=\"wpstg--backups--import--file-list\">Select file to import:</span><br />");
140
+ res.forEach(function (file, index) {
141
+ // var checked = (index === 0) ? 'checked' : '';
142
+ $ul.append("<li><label><input name=\"backup_import_file\" type=\"radio\" value=\"" + file.fullPath + "\">" + file.name + " <br /> " + file.size + "</label></li>");
143
+ }); // $('.wpstg--modal--actions .swal2-confirm').prop('disabled', false);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
144
 
145
+ return res;
146
+ })["catch"](function (e) {
147
+ return WPStagingLegacyDatabase.showAjaxFatalError(e, '', 'Submit an error report.');
148
+ });
149
+ }).off('change', 'input[type="file"][name="wpstg--backup--import--upload--file"]').on('change', 'input[type="file"][name="wpstg--backup--import--upload--file"]', function () {
150
+ WPStagingLegacyDatabase.modal["import"].setFile(this.files[0] || null);
151
+ $('.wpstg--backup--import--choose-option').click();
152
+ }).off('change', 'input[type="radio"][name="backup_import_file"]').on('change', 'input[type="radio"][name="backup_import_file"]', function () {
153
+ $('.wpstg--modal--actions .swal2-confirm').prop('disabled', false);
154
+ WPStagingLegacyDatabase.modal["import"].data.file = this.value;
155
+ }) // Drag & Drop
156
+ .on('drag dragstart dragend dragover dragenter dragleave drop', '.wpstg--modal--backup--import--upload--container', function (e) {
157
+ e.preventDefault();
158
+ e.stopPropagation();
159
+ }).on('dragover dragenter', '.wpstg--modal--backup--import--upload--container', function () {
160
+ $(this).addClass('wpstg--has-dragover');
161
+ }).on('dragleave dragend drop', '.wpstg--modal--backup--import--upload--container', function () {
162
+ $(this).removeClass('wpstg--has-dragover');
163
+ }).on('drop', '.wpstg--modal--backup--import--upload--container', function (e) {
164
+ WPStagingLegacyDatabase.modal["import"].setFile(e.originalEvent.dataTransfer.files[0] || null);
165
+ });
166
+ },
167
+ create: function create() {
168
+ var createBackup = function createBackup(data) {
169
+ WPStagingLegacyDatabase.resetErrors();
170
 
171
+ if (WPStagingLegacyDatabase.isCancelled) {
172
+ // Swal.close();
173
+ return;
174
+ }
 
175
 
176
+ var reset = data['reset'];
177
+ delete data['reset'];
178
+ var requestData = Object.assign({}, data);
179
+ var useResponseTitle = true;
180
+
181
+ if (data.type === 'database') {
182
+ WPStagingLegacyDatabase.type = data.type; // Only send to back-end what BE is expecting to receive.
183
+ // Prevent error: Trying to hydrate DTO with value that does not exist.
184
+
185
+ delete requestData['includedDirectories'];
186
+ delete requestData['wpContentDir'];
187
+ delete requestData['availableDirectories'];
188
+ delete requestData['wpStagingDir'];
189
+ delete requestData['exportDatabase'];
190
+ delete requestData['includeOtherFilesInWpContent'];
191
+ requestData = WPStagingLegacyDatabase.requestData('tasks.backup.database.create', _extends({}, requestData, {
192
+ type: 'manual'
193
+ }));
194
+ } else if (data.type === 'site') {
195
+ WPStagingLegacyDatabase.type = data.type; // Only send to back-end what BE is expecting to receive.
196
+ // Prevent error: Trying to hydrate DTO with value that does not exist.
197
+
198
+ delete requestData['type'];
199
+ requestData = WPStagingLegacyDatabase.requestData('jobs.backup.site.create', requestData);
200
+ useResponseTitle = false;
201
+ requestData.jobs.backup.site.create.directories = [data.wpContentDir];
202
+ requestData.jobs.backup.site.create.excludedDirectories = data.availableDirectories.split('|').filter(function (item) {
203
+ return !data.includedDirectories.includes(item);
204
+ }).map(function (item) {
205
+ return item;
206
+ });
207
+ requestData.jobs.backup.site.create.includeOtherFilesInWpContent = [data.includeOtherFilesInWpContent]; // Do not exclude the wp-content/uploads/wp-staging using regex by default
208
+ // This folder is excluded by PHP without REGEX.
209
+ // requestData.jobs.backup.site.create.excludedDirectories.push(`#${data.wpStagingDir}*#`);
210
+ // delete requestData.jobs.backup.site.create.includedDirectories;
211
+
212
+ delete requestData.jobs.backup.site.create.wpContentDir;
213
+ delete requestData.jobs.backup.site.create.wpStagingDir;
214
+ delete requestData.jobs.backup.site.create.availableDirectories;
215
+ } else {
216
+ WPStagingLegacyDatabase.type = null;
217
+ Swal.close();
218
+ WPStagingLegacyDatabase.showError('Invalid Backup Type');
219
  return;
220
  }
221
 
222
+ WPStagingLegacyDatabase.timer.start();
223
+
224
+ var statusStop = function statusStop() {
225
+ console.log('Status: Stop');
226
+ clearInterval(WPStagingLegacyDatabase.processInfo.interval);
227
+ WPStagingLegacyDatabase.processInfo.interval = null;
228
+ };
229
 
230
+ var status = function status() {
231
+ if (WPStagingLegacyDatabase.processInfo.interval !== null) {
232
  return;
233
  }
234
 
235
+ console.log('Status: Start');
236
+ WPStagingLegacyDatabase.processInfo.interval = setInterval(function () {
237
+ if (true === WPStagingLegacyDatabase.isCancelled) {
 
 
 
 
238
  statusStop();
239
+ return;
240
  }
241
 
242
+ if (WPStagingLegacyDatabase.status.hasResponse === false) {
243
  return;
244
  }
245
 
246
+ WPStagingLegacyDatabase.status.hasResponse = false;
247
+ fetch(ajaxurl + "?action=wpstg--backups--status&accessToken=" + wpstg.accessToken + "&nonce=" + wpstg.nonce).then(function (res) {
248
+ return res.json();
249
+ }).then(function (res) {
250
+ WPStagingLegacyDatabase.status.hasResponse = true;
 
 
 
 
 
251
 
252
+ if (typeof res === 'undefined') {
253
+ statusStop();
254
+ }
 
 
 
 
 
 
 
 
 
 
 
 
255
 
256
+ if (WPStagingLegacyDatabase.processInfo.title === res.currentStatusTitle) {
257
+ return;
258
+ }
259
 
260
+ WPStagingLegacyDatabase.processInfo.title = res.currentStatusTitle;
261
+ var $container = $(Swal.getContainer());
262
+ $container.find('.wpstg--modal--process--title').text(res.currentStatusTitle);
263
+ $container.find('.wpstg--modal--process--percent').text('0');
264
+ })["catch"](function (e) {
265
+ WPStagingLegacyDatabase.status.hasResponse = true;
266
+ WPStagingLegacyDatabase.showAjaxFatalError(e, '', 'Submit an error report.');
267
+ });
268
+ }, 5000);
269
+ };
270
 
271
+ WPStaging.ajax({
272
+ action: 'wpstg--backups--database-legacy-create',
273
+ accessToken: wpstg.accessToken,
274
+ nonce: wpstg.nonce,
275
+ reset: reset,
276
+ wpstg: requestData
277
+ }, function (response) {
278
+ if (typeof response === 'undefined') {
279
+ setTimeout(function () {
280
+ createBackup(data);
281
+ }, wpstg.delayReq);
282
  return;
283
  }
284
 
285
+ WPStagingLegacyDatabase.processResponse(response, useResponseTitle);
 
 
 
 
 
 
286
 
287
+ if (!useResponseTitle && !WPStagingLegacyDatabase.processInfo.interval) {
288
+ status();
289
+ }
290
 
291
+ if (response.status === false) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
292
  createBackup(data);
293
+ } else if (response.status === true) {
294
+ $('#wpstg--progress--status').text('Backup successfully created!');
295
+ WPStagingLegacyDatabase.type = null;
296
+
297
+ if (WPStagingLegacyDatabase.messages.shouldWarn()) {
298
+ // noinspection JSIgnoredPromiseFromCall
299
+ WPStagingLegacyDatabase.fetchListing();
300
+ WPStagingLegacyDatabase.logsModal();
301
+ return;
302
+ }
303
 
304
+ statusStop();
305
+ Swal.close();
306
+ WPStagingLegacyDatabase.fetchListing().then(function () {
307
+ if (!response.backupId) {
308
+ WPStagingLegacyDatabase.showError('Failed to get backup ID from response');
309
+ return;
310
+ } // TODO RPoC
311
+
312
+
313
+ var $el = $(".wpstg--backup--download[data-id=\"" + response.backupId + "\"]");
314
+ WPStagingLegacyDatabase.downloadModal({
315
+ id: $el.data('id'),
316
+ url: $el.data('url'),
317
+ title: $el.data('title'),
318
+ titleExport: $el.data('title-export'),
319
+ btnTxtCancel: $el.data('btn-cancel-txt'),
320
+ btnTxtConfirm: $el.data('btn-download-txt')
321
+ });
322
+ $('.wpstg--modal--download--logs--wrapper').show();
323
+ var $logsContainer = $('.wpstg--modal--process--logs');
324
+ WPStagingLegacyDatabase.messages.data.all.forEach(function (message) {
325
+ var msgClass = "wpstg--modal--process--msg--" + message.type.toLowerCase();
326
+ $logsContainer.append("<p class=\"" + msgClass + "\">[" + message.type + "] - [" + message.date + "] - " + message.message + "</p>");
327
+ });
328
+ });
329
+ } else {
330
+ setTimeout(function () {
331
+ createBackup(data);
332
+ }, wpstg.delayReq);
333
+ }
334
+ }, 'json', false, 0, // Don't retry upon failure
335
+ 1.25);
336
+ };
337
 
338
+ var $body = $('body');
339
+ $body.off('click', 'input[name="backup_type"]').on('click', 'input[name="backup_type"]', function () {
340
+ var advancedOptions = $('.wpstg-advanced-options');
 
341
 
342
+ if (this.value === 'database') {
343
+ advancedOptions.hide();
344
+ return;
345
+ }
346
 
347
+ advancedOptions.show();
348
+ }).off('click', '.wpstg--tab--toggle').on('click', '.wpstg--tab--toggle', function () {
349
+ var $target = $($(this).attr('data-target'));
350
+ $target.toggle();
 
 
 
 
351
 
352
+ if ($target.is(':visible')) {
353
+ $(this).find('span').text('');
354
+ } else {
355
+ $(this).find('span').text('');
356
+ }
357
+ }).off('change', '[name="includedDirectories\[\]"], [type="checkbox"][name="export_database"]').on('change', '[type="checkbox"][name="includedDirectories\[\]"], [type="checkbox"][name="export_database"]', function () {
358
+ var totalDirs = $('[type="checkbox"][name="includedDirectories\[\]"]:checked').length;
359
+ var isExportDatabase = $('[type="checkbox"][name="export_database"]:checked').length === 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
360
 
361
+ if (totalDirs < 1 && !isExportDatabase) {
362
+ $('.swal2-confirm').prop('disabled', true);
363
+ } else {
364
+ $('.swal2-confirm').prop('disabled', false);
365
+ }
366
+ }); // Add backup name and notes
367
+
368
+ $('#wpstg--tab--database-backups').off('click', '#wpstg-new-database-backup').on('click', '#wpstg-new-database-backup', /*#__PURE__*/function () {
369
+ var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(e) {
370
+ var $newBackupModal, html, btnTxt, _yield$Swal$fire, formValues;
371
+
372
+ return regeneratorRuntime.wrap(function _callee$(_context) {
373
+ while (1) {
374
+ switch (_context.prev = _context.next) {
375
+ case 0:
376
+ WPStagingLegacyDatabase.resetErrors();
377
+ e.preventDefault();
378
+ WPStagingLegacyDatabase.isCancelled = false;
379
+
380
+ if (!WPStagingLegacyDatabase.modal.create.html || !WPStagingLegacyDatabase.modal.create.confirmBtnTxt) {
381
+ $newBackupModal = $('#wpstg--modal--database--new');
382
+ html = $newBackupModal.html();
383
+ btnTxt = $newBackupModal.attr('data-confirmButtonText');
384
+ WPStagingLegacyDatabase.modal.create.html = html || null;
385
+ WPStagingLegacyDatabase.modal.create.confirmBtnTxt = btnTxt || null;
386
+ $newBackupModal.remove();
387
  }
 
388
 
389
+ _context.next = 6;
390
+ return Swal.fire({
391
+ title: '',
392
+ html: WPStagingLegacyDatabase.modal.create.html,
393
+ focusConfirm: false,
394
+ confirmButtonText: WPStagingLegacyDatabase.modal.create.confirmBtnTxt,
395
+ showCancelButton: true,
396
+ preConfirm: function preConfirm() {
397
+ var container = Swal.getContainer();
398
+ return {
399
+ type: 'database',
400
+ name: container.querySelector('input[name="backup_name"]').value || null,
401
+ notes: container.querySelector('textarea[name="backup_note"]').value || null,
402
+ includedDirectories: Array.from(container.querySelectorAll('input[name="includedDirectories\\[\\]"]:checked') || []).map(function (i) {
403
+ return i.value;
404
+ }),
405
+ wpContentDir: container.querySelector('input[name="wpContentDir"]').value || null,
406
+ availableDirectories: container.querySelector('input[name="availableDirectories"]').value || null,
407
+ wpStagingDir: container.querySelector('input[name="wpStagingDir"]').value || null,
408
+ exportDatabase: container.querySelector('input[name="export_database"]:checked') !== null,
409
+ includeOtherFilesInWpContent: container.querySelector('input[name="includeOtherFilesInWpContent"]:checked') !== null
410
+ };
411
+ }
412
+ });
413
+
414
+ case 6:
415
+ _yield$Swal$fire = _context.sent;
416
+ formValues = _yield$Swal$fire.value;
417
+
418
+ if (formValues) {
419
+ _context.next = 10;
420
+ break;
421
+ }
422
 
423
+ return _context.abrupt("return");
424
 
425
+ case 10:
426
+ formValues.reset = true;
427
+ WPStagingLegacyDatabase.process({
428
+ execute: function execute() {
429
+ WPStagingLegacyDatabase.messages.reset();
430
+ createBackup(formValues);
431
+ }
432
+ });
433
 
434
+ case 12:
435
+ case "end":
436
+ return _context.stop();
437
+ }
438
  }
439
+ }, _callee);
440
+ }));
 
441
 
442
+ return function (_x) {
443
+ return _ref.apply(this, arguments);
444
+ };
445
+ }());
446
+ },
447
+ isEmpty: function isEmpty(obj) {
448
+ for (var prop in obj) {
449
+ if (obj.hasOwnProperty(prop)) {
450
+ return false;
451
+ }
452
  }
 
453
 
454
+ return true;
455
+ },
456
+ isLoading: function isLoading(_isLoading) {
457
+ if (!_isLoading || _isLoading === false) {
458
+ WPStagingLegacyDatabase.cache.get('.wpstg-loader').hide();
459
+ } else {
460
+ WPStagingLegacyDatabase.cache.get('.wpstg-loader').show();
461
+ }
462
+ },
463
+ showAjaxFatalError: function showAjaxFatalError(response, prependMessage, appendMessage) {
464
+ prependMessage = prependMessage ? prependMessage + '<br/><br/>' : 'Something went wrong! <br/><br/>';
465
+ appendMessage = appendMessage ? appendMessage + '<br/><br/>' : '<br/><br/>Please try the <a href=\'https://wp-staging.com/docs/wp-staging-settings-for-small-servers/\' target=\'_blank\'>WP Staging Small Server Settings</a> or submit an error report and contact us.';
 
 
 
 
 
 
466
 
467
+ if (response === false) {
468
+ showError(prependMessage + ' Error: No response.' + appendMessage);
469
+ window.removeEventListener('beforeunload', WPStaging.warnIfClosingDuringProcess);
470
+ return;
471
+ }
 
 
 
 
 
 
472
 
473
+ if (typeof response.error !== 'undefined' && response.error) {
474
+ console.error(response.message);
475
+ showError(prependMessage + ' Error: ' + response.message + appendMessage);
476
+ window.removeEventListener('beforeunload', WPStaging.warnIfClosingDuringProcess);
477
+ return;
478
+ }
479
+ },
480
+ handleFetchErrors: function handleFetchErrors(response) {
481
+ if (!response.ok) {
482
+ showError('Error: ' + response.status + ' - ' + response.statusText + '. Please try again or contact support.');
483
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
484
 
485
+ return response;
486
+ },
487
+ showError: function showError(message) {
488
+ WPStagingLegacyDatabase.cache.get('#wpstg-try-again').css('display', 'inline-block');
489
+ WPStagingLegacyDatabase.cache.get('#wpstg-cancel-cloning').text('Reset');
490
+ WPStagingLegacyDatabase.cache.get('#wpstg-resume-cloning').show();
491
+ WPStagingLegacyDatabase.cache.get('#wpstg-error-wrapper').show();
492
+ WPStagingLegacyDatabase.cache.get('#wpstg-error-details').show().html(message);
493
+ WPStagingLegacyDatabase.cache.get('#wpstg-removing-clone').removeClass('loading');
494
+ WPStagingLegacyDatabase.cache.get('.wpstg-loader').hide();
495
+ $('.wpstg--modal--process--generic-problem').show().html(message);
496
+ },
497
+ resetErrors: function resetErrors() {
498
+ WPStagingLegacyDatabase.cache.get('#wpstg-error-details').hide().html('');
499
+ },
500
 
501
+ /**
502
+ * Ajax Requests
503
+ * @param {Object} data
504
+ * @param {Function} callback
505
+ * @param {string} dataType
506
+ * @param {bool} showErrors
507
+ * @param {int} tryCount
508
+ * @param {float} incrementRatio
509
+ */
510
+ ajax: function ajax(data, callback, dataType, showErrors, tryCount, incrementRatio) {
511
+ if (incrementRatio === void 0) {
512
+ incrementRatio = null;
513
+ }
514
 
515
+ if ('undefined' === typeof dataType) {
516
+ dataType = 'json';
517
+ }
 
518
 
519
+ if (false !== showErrors) {
520
+ showErrors = true;
521
+ }
522
 
523
+ tryCount = 'undefined' === typeof tryCount ? 0 : tryCount;
524
+ var retryLimit = 10;
525
+ var retryTimeout = 10000 * tryCount;
526
+ incrementRatio = parseInt(incrementRatio);
 
 
 
 
527
 
528
+ if (!isNaN(incrementRatio)) {
529
+ retryTimeout *= incrementRatio;
530
+ }
531
 
532
+ $.ajax({
533
+ url: ajaxurl + '?action=wpstg_processing&_=' + Date.now() / 1000,
534
+ type: 'POST',
535
+ dataType: dataType,
536
+ cache: false,
537
+ data: data,
538
+ error: function error(xhr, textStatus, errorThrown) {
539
+ console.log(xhr.status + ' ' + xhr.statusText + '---' + textStatus); // try again after 10 seconds
540
+
541
+ tryCount++;
542
+
543
+ if (tryCount <= retryLimit) {
544
+ setTimeout(function () {
545
+ WPStagingLegacyDatabase.ajax(data, callback, dataType, showErrors, tryCount, incrementRatio);
546
+ return;
547
+ }, retryTimeout);
548
+ } else {
549
+ var errorCode = 'undefined' === typeof xhr.status ? 'Unknown' : xhr.status;
550
+ WPStagingLegacyDatabase.showError('Fatal Error: ' + errorCode + ' Please try the <a href=\'https://wp-staging.com/docs/wp-staging-settings-for-small-servers/\' target=\'_blank\'>WP Staging Small Server Settings</a> or submit an error report and contact us.');
551
  }
552
  },
553
+ success: function success(data) {
554
+ if ('function' === typeof callback) {
555
+ callback(data);
556
  }
557
  },
558
+ statusCode: {
559
+ 404: function _() {
560
+ if (tryCount >= retryLimit) {
561
+ WPStagingLegacyDatabase.showError('Error 404 - Can\'t find ajax request URL! Please try the <a href=\'https://wp-staging.com/docs/wp-staging-settings-for-small-servers/\' target=\'_blank\'>WP Staging Small Server Settings</a> or submit an error report and contact us.');
562
+ }
563
+ },
564
+ 500: function _() {
565
+ if (tryCount >= retryLimit) {
566
+ WPStagingLegacyDatabase.showError('Fatal Error 500 - Internal server error while processing the request! Please try the <a href=\'https://wp-staging.com/docs/wp-staging-settings-for-small-servers/\' target=\'_blank\'>WP Staging Small Server Settings</a> or submit an error report and contact us.');
567
+ }
568
+ },
569
+ 504: function _() {
570
+ if (tryCount > retryLimit) {
571
+ WPStagingLegacyDatabase.showError('Error 504 - It looks like your server is rate limiting ajax requests. Please try to resume after a minute. If this still not works try the <a href=\'https://wp-staging.com/docs/wp-staging-settings-for-small-servers/\' target=\'_blank\'>WP Staging Small Server Settings</a> or submit an error report and contact us.\n\ ');
572
+ }
573
+ },
574
+ 502: function _() {
575
+ if (tryCount >= retryLimit) {
576
+ WPStagingLegacyDatabase.showError('Error 502 - It looks like your server is rate limiting ajax requests. Please try to resume after a minute. If this still not works try the <a href=\'https://wp-staging.com/docs/wp-staging-settings-for-small-servers/\' target=\'_blank\'>WP Staging Small Server Settings</a> or submit an error report and contact us.\n\ ');
577
+ }
578
+ },
579
+ 503: function _() {
580
+ if (tryCount >= retryLimit) {
581
+ WPStagingLegacyDatabase.showError('Error 503 - It looks like your server is rate limiting ajax requests. Please try to resume after a minute. If this still not works try the <a href=\'https://wp-staging.com/docs/wp-staging-settings-for-small-servers/\' target=\'_blank\'>WP Staging Small Server Settings</a> or submit an error report and contact us.\n\ ');
582
+ }
583
+ },
584
+ 429: function _() {
585
+ if (tryCount >= retryLimit) {
586
+ WPStagingLegacyDatabase.showError('Error 429 - It looks like your server is rate limiting ajax requests. Please try to resume after a minute. If this still not works try the <a href=\'https://wp-staging.com/docs/wp-staging-settings-for-small-servers/\' target=\'_blank\'>WP Staging Small Server Settings</a> or submit an error report and contact us.\n\ ');
587
+ }
588
+ },
589
+ 403: function _() {
590
+ if (tryCount >= retryLimit) {
591
+ WPStagingLegacyDatabase.showError('Refresh page or login again! The process should be finished successfully. \n\ ');
592
+ }
593
  }
594
+ }
595
+ });
596
+ },
597
+ modal: {
598
+ create: {
599
+ html: null,
600
+ confirmBtnTxt: null
601
+ },
602
+ process: {
603
+ html: null,
604
+ cancelBtnTxt: null,
605
+ modal: null
606
+ },
607
+ download: {
608
+ html: null
609
+ },
610
+ "import": {
611
+ html: null,
612
+ btnTxtNext: null,
613
+ btnTxtConfirm: null,
614
+ btnTxtCancel: null,
615
+ searchReplaceForm: null,
616
+ file: null,
617
+ containerUpload: null,
618
+ containerFilesystem: null,
619
+ setFile: function setFile(file, upload) {
620
+ if (upload === void 0) {
621
+ upload = true;
622
  }
623
+
624
+ var toUnit = function toUnit(bytes) {
625
+ var i = Math.floor(Math.log(bytes) / Math.log(1024));
626
+ return (bytes / Math.pow(1024, i)).toFixed(2) * 1 + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i];
627
+ };
628
+
629
+ if (!file) {
630
+ return;
631
  }
632
+
633
+ WPStagingLegacyDatabase.modal["import"].file = file;
634
+ WPStagingLegacyDatabase.modal["import"].data.file = file.name;
635
+ console.log("File " + file.name);
636
+ $('.wpstg--backup--import--selected-file').html(file.name + " <br /> (" + toUnit(file.size) + ")").show();
637
+ $('.wpstg--drag').hide();
638
+ $('.wpstg--drag-or-upload').show();
639
+
640
+ if (upload) {
641
+ $('.wpstg--modal--actions .swal2-confirm').prop('disabled', true);
642
+ WPStagingLegacyDatabase.upload.start();
643
  }
644
  },
645
+ baseDirectory: null,
646
+ data: {
647
+ file: null,
648
+ search: [],
649
+ replace: []
650
  }
651
  }
 
 
 
 
 
 
 
 
 
 
 
652
  },
653
+ messages: {
654
+ WARNING: 'warning',
655
+ ERROR: 'error',
656
+ INFO: 'info',
657
+ DEBUG: 'debug',
658
+ CRITICAL: 'critical',
659
+ data: {
660
+ all: [],
661
+ // TODO RPoC
662
+ info: [],
663
+ error: [],
664
+ critical: [],
665
+ warning: [],
666
+ debug: []
667
+ },
668
+ shouldWarn: function shouldWarn() {
669
+ return WPStagingLegacyDatabase.messages.data.error.length > 0 || WPStagingLegacyDatabase.messages.data.critical.length > 0;
670
+ },
671
+ countByType: function countByType(type) {
672
+ if (type === void 0) {
673
+ type = WPStagingLegacyDatabase.messages.ERROR;
674
  }
675
 
676
+ return WPStagingLegacyDatabase.messages.data[type].length;
677
+ },
678
+ addMessage: function addMessage(message) {
679
+ if (Array.isArray(message)) {
680
+ message.forEach(function (item) {
681
+ WPStagingLegacyDatabase.messages.addMessage(item);
682
+ });
683
  return;
684
  }
685
 
686
+ var type = message.type.toLowerCase() || 'info';
 
 
 
 
 
687
 
688
+ if (!WPStagingLegacyDatabase.messages.data[type]) {
689
+ WPStagingLegacyDatabase.messages.data[type] = [];
 
690
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
691
 
692
+ WPStagingLegacyDatabase.messages.data.all.push(message); // TODO RPoC
693
 
694
+ WPStagingLegacyDatabase.messages.data[type].push(message);
695
+ },
696
+ reset: function reset() {
697
+ WPStagingLegacyDatabase.messages.data = {
698
+ all: [],
699
+ info: [],
700
+ error: [],
701
+ critical: [],
702
+ warning: [],
703
+ debug: []
704
+ };
705
  }
 
 
 
 
706
  },
707
+ timer: {
708
+ totalSeconds: 0,
709
+ interval: null,
710
+ start: function start() {
711
+ if (null !== WPStagingLegacyDatabase.timer.interval) {
712
+ return;
713
+ }
 
 
 
 
 
 
 
 
 
 
 
714
 
715
+ var prettify = function prettify(seconds) {
716
+ console.log("Process running for " + seconds + " seconds"); // If potentially anything can exceed 24h execution time than that;
717
+ // const _seconds = parseInt(seconds, 10)
718
+ // const hours = Math.floor(_seconds / 3600)
719
+ // const minutes = Math.floor(_seconds / 60) % 60
720
+ // seconds = _seconds % 60
721
+ //
722
+ // return [hours, minutes, seconds]
723
+ // .map(v => v < 10 ? '0' + v : v)
724
+ // .filter((v,i) => v !== '00' || i > 0)
725
+ // .join(':')
726
+ // ;
727
+ // Are we sure we won't create anything that exceeds 24h execution time? If not then this;
728
+
729
+ return "" + new Date(seconds * 1000).toISOString().substr(11, 8);
730
+ };
731
 
732
+ WPStagingLegacyDatabase.timer.interval = setInterval(function () {
733
+ $('.wpstg--modal--process--elapsed-time').text(prettify(WPStagingLegacyDatabase.timer.totalSeconds));
734
+ WPStagingLegacyDatabase.timer.totalSeconds++;
735
+ }, 1000);
736
+ },
737
+ stop: function stop() {
738
+ WPStagingLegacyDatabase.timer.totalSeconds = 0;
739
 
740
+ if (WPStagingLegacyDatabase.timer.interval) {
741
+ clearInterval(WPStagingLegacyDatabase.timer.interval);
742
+ WPStagingLegacyDatabase.timer.interval = null;
743
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
744
  }
 
 
 
745
  },
746
+ upload: {
747
+ reader: null,
748
+ file: null,
749
+ iop: 1000 * 1024,
750
+ uploadInfo: function uploadInfo(isShow) {
751
+ var $containerUpload = $('.wpstg--modal--import--upload--process');
752
+ var $containerUploader = $('.wpstg--uploader');
753
+
754
+ if (isShow) {
755
+ $containerUpload.css('display', 'flex');
756
+ $containerUploader.hide();
757
+ return;
758
+ }
 
 
759
 
760
+ $containerUploader.css('display', 'flex');
761
+ $containerUpload.hide();
762
+ },
763
+ start: function start() {
764
+ console.log("file " + WPStagingLegacyDatabase.modal["import"].data.file);
765
+ WPStagingLegacyDatabase.upload.reader = new FileReader();
766
+ WPStagingLegacyDatabase.upload.file = WPStagingLegacyDatabase.modal["import"].file;
767
+ WPStagingLegacyDatabase.upload.uploadInfo(true);
768
+ WPStagingLegacyDatabase.upload.sendChunk();
769
+ },
770
+ sendChunk: function sendChunk(startsAt) {
771
+ if (startsAt === void 0) {
772
+ startsAt = 0;
773
+ }
774
 
775
+ if (!WPStagingLegacyDatabase.upload.file) {
 
776
  return;
777
  }
778
 
779
+ var isReset = startsAt < 1;
780
+ var endsAt = startsAt + WPStagingLegacyDatabase.upload.iop + 1;
781
+ var blob = WPStagingLegacyDatabase.upload.file.slice(startsAt, endsAt);
 
 
 
 
 
 
 
 
 
 
 
 
782
 
783
+ WPStagingLegacyDatabase.upload.reader.onloadend = function (event) {
784
+ if (event.target.readyState !== FileReader.DONE) {
 
 
785
  return;
786
  }
787
 
788
+ var body = new FormData();
789
+ body.append('accessToken', wpstg.accessToken);
790
+ body.append('nonce', wpstg.nonce);
791
+ body.append('data', event.target.result);
792
+ body.append('filename', WPStagingLegacyDatabase.upload.file.name);
793
+ body.append('reset', isReset ? '1' : '0');
794
+ fetch(ajaxurl + "?action=wpstg--backups--import--file-upload", {
795
+ method: 'POST',
796
+ body: body
797
+ }).then(WPStagingLegacyDatabase.handleFetchErrors).then(function (res) {
798
+ return res.json();
799
+ }).then(function (res) {
800
+ WPStagingLegacyDatabase.showAjaxFatalError(res, '', 'Submit an error report.');
801
+ var writtenBytes = startsAt + WPStagingLegacyDatabase.upload.iop;
802
+ var percent = Math.floor(writtenBytes / WPStagingLegacyDatabase.upload.file.size * 100);
803
+
804
+ if (endsAt >= WPStagingLegacyDatabase.upload.file.size) {
805
+ WPStagingLegacyDatabase.upload.uploadInfo(false);
806
+ WPStagingLegacyDatabase.isLoading(false);
807
+ $('.wpstg--modal--actions .swal2-confirm').prop('disabled', false);
808
+ return;
809
+ }
810
+
811
+ $('.wpstg--modal--import--upload--progress--title > span').text(percent);
812
+ $('.wpstg--modal--import--upload--progress').css('width', percent + "%");
813
+ WPStagingLegacyDatabase.upload.sendChunk(endsAt);
814
+ })["catch"](function (e) {
815
+ return WPStagingLegacyDatabase.showAjaxFatalError(e, '', 'Submit an error report.');
816
+ });
817
+ };
818
 
819
+ WPStagingLegacyDatabase.upload.reader.readAsDataURL(blob);
820
+ }
821
+ },
822
+ status: {
823
+ hasResponse: null,
824
+ reTryAfter: 5000
825
+ },
826
+ fetchListing: function fetchListing(isResetErrors) {
827
+ if (isResetErrors === void 0) {
828
+ isResetErrors = true;
829
+ }
830
 
831
+ WPStagingLegacyDatabase.isLoading(true);
832
 
833
+ if (isResetErrors) {
834
+ WPStagingLegacyDatabase.resetErrors();
835
+ }
836
 
837
+ return fetch(ajaxurl + "?action=wpstg--backups--database-legacy-listing&_=" + Math.random() + "&accessToken=" + wpstg.accessToken + "&nonce=" + wpstg.nonce).then(WPStagingLegacyDatabase.handleFetchErrors).then(function (res) {
838
+ return res.json();
839
+ }).then(function (res) {
840
+ WPStagingLegacyDatabase.showAjaxFatalError(res, '', 'Submit an error report.');
841
+ WPStagingLegacyDatabase.cache.get('#wpstg--tab--database-backups').html(res);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
842
  WPStagingLegacyDatabase.isLoading(false);
843
+ return res;
844
+ })["catch"](function (e) {
845
+ return WPStagingLegacyDatabase.showAjaxFatalError(e, '', 'Submit an error report.');
846
  });
847
+ },
848
+ "delete": function _delete() {
849
+ $('#wpstg--tab--database-backups').off('click', '.wpstg-delete-backup[data-id]').on('click', '.wpstg-delete-backup[data-id]', function (e) {
850
+ e.preventDefault();
851
+ WPStagingLegacyDatabase.resetErrors();
852
+ WPStagingLegacyDatabase.isLoading(true);
853
+ WPStagingLegacyDatabase.cache.get('#wpstg-existing-database-backups').hide();
854
+ var id = this.getAttribute('data-id');
855
+ WPStagingLegacyDatabase.ajax({
856
+ action: 'wpstg--backups--database-legacy-delete-confirm',
857
+ id: id,
858
+ accessToken: wpstg.accessToken,
859
+ nonce: wpstg.nonce
860
+ }, function (response) {
861
+ WPStagingLegacyDatabase.showAjaxFatalError(response, '', ' Please submit an error report by using the REPORT ISSUE button.');
862
+ WPStagingLegacyDatabase.isLoading(false);
863
+ WPStagingLegacyDatabase.cache.get('#wpstg-delete-confirmation').html(response);
864
+ });
865
+ }) // Delete final confirmation page
866
+ .off('click', '#wpstg-delete-backup').on('click', '#wpstg-delete-backup', function (e) {
867
+ e.preventDefault();
868
+ WPStagingLegacyDatabase.resetErrors();
869
+ WPStagingLegacyDatabase.isLoading(true);
870
+ var id = this.getAttribute('data-id');
871
+ WPStagingLegacyDatabase.ajax({
872
+ action: 'wpstg--backups--database-legacy-delete',
873
+ id: id,
874
+ accessToken: wpstg.accessToken,
875
+ nonce: wpstg.nonce
876
+ }, function (response) {
877
+ WPStagingLegacyDatabase.showAjaxFatalError(response, '', ' Please submit an error report by using the REPORT ISSUE button.'); // noinspection JSIgnoredPromiseFromCall
878
 
879
+ WPStagingLegacyDatabase.fetchListing();
880
+ WPStagingLegacyDatabase.isLoading(false);
881
+ });
882
+ }).off('click', '#wpstg-cancel-backup-delete').on('click', '#wpstg-cancel-backup-delete', function (e) {
883
+ e.preventDefault();
884
+ WPStagingLegacyDatabase.isLoading(false); // noinspection JSIgnoredPromiseFromCall
885
 
886
+ WPStagingLegacyDatabase.fetchListing();
887
+ }); // Force delete if backup tables do not exist
888
+ // TODO This is bloated, no need extra ID, use existing one?
889
 
890
+ $('#wpstg-error-wrapper').off('click', '#wpstg-backup-force-delete').on('click', '#wpstg-backup-force-delete', function (e) {
891
+ e.preventDefault();
892
+ WPStagingLegacyDatabase.resetErrors();
893
+ WPStagingLegacyDatabase.isLoading(true);
894
+ var id = this.getAttribute('data-id');
895
 
896
+ if (!confirm('Do you want to delete this backup ' + id + ' from the listed backups?')) {
897
+ WPStagingLegacyDatabase.isLoading(false);
898
+ return false;
899
+ }
900
 
901
+ WPStagingLegacyDatabase.ajax({
902
+ action: 'wpstg--backups--database-legacy-delete',
903
+ id: id,
904
+ accessToken: wpstg.accessToken,
905
+ nonce: wpstg.nonce
906
+ }, function (response) {
907
+ WPStagingLegacyDatabase.showAjaxFatalError(response, '', ' Please submit an error report by using the REPORT ISSUE button.'); // noinspection JSIgnoredPromiseFromCall
908
 
909
+ WPStagingLegacyDatabase.fetchListing();
910
+ WPStagingLegacyDatabase.isLoading(false);
911
+ });
912
  });
913
+ },
914
+ restore: function restore() {
915
+ var restoreBackup = function restoreBackup(prefix, reset) {
916
+ WPStagingLegacyDatabase.isLoading(true);
917
+ WPStagingLegacyDatabase.resetErrors();
 
918
 
919
+ if (typeof reset === 'undefined') {
920
+ reset = false;
921
+ }
922
 
923
+ WPStaging.ajax({
924
+ action: 'wpstg--backups--database-legacy-restore',
925
+ accessToken: wpstg.accessToken,
926
+ nonce: wpstg.nonce,
927
+ wpstg: {
928
+ tasks: {
929
+ backup: {
930
+ database: {
931
+ create: {
932
+ source: prefix,
933
+ reset: reset
934
+ }
935
  }
936
  }
937
  }
938
  }
939
+ }, function (response) {
940
+ if (typeof response === 'undefined') {
941
+ setTimeout(function () {
942
+ restoreBackup(prefix);
943
+ }, wpstg.delayReq);
944
+ return;
945
+ }
 
 
 
946
 
947
+ WPStagingLegacyDatabase.processResponse(response);
 
 
 
 
 
 
948
 
949
+ if (response.status === false || response.job_done === false) {
 
 
 
 
950
  restoreBackup(prefix);
951
+ } else if (response.status === true && response.job_done === true) {
952
+ WPStagingLegacyDatabase.isLoading(false);
953
+ $('.wpstg--modal--process--title').text('Backup successfully restored');
954
+ setTimeout(function () {
955
+ Swal.close(); // noinspection JSIgnoredPromiseFromCall
956
+
957
+ alert('Backup successfully restored. Please log-in again to WordPress.');
958
+ WPStagingLegacyDatabase.fetchListing();
959
+ }, 1000);
960
+ } else {
961
+ setTimeout(function () {
962
+ restoreBackup(prefix);
963
+ }, wpstg.delayReq);
964
+ }
965
+ }, 'json', false, 0, 1.25);
966
+ };
 
 
 
967
 
968
+ $('#wpstg--tab--database-backups').off('click', '.wpstg--backup--restore[data-id]').on('click', '.wpstg--backup--restore[data-id]', function (e) {
969
+ e.preventDefault();
970
+ WPStagingLegacyDatabase.resetErrors();
971
+ WPStagingLegacyDatabase.ajax({
972
+ action: 'wpstg--backups--database-legacy-restore-confirm',
973
+ accessToken: wpstg.accessToken,
974
+ nonce: wpstg.nonce,
975
+ id: $(this).data('id')
976
+ }, function (data) {
977
+ WPStagingLegacyDatabase.cache.get('#wpstg--tab--database-backups').html(data);
978
+ });
979
+ }).off('click', '#wpstg--backup--restore--cancel').on('click', '#wpstg--backup--restore--cancel', function (e) {
980
+ WPStagingLegacyDatabase.resetErrors();
981
+ e.preventDefault(); // noinspection JSIgnoredPromiseFromCall
982
+
983
+ WPStagingLegacyDatabase.fetchListing();
984
+ }).off('click', '#wpstg--backup--restore[data-id]').on('click', '#wpstg--backup--restore[data-id]', function (e) {
985
+ e.preventDefault();
986
+ WPStagingLegacyDatabase.resetErrors();
987
+ var id = this.getAttribute('data-id');
988
+ WPStagingLegacyDatabase.process({
989
+ execute: function execute() {
990
+ WPStagingLegacyDatabase.messages.reset();
991
+ restoreBackup(id, true);
992
+ },
993
+ isShowCancelButton: false
994
+ });
995
  });
996
+ },
997
+ // Edit backups name and notes
998
+ edit: function edit() {
999
+ $('#wpstg--tab--database-backups').off('click', '.wpstg--backup--edit[data-id]').on('click', '.wpstg--backup--edit[data-id]', /*#__PURE__*/function () {
1000
+ var _ref2 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(e) {
1001
+ var name, notes, _yield$Swal$fire2, formValues;
1002
+
1003
+ return regeneratorRuntime.wrap(function _callee2$(_context2) {
1004
+ while (1) {
1005
+ switch (_context2.prev = _context2.next) {
1006
+ case 0:
1007
+ e.preventDefault();
1008
+ name = $(this).data('name');
1009
+ notes = $(this).data('notes');
1010
+ _context2.next = 5;
1011
+ return Swal.fire({
1012
+ title: '',
1013
+ html: "\n <label id=\"wpstg-backup-edit-name\">Backup Name</label>\n <input id=\"wpstg-backup-edit-name-input\" class=\"swal2-input\" value=\"" + name + "\">\n <label>Additional Notes</label>\n <textarea id=\"wpstg-backup-edit-notes-textarea\" class=\"swal2-textarea\">" + notes + "</textarea>\n ",
1014
+ focusConfirm: false,
1015
+ confirmButtonText: 'Update Backup',
1016
+ showCancelButton: true,
1017
+ preConfirm: function preConfirm() {
1018
+ return {
1019
+ name: document.getElementById('wpstg-backup-edit-name-input').value || null,
1020
+ notes: document.getElementById('wpstg-backup-edit-notes-textarea').value || null
1021
+ };
1022
+ }
1023
+ });
1024
+
1025
+ case 5:
1026
+ _yield$Swal$fire2 = _context2.sent;
1027
+ formValues = _yield$Swal$fire2.value;
1028
+
1029
+ if (formValues) {
1030
+ _context2.next = 9;
1031
+ break;
1032
  }
 
1033
 
1034
+ return _context2.abrupt("return");
1035
+
1036
+ case 9:
1037
+ WPStagingLegacyDatabase.ajax({
1038
+ action: 'wpstg--backups--database-legacy-edit',
1039
+ accessToken: wpstg.accessToken,
1040
+ nonce: wpstg.nonce,
1041
+ id: $(this).data('id'),
1042
+ name: formValues.name,
1043
+ notes: formValues.notes
1044
+ }, function (response) {
1045
+ WPStagingLegacyDatabase.showAjaxFatalError(response, '', 'Submit an error report.'); // noinspection JSIgnoredPromiseFromCall
1046
+
1047
+ WPStagingLegacyDatabase.fetchListing();
1048
+ });
1049
+
1050
+ case 10:
1051
+ case "end":
1052
+ return _context2.stop();
1053
+ }
 
 
 
 
 
 
 
 
1054
  }
1055
+ }, _callee2, this);
1056
+ }));
 
1057
 
1058
+ return function (_x2) {
1059
+ return _ref2.apply(this, arguments);
1060
+ };
1061
+ }());
1062
+ },
1063
+ cancel: function cancel() {
1064
+ WPStagingLegacyDatabase.timer.stop();
1065
+ WPStagingLegacyDatabase.isCancelled = true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1066
  Swal.close();
1067
+ setTimeout(function () {
1068
+ return WPStagingLegacyDatabase.ajax({
1069
+ action: 'wpstg--backups--cancel',
1070
+ accessToken: wpstg.accessToken,
1071
+ nonce: wpstg.nonce,
1072
+ type: WPStagingLegacyDatabase.type
1073
+ }, function (response) {
1074
+ WPStagingLegacyDatabase.showAjaxFatalError(response, '', 'Submit an error report.');
1075
+ });
1076
+ }, 500);
1077
+ },
1078
+
1079
+ /**
1080
+ * If process.execute exists, process.data and process.onResponse is not used
1081
+ * process = { data: {}, onResponse: (resp) => {}, onAfterClose: () => {}, execute: () => {}, isShowCancelButton: bool }
1082
+ * @param {object} process
1083
+ */
1084
+ process: function process(_process) {
1085
+ if (typeof _process.execute !== 'function' && (!_process.data || !_process.onResponse)) {
1086
+ Swal.close();
1087
+ WPStagingLegacyDatabase.showError('process.data and / or process.onResponse is not set');
1088
+ return;
1089
+ } // TODO move to backend and get the contents as xhr response?
1090
 
 
 
 
 
 
1091
 
1092
+ if (!WPStagingLegacyDatabase.modal.process.html || !WPStagingLegacyDatabase.modal.process.cancelBtnTxt) {
1093
+ var $modal = $('#wpstg--modal--backup--process');
1094
+ var html = $modal.html();
1095
+ var btnTxt = $modal.attr('data-cancelButtonText');
1096
+ WPStagingLegacyDatabase.modal.process.html = html || null;
1097
+ WPStagingLegacyDatabase.modal.process.cancelBtnTxt = btnTxt || null;
1098
+ $modal.remove();
1099
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1100
 
1101
+ $('body').off('click', '.wpstg--modal--process--logs--tail').on('click', '.wpstg--modal--process--logs--tail', function (e) {
1102
+ e.preventDefault();
1103
+ var container = Swal.getContainer();
1104
+ var $logs = $(container).find('.wpstg--modal--process--logs');
1105
+ $logs.toggle();
1106
 
1107
+ if ($logs.is(':visible')) {
1108
+ container.childNodes[0].style.width = '100%';
1109
+ container.style['z-index'] = 9999;
1110
+ } else {
1111
+ container.childNodes[0].style.width = '600px';
1112
  }
1113
+ });
1114
+ _process.isShowCancelButton = false !== _process.isShowCancelButton;
1115
+ WPStagingLegacyDatabase.modal.process.modal = Swal.mixin({
1116
+ customClass: {
1117
+ cancelButton: 'wpstg--btn--cancel wpstg-blue-primary wpstg-link-btn',
1118
+ content: 'wpstg--process--content'
1119
+ },
1120
+ buttonsStyling: false
1121
+ }).fire({
1122
+ html: WPStagingLegacyDatabase.modal.process.html,
1123
+ cancelButtonText: WPStagingLegacyDatabase.modal.process.cancelBtnTxt,
1124
+ showCancelButton: _process.isShowCancelButton,
1125
+ showConfirmButton: false,
1126
+ allowOutsideClick: false,
1127
+ allowEscapeKey: false,
1128
+ width: 600,
1129
+ onRender: function onRender() {
1130
+ var _btnCancel = Swal.getContainer().getElementsByClassName('swal2-cancel wpstg--btn--cancel')[0];
1131
 
1132
+ var btnCancel = _btnCancel.cloneNode(true);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1133
 
1134
+ _btnCancel.parentNode.replaceChild(btnCancel, _btnCancel);
 
 
 
 
1135
 
1136
+ btnCancel.addEventListener('click', function (e) {
1137
+ if (confirm('Are You Sure? This will cancel the process!')) {
1138
+ Swal.close();
1139
+ }
1140
+ });
1141
 
1142
+ if (typeof _process.execute === 'function') {
1143
+ _process.execute();
 
 
1144
 
1145
+ return;
1146
+ }
1147
 
1148
+ if (!_process.data || !_process.onResponse) {
1149
+ Swal.close();
1150
+ WPStagingLegacyDatabase.showError('process.data and / or process.onResponse is not set');
1151
+ return;
 
1152
  }
1153
 
1154
+ WPStagingLegacyDatabase.ajax(_process.data, _process.onResponse);
1155
+ },
1156
+ onAfterClose: function onAfterClose() {
1157
+ return typeof _process.onAfterClose === 'function' && _process.onAfterClose();
1158
+ },
1159
+ onClose: function onClose() {
1160
+ console.log('cancelled');
1161
+ WPStagingLegacyDatabase.cancel();
1162
  }
1163
+ });
1164
+ },
1165
+ processResponse: function processResponse(response, useTitle) {
1166
+ if (response === null) {
1167
+ Swal.close();
1168
+ WPStagingLegacyDatabase.showError('Invalid Response; null');
1169
+ throw new Error("Invalid Response; " + response);
1170
+ }
1171
 
1172
+ var $container = $(Swal.getContainer());
 
1173
 
1174
+ var title = function title() {
1175
+ if ((response.title || response.statusTitle) && useTitle === true) {
1176
+ $container.find('.wpstg--modal--process--title').text(response.title || response.statusTitle);
1177
  }
1178
  };
1179
 
1180
+ var percentage = function percentage() {
1181
+ if (response.percentage) {
1182
+ $container.find('.wpstg--modal--process--percent').text(response.percentage);
1183
+ }
1184
+ };
1185
 
1186
+ var logs = function logs() {
1187
+ if (!response.messages) {
1188
+ return;
1189
  }
1190
 
1191
+ var $logsContainer = $container.find('.wpstg--modal--process--logs');
1192
+ var stoppingTypes = [WPStagingLegacyDatabase.messages.ERROR, WPStagingLegacyDatabase.messages.CRITICAL];
 
1193
 
1194
+ var appendMessage = function appendMessage(message) {
1195
+ if (Array.isArray(message)) {
1196
+ for (var _iterator = _createForOfIteratorHelperLoose(message), _step; !(_step = _iterator()).done;) {
1197
+ var item = _step.value;
1198
+ appendMessage(item);
1199
+ }
1200
 
1201
+ return;
1202
+ }
1203
+
1204
+ var msgClass = "wpstg--modal--process--msg--" + message.type.toLowerCase();
1205
+ $logsContainer.append("<p class=\"" + msgClass + "\">[" + message.type + "] - [" + message.date + "] - " + message.message + "</p>");
1206
 
1207
+ if (stoppingTypes.includes(message.type.toLowerCase())) {
1208
+ WPStagingLegacyDatabase.cancel();
1209
+ setTimeout(WPStagingLegacyDatabase.logsModal, 500);
1210
+ }
1211
+ };
 
1212
 
1213
+ for (var _iterator2 = _createForOfIteratorHelperLoose(response.messages), _step2; !(_step2 = _iterator2()).done;) {
1214
+ var message = _step2.value;
 
1215
 
1216
+ if (!message) {
1217
+ continue;
1218
+ }
1219
+
1220
+ WPStagingLegacyDatabase.messages.addMessage(message);
1221
+ appendMessage(message);
1222
+ }
1223
+
1224
+ if ($logsContainer.is(':visible')) {
1225
+ $logsContainer.scrollTop($logsContainer[0].scrollHeight);
1226
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1227
 
1228
  if (!WPStagingLegacyDatabase.messages.shouldWarn()) {
1229
+ return;
1230
  }
1231
 
1232
+ var $btnShowLogs = $container.find('.wpstg--modal--process--logs--tail');
1233
+ $btnShowLogs.html($btnShowLogs.attr('data-txt-bad'));
1234
+ $btnShowLogs.find('.wpstg--modal--logs--critical-count').text(WPStagingLegacyDatabase.messages.countByType(WPStagingLegacyDatabase.messages.CRITICAL));
1235
+ $btnShowLogs.find('.wpstg--modal--logs--error-count').text(WPStagingLegacyDatabase.messages.countByType(WPStagingLegacyDatabase.messages.ERROR));
1236
+ $btnShowLogs.find('.wpstg--modal--logs--warning-count').text(WPStagingLegacyDatabase.messages.countByType(WPStagingLegacyDatabase.messages.WARNING));
1237
+ };
1238
 
1239
+ title();
1240
+ percentage();
1241
+ logs();
1242
 
1243
+ if (response.status === true && response.job_done === true) {
1244
+ WPStagingLegacyDatabase.timer.stop();
1245
+ WPStagingLegacyDatabase.isCancelled = true;
 
 
 
1246
  }
1247
+ },
1248
+ requestData: function requestData(notation, data) {
1249
+ var obj = {};
1250
+ var keys = notation.split('.');
1251
+ var lastIndex = keys.length - 1;
1252
+ keys.reduce(function (accumulated, current, index) {
1253
+ return accumulated[current] = index >= lastIndex ? data : {};
1254
+ }, obj);
1255
+ return obj;
1256
+ },
1257
+ logsModal: function logsModal() {
1258
+ Swal.fire({
1259
+ html: "<div class=\"wpstg--modal--error--logs\" style=\"display:block\"></div><div class=\"wpstg--modal--process--logs\" style=\"display:block\"></div>",
1260
+ width: '95%',
 
 
 
 
 
 
 
 
 
 
 
 
 
1261
  onRender: function onRender() {
1262
+ var $container = $(Swal.getContainer());
1263
+ $container[0].style['z-index'] = 9999;
1264
+ var $logsContainer = $container.find('.wpstg--modal--process--logs');
1265
+ var $errorContainer = $container.find('.wpstg--modal--error--logs');
1266
+ var $translations = $('#wpstg--js--translations');
1267
+ var messages = WPStagingLegacyDatabase.messages;
1268
+ var title = $translations.attr('data-modal-logs-title').replace('{critical}', messages.countByType(messages.CRITICAL)).replace('{errors}', messages.countByType(messages.ERROR)).replace('{warnings}', messages.countByType(messages.WARNING));
1269
+ $errorContainer.before("<h3>" + title + "</h3>");
1270
+ var warnings = [WPStagingLegacyDatabase.messages.CRITICAL, WPStagingLegacyDatabase.messages.ERROR, WPStagingLegacyDatabase.messages.WARNING];
1271
+
1272
+ if (!WPStagingLegacyDatabase.messages.shouldWarn()) {
1273
+ $errorContainer.hide();
1274
+ }
1275
+
1276
+ for (var _iterator3 = _createForOfIteratorHelperLoose(messages.data.all), _step3; !(_step3 = _iterator3()).done;) {
1277
+ var message = _step3.value;
1278
+ var msgClass = "wpstg--modal--process--msg--" + message.type.toLowerCase(); // TODO RPoC
1279
+
1280
+ if (warnings.includes(message.type)) {
1281
+ $errorContainer.append("<p class=\"" + msgClass + "\">[" + message.type + "] - [" + message.date + "] - " + message.message + "</p>");
1282
  }
1283
 
1284
+ $logsContainer.append("<p class=\"" + msgClass + "\">[" + message.type + "] - [" + message.date + "] - " + message.message + "</p>");
1285
+ }
1286
+ },
1287
+ onOpen: function onOpen(container) {
1288
+ var $logsContainer = $(container).find('.wpstg--modal--process--logs');
1289
+ $logsContainer.scrollTop($logsContainer[0].scrollHeight);
 
 
1290
  }
1291
  });
1292
+ },
1293
+ downloadModal: function downloadModal(_ref3) {
1294
+ var _ref3$title = _ref3.title,
1295
+ title = _ref3$title === void 0 ? null : _ref3$title,
1296
+ _ref3$titleExport = _ref3.titleExport,
1297
+ titleExport = _ref3$titleExport === void 0 ? null : _ref3$titleExport,
1298
+ _ref3$id = _ref3.id,
1299
+ id = _ref3$id === void 0 ? null : _ref3$id,
1300
+ _ref3$url = _ref3.url,
1301
+ url = _ref3$url === void 0 ? null : _ref3$url,
1302
+ _ref3$btnTxtCancel = _ref3.btnTxtCancel,
1303
+ btnTxtCancel = _ref3$btnTxtCancel === void 0 ? 'Cancel' : _ref3$btnTxtCancel,
1304
+ _ref3$btnTxtConfirm = _ref3.btnTxtConfirm,
1305
+ btnTxtConfirm = _ref3$btnTxtConfirm === void 0 ? 'Download' : _ref3$btnTxtConfirm;
1306
+
1307
+ if (null === WPStagingLegacyDatabase.modal.download.html) {
1308
+ var $el = $('#wpstg--modal--backup--download');
1309
+ WPStagingLegacyDatabase.modal.download.html = $el.html();
1310
+ $el.remove();
 
 
 
 
 
1311
  }
1312
 
1313
+ var exportModal = function exportModal() {
1314
+ return Swal.fire({
1315
+ html: "<h2>" + titleExport + "</h2><span class=\"wpstg-loader\"></span>",
1316
+ showCancelButton: false,
1317
+ showConfirmButton: false,
1318
+ onRender: function onRender() {
1319
+ WPStagingLegacyDatabase.ajax({
1320
+ action: 'wpstg--backups--database-legacy-export',
1321
+ accessToken: wpstg.accessToken,
1322
+ nonce: wpstg.nonce,
1323
+ id: id
1324
+ }, function (response) {
1325
+ console.log(response);
1326
+
1327
+ if (!response || !response.success || !response.data || response.data.length < 1) {
1328
+ return;
1329
+ }
1330
 
1331
+ var a = document.createElement('a');
1332
+ a.style.display = 'none';
1333
+ a.href = response.data;
1334
+ document.body.appendChild(a);
1335
+ a.click();
1336
+ document.body.removeChild(a);
1337
+ Swal.close();
1338
+ });
1339
+ }
1340
+ });
1341
+ };
1342
 
1343
+ Swal.mixin({
1344
+ customClass: {
1345
+ cancelButton: 'wpstg--btn--cancel wpstg-blue-primary wpstg-link-btn',
1346
+ confirmButton: 'wpstg--btn--confirm wpstg-blue-primary wpstg-button wpstg-link-btn',
1347
+ actions: 'wpstg--modal--actions'
1348
+ },
1349
+ buttonsStyling: false
1350
+ }).fire({
1351
+ icon: 'success',
1352
+ html: WPStagingLegacyDatabase.modal.download.html.replace('{title}', title).replace('{btnTxtLog}', 'Show Logs'),
1353
+ cancelButtonText: btnTxtCancel,
1354
+ confirmButtonText: btnTxtConfirm,
1355
+ showCancelButton: true,
1356
+ showConfirmButton: true
1357
+ }).then(function (isConfirm) {
1358
+ if (!isConfirm || !isConfirm.value) {
1359
+ return;
1360
+ }
1361
 
1362
+ if (url && url.length > 0) {
1363
+ window.location.href = url;
1364
+ return;
1365
+ }
1366
 
1367
+ exportModal();
1368
+ });
1369
+ },
1370
+ importModal: function importModal() {
1371
+ var restoreSiteBackup = function restoreSiteBackup(data) {
1372
+ WPStagingLegacyDatabase.resetErrors();
1373
 
1374
+ if (WPStagingLegacyDatabase.isCancelled) {
1375
+ console.log('cancelled'); // Swal.close();
 
 
 
1376
 
 
 
1377
  return;
1378
  }
1379
 
1380
+ var reset = data['reset'];
1381
+ delete data['reset'];
1382
+ data['mergeMediaFiles'] = 1; // always merge for uploads / media
 
 
 
1383
 
1384
+ var requestData = Object.assign({}, data);
1385
+ requestData = WPStagingLegacyDatabase.requestData('jobs.backup.site.restore', _extends({}, WPStagingLegacyDatabase.modal["import"].data));
1386
+ WPStagingLegacyDatabase.timer.start();
1387
+
1388
+ var statusStop = function statusStop() {
1389
+ console.log('Status: Stop');
1390
+ clearInterval(WPStagingLegacyDatabase.processInfo.interval);
1391
+ WPStagingLegacyDatabase.processInfo.interval = null;
1392
+ };
1393
+
1394
+ var status = function status() {
1395
+ if (WPStagingLegacyDatabase.processInfo.interval !== null) {
1396
  return;
1397
  }
1398
 
1399
+ console.log('Status: Start');
1400
+ WPStagingLegacyDatabase.processInfo.interval = setInterval(function () {
1401
+ if (true === WPStagingLegacyDatabase.isCancelled) {
 
 
 
 
1402
  statusStop();
1403
+ return;
1404
  }
1405
 
1406
+ if (WPStagingLegacyDatabase.status.hasResponse === false) {
1407
  return;
1408
  }
1409
 
1410
+ WPStagingLegacyDatabase.status.hasResponse = false;
1411
+ fetch(ajaxurl + "?action=wpstg--backups--status&process=restore&accessToken=" + wpstg.accessToken + "&nonce=" + wpstg.nonce).then(function (res) {
1412
+ return res.json();
1413
+ }).then(function (res) {
1414
+ WPStagingLegacyDatabase.status.hasResponse = true;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1415
 
1416
+ if (typeof res === 'undefined') {
1417
+ statusStop();
1418
+ }
1419
 
1420
+ if (WPStagingLegacyDatabase.processInfo.title === res.currentStatusTitle) {
1421
+ return;
1422
+ }
1423
 
1424
+ WPStagingLegacyDatabase.processInfo.title = res.currentStatusTitle;
1425
+ var $container = $(Swal.getContainer());
1426
+ $container.find('.wpstg--modal--process--title').text(res.currentStatusTitle);
1427
+ $container.find('.wpstg--modal--process--percent').text('0');
1428
+ })["catch"](function (e) {
1429
+ WPStagingLegacyDatabase.status.hasResponse = true;
1430
+ WPStagingLegacyDatabase.showAjaxFatalError(e, '', 'Submit an error report.');
1431
+ });
1432
+ }, 5000);
1433
+ };
1434
 
1435
+ WPStaging.ajax({
1436
+ action: 'wpstg--backups--database-legacy-restore',
1437
+ accessToken: wpstg.accessToken,
1438
+ nonce: wpstg.nonce,
1439
+ reset: reset,
1440
+ wpstg: requestData
1441
+ }, function (response) {
1442
+ if (typeof response === 'undefined') {
1443
+ setTimeout(function () {
1444
+ restoreSiteBackup(data);
1445
+ }, wpstg.delayReq);
1446
  return;
1447
  }
1448
 
1449
+ WPStagingLegacyDatabase.processResponse(response, true);
 
 
 
 
 
 
1450
 
1451
+ if (!WPStagingLegacyDatabase.processInfo.interval) {
1452
+ status();
1453
+ }
 
 
1454
 
1455
+ if (response.status === false) {
 
 
1456
  restoreSiteBackup(data);
1457
+ } else if (response.status === true) {
1458
+ $('#wpstg--progress--status').text('Backup successfully restored!');
1459
+ WPStagingLegacyDatabase.type = null;
1460
+
1461
+ if (WPStagingLegacyDatabase.messages.shouldWarn()) {
1462
+ // noinspection JSIgnoredPromiseFromCall
1463
+ WPStagingLegacyDatabase.fetchListing();
1464
+ WPStagingLegacyDatabase.logsModal();
1465
+ return;
1466
+ }
 
 
 
 
 
 
 
 
 
 
1467
 
1468
+ statusStop();
1469
+ var logEntries = $('.wpstg--modal--process--logs').get(1).innerHTML;
1470
+ var html = '<div class="wpstg--modal--process--logs">' + logEntries + '</div>';
1471
+ var issueFound = html.includes('wpstg--modal--process--msg--warning') || html.includes('wpstg--modal--process--msg--error') ? 'Issues(s) found! ' : '';
1472
+ console.log('errors found: ' + issueFound); // var errorMessage = html.includes('wpstg--modal--process--msg--error') ? 'Errors(s) found! ' : '';
1473
+ // var Message = warningMessage + errorMessage;
1474
+ // Swal.close();
1475
+
1476
+ Swal.fire({
1477
+ icon: 'success',
1478
+ title: 'Finished',
1479
+ html: 'System restored from backup. <br/><span class="wpstg--modal--process--msg-found">' + issueFound + '</span><button class="wpstg--modal--process--logs--tail" data-txt-bad="">Show Logs</button><br/>' + html
1480
+ }); // noinspection JSIgnoredPromiseFromCall
1481
+
1482
+ WPStagingLegacyDatabase.fetchListing();
1483
+ } else {
1484
+ setTimeout(function () {
1485
+ restoreSiteBackup(data);
1486
+ }, wpstg.delayReq);
1487
+ }
1488
+ }, 'json', false, 0, // Don't retry upon failure
1489
+ 1.25);
1490
+ };
1491
+
1492
+ if (!WPStagingLegacyDatabase.modal["import"].html) {
1493
+ var $modal = $('#wpstg--modal--backup--import'); // Search & Replace Form
1494
+
1495
+ var $form = $modal.find('.wpstg--modal--backup--import--search-replace--input--container');
1496
+ WPStagingLegacyDatabase.modal["import"].searchReplaceForm = $form.html();
1497
+ $form.find('.wpstg--modal--backup--import--search-replace--input-group').remove();
1498
+ $form.html(WPStagingLegacyDatabase.modal["import"].searchReplaceForm.replace(/{i}/g, 0));
1499
+ WPStagingLegacyDatabase.modal["import"].html = $modal.html();
1500
+ WPStagingLegacyDatabase.modal["import"].baseDirectory = $modal.attr('data-baseDirectory');
1501
+ WPStagingLegacyDatabase.modal["import"].btnTxtNext = $modal.attr('data-nextButtonText');
1502
+ WPStagingLegacyDatabase.modal["import"].btnTxtConfirm = $modal.attr('data-confirmButtonText');
1503
+ WPStagingLegacyDatabase.modal["import"].btnTxtCancel = $modal.attr('data-cancelButtonText');
1504
+ $modal.remove();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1505
  }
1506
 
1507
+ WPStagingLegacyDatabase.modal["import"].data.search = [];
1508
+ WPStagingLegacyDatabase.modal["import"].data.replace = [];
1509
+ var $btnConfirm = null;
1510
+ Swal.mixin({
1511
+ customClass: {
1512
+ confirmButton: 'wpstg--btn--confirm wpstg-blue-primary wpstg-button wpstg-link-btn',
1513
+ cancelButton: 'wpstg--btn--cancel wpstg-blue-primary wpstg-link-btn',
1514
+ actions: 'wpstg--modal--actions'
1515
+ },
1516
+ buttonsStyling: false // progressSteps: ['1', '2']
1517
+
1518
+ }).queue([{
1519
+ html: WPStagingLegacyDatabase.modal["import"].html,
1520
+ confirmButtonText: WPStagingLegacyDatabase.modal["import"].btnTxtNext,
1521
+ showCancelButton: false,
1522
+ showConfirmButton: true,
1523
+ showLoaderOnConfirm: true,
1524
+ width: 650,
1525
+ onRender: function onRender() {
1526
+ $btnConfirm = $('.wpstg--modal--actions .swal2-confirm');
1527
+ $btnConfirm.prop('disabled', true);
1528
+ WPStagingLegacyDatabase.modal["import"].containerUpload = $('.wpstg--modal--backup--import--upload');
1529
+ WPStagingLegacyDatabase.modal["import"].containerFilesystem = $('.wpstg--modal--backup--import--filesystem');
1530
+ },
1531
+ preConfirm: function preConfirm() {
1532
+ var body = new FormData();
1533
+ body.append('accessToken', wpstg.accessToken);
1534
+ body.append('nonce', wpstg.nonce);
1535
+ body.append('filePath', WPStagingLegacyDatabase.modal["import"].data.file);
1536
+ WPStagingLegacyDatabase.modal["import"].data.search.forEach(function (item, index) {
1537
+ body.append("search[" + index + "]", item);
1538
+ });
1539
+ WPStagingLegacyDatabase.modal["import"].data.replace.forEach(function (item, index) {
1540
+ body.append("replace[" + index + "]", item);
1541
+ });
1542
+ return fetch(ajaxurl + "?action=wpstg--backups--import--file-info", {
1543
+ method: 'POST',
1544
+ body: body
1545
+ }).then(WPStagingLegacyDatabase.handleFetchErrors).then(function (res) {
1546
+ return res.json();
1547
+ }).then(function (html) {
1548
+ return Swal.insertQueueStep({
1549
+ html: html,
1550
+ confirmButtonText: WPStagingLegacyDatabase.modal["import"].btnTxtConfirm,
1551
+ cancelButtonText: WPStagingLegacyDatabase.modal["import"].btnTxtCancel,
1552
+ showCancelButton: true
1553
+ });
1554
+ })["catch"](function (e) {
1555
+ return WPStagingLegacyDatabase.showAjaxFatalError(e, '', 'Submit an error report.');
1556
+ });
1557
+ }
1558
+ }]).then(function (res) {
1559
+ if (!res || !res.value || !res.value[1] || res.value[1] !== true) {
1560
+ return;
1561
  }
1562
+
1563
+ WPStagingLegacyDatabase.isCancelled = false;
1564
+ var data = WPStagingLegacyDatabase.modal["import"].data;
1565
+ data['file'] = WPStagingLegacyDatabase.modal["import"].baseDirectory + data['file'];
1566
+ data['reset'] = true;
1567
+ WPStagingLegacyDatabase.process({
1568
+ execute: function execute() {
1569
+ WPStagingLegacyDatabase.messages.reset();
1570
+ restoreSiteBackup(data);
1571
+ }
1572
+ });
1573
  });
1574
+ }
1575
+ };
1576
+ })(jQuery);
constantsFree.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // WP STAGING version number
4
  if (!defined('WPSTG_VERSION')) {
5
- define('WPSTG_VERSION', '2.8.2');
6
  }
7
 
8
  // Compatible up to WordPress Version
2
 
3
  // WP STAGING version number
4
  if (!defined('WPSTG_VERSION')) {
5
+ define('WPSTG_VERSION', '2.8.3');
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.8.2';
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.8.3';
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
@@ -9,7 +9,7 @@ License URI: http://www.gnu.org/licenses/gpl-2.0.html
9
  Tags: backup, database backup, staging, duplication, clone
10
  Requires at least: 3.6+
11
  Tested up to: 5.7
12
- Stable tag: 2.8.2
13
  Requires PHP: 5.5
14
 
15
  A backup & duplicator plugin - clone, move, duplicate & migrate websites to staging, backup and development sites for authorized users only.
@@ -166,6 +166,21 @@ https://wp-staging.com
166
 
167
  == Changelog ==
168
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  = 2.8.2 =
170
  * Feat: Compatible up to WP 5.7
171
  * Feat: Check database connection in clone data edit #650
9
  Tags: backup, database backup, staging, duplication, clone
10
  Requires at least: 3.6+
11
  Tested up to: 5.7
12
+ Stable tag: 2.8.3
13
  Requires PHP: 5.5
14
 
15
  A backup & duplicator plugin - clone, move, duplicate & migrate websites to staging, backup and development sites for authorized users only.
166
 
167
  == Changelog ==
168
 
169
+ = 2.8.3 =
170
+ * Enh: Add Shutdownable interface to replace usages of __destruct in the code #729
171
+ * Enh: Refactor on how the plugin keeps track of a request running time #766
172
+ * Fix: Replace deprecated jQuery click method #730
173
+ * Fix: Fix overlapping of sweetalert confirmation on push with sidebar #742
174
+ * Fix: Exclude wp staging content folder during staging #741
175
+ * Fix: Add sanitizing for path to fix comparing for Windows paths #751
176
+ * Fix: _cerber_files tables are excluded and could not be copied Fix #770
177
+ * Fix: Replaced jQuery assignment with an IIFE wrapper #761
178
+ * Dev: Update php-scoper and other development dependencies #744
179
+ * Dev: Build javascript when building the distributable version of the plugin #750
180
+ * Dev: Internal helper CLI command to order the changelog notes according to type #749
181
+ * Dev: Refactor Job(s) implementation to use the Resources Trait #765
182
+ * Dev: Add internal documentation to versioning and hotfixes #780
183
+
184
  = 2.8.2 =
185
  * Feat: Compatible up to WP 5.7
186
  * Feat: Check database connection in clone data edit #650
vendor_wpstg/autoload/src.php CHANGED
@@ -204,6 +204,7 @@ return array(
204
  'WPStaging\\Framework\\Filesystem\\WpUploadsFolderSymlinker' => $baseDir . '/Framework/Filesystem/WpUploadsFolderSymlinker.php',
205
  'WPStaging\\Framework\\Interfaces\\ArrayableInterface' => $baseDir . '/Framework/Interfaces/ArrayableInterface.php',
206
  'WPStaging\\Framework\\Interfaces\\HydrateableInterface' => $baseDir . '/Framework/Interfaces/HydrateableInterface.php',
 
207
  'WPStaging\\Framework\\Interfaces\\TransientInterface' => $baseDir . '/Framework/Interfaces/TransientInterface.php',
208
  'WPStaging\\Framework\\Mails\\Report\\Report' => $baseDir . '/Framework/Mails/Report/Report.php',
209
  'WPStaging\\Framework\\Mails\\Report\\ReportSubmitTransient' => $baseDir . '/Framework/Mails/Report/ReportSubmitTransient.php',
204
  'WPStaging\\Framework\\Filesystem\\WpUploadsFolderSymlinker' => $baseDir . '/Framework/Filesystem/WpUploadsFolderSymlinker.php',
205
  'WPStaging\\Framework\\Interfaces\\ArrayableInterface' => $baseDir . '/Framework/Interfaces/ArrayableInterface.php',
206
  'WPStaging\\Framework\\Interfaces\\HydrateableInterface' => $baseDir . '/Framework/Interfaces/HydrateableInterface.php',
207
+ 'WPStaging\\Framework\\Interfaces\\ShutdownableInterface' => $baseDir . '/Framework/Interfaces/ShutdownableInterface.php',
208
  'WPStaging\\Framework\\Interfaces\\TransientInterface' => $baseDir . '/Framework/Interfaces/TransientInterface.php',
209
  'WPStaging\\Framework\\Mails\\Report\\Report' => $baseDir . '/Framework/Mails/Report/Report.php',
210
  'WPStaging\\Framework\\Mails\\Report\\ReportSubmitTransient' => $baseDir . '/Framework/Mails/Report/ReportSubmitTransient.php',
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.8.2
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.8.3
11
  * Text Domain: wp-staging
12
  * Domain Path: /languages/
13
  *