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

Version Description

  • Enh: Preview of the new backup & migration feature in WP STAGING | PRO
  • Enh: Replace CSS based hover with pure js hoverintent for tooltips #1106
  • Enh: Cleanup logs older than 7 days automatically #1116
  • Enh: Update the version to check in Outdated WP Staging Hooks notice #1118
  • Enh: Schedule the uploads backup to be deleted after one week if that option was selected during push #980
  • Enh: Allow copying of only that symlink whose source is a directory #979
  • Enh: Show notice only to user who can manage_options if wp_options table is missing primary key #1009
  • Enh: Delete Optimizer Plugin on WP Staging plugins deactivate instead of uninstall #1096
  • Fix: Fixed conflict with Rank Math Seo PRO when Rank Math Seo PRO is activated network wide in multisites #1111
  • Fix: Make Scan::hasFreeDiskSpace() return other info even if disk_free_space is unavailable #1093
  • Fix: Replace the deprecated of calling a non-static method in daily version check hooks #1092
  • Fix: Try catch all instance of directory iterators #1101
  • Fix: Handle error properly for Filesystem::delete() method #974
  • Fix: Remove loading wpstg scripts as ESM to allow loading them as asynchronous #1007
  • Fix: Properly handle exception while cleaning themes and plugins bak and tmp directories #1017
  • Fix: Delete the clone even if in any case a corrupted delete job cache file existed for delete job #1033
  • Fix: No cloning/pushing logs were written to file. Now fixed. #1040
  • Fix: Wrap wp_doing_ajax in a adapter and use that adapter to call it to make it usable in WP < 4.7 #1047
  • Fix: Fix typo and wrap up text in i18n for src/Backend/views/clone/ajax/start.php #1051
  • Fix: Fix missing clone options warning during scanning process for old clones for UPDATE and RESET #1058
  • Fix: Make isExcludedDirectories condition works for relative directories path too #1054
  • Fix: Set donation link to redirect to WP Staging pricing page #1080
  • Dev: Add a shortcut to allow to use the DI container as a Service Locator easier under some circumstances #1039
  • Dev: Add trait to allow for easier use of the uopz extension in tests #1053
  • Dev: Replace const related tests logic with UOPZ for better readability and control #1079
Download this release

Release Info

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

Code changes from version 2.8.4 to 2.8.5

Files changed (146) hide show
  1. Backend/Administrator.php +61 -20
  2. Backend/Modules/Jobs/Data.php +6 -4
  3. Backend/Modules/Jobs/Database.php +17 -10
  4. Backend/Modules/Jobs/Delete.php +49 -45
  5. Backend/Modules/Jobs/Directories.php +6 -16
  6. Backend/Modules/Jobs/Files.php +16 -8
  7. Backend/Modules/Jobs/Job.php +19 -10
  8. Backend/Modules/Jobs/ProcessLock.php +1 -1
  9. Backend/Modules/Jobs/Scan.php +118 -85
  10. Backend/Modules/Jobs/SearchReplace.php +20 -67
  11. Backend/Modules/SystemInfo.php +1 -1
  12. Backend/Notices/DisabledItemsNotice.php +1 -1
  13. Backend/Notices/Notices.php +65 -31
  14. Backend/Optimizer/wp-staging-optimizer.php +11 -8
  15. Backend/views/_main/footer.php +29 -12
  16. Backend/views/_main/header.php +9 -34
  17. Backend/views/_main/report-issue.php +2 -1
  18. Backend/views/backup/free-version.php +16 -0
  19. Backend/views/backup/listing-backups-no-results.php +18 -0
  20. Backend/views/backup/listing-single-backup.php +72 -26
  21. Backend/views/backup/listing.php +30 -10
  22. Backend/views/backup/{site/info.php → modal/confirm-restore.php} +9 -2
  23. Backend/views/backup/modal/download.php +7 -4
  24. Backend/views/backup/modal/export.php +19 -20
  25. Backend/views/backup/modal/import.php +4 -5
  26. Backend/views/backup/modal/partials/import-configure.php +0 -33
  27. Backend/views/backup/modal/partials/import-database-search-replace.php +21 -0
  28. Backend/views/backup/modal/partials/import-filesystem.php +0 -17
  29. Backend/views/backup/modal/partials/import-introduction.php +18 -0
  30. Backend/views/backup/modal/partials/import-upload.php +0 -59
  31. Backend/views/backup/modal/progress.php +3 -3
  32. Backend/views/backup/modal/upload.php +68 -0
  33. Backend/views/backup/multisite-disabled.php +17 -0
  34. Backend/views/backup/restore-wait.php +13 -0
  35. Backend/views/clone/ajax/custom-directory.php +116 -39
  36. Backend/views/clone/ajax/delete-confirmation.php +13 -13
  37. Backend/views/clone/ajax/exclude-settings.php +5 -4
  38. Backend/views/clone/ajax/external-database.php +68 -34
  39. Backend/views/clone/ajax/mail-setting.php +56 -14
  40. Backend/views/clone/ajax/scan.php +45 -35
  41. Backend/views/clone/ajax/single-overview.php +18 -5
  42. Backend/views/clone/ajax/start.php +16 -19
  43. Backend/views/clone/ajax/update.php +1 -1
  44. Backend/views/clone/index.php +32 -23
  45. Backend/views/clone/single-site/index.php +8 -5
  46. Backend/views/clone/staging-site/index.php +17 -11
  47. Backend/views/database/legacy/confirm-delete.php +0 -31
  48. Backend/views/database/legacy/confirm-restore.php +0 -114
  49. Backend/views/database/legacy/listing.php +0 -331
  50. Backend/views/notices/cache-directory-permission-problem.php +5 -4
  51. Backend/views/notices/directory-listing-could-not-be-prevented.php +5 -4
  52. Backend/views/notices/disabled-items-notice.php +6 -4
  53. Backend/views/notices/logs-directory-permission-problem.php +5 -3
  54. Backend/views/notices/low-memory-limit.php +1 -1
  55. Backend/views/notices/no-license-key.php +0 -11
  56. Backend/views/notices/outdated-wp-staging-hooks.php +3 -3
  57. Backend/views/notices/rating.php +15 -19
  58. Backend/views/notices/staging-directory-permission-problem.php +7 -5
  59. Backend/views/notices/transient.php +1 -1
  60. Backend/views/notices/vars-directory-permission-problem.php +5 -3
  61. Backend/views/notices/wp-options-missing-pk.php +14 -0
  62. Backend/views/notices/wp-version-compatible-message.php +3 -3
  63. Backend/views/notices/wrong-scheme.php +4 -3
  64. Backend/views/selections/database-tables.php +7 -5
  65. Backend/views/selections/files.php +9 -7
  66. Backend/views/settings/tabs/mail-settings.php +1 -1
  67. Backend/views/templates/exclude-filters/dir-name-exclude-filter.php +2 -2
  68. Backend/views/templates/exclude-filters/file-ext-exclude-filter.php +2 -2
  69. Backend/views/templates/exclude-filters/file-name-exclude-filter.php +2 -2
  70. Backend/views/templates/exclude-filters/file-size-exclude-filter.php +2 -2
  71. Backend/views/welcome/welcome.php +16 -11
  72. Core/Utils/Directories.php +21 -18
  73. Core/Utils/Helper.php +6 -4
  74. Core/Utils/Logger.php +1 -12
  75. Core/Utils/functions.php +9 -105
  76. Core/WPStaging.php +66 -10
  77. Deactivate.php +65 -0
  78. Framework/Adapter/Database.php +13 -1
  79. Framework/Adapter/Database/InterfaceDatabaseClient.php +15 -1
  80. Framework/Adapter/Database/MysqlAdapter.php +17 -0
  81. Framework/Adapter/Database/MysqliAdapter.php +18 -1
  82. Framework/Adapter/Directory.php +253 -12
  83. Framework/Adapter/WpAdapter.php +24 -0
  84. Framework/Assets/Assets.php +65 -33
  85. Framework/BackgroundProcessing/FeatureDetection.php +3 -1
  86. Framework/CloningProcess/Database/CompareExternalDatabase.php +82 -0
  87. Framework/CloningProcess/Database/DatabaseCloningService.php +9 -5
  88. Framework/CloningProcess/SearchReplace/SearchReplaceService.php +0 -45
  89. Framework/CommonServiceProvider.php +21 -0
  90. Framework/Component/AbstractTemplateComponent.php +4 -1
  91. Framework/Database/LegacyDatabaseInfo.php +0 -24
  92. Framework/Database/SearchReplace.php +17 -3
  93. Framework/Database/TableService.php +57 -30
  94. Framework/Exceptions/WPStagingException.php +10 -0
  95. Framework/Filesystem/DirectoryScanner.php +0 -57
  96. Framework/Filesystem/DirectoryScannerControl.php +0 -147
  97. Framework/Filesystem/DiskFullException.php +0 -16
  98. Framework/Filesystem/DiskWriteCheck.php +136 -0
  99. Framework/Filesystem/File.php +50 -2
  100. Framework/Filesystem/FileScanner.php +0 -154
  101. Framework/Filesystem/FileScannerControl.php +0 -129
  102. Framework/Filesystem/Filesystem.php +31 -4
  103. Framework/Filesystem/FilterableDirectoryIterator.php +9 -4
  104. Framework/Filesystem/LogCleanup.php +38 -0
  105. Framework/Filesystem/PathIdentifier.php +149 -0
  106. Framework/Filesystem/WpUploadsFolderSymlinker.php +1 -1
  107. Framework/Mails/Report/Report.php +1 -1
  108. Framework/Queue/FileSeekableQueue.php +207 -0
  109. Framework/Queue/Queue.php +21 -1
  110. Framework/Queue/SeekableQueueInterface.php +64 -0
  111. Framework/Queue/Storage/ArrayStorage.php +11 -0
  112. Framework/Queue/Storage/BufferedCacheStorage.php +12 -0
  113. Framework/Queue/Storage/CacheStorage.php +15 -0
  114. Framework/Queue/Storage/ObjectCacheStorage.php +277 -0
  115. Framework/Queue/Storage/SPL/JsonDoublyLinkedList.php +35 -0
  116. Framework/Queue/Storage/StorageInterface.php +11 -0
  117. Framework/Security/AccessToken.php +22 -0
  118. Framework/SiteInfo.php +32 -0
  119. Framework/TemplateEngine/TemplateEngine.php +7 -0
  120. Framework/Traits/DatabaseSearchReplaceTrait.php +98 -0
  121. Framework/Traits/DeveloperTimerTrait.php +99 -0
  122. Framework/Traits/FileScanToCacheTrait.php +34 -25
  123. Framework/Traits/HydrateTrait.php +0 -1
  124. Framework/Traits/MySQLRowsGeneratorTrait.php +187 -0
  125. Framework/Traits/ResourceTrait.php +107 -35
  126. Framework/Traits/TimerTrait.php +0 -16
  127. Framework/Utils/Cache/BufferedCache.php +142 -66
  128. Framework/Utils/Math.php +27 -0
  129. Framework/Utils/Urls.php +20 -3
  130. Frontend/FrontendServiceProvider.php +33 -0
  131. Frontend/LoginAfterImport.php +70 -0
  132. Frontend/views/loginAfterImport.php +68 -0
  133. Frontend/views/loginForm.php +1 -1
  134. assets/css/dist/wpstg-admin.css +1098 -517
  135. assets/css/dist/wpstg-admin.css.map +1 -1
  136. assets/css/dist/wpstg-admin.min.css +1 -1
  137. assets/css/dist/wpstg-admin.min.css.map +1 -1
  138. assets/img/loading_v1.gif +0 -0
  139. assets/img/logo-wp-staging-1468x230.png +0 -0
  140. assets/img/wp-staging274x463-1.png +0 -0
  141. assets/img/wpstaging-banner200x400-tryout.gif +0 -0
  142. assets/img/wpstaging-banner200x400.gif +0 -0
  143. assets/js/dist/wpstg-admin-rating.js.map +1 -1
  144. assets/js/dist/wpstg-admin-rating.min.js.map +1 -1
  145. assets/js/dist/wpstg-admin.js +722 -1514
  146. assets/js/dist/wpstg-admin.js.map +0 -1
Backend/Administrator.php CHANGED
@@ -27,11 +27,13 @@ use WPStaging\Backend\Modules\Views\Forms\Settings as FormSettings;
27
  use WPStaging\Backend\Activation;
28
  use WPStaging\Backend\Feedback;
29
  use WPStaging\Backend\Pro\Modules\Jobs\Processing;
 
30
  use WPStaging\Backend\Pluginmeta\Pluginmeta;
31
  use WPStaging\Core\DTO\Settings;
32
  use WPStaging\Framework\Filesystem\Filters\ExcludeFilter;
33
  use WPStaging\Framework\TemplateEngine\TemplateEngine;
34
- use WPStaging\Pro\Database\CompareExternalDatabase;
 
35
 
36
  /**
37
  * Class Administrator
@@ -170,6 +172,12 @@ class Administrator
170
  add_action("wp_ajax_wpstg_scan", [$this, "ajaxPushScan"]);
171
  add_action("wp_ajax_wpstg_push_processing", [$this, "ajaxPushProcessing"]);
172
  add_action("wp_ajax_nopriv_wpstg_push_processing", [$this, "ajaxPushProcessing"]);
 
 
 
 
 
 
173
  }
174
 
175
  /**
@@ -269,21 +277,17 @@ class Administrator
269
 
270
  $logo = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgMTAwMCAxMDAwIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMDAwIDEwMDAiIHhtbDpzcGFjZT0icHJlc2VydmUiIGZpbGw9Im5vbmUiPgo8Zz48Zz48cGF0aCBzdHlsZT0iZmlsbDojZmZmIiAgZD0iTTEzNy42LDU2MS4zSDEzLjhIMTB2MzA2LjNsOTAuNy04My40QzE4OS42LDkwOC43LDMzNS4zLDk5MCw1MDAsOTkwYzI0OS45LDAsNDU2LjEtMTg3LjEsNDg2LjItNDI4LjhIODYyLjRDODMzLjMsNzM1LjEsNjgyLjEsODY3LjUsNTAwLDg2Ny41Yy0xMjksMC0yNDIuNS02Ni41LTMwOC4xLTE2Ny4ybDE1MS4zLTEzOS4xSDEzNy42eiIvPjxwYXRoIHN0eWxlPSJmaWxsOiNmZmYiICBkPSJNNTAwLDEwQzI1MC4xLDEwLDQzLjksMTk3LjEsMTMuOCw0MzguOGgxMjMuOEMxNjYuNywyNjQuOSwzMTcuOSwxMzIuNSw1MDAsMTMyLjVjMTMyLjksMCwyNDkuMyw3MC41LDMxMy44LDE3Ni4yTDY4My44LDQzOC44aDEyMi41aDU2LjJoMTIzLjhoMy44VjEzMi41bC04Ny43LDg3LjdDODEzLjgsOTMuMSw2NjYuNiwxMCw1MDAsMTB6Ii8+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjwvZz4KPC9zdmc+';
271
 
272
- if (defined('WPSTGPRO_VERSION')) {
273
- $pro = 'Pro';
274
- } else {
275
- $pro = '';
276
- }
277
-
278
  $pos = self::MENU_POSITION_ORDER;
279
  if (is_multisite()) {
280
  $pos = self::MENU_POSITION_ORDER_MULTISITE;
281
  }
282
 
 
 
283
  // Main WP Staging Menu
284
  add_menu_page(
285
- "WP-Staging",
286
- __("WP Staging " . $pro, "wp-staging"),
287
  "manage_options",
288
  "wpstg_clone",
289
  [$this, "getClonePage"],
@@ -295,12 +299,21 @@ class Administrator
295
  add_submenu_page(
296
  "wpstg_clone",
297
  __("WP Staging Jobs", "wp-staging"),
298
- __("Sites / Start", "wp-staging"),
299
  "manage_options",
300
  "wpstg_clone",
301
  [$this, "getClonePage"]
302
  );
303
 
 
 
 
 
 
 
 
 
 
304
  // Page: Settings
305
  add_submenu_page(
306
  "wpstg_clone",
@@ -333,7 +346,7 @@ class Administrator
333
  );
334
  }
335
 
336
- if (defined('WPSTGPRO_VERSION') && $this->siteInfo->isStaging() === false) {
337
  // Page: License
338
  add_submenu_page(
339
  "wpstg_clone",
@@ -376,6 +389,19 @@ class Administrator
376
  require_once "{$this->path}views/clone/index.php";
377
  }
378
 
 
 
 
 
 
 
 
 
 
 
 
 
 
379
  /**
380
  * Welcome Page
381
  */
@@ -564,6 +590,8 @@ class Administrator
564
  // Get db
565
  $db = WPStaging::getInstance()->get('wpdb');
566
 
 
 
567
  require_once "{$this->path}views/clone/ajax/single-overview.php";
568
 
569
  wp_die();
@@ -594,6 +622,7 @@ class Administrator
594
  // Scan
595
  $scan = new Scan();
596
  $scan->setGifLoaderPath($this->assets->getAssetsUrl('img/spinner.gif'));
 
597
  $scan->start();
598
 
599
  // Get Options
@@ -671,7 +700,7 @@ class Administrator
671
  return;
672
  }
673
 
674
- $cloning = new Updating();
675
 
676
  if (!$cloning->save()) {
677
  wp_die('Can not save clone data');
@@ -691,7 +720,7 @@ class Administrator
691
  return;
692
  }
693
 
694
- $cloning = new Updating();
695
  $cloning->setMainJob(Updating::RESET_UPDATE);
696
  if (!$cloning->save()) {
697
  wp_die('can not save clone data');
@@ -714,7 +743,7 @@ class Administrator
714
  $processLock = new ProcessLock();
715
  $processLock->isRunning();
716
 
717
- $cloning = new Cloning();
718
 
719
  if (!$cloning->save()) {
720
  wp_die('can not save clone data');
@@ -734,7 +763,7 @@ class Administrator
734
  return;
735
  }
736
 
737
- wp_send_json((new Cloning())->start());
738
  }
739
 
740
  /**
@@ -746,7 +775,7 @@ class Administrator
746
  return;
747
  }
748
 
749
- wp_send_json((new Cloning())->start());
750
  }
751
 
752
  /**
@@ -758,7 +787,7 @@ class Administrator
758
  return;
759
  }
760
 
761
- wp_send_json((new Cloning())->start());
762
  }
763
 
764
  /**
@@ -770,7 +799,7 @@ class Administrator
770
  return;
771
  }
772
 
773
- wp_send_json((new Cloning())->start());
774
  }
775
 
776
  /**
@@ -782,7 +811,7 @@ class Administrator
782
  return;
783
  }
784
 
785
- wp_send_json((new Cloning())->start());
786
  }
787
 
788
  /**
@@ -1030,6 +1059,9 @@ class Administrator
1030
  // Get Options
1031
  $options = $scan->getOptions();
1032
 
 
 
 
1033
  require_once "{$this->path}Pro/views/scan.php";
1034
 
1035
  wp_die();
@@ -1049,7 +1081,7 @@ class Administrator
1049
  }
1050
 
1051
  // Start the process
1052
- wp_send_json((new Processing())->start());
1053
  }
1054
 
1055
  /**
@@ -1294,6 +1326,15 @@ class Administrator
1294
  exit();
1295
  }
1296
 
 
 
 
 
 
 
 
 
 
1297
  /**
1298
  * Toggle staging site cloning
1299
  *
27
  use WPStaging\Backend\Activation;
28
  use WPStaging\Backend\Feedback;
29
  use WPStaging\Backend\Pro\Modules\Jobs\Processing;
30
+ use WPStaging\Backend\Pro\Modules\Jobs\Backups\BackupUploadsDir;
31
  use WPStaging\Backend\Pluginmeta\Pluginmeta;
32
  use WPStaging\Core\DTO\Settings;
33
  use WPStaging\Framework\Filesystem\Filters\ExcludeFilter;
34
  use WPStaging\Framework\TemplateEngine\TemplateEngine;
35
+ use WPStaging\Framework\CloningProcess\Database\CompareExternalDatabase;
36
+ use WPStaging\Framework\Utils\Math;
37
 
38
  /**
39
  * Class Administrator
172
  add_action("wp_ajax_wpstg_scan", [$this, "ajaxPushScan"]);
173
  add_action("wp_ajax_wpstg_push_processing", [$this, "ajaxPushProcessing"]);
174
  add_action("wp_ajax_nopriv_wpstg_push_processing", [$this, "ajaxPushProcessing"]);
175
+
176
+ // TODO: replace uploads backup during push once we have backups PR ready,
177
+ // Then there will be no need to have any cron to delete those backups
178
+ if (class_exists('WPStaging\Backend\Pro\Modules\Jobs\Backups\BackupUploadsDir')) {
179
+ add_action(BackupUploadsDir::BACKUP_DELETE_CRON_HOOK_NAME, [$this, "removeOldUploadsBackup"]);
180
+ }
181
  }
182
 
183
  /**
277
 
278
  $logo = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgMTAwMCAxMDAwIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxMDAwIDEwMDAiIHhtbDpzcGFjZT0icHJlc2VydmUiIGZpbGw9Im5vbmUiPgo8Zz48Zz48cGF0aCBzdHlsZT0iZmlsbDojZmZmIiAgZD0iTTEzNy42LDU2MS4zSDEzLjhIMTB2MzA2LjNsOTAuNy04My40QzE4OS42LDkwOC43LDMzNS4zLDk5MCw1MDAsOTkwYzI0OS45LDAsNDU2LjEtMTg3LjEsNDg2LjItNDI4LjhIODYyLjRDODMzLjMsNzM1LjEsNjgyLjEsODY3LjUsNTAwLDg2Ny41Yy0xMjksMC0yNDIuNS02Ni41LTMwOC4xLTE2Ny4ybDE1MS4zLTEzOS4xSDEzNy42eiIvPjxwYXRoIHN0eWxlPSJmaWxsOiNmZmYiICBkPSJNNTAwLDEwQzI1MC4xLDEwLDQzLjksMTk3LjEsMTMuOCw0MzguOGgxMjMuOEMxNjYuNywyNjQuOSwzMTcuOSwxMzIuNSw1MDAsMTMyLjVjMTMyLjksMCwyNDkuMyw3MC41LDMxMy44LDE3Ni4yTDY4My44LDQzOC44aDEyMi41aDU2LjJoMTIzLjhoMy44VjEzMi41bC04Ny43LDg3LjdDODEzLjgsOTMuMSw2NjYuNiwxMCw1MDAsMTB6Ii8+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjwvZz4KPC9zdmc+';
279
 
 
 
 
 
 
 
280
  $pos = self::MENU_POSITION_ORDER;
281
  if (is_multisite()) {
282
  $pos = self::MENU_POSITION_ORDER_MULTISITE;
283
  }
284
 
285
+ $proSlug = defined('WPSTGPRO_VERSION') ? 'Pro' : '';
286
+
287
  // Main WP Staging Menu
288
  add_menu_page(
289
+ "WP STAGING",
290
+ __("WP Staging " . $proSlug, "wp-staging"),
291
  "manage_options",
292
  "wpstg_clone",
293
  [$this, "getClonePage"],
299
  add_submenu_page(
300
  "wpstg_clone",
301
  __("WP Staging Jobs", "wp-staging"),
302
+ __("Staging Sites", "wp-staging"),
303
  "manage_options",
304
  "wpstg_clone",
305
  [$this, "getClonePage"]
306
  );
307
 
308
+ add_submenu_page(
309
+ "wpstg_clone",
310
+ __("WP Staging Jobs", "wp-staging"),
311
+ __("Backup & Migration", "wp-staging"),
312
+ "manage_options",
313
+ "wpstg_backup",
314
+ [$this, "getBackupPage"]
315
+ );
316
+
317
  // Page: Settings
318
  add_submenu_page(
319
  "wpstg_clone",
346
  );
347
  }
348
 
349
+ if (defined('WPSTGPRO_VERSION')) {
350
  // Page: License
351
  add_submenu_page(
352
  "wpstg_clone",
389
  require_once "{$this->path}views/clone/index.php";
390
  }
391
 
392
+ /**
393
+ * Backup & Migration Page
394
+ */
395
+ public function getBackupPage()
396
+ {
397
+ // Existing clones
398
+ $availableClones = get_option("wpstg_existing_clones_beta", []);
399
+
400
+ $openBackupPage = true;
401
+
402
+ require_once "{$this->path}views/clone/index.php";
403
+ }
404
+
405
  /**
406
  * Welcome Page
407
  */
590
  // Get db
591
  $db = WPStaging::getInstance()->get('wpdb');
592
 
593
+ $iconPath = $this->assets->getAssetsUrl('svg/vendor/dashicons/cloud.svg');
594
+
595
  require_once "{$this->path}views/clone/ajax/single-overview.php";
596
 
597
  wp_die();
622
  // Scan
623
  $scan = new Scan();
624
  $scan->setGifLoaderPath($this->assets->getAssetsUrl('img/spinner.gif'));
625
+ $scan->setInfoIcon($this->assets->getAssetsUrl('svg/vendor/dashicons/info-outline.svg'));
626
  $scan->start();
627
 
628
  // Get Options
700
  return;
701
  }
702
 
703
+ $cloning = WPStaging::make(Updating::class);
704
 
705
  if (!$cloning->save()) {
706
  wp_die('Can not save clone data');
720
  return;
721
  }
722
 
723
+ $cloning = WPStaging::make(Updating::class);
724
  $cloning->setMainJob(Updating::RESET_UPDATE);
725
  if (!$cloning->save()) {
726
  wp_die('can not save clone data');
743
  $processLock = new ProcessLock();
744
  $processLock->isRunning();
745
 
746
+ $cloning = WPStaging::make(Cloning::class);
747
 
748
  if (!$cloning->save()) {
749
  wp_die('can not save clone data');
763
  return;
764
  }
765
 
766
+ wp_send_json(WPStaging::make(Cloning::class)->start());
767
  }
768
 
769
  /**
775
  return;
776
  }
777
 
778
+ wp_send_json(WPStaging::make(Cloning::class)->start());
779
  }
780
 
781
  /**
787
  return;
788
  }
789
 
790
+ wp_send_json(WPStaging::make(Cloning::class)->start());
791
  }
792
 
793
  /**
799
  return;
800
  }
801
 
802
+ wp_send_json(WPStaging::make(Cloning::class)->start());
803
  }
804
 
805
  /**
811
  return;
812
  }
813
 
814
+ wp_send_json(WPStaging::make(Cloning::class)->start());
815
  }
816
 
817
  /**
1059
  // Get Options
1060
  $options = $scan->getOptions();
1061
 
1062
+ // Get Framework\Utils\Math
1063
+ $utilsMath = new Math();
1064
+
1065
  require_once "{$this->path}Pro/views/scan.php";
1066
 
1067
  wp_die();
1081
  }
1082
 
1083
  // Start the process
1084
+ wp_send_json(WPStaging::make(Processing::class)->start());
1085
  }
1086
 
1087
  /**
1326
  exit();
1327
  }
1328
 
1329
+ /**
1330
+ * Remove uploads backup
1331
+ */
1332
+ public function removeOldUploadsBackup()
1333
+ {
1334
+ $backup = new BackupUploadsDir(null);
1335
+ $backup->removeUploadsBackup();
1336
+ }
1337
+
1338
  /**
1339
  * Toggle staging site cloning
1340
  *
Backend/Modules/Jobs/Data.php CHANGED
@@ -2,6 +2,8 @@
2
 
3
  namespace WPStaging\Backend\Modules\Jobs;
4
 
 
 
5
  use WPStaging\Framework\CloningProcess\Data\DataCloningDto;
6
  use WPStaging\Framework\CloningProcess\Data\CopyWpConfig;
7
  use WPStaging\Framework\CloningProcess\Data\MultisiteAddNetworkAdministrators;
@@ -13,9 +15,8 @@ use WPStaging\Framework\CloningProcess\Data\UpdateWpConfigConstants;
13
  use WPStaging\Framework\CloningProcess\Data\UpdateWpConfigTablePrefix;
14
  use WPStaging\Framework\CloningProcess\Data\UpdateWpOptionsTablePrefix;
15
  use WPStaging\Framework\CloningProcess\Data\UpdateStagingOptionsTable;
16
- use WPStaging\Core\Utils\Helper;
17
- use WPStaging\Framework\Utils\Strings;
18
  use WPStaging\Framework\SiteInfo;
 
19
  use WPStaging\Framework\Utils\WpDefaultDirectories;
20
 
21
  /**
@@ -63,7 +64,7 @@ class Data extends CloningProcess
63
  $this->baseUrl = (new Helper())->getBaseUrl();
64
 
65
  // Reset current step
66
- if ($this->options->currentStep == 0) {
67
  $this->options->currentStep = 0;
68
  }
69
  }
@@ -120,8 +121,9 @@ class Data extends CloningProcess
120
  $strings = new Strings();
121
  $this->tables = [];
122
  foreach ($this->options->tables as $table) {
123
- $this->tables[] = $this->options->prefix . $strings->str_replace_first($this->productionDb->prefix, null, $table);
124
  }
 
125
  if ($this->isMultisiteAndPro()) {
126
  // Add extra global tables from main multisite (wpstg[x]_users and wpstg[x]_usermeta)
127
  $this->tables[] = $this->options->prefix . 'users';
2
 
3
  namespace WPStaging\Backend\Modules\Jobs;
4
 
5
+ use WPStaging\Core\Utils\Helper;
6
+ use WPStaging\Core\WPStaging;
7
  use WPStaging\Framework\CloningProcess\Data\DataCloningDto;
8
  use WPStaging\Framework\CloningProcess\Data\CopyWpConfig;
9
  use WPStaging\Framework\CloningProcess\Data\MultisiteAddNetworkAdministrators;
15
  use WPStaging\Framework\CloningProcess\Data\UpdateWpConfigTablePrefix;
16
  use WPStaging\Framework\CloningProcess\Data\UpdateWpOptionsTablePrefix;
17
  use WPStaging\Framework\CloningProcess\Data\UpdateStagingOptionsTable;
 
 
18
  use WPStaging\Framework\SiteInfo;
19
+ use WPStaging\Framework\Utils\Strings;
20
  use WPStaging\Framework\Utils\WpDefaultDirectories;
21
 
22
  /**
64
  $this->baseUrl = (new Helper())->getBaseUrl();
65
 
66
  // Reset current step
67
+ if ($this->options->currentStep === 0) {
68
  $this->options->currentStep = 0;
69
  }
70
  }
121
  $strings = new Strings();
122
  $this->tables = [];
123
  foreach ($this->options->tables as $table) {
124
+ $this->tables[] = $this->options->prefix . $strings->str_replace_first(WPStaging::getTablePrefix(), null, $table);
125
  }
126
+
127
  if ($this->isMultisiteAndPro()) {
128
  // Add extra global tables from main multisite (wpstg[x]_users and wpstg[x]_usermeta)
129
  $this->tables[] = $this->options->prefix . 'users';
Backend/Modules/Jobs/Database.php CHANGED
@@ -2,7 +2,9 @@
2
 
3
  namespace WPStaging\Backend\Modules\Jobs;
4
 
 
5
  use WPStaging\Backend\Modules\Jobs\Exceptions\FatalException;
 
6
  use WPStaging\Framework\CloningProcess\CloningDto;
7
  use WPStaging\Framework\CloningProcess\Database\DatabaseCloningService;
8
  use WPStaging\Framework\Adapter\Database as DatabaseAdapter;
@@ -175,7 +177,7 @@ class Database extends CloningProcess
175
  return (
176
  $old === $name &&
177
  (
178
- !isset($this->options->job->current, $this->options->job->start) || $this->options->job->start == 0
179
  )
180
  );
181
  }
@@ -204,7 +206,7 @@ class Database extends CloningProcess
204
  $this->options->clonedTables[] = isset($this->options->tables[$this->options->currentStep]) ? $this->options->tables[$this->options->currentStep] : false;
205
 
206
  // Reset job
207
- $this->options->job = new \stdClass();
208
 
209
  return true;
210
  }
@@ -327,7 +329,7 @@ class Database extends CloningProcess
327
  return false;
328
  }
329
 
330
- if ($this->options->job->start != 0) {
331
  return true;
332
  }
333
 
@@ -343,7 +345,7 @@ class Database extends CloningProcess
343
  return true;
344
  }
345
 
346
- if ($this->options->job->total == 0) {
347
  $this->finishStep();
348
  return false;
349
  }
@@ -361,13 +363,14 @@ class Database extends CloningProcess
361
  */
362
  private function addMissingTables()
363
  {
364
- if (!in_array($this->productionDb->prefix . 'users', $this->options->tables)) {
365
- $this->options->tables[] = $this->productionDb->prefix . 'users';
 
366
  $this->saveOptions();
367
  }
368
 
369
- if (!in_array($this->productionDb->prefix . 'usermeta', $this->options->tables)) {
370
- $this->options->tables[] = $this->productionDb->prefix . 'usermeta';
371
  $this->saveOptions();
372
  }
373
  }
@@ -377,7 +380,8 @@ class Database extends CloningProcess
377
  */
378
  private function abortIfStagingPrefixEqualsProdPrefix()
379
  {
380
- if ($this->productionDb->prefix === $this->getStagingPrefix()) {
 
381
  $error = 'Fatal error 7: The destination database table prefix ' . $this->getStagingPrefix() . ' is identical to the table prefix of the production site. Go to Sites > Actions > Edit Data and correct the table prefix or contact us.';
382
  $this->returnException($error);
383
  return true;
@@ -394,7 +398,10 @@ class Database extends CloningProcess
394
  {
395
  if ($this->isExternalDatabase()) {
396
  $this->options->prefix = !empty($this->options->databasePrefix) ? $this->options->databasePrefix : $this->productionDb->prefix;
397
- return $this->options->prefix;
 
 
 
398
  }
399
 
400
  return $this->options->prefix;
2
 
3
  namespace WPStaging\Backend\Modules\Jobs;
4
 
5
+ use stdClass;
6
  use WPStaging\Backend\Modules\Jobs\Exceptions\FatalException;
7
+ use WPStaging\Core\WPStaging;
8
  use WPStaging\Framework\CloningProcess\CloningDto;
9
  use WPStaging\Framework\CloningProcess\Database\DatabaseCloningService;
10
  use WPStaging\Framework\Adapter\Database as DatabaseAdapter;
177
  return (
178
  $old === $name &&
179
  (
180
+ !isset($this->options->job->current, $this->options->job->start) || $this->options->job->start === 0
181
  )
182
  );
183
  }
206
  $this->options->clonedTables[] = isset($this->options->tables[$this->options->currentStep]) ? $this->options->tables[$this->options->currentStep] : false;
207
 
208
  // Reset job
209
+ $this->options->job = new stdClass();
210
 
211
  return true;
212
  }
329
  return false;
330
  }
331
 
332
+ if ($this->options->job->start !== 0) {
333
  return true;
334
  }
335
 
345
  return true;
346
  }
347
 
348
+ if ($this->options->job->total === 0) {
349
  $this->finishStep();
350
  return false;
351
  }
363
  */
364
  private function addMissingTables()
365
  {
366
+ $dbPrefix = WPStaging::getTablePrefix();
367
+ if (!in_array($dbPrefix . 'users', $this->options->tables)) {
368
+ $this->options->tables[] = $dbPrefix . 'users';
369
  $this->saveOptions();
370
  }
371
 
372
+ if (!in_array($dbPrefix . 'usermeta', $this->options->tables)) {
373
+ $this->options->tables[] = $dbPrefix . 'usermeta';
374
  $this->saveOptions();
375
  }
376
  }
380
  */
381
  private function abortIfStagingPrefixEqualsProdPrefix()
382
  {
383
+ $dbPrefix = WPStaging::getTablePrefix();
384
+ if ($dbPrefix === $this->getStagingPrefix()) {
385
  $error = 'Fatal error 7: The destination database table prefix ' . $this->getStagingPrefix() . ' is identical to the table prefix of the production site. Go to Sites > Actions > Edit Data and correct the table prefix or contact us.';
386
  $this->returnException($error);
387
  return true;
398
  {
399
  if ($this->isExternalDatabase()) {
400
  $this->options->prefix = !empty($this->options->databasePrefix) ? $this->options->databasePrefix : $this->productionDb->prefix;
401
+ }
402
+
403
+ if (strncasecmp(PHP_OS, 'WIN', 3) === 0) {
404
+ return strtolower($this->options->prefix);
405
  }
406
 
407
  return $this->options->prefix;
Backend/Modules/Jobs/Delete.php CHANGED
@@ -2,6 +2,12 @@
2
 
3
  namespace WPStaging\Backend\Modules\Jobs;
4
 
 
 
 
 
 
 
5
  use WPStaging\Backend\Modules\Jobs\Exceptions\CloneNotFoundException;
6
  use WPStaging\Core\Utils\Logger;
7
  use WPStaging\Core\WPStaging;
@@ -16,7 +22,7 @@ class Delete extends Job
16
  {
17
 
18
  /**
19
- * @var \stdClass
20
  */
21
  private $clone = false;
22
 
@@ -43,7 +49,7 @@ class Delete extends Job
43
 
44
  /**
45
  *
46
- * @var object
47
  */
48
  public $wpdb;
49
 
@@ -95,7 +101,7 @@ class Delete extends Job
95
  */
96
  private function getStagingDb()
97
  {
98
- return new \wpdb($this->clone->databaseUser, $this->clone->databasePassword, $this->clone->databaseDatabase, $this->clone->databaseServer);
99
  }
100
 
101
  /**
@@ -175,7 +181,7 @@ class Delete extends Job
175
  foreach ($tables as $table) {
176
  $this->tables[] = [
177
  "name" => $table->Name,
178
- "size" => $this->formatSize(($table->Data_length + $table->Index_length))
179
  ];
180
  }
181
  }
@@ -199,6 +205,7 @@ class Delete extends Job
199
  if (($content = @file_get_contents($path)) === false) {
200
  $this->log("Can not open {$path}. Can't read contents", Logger::TYPE_ERROR);
201
  }
 
202
  preg_match("/table_prefix\s*=\s*'(\w*)';/", $content, $matches);
203
 
204
  if (!empty($matches[1])) {
@@ -221,27 +228,6 @@ class Delete extends Job
221
  return $this->clone->prefix;
222
  }
223
 
224
- /**
225
- * Format bytes into human readable form
226
- * @param int $bytes
227
- * @param int $precision
228
- * @return string
229
- */
230
- public function formatSize($bytes, $precision = 2)
231
- {
232
- if ((int)$bytes < 1) {
233
- return '';
234
- }
235
-
236
- $units = ['B', "KB", "MB", "GB", "TB"];
237
-
238
- $bytes = (int)$bytes;
239
- $base = log($bytes) / log(1000); // 1024 would be for MiB KiB etc
240
- $pow = pow(1000, $base - floor($base)); // Same rule for 1000
241
-
242
- return round($pow, $precision) . ' ' . $units[(int)floor($base)];
243
- }
244
-
245
  /**
246
  * @return false
247
  */
@@ -261,7 +247,7 @@ class Delete extends Job
261
  /**
262
  * Start Module
263
  * @param null|array $clone
264
- * @return bool
265
  */
266
  public function start($clone = null)
267
  {
@@ -272,7 +258,15 @@ class Delete extends Job
272
  $this->getJob();
273
 
274
  $method = "delete" . ucwords($this->job->current);
275
- return $this->{$method}();
 
 
 
 
 
 
 
 
276
  }
277
 
278
  /**
@@ -280,10 +274,10 @@ class Delete extends Job
280
  */
281
  private function getJob()
282
  {
283
- $this->job = $this->cache->get("delete_job_{$this->clone->name}");
284
 
285
 
286
- if ($this->job !== null) {
287
  return;
288
  }
289
 
@@ -294,7 +288,7 @@ class Delete extends Job
294
  "name" => $this->clone->name
295
  ];
296
 
297
- $this->cache->save("delete_job_{$this->clone->name}", $this->job);
298
  }
299
 
300
  /**
@@ -303,7 +297,7 @@ class Delete extends Job
303
  private function updateJob()
304
  {
305
  $this->job->nextDirectoryToDelete = trim($this->job->nextDirectoryToDelete);
306
- return $this->cache->save("delete_job_{$this->clone->name}", $this->job);
307
  }
308
 
309
  /**
@@ -349,7 +343,6 @@ class Delete extends Job
349
  // PROTECTION: Never delete any table that beginns with wp prefix of live site
350
  if (!$this->isExternalDatabase() && (new Strings())->startsWith($table, $this->wpdb->prefix)) {
351
  $this->log("Fatal Error: Trying to delete table {$table} of main WP installation!", Logger::TYPE_CRITICAL);
352
- return false;
353
  }
354
 
355
  $this->wpdb->query("DROP TABLE {$table}");
@@ -361,32 +354,32 @@ class Delete extends Job
361
  }
362
 
363
  /**
364
- *
365
  * Delete complete directory including all files and sub folders
366
- * @throws \Exception
367
  */
368
  public function deleteDirectory()
369
  {
370
  if ($this->isFatalError()) {
371
  $this->returnException('Can not delete directory: ' . $this->deleteDir . '. This seems to be the root directory. Exclude this directory from deleting and try again.');
372
- throw new \Exception('Can not delete directory: ' . $this->deleteDir . ' This seems to be the root directory. Exclude this directory from deleting and try again.');
373
  }
374
 
375
  // Finished or path does not exist
376
  if (
377
  empty($this->deleteDir) ||
378
- $this->deleteDir == get_home_path() ||
379
  !is_dir($this->deleteDir)
380
  ) {
381
  $this->job->current = "finish";
382
  $this->updateJob();
383
- return $this->deleteFinish();
 
384
  }
385
 
386
  $this->log("Delete staging site: " . $this->clone->path, Logger::TYPE_INFO);
387
 
388
  // Make sure the root dir is never deleted!
389
- if ($this->deleteDir == get_home_path()) {
390
  $this->log("Fatal Error 8: Trying to delete root of WP installation!", Logger::TYPE_CRITICAL);
391
  $this->returnException('Fatal Error 8: Trying to delete root of WP installation!');
392
  }
@@ -407,7 +400,7 @@ class Delete extends Job
407
  if (!$fs->delete($this->deleteDir)) {
408
  return;
409
  }
410
- } catch (\RuntimeException $ex) {
411
  $errorMessage = $ex->getMessage();
412
  $deleteStatus = "unfinished";
413
  }
@@ -426,7 +419,7 @@ class Delete extends Job
426
  }
427
 
428
  // Successful finish deleting job
429
- return $this->deleteFinish();
430
  }
431
 
432
  /**
@@ -439,9 +432,10 @@ class Delete extends Job
439
  // Throw fatal error if the folder has still not been deleted and there are files in it
440
  $isDirNotEmpty = false;
441
  if (is_dir($dir)) {
442
- $iterator = new \FilesystemIterator($dir);
443
  $isDirNotEmpty = $iterator->valid();
444
  }
 
445
  return $isDirNotEmpty;
446
  }
447
 
@@ -452,7 +446,7 @@ class Delete extends Job
452
  public function isFatalError()
453
  {
454
  $homePath = rtrim(get_home_path(), "/");
455
- return $homePath == rtrim($this->deleteDir, "/");
456
  }
457
 
458
  /**
@@ -470,7 +464,7 @@ class Delete extends Job
470
  // Check if clone exist and then remove it from options
471
  $this->log("Verifying existing clones...");
472
  foreach ($existingClones as $name => $clone) {
473
- if ($clone["path"] == $this->clone->path) {
474
  unset($existingClones[$name]);
475
  }
476
  }
@@ -480,7 +474,7 @@ class Delete extends Job
480
  }
481
 
482
  // Delete cached file
483
- $this->cache->delete("delete_job_{$this->clone->name}");
484
  $this->cache->delete("delete_directories_{$this->clone->name}");
485
  $this->cache->delete("clone_options");
486
 
@@ -496,11 +490,21 @@ class Delete extends Job
496
  */
497
  private function isExternalDatabaseError()
498
  {
499
- $db = new \mysqli($this->clone->databaseServer, $this->clone->databaseUser, $this->clone->databasePassword, $this->clone->databaseDatabase);
500
  if ($db->connect_error) {
501
  return true;
502
  }
503
 
504
  return false;
505
  }
 
 
 
 
 
 
 
 
 
 
506
  }
2
 
3
  namespace WPStaging\Backend\Modules\Jobs;
4
 
5
+ use Exception;
6
+ use FilesystemIterator;
7
+ use mysqli;
8
+ use RuntimeException;
9
+ use stdClass;
10
+ use wpdb;
11
  use WPStaging\Backend\Modules\Jobs\Exceptions\CloneNotFoundException;
12
  use WPStaging\Core\Utils\Logger;
13
  use WPStaging\Core\WPStaging;
22
  {
23
 
24
  /**
25
+ * @var stdClass
26
  */
27
  private $clone = false;
28
 
49
 
50
  /**
51
  *
52
+ * @var wpdb
53
  */
54
  public $wpdb;
55
 
101
  */
102
  private function getStagingDb()
103
  {
104
+ return new wpdb($this->clone->databaseUser, $this->clone->databasePassword, $this->clone->databaseDatabase, $this->clone->databaseServer);
105
  }
106
 
107
  /**
181
  foreach ($tables as $table) {
182
  $this->tables[] = [
183
  "name" => $table->Name,
184
+ "size" => $this->utilsMath->formatSize($table->Data_length + $table->Index_length)
185
  ];
186
  }
187
  }
205
  if (($content = @file_get_contents($path)) === false) {
206
  $this->log("Can not open {$path}. Can't read contents", Logger::TYPE_ERROR);
207
  }
208
+
209
  preg_match("/table_prefix\s*=\s*'(\w*)';/", $content, $matches);
210
 
211
  if (!empty($matches[1])) {
228
  return $this->clone->prefix;
229
  }
230
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
231
  /**
232
  * @return false
233
  */
247
  /**
248
  * Start Module
249
  * @param null|array $clone
250
+ * @return boolean
251
  */
252
  public function start($clone = null)
253
  {
258
  $this->getJob();
259
 
260
  $method = "delete" . ucwords($this->job->current);
261
+
262
+ if (method_exists($this, $method)) {
263
+ return $this->{$method}();
264
+ }
265
+
266
+ // If method doesn't exist probably the cache file was corrupted
267
+ // Just delete that corrupted cache file and restart itself.
268
+ $this->cache->delete($this->getJobCacheFileName());
269
+ return $this->start($clone);
270
  }
271
 
272
  /**
274
  */
275
  private function getJob()
276
  {
277
+ $this->job = $this->cache->get($this->getJobCacheFileName());
278
 
279
 
280
+ if ($this->job !== null && isset($this->job->current)) {
281
  return;
282
  }
283
 
288
  "name" => $this->clone->name
289
  ];
290
 
291
+ $this->cache->save($this->getJobCacheFileName(), $this->job);
292
  }
293
 
294
  /**
297
  private function updateJob()
298
  {
299
  $this->job->nextDirectoryToDelete = trim($this->job->nextDirectoryToDelete);
300
+ return $this->cache->save($this->getJobCacheFileName(), $this->job);
301
  }
302
 
303
  /**
343
  // PROTECTION: Never delete any table that beginns with wp prefix of live site
344
  if (!$this->isExternalDatabase() && (new Strings())->startsWith($table, $this->wpdb->prefix)) {
345
  $this->log("Fatal Error: Trying to delete table {$table} of main WP installation!", Logger::TYPE_CRITICAL);
 
346
  }
347
 
348
  $this->wpdb->query("DROP TABLE {$table}");
354
  }
355
 
356
  /**
 
357
  * Delete complete directory including all files and sub folders
358
+ * @throws Exception
359
  */
360
  public function deleteDirectory()
361
  {
362
  if ($this->isFatalError()) {
363
  $this->returnException('Can not delete directory: ' . $this->deleteDir . '. This seems to be the root directory. Exclude this directory from deleting and try again.');
364
+ throw new Exception('Can not delete directory: ' . $this->deleteDir . ' This seems to be the root directory. Exclude this directory from deleting and try again.');
365
  }
366
 
367
  // Finished or path does not exist
368
  if (
369
  empty($this->deleteDir) ||
370
+ $this->deleteDir === get_home_path() ||
371
  !is_dir($this->deleteDir)
372
  ) {
373
  $this->job->current = "finish";
374
  $this->updateJob();
375
+ $this->deleteFinish();
376
+ return;
377
  }
378
 
379
  $this->log("Delete staging site: " . $this->clone->path, Logger::TYPE_INFO);
380
 
381
  // Make sure the root dir is never deleted!
382
+ if ($this->deleteDir === get_home_path()) {
383
  $this->log("Fatal Error 8: Trying to delete root of WP installation!", Logger::TYPE_CRITICAL);
384
  $this->returnException('Fatal Error 8: Trying to delete root of WP installation!');
385
  }
400
  if (!$fs->delete($this->deleteDir)) {
401
  return;
402
  }
403
+ } catch (RuntimeException $ex) {
404
  $errorMessage = $ex->getMessage();
405
  $deleteStatus = "unfinished";
406
  }
419
  }
420
 
421
  // Successful finish deleting job
422
+ $this->deleteFinish();
423
  }
424
 
425
  /**
432
  // Throw fatal error if the folder has still not been deleted and there are files in it
433
  $isDirNotEmpty = false;
434
  if (is_dir($dir)) {
435
+ $iterator = new FilesystemIterator($dir);
436
  $isDirNotEmpty = $iterator->valid();
437
  }
438
+
439
  return $isDirNotEmpty;
440
  }
441
 
446
  public function isFatalError()
447
  {
448
  $homePath = rtrim(get_home_path(), "/");
449
+ return $homePath === rtrim($this->deleteDir, "/");
450
  }
451
 
452
  /**
464
  // Check if clone exist and then remove it from options
465
  $this->log("Verifying existing clones...");
466
  foreach ($existingClones as $name => $clone) {
467
+ if ($clone["path"] === $this->clone->path) {
468
  unset($existingClones[$name]);
469
  }
470
  }
474
  }
475
 
476
  // Delete cached file
477
+ $this->cache->delete($this->getJobCacheFileName());
478
  $this->cache->delete("delete_directories_{$this->clone->name}");
479
  $this->cache->delete("clone_options");
480
 
490
  */
491
  private function isExternalDatabaseError()
492
  {
493
+ $db = new mysqli($this->clone->databaseServer, $this->clone->databaseUser, $this->clone->databasePassword, $this->clone->databaseDatabase);
494
  if ($db->connect_error) {
495
  return true;
496
  }
497
 
498
  return false;
499
  }
500
+
501
+ /**
502
+ * Return the cache file which contains the info about current job
503
+ *
504
+ * @return string
505
+ */
506
+ private function getJobCacheFileName()
507
+ {
508
+ return "delete_job_{$this->clone->name}";
509
+ }
510
  }
Backend/Modules/Jobs/Directories.php CHANGED
@@ -4,7 +4,9 @@ namespace WPStaging\Backend\Modules\Jobs;
4
 
5
  use Exception;
6
  use WPStaging\Core\WPStaging;
 
7
  use WPStaging\Framework\CloningProcess\ExcludedPlugins;
 
8
  use WPStaging\Framework\Filesystem\Filters\ExcludeFilter;
9
  use WPStaging\Framework\Traits\FileScanToCacheTrait;
10
  use WPStaging\Framework\Utils\SlashMode;
@@ -452,25 +454,13 @@ class Directories extends JobExecutable
452
  /**
453
  * Check if directory is excluded
454
  * @param string $directory
455
- * @return bool
 
456
  */
457
  protected function isDirectoryExcluded($directory)
458
  {
459
- $directory = $this->strUtils->sanitizeDirectorySeparator($directory);
460
- foreach ($this->options->excludedDirectories as $excludedDirectory) {
461
- $excludedDirectory = $this->strUtils->sanitizeDirectorySeparator($excludedDirectory);
462
- // Check whether directory is itself is a part of excluded directories
463
- if ($excludedDirectory === $directory) {
464
- return true;
465
- }
466
-
467
- // Check whether directory a child of any excluded directories
468
- if ($this->strUtils->startsWith($directory, $excludedDirectory . '/')) {
469
- return true;
470
- }
471
- }
472
-
473
- return false;
474
  }
475
 
476
  /**
4
 
5
  use Exception;
6
  use WPStaging\Core\WPStaging;
7
+ use WPStaging\Framework\Adapter\Directory;
8
  use WPStaging\Framework\CloningProcess\ExcludedPlugins;
9
+ use WPStaging\Framework\Filesystem\Filesystem;
10
  use WPStaging\Framework\Filesystem\Filters\ExcludeFilter;
11
  use WPStaging\Framework\Traits\FileScanToCacheTrait;
12
  use WPStaging\Framework\Utils\SlashMode;
454
  /**
455
  * Check if directory is excluded
456
  * @param string $directory
457
+ *
458
+ * @return boolean
459
  */
460
  protected function isDirectoryExcluded($directory)
461
  {
462
+ // TODO: Inject Directory using DI
463
+ return WPStaging::make(Directory::class)->isPathInPathsList($directory, $this->options->excludedDirectories, true);
 
 
 
 
 
 
 
 
 
 
 
 
 
464
  }
465
 
466
  /**
Backend/Modules/Jobs/Files.php CHANGED
@@ -6,6 +6,7 @@ use SplFileObject;
6
  use WPStaging\Backend\Modules\Jobs\Cleaners\WpContentCleaner;
7
  use WPStaging\Core\Utils\Logger;
8
  use WPStaging\Core\WPStaging;
 
9
  use WPStaging\Framework\Filesystem\Filesystem;
10
  use WPStaging\Framework\Filesystem\Permissions;
11
  use WPStaging\Framework\Filesystem\WpUploadsFolderSymlinker;
@@ -580,6 +581,8 @@ class Files extends JobExecutable
580
  *
581
  * @param string $path Path
582
  * @return string
 
 
583
  */
584
  private function sanitizeDirectorySeparator($path)
585
  {
@@ -590,24 +593,29 @@ class Files extends JobExecutable
590
  * Check if directory is excluded from copying
591
  * @param string $directory
592
  * @return bool
 
 
593
  */
594
  private function isDirectoryExcluded($directory)
595
  {
 
 
 
 
 
 
 
596
  // Make sure that wp-staging-pro directory / plugin is never excluded
597
  if (strpos($directory, 'wp-staging') !== false || strpos($directory, 'wp-staging-pro') !== false) {
598
  return false;
599
  }
600
 
601
- $directory = trailingslashit($this->sanitizeDirectorySeparator($directory));
602
-
603
- foreach ($this->options->excludedDirectories as $excludedDirectory) {
604
- $excludedDirectory = trailingslashit($this->sanitizeDirectorySeparator($excludedDirectory));
605
- if (strpos($directory, $excludedDirectory) === 0 && !$this->isExtraDirectory($directory)) {
606
- return true;
607
- }
608
  }
609
 
610
- return false;
 
611
  }
612
 
613
  /**
6
  use WPStaging\Backend\Modules\Jobs\Cleaners\WpContentCleaner;
7
  use WPStaging\Core\Utils\Logger;
8
  use WPStaging\Core\WPStaging;
9
+ use WPStaging\Framework\Adapter\Directory;
10
  use WPStaging\Framework\Filesystem\Filesystem;
11
  use WPStaging\Framework\Filesystem\Permissions;
12
  use WPStaging\Framework\Filesystem\WpUploadsFolderSymlinker;
581
  *
582
  * @param string $path Path
583
  * @return string
584
+ *
585
+ * @todo replace usage with Strings::sanitizeDirectorySeparator
586
  */
587
  private function sanitizeDirectorySeparator($path)
588
  {
593
  * Check if directory is excluded from copying
594
  * @param string $directory
595
  * @return bool
596
+ *
597
+ * @todo Check can it be safely replaced with Directories::isDirectoryExcluded
598
  */
599
  private function isDirectoryExcluded($directory)
600
  {
601
+ $abspath = $this->sanitizeDirectorySeparator(ABSPATH);
602
+ $directory = $this->sanitizeDirectorySeparator($directory);
603
+
604
+ if ($abspath === $directory . '/') {
605
+ return false;
606
+ }
607
+
608
  // Make sure that wp-staging-pro directory / plugin is never excluded
609
  if (strpos($directory, 'wp-staging') !== false || strpos($directory, 'wp-staging-pro') !== false) {
610
  return false;
611
  }
612
 
613
+ if ($this->isExtraDirectory($directory)) {
614
+ return false;
 
 
 
 
 
615
  }
616
 
617
+ // TODO: Inject Directory using DI.
618
+ return WPStaging::make(Directory::class)->isPathInPathsList($directory, $this->options->excludedDirectories, true);
619
  }
620
 
621
  /**
Backend/Modules/Jobs/Job.php CHANGED
@@ -2,20 +2,17 @@
2
 
3
  namespace WPStaging\Backend\Modules\Jobs;
4
 
5
- // No Direct Access
6
- if (!defined("WPINC")) {
7
- die;
8
- }
9
-
10
  use DateInterval;
11
  use DateTime;
12
  use Exception;
 
13
  use WPStaging\Core\Utils\Cache;
14
  use WPStaging\Core\Utils\Logger;
15
  use WPStaging\Core\WPStaging;
16
  use WPStaging\Framework\Database\ExcludedTables;
17
  use WPStaging\Framework\Interfaces\ShutdownableInterface;
18
  use WPStaging\Framework\Traits\ResourceTrait;
 
19
 
20
  /**
21
  * Class Job
@@ -61,12 +58,18 @@ abstract class Job implements ShutdownableInterface
61
  */
62
  protected $excludedTableService;
63
 
 
 
 
64
  /**
65
  * Job constructor.
66
  * @throws Exception
67
  */
68
  public function __construct()
69
  {
 
 
 
70
  // TODO: inject using DI
71
  $this->excludedTableService = new ExcludedTables();
72
 
@@ -80,7 +83,7 @@ abstract class Job implements ShutdownableInterface
80
  $this->settings = (object)get_option("wpstg_settings", []);
81
 
82
  if (!$this->options) {
83
- $this->options = new \stdClass();
84
  }
85
 
86
  if (isset($this->options->existingClones) && is_object($this->options->existingClones)) {
@@ -97,7 +100,7 @@ abstract class Job implements ShutdownableInterface
97
  !isset($this->settings->maxFileSize) ||
98
  !isset($this->settings->fileLimit)
99
  ) {
100
- $this->settings = new \stdClass();
101
  $this->setDefaultSettings();
102
  }
103
 
@@ -110,6 +113,11 @@ abstract class Job implements ShutdownableInterface
110
  {
111
  // Commit logs
112
  if ($this->logger instanceof Logger) {
 
 
 
 
 
113
  $this->logger->commit();
114
  } else {
115
  if (defined('WPSTG_DEBUG') && WPSTG_DEBUG) {
@@ -141,9 +149,9 @@ abstract class Job implements ShutdownableInterface
141
  }
142
 
143
  /**
144
- * Save options
145
  * @param null|array|object $options
146
  * @return bool
 
147
  */
148
  public function saveOptions($options = null)
149
  {
@@ -220,7 +228,7 @@ abstract class Job implements ShutdownableInterface
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
  );
@@ -270,7 +278,7 @@ abstract class Job implements ShutdownableInterface
270
  }
271
 
272
  /**
273
- * Throw a errror message via json and stop further execution
274
  * @param string $message
275
  */
276
  public function returnException($message = '')
@@ -288,6 +296,7 @@ abstract class Job implements ShutdownableInterface
288
  }
289
 
290
  /**
 
291
  * @return bool
292
  */
293
  protected function isRunning()
2
 
3
  namespace WPStaging\Backend\Modules\Jobs;
4
 
 
 
 
 
 
5
  use DateInterval;
6
  use DateTime;
7
  use Exception;
8
+ use stdClass;
9
  use WPStaging\Core\Utils\Cache;
10
  use WPStaging\Core\Utils\Logger;
11
  use WPStaging\Core\WPStaging;
12
  use WPStaging\Framework\Database\ExcludedTables;
13
  use WPStaging\Framework\Interfaces\ShutdownableInterface;
14
  use WPStaging\Framework\Traits\ResourceTrait;
15
+ use WPStaging\Framework\Utils\Math;
16
 
17
  /**
18
  * Class Job
58
  */
59
  protected $excludedTableService;
60
 
61
+ /** @var \stdClass */
62
+ protected $utilsMath;
63
+
64
  /**
65
  * Job constructor.
66
  * @throws Exception
67
  */
68
  public function __construct()
69
  {
70
+
71
+ $this->utilsMath = new Math();
72
+
73
  // TODO: inject using DI
74
  $this->excludedTableService = new ExcludedTables();
75
 
83
  $this->settings = (object)get_option("wpstg_settings", []);
84
 
85
  if (!$this->options) {
86
+ $this->options = new stdClass();
87
  }
88
 
89
  if (isset($this->options->existingClones) && is_object($this->options->existingClones)) {
100
  !isset($this->settings->maxFileSize) ||
101
  !isset($this->settings->fileLimit)
102
  ) {
103
+ $this->settings = new stdClass();
104
  $this->setDefaultSettings();
105
  }
106
 
113
  {
114
  // Commit logs
115
  if ($this->logger instanceof Logger) {
116
+ if (isset($this->options->mainJob)) {
117
+ $timestamp = $this->options->existingClones[$this->options->clone]['datetime'];
118
+ $this->logger->setFileName($this->options->mainJob . '_' . date('Y-m-d_H-i-s', $timestamp));
119
+ }
120
+
121
  $this->logger->commit();
122
  } else {
123
  if (defined('WPSTG_DEBUG') && WPSTG_DEBUG) {
149
  }
150
 
151
  /**
 
152
  * @param null|array|object $options
153
  * @return bool
154
+ * @throws Exception
155
  */
156
  public function saveOptions($options = null)
157
  {
228
  sprintf(
229
  "RESET TIME: current time: %s, Start Time: %d, exec time limit: %s",
230
  $this->getRunningTime(),
231
+ WPStaging::$startTime,
232
  $this->findExecutionTimeLimit()
233
  )
234
  );
278
  }
279
 
280
  /**
281
+ * Throw an error message via json and stop further execution
282
  * @param string $message
283
  */
284
  public function returnException($message = '')
296
  }
297
 
298
  /**
299
+ * Is job running
300
  * @return bool
301
  */
302
  protected function isRunning()
Backend/Modules/Jobs/ProcessLock.php CHANGED
@@ -49,7 +49,7 @@ class ProcessLock extends JobExecutable
49
  // TODO: Create a Swal Response Class and Js library to handle that response or, Implement own Swal alternative
50
  'swalOptions' => [
51
  'title' => __('Error!', 'wp-staging'),
52
- 'html' => __('Hold on, another WP Staging process is already running...', 'wp-staging'),
53
  'confirmButtonText' => __('Stop other process', 'wp-staging'),
54
  'showCancelButton' => true,
55
  ],
49
  // TODO: Create a Swal Response Class and Js library to handle that response or, Implement own Swal alternative
50
  'swalOptions' => [
51
  'title' => __('Error!', 'wp-staging'),
52
+ 'html' => __('Hold on, another WP STAGING process is already running...', 'wp-staging'),
53
  'confirmButtonText' => __('Stop other process', 'wp-staging'),
54
  'showCancelButton' => true,
55
  ],
Backend/Modules/Jobs/Scan.php CHANGED
@@ -2,21 +2,20 @@
2
 
3
  namespace WPStaging\Backend\Modules\Jobs;
4
 
5
- // No Direct Access
6
- if (!defined("WPINC")) {
7
- die;
8
- }
9
-
10
  use Countable;
11
  use DirectoryIterator;
12
  use Exception;
 
 
13
  use WPStaging\Backend\Optimizer\Optimizer;
14
  use WPStaging\Core\Utils\Directories as DirectoriesUtil;
15
  use WPStaging\Core\WPStaging;
16
- use WPStaging\Framework\Database\LegacyDatabaseInfo;
 
17
  use WPStaging\Framework\Filesystem\Scanning\ScanConst;
18
  use WPStaging\Framework\Utils\Strings;
19
  use WPStaging\Framework\Utils\WpDefaultDirectories;
 
20
 
21
  /**
22
  * Class Scan
@@ -28,7 +27,7 @@ class Scan extends Job
28
  {
29
 
30
  /**
31
- * Class to use for WordPress core directories like wp-content, wp-admin, wp-includes
32
  * This doesn't contains class selector prefix
33
  *
34
  * @var string
@@ -36,7 +35,7 @@ class Scan extends Job
36
  const WP_CORE_DIR = "wpstg-wp-core-dir";
37
 
38
  /**
39
- * Class to use for WordPress non core directories
40
  * This doesn't contains class selector prefix
41
  *
42
  * @var string
@@ -49,9 +48,7 @@ class Scan extends Job
49
  /** @var DirectoriesUtil */
50
  private $objDirectories;
51
 
52
- /**
53
- * @var string
54
- */
55
  private $directoryToScanOnly;
56
 
57
  /**
@@ -59,6 +56,26 @@ class Scan extends Job
59
  */
60
  private $gifLoaderPath;
61
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  public function __construct($directoryToScanOnly = null)
63
  {
64
  // Accept both the absolute path or relative path with respect to wp root
@@ -68,17 +85,39 @@ class Scan extends Job
68
  $this->directoryToScanOnly = $directoryToScanOnly;
69
  }
70
 
 
 
 
 
71
  parent::__construct();
72
  }
73
 
74
  /**
75
- * @param $string $gifLoaderPath
76
  */
77
  public function setGifLoaderPath($gifLoaderPath)
78
  {
79
  $this->gifLoaderPath = $gifLoaderPath;
80
  }
81
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
82
  /**
83
  * Upon class initialization
84
  */
@@ -113,6 +152,11 @@ class Scan extends Job
113
  if (isset($_POST["clone"]) && array_key_exists($_POST["clone"], $this->options->existingClones)) {
114
  $this->options->current = $_POST["clone"];
115
  $this->options->currentClone = $this->options->existingClones[$this->options->current];
 
 
 
 
 
116
  }
117
 
118
  // Tables
@@ -167,27 +211,6 @@ class Scan extends Job
167
  $optimizer->installOptimizer();
168
  }
169
 
170
- /**
171
- * Format bytes into human readable form
172
- * @param float $bytes
173
- * @param int $precision
174
- * @return string
175
- */
176
- public function formatSize($bytes, $precision = 2)
177
- {
178
- if ((double) $bytes < 1) {
179
- return '';
180
- }
181
-
182
- $units = ['B', "KB", "MB", "GB", "TB"];
183
-
184
- $bytes = (double) $bytes;
185
- $base = log($bytes) / log(1000); // 1024 would be for MiB KiB etc
186
- $pow = pow(1000, $base - floor($base)); // Same rule for 1000
187
-
188
- return round($pow, $precision) . ' ' . $units[(int) floor($base)];
189
- }
190
-
191
  /**
192
  * @param null|bool $parentChecked Is parent folder selected
193
  * @param bool $forceDefault Default false. Set it to true,
@@ -200,8 +223,9 @@ class Scan extends Job
200
  */
201
  public function directoryListing($parentChecked = null, $forceDefault = false)
202
  {
 
203
  $directories = $this->directories;
204
- // Sort results
205
  uksort($directories, 'strcasecmp');
206
 
207
  $excludedDirectories = [];
@@ -214,7 +238,7 @@ class Scan extends Job
214
  }
215
 
216
  $output = '';
217
- foreach ($directories as $name => $directory) {
218
  // Not a directory, possibly a symlink, therefore we will skip it
219
  if (!is_array($directory)) {
220
  continue;
@@ -226,37 +250,33 @@ class Scan extends Job
226
 
227
  $dataPath = isset($data["path"]) ? $data["path"] : '';
228
  $dataSize = isset($data["size"]) ? $data["size"] : '';
229
- $strUtils = new Strings();
230
- $path = $strUtils->sanitizeDirectorySeparator($dataPath);
231
- $wpRoot = $strUtils->sanitizeDirectorySeparator(ABSPATH);
232
  $relPath = str_replace($wpRoot, '', $path);
233
  $dirPath = '/' . $relPath;
234
 
235
- // Select all wp core folders and their sub dirs.
236
- // Unselect all other folders (default setting)
237
- $isDisabled = ($name !== 'wp-admin' &&
238
- $name !== 'wp-includes' &&
239
- $name !== 'wp-content' &&
240
- $name !== 'sites') &&
241
- strpos(strrev($path), strrev($wpRoot . "wp-admin")) === false &&
242
- strpos(strrev($path), strrev($wpRoot . "wp-includes")) === false &&
243
- strpos(strrev($path), strrev($wpRoot . "wp-content")) === false;
244
-
245
- // make only wp-includes and wp-admin dirs not navigateable
246
- $isNavigateable = true;
247
- if ($strUtils->startsWith($path, $wpRoot . "wp-admin") !== false || $strUtils->startsWith($path, $wpRoot . "wp-includes") !== false) {
248
- $isNavigateable = false;
 
249
  }
250
 
251
- $isNavigateable = $isNavigateable ? 'true' : 'false';
252
-
253
- // class to differentiate between wp core and non core folders
254
- $class = !$isDisabled ? self::WP_CORE_DIR : self::WP_NON_CORE_DIR;
255
-
256
  $output .= "<div class='wpstg-dir'>";
257
  $output .= "<input type='checkbox' class='wpstg-check-dir " . $class . "'";
258
 
259
- $shouldBeChecked = $parentChecked !== null ? $parentChecked : !$isDisabled;
 
260
  if (!$forceDefault && $this->isUpdateOrResetJob() && (!$this->isPathInDirectories($dirPath, $excludedDirectories))) {
261
  $shouldBeChecked = true;
262
  } elseif (!$forceDefault && $this->isUpdateOrResetJob()) {
@@ -274,14 +294,16 @@ class Scan extends Job
274
  $output .= " name='selectedDirectories[]' value='{$relPath}' data-scanned='false' data-navigateable='{$isNavigateable}'>";
275
 
276
  $output .= "<a href='#' class='wpstg-expand-dirs ";
277
- if ($isDisabled) {
 
 
278
  $output .= " disabled";
279
  }
280
 
281
- $output .= "'>{$name}";
282
  $output .= "</a>";
283
  $output .= ($this->gifLoaderPath !== '' && $isNavigateable === 'true') ? "<img src='{$this->gifLoaderPath}' class='wpstg-is-dir-loading' alt='loading' />" : "";
284
- $output .= "<span class='wpstg-size-info'>{$this->formatSize( $dataSize )}</span>";
285
  $output .= isset($this->settings->debugMode) ? "<span class='wpstg-size-info'> {$dataPath}</span>" : "";
286
  $output .= "</div>";
287
  }
@@ -299,10 +321,6 @@ class Scan extends Job
299
  */
300
  public function hasFreeDiskSpace($excludedDirectories, $extraDirectories)
301
  {
302
- if (!function_exists("disk_free_space")) {
303
- return null;
304
- }
305
-
306
  $dirUtils = new WpDefaultDirectories();
307
  $selectedDirectories = $dirUtils->getWpCoreDirectories();
308
  $excludedDirectories = $dirUtils->getExcludedDirectories($excludedDirectories);
@@ -326,8 +344,18 @@ class Scan extends Job
326
  }
327
  }
328
 
 
 
 
 
 
 
 
 
 
329
  $data = [
330
- 'usedspace' => $this->formatSize($size)
 
331
  ];
332
 
333
  echo json_encode($data);
@@ -340,6 +368,7 @@ class Scan extends Job
340
  protected function getTables()
341
  {
342
  $db = WPStaging::getInstance()->get("wpdb");
 
343
 
344
  $sql = "SHOW TABLE STATUS";
345
 
@@ -354,13 +383,13 @@ class Scan extends Job
354
  // On the main website of a multisite installation, do not select network site tables beginning with wp_1_, wp_2_ etc.
355
  // (On network sites, the correct tables are selected anyway)
356
  if (
357
- ( ! empty($db->prefix) && strpos($table->Name, $db->prefix) !== 0)
358
- || (is_multisite() && is_main_site() && preg_match('/^' . $db->prefix . '\d+_/', $table->Name))
359
  ) {
360
  $this->options->excludedTables[] = $table->Name;
361
  }
362
 
363
- if ($table->Comment !== "VIEW" && !LegacyDatabaseInfo::isBackupTable($table->Name)) {
364
  $currentTables[] = [
365
  "name" => $table->Name,
366
  "size" => ($table->Data_length + $table->Index_length)
@@ -381,7 +410,24 @@ class Scan extends Job
381
  return;
382
  }
383
 
384
- $directories = new DirectoryIterator($dirPath);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
385
 
386
  foreach ($directories as $directory) {
387
  // Not a valid directory
@@ -523,26 +569,13 @@ class Scan extends Job
523
  /**
524
  * Is the path present is given list of directories
525
  * @param string $path
526
- * @param array $directories
527
  *
528
  * @return boolean
529
  */
530
  protected function isPathInDirectories($path, $directories)
531
  {
532
- // Check whether directory is itself is a part of excluded directories
533
- if (in_array($path, $directories)) {
534
- return true;
535
- }
536
-
537
- // Check whether directory a child of any excluded directories
538
- $strUtils = new Strings();
539
- foreach ($directories as $directory) {
540
- if ($strUtils->startsWith($path, $directory . '/')) {
541
- return true;
542
- }
543
- }
544
-
545
- return false;
546
  }
547
 
548
  /**
2
 
3
  namespace WPStaging\Backend\Modules\Jobs;
4
 
 
 
 
 
 
5
  use Countable;
6
  use DirectoryIterator;
7
  use Exception;
8
+ use RuntimeException;
9
+ use UnexpectedValueException;
10
  use WPStaging\Backend\Optimizer\Optimizer;
11
  use WPStaging\Core\Utils\Directories as DirectoriesUtil;
12
  use WPStaging\Core\WPStaging;
13
+ use WPStaging\Framework\Adapter\Directory;
14
+ use WPStaging\Framework\Filesystem\DiskWriteCheck;
15
  use WPStaging\Framework\Filesystem\Scanning\ScanConst;
16
  use WPStaging\Framework\Utils\Strings;
17
  use WPStaging\Framework\Utils\WpDefaultDirectories;
18
+ use WPStaging\Pro\Backup\Exceptions\DiskNotWritableException;
19
 
20
  /**
21
  * Class Scan
27
  {
28
 
29
  /**
30
+ * CSS class name to use for WordPress core directories like wp-content, wp-admin, wp-includes
31
  * This doesn't contains class selector prefix
32
  *
33
  * @var string
35
  const WP_CORE_DIR = "wpstg-wp-core-dir";
36
 
37
  /**
38
+ * CSS class name to use for WordPress non core directories
39
  * This doesn't contains class selector prefix
40
  *
41
  * @var string
48
  /** @var DirectoriesUtil */
49
  private $objDirectories;
50
 
51
+ /** @var string */
 
 
52
  private $directoryToScanOnly;
53
 
54
  /**
56
  */
57
  private $gifLoaderPath;
58
 
59
+ /**
60
+ * @var Strings
61
+ */
62
+ private $strUtils;
63
+
64
+ /**
65
+ * @var Directory
66
+ */
67
+ private $dirAdapter;
68
+
69
+ /**
70
+ * @var DiskWriteCheck
71
+ */
72
+ private $diskWriteCheck;
73
+
74
+ /**
75
+ * @var string Path to the info icon
76
+ */
77
+ private $infoIconPath;
78
+
79
  public function __construct($directoryToScanOnly = null)
80
  {
81
  // Accept both the absolute path or relative path with respect to wp root
85
  $this->directoryToScanOnly = $directoryToScanOnly;
86
  }
87
 
88
+ // TODO: inject using DI when available
89
+ $this->strUtils = new Strings();
90
+ $this->dirAdapter = WPStaging::make(Directory::class);
91
+ $this->diskWriteCheck = WPStaging::make(DiskWriteCheck::class);
92
  parent::__construct();
93
  }
94
 
95
  /**
96
+ * @param string $gifLoaderPath
97
  */
98
  public function setGifLoaderPath($gifLoaderPath)
99
  {
100
  $this->gifLoaderPath = $gifLoaderPath;
101
  }
102
 
103
+ /**
104
+ * @param string $infoIconPath
105
+ */
106
+ public function setInfoIcon($infoIconPath)
107
+ {
108
+ $this->infoIconPath = $infoIconPath;
109
+ }
110
+
111
+ /**
112
+ * Return the path of info icon
113
+ *
114
+ * @return string
115
+ */
116
+ public function getInfoIcon()
117
+ {
118
+ return $this->infoIconPath;
119
+ }
120
+
121
  /**
122
  * Upon class initialization
123
  */
152
  if (isset($_POST["clone"]) && array_key_exists($_POST["clone"], $this->options->existingClones)) {
153
  $this->options->current = $_POST["clone"];
154
  $this->options->currentClone = $this->options->existingClones[$this->options->current];
155
+ // Make sure no warning is shown when updating/resetting an old clone having no exclude rules options
156
+ $this->options->currentClone['excludeSizeRules'] = isset($this->options->currentClone['excludeSizeRules']) ? $this->options->currentClone['excludeSizeRules'] : [];
157
+ $this->options->currentClone['excludeGlobRules'] = isset($this->options->currentClone['excludeGlobRules']) ? $this->options->currentClone['excludeGlobRules'] : [];
158
+ // Make sure no warning is shown when updating/resetting an old clone having emails allowed option
159
+ $this->options->currentClone['emailsAllowed'] = isset($this->options->currentClone['emailsAllowed']) ? $this->options->currentClone['emailsAllowed'] : true;
160
  }
161
 
162
  // Tables
211
  $optimizer->installOptimizer();
212
  }
213
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
214
  /**
215
  * @param null|bool $parentChecked Is parent folder selected
216
  * @param bool $forceDefault Default false. Set it to true,
223
  */
224
  public function directoryListing($parentChecked = null, $forceDefault = false)
225
  {
226
+
227
  $directories = $this->directories;
228
+
229
  uksort($directories, 'strcasecmp');
230
 
231
  $excludedDirectories = [];
238
  }
239
 
240
  $output = '';
241
+ foreach ($directories as $dirName => $directory) {
242
  // Not a directory, possibly a symlink, therefore we will skip it
243
  if (!is_array($directory)) {
244
  continue;
250
 
251
  $dataPath = isset($data["path"]) ? $data["path"] : '';
252
  $dataSize = isset($data["size"]) ? $data["size"] : '';
253
+ $path = $this->strUtils->sanitizeDirectorySeparator($dataPath);
254
+ $wpRoot = $this->strUtils->sanitizeDirectorySeparator(ABSPATH);
 
255
  $relPath = str_replace($wpRoot, '', $path);
256
  $dirPath = '/' . $relPath;
257
 
258
+ // Check if directory name or directory path is not WP core folder
259
+ $isNotWPCoreDir = ($dirName !== 'wp-admin' &&
260
+ $dirName !== 'wp-includes' &&
261
+ $dirName !== 'wp-content') &&
262
+ strpos($path, $wpRoot . "wp-admin") === false &&
263
+ strpos($path, $wpRoot . "wp-includes") === false &&
264
+ strpos($path, $wpRoot . "wp-content") === false;
265
+
266
+ // html class to differentiate between wp core and non core folders
267
+ $class = $isNotWPCoreDir ? self::WP_NON_CORE_DIR : self::WP_CORE_DIR;
268
+
269
+ // Make wp-includes and wp-admin directory items not expandable
270
+ $isNavigateable = 'true';
271
+ if ($this->strUtils->startsWith($path, $wpRoot . "wp-admin") !== false || $this->strUtils->startsWith($path, $wpRoot . "wp-includes") !== false) {
272
+ $isNavigateable = 'false';
273
  }
274
 
 
 
 
 
 
275
  $output .= "<div class='wpstg-dir'>";
276
  $output .= "<input type='checkbox' class='wpstg-check-dir " . $class . "'";
277
 
278
+ // Decide if item checkbox is active or not
279
+ $shouldBeChecked = $parentChecked !== null ? $parentChecked : !$isNotWPCoreDir;
280
  if (!$forceDefault && $this->isUpdateOrResetJob() && (!$this->isPathInDirectories($dirPath, $excludedDirectories))) {
281
  $shouldBeChecked = true;
282
  } elseif (!$forceDefault && $this->isUpdateOrResetJob()) {
294
  $output .= " name='selectedDirectories[]' value='{$relPath}' data-scanned='false' data-navigateable='{$isNavigateable}'>";
295
 
296
  $output .= "<a href='#' class='wpstg-expand-dirs ";
297
+
298
+ // Set menu item to 'disable'
299
+ if ($isNotWPCoreDir) {
300
  $output .= " disabled";
301
  }
302
 
303
+ $output .= "'>{$dirName}";
304
  $output .= "</a>";
305
  $output .= ($this->gifLoaderPath !== '' && $isNavigateable === 'true') ? "<img src='{$this->gifLoaderPath}' class='wpstg-is-dir-loading' alt='loading' />" : "";
306
+ $output .= "<span class='wpstg-size-info'>{$this->utilsMath->formatSize( $dataSize )}</span>";
307
  $output .= isset($this->settings->debugMode) ? "<span class='wpstg-size-info'> {$dataPath}</span>" : "";
308
  $output .= "</div>";
309
  }
321
  */
322
  public function hasFreeDiskSpace($excludedDirectories, $extraDirectories)
323
  {
 
 
 
 
324
  $dirUtils = new WpDefaultDirectories();
325
  $selectedDirectories = $dirUtils->getWpCoreDirectories();
326
  $excludedDirectories = $dirUtils->getExcludedDirectories($excludedDirectories);
344
  }
345
  }
346
 
347
+ $errorMessage = null;
348
+ try {
349
+ $this->diskWriteCheck->checkPathCanStoreEnoughBytes(ABSPATH, $size);
350
+ } catch (RuntimeException $ex) {
351
+ $errorMessage = $ex->getMessage();
352
+ } catch (DiskNotWritableException $ex) {
353
+ $errorMessage = $ex->getMessage();
354
+ }
355
+
356
  $data = [
357
+ 'requiredSpace' => $this->utilsMath->formatSize($size),
358
+ 'errorMessage' => $errorMessage
359
  ];
360
 
361
  echo json_encode($data);
368
  protected function getTables()
369
  {
370
  $db = WPStaging::getInstance()->get("wpdb");
371
+ $dbPrefix = WPStaging::getTablePrefix();
372
 
373
  $sql = "SHOW TABLE STATUS";
374
 
383
  // On the main website of a multisite installation, do not select network site tables beginning with wp_1_, wp_2_ etc.
384
  // (On network sites, the correct tables are selected anyway)
385
  if (
386
+ ( ! empty($dbPrefix) && strpos($table->Name, $dbPrefix) !== 0)
387
+ || (is_multisite() && is_main_site() && preg_match('/^' . $dbPrefix . '\d+_/', $table->Name))
388
  ) {
389
  $this->options->excludedTables[] = $table->Name;
390
  }
391
 
392
+ if ($table->Comment !== "VIEW") {
393
  $currentTables[] = [
394
  "name" => $table->Name,
395
  "size" => ($table->Data_length + $table->Index_length)
410
  return;
411
  }
412
 
413
+ try {
414
+ $directories = new DirectoryIterator($dirPath);
415
+ } catch (UnexpectedValueException $ex) {
416
+ echo json_encode([
417
+ 'success' => false,
418
+ 'type' => '',
419
+ // TODO: Create a Swal Response Class and Js library to handle that response or, Implement own Swal alternative
420
+ 'swalOptions' => [
421
+ 'title' => __('Error!', 'wp-staging'),
422
+ 'html' => $ex->getMessage(),
423
+ 'cancelButtonText' => __('Ok', 'wp-staging'),
424
+ 'showCancelButton' => true,
425
+ 'showConfirmButton' => false,
426
+ ],
427
+ ]);
428
+
429
+ exit();
430
+ }
431
 
432
  foreach ($directories as $directory) {
433
  // Not a valid directory
569
  /**
570
  * Is the path present is given list of directories
571
  * @param string $path
572
+ * @param array $directories List of directories relative to ABSPATH with leading slash
573
  *
574
  * @return boolean
575
  */
576
  protected function isPathInDirectories($path, $directories)
577
  {
578
+ return $this->dirAdapter->isPathInPathsList($path, $directories, true);
 
 
 
 
 
 
 
 
 
 
 
 
 
579
  }
580
 
581
  /**
Backend/Modules/Jobs/SearchReplace.php CHANGED
@@ -2,10 +2,12 @@
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;
8
- use WPStaging\Framework\CloningProcess\SearchReplace\SearchReplaceService;
 
9
  use WPStaging\Framework\Traits\DbRowsGeneratorTrait;
10
  use WPStaging\Framework\Utils\Strings;
11
 
@@ -23,6 +25,7 @@ class SearchReplace extends CloningProcess
23
  {
24
  use TotalStepsAreNumberOfTables;
25
  use DbRowsGeneratorTrait;
 
26
 
27
  /**
28
  * The maximum number of failed attempts after which the Job should just move on.
@@ -67,29 +70,17 @@ class SearchReplace extends CloningProcess
67
  */
68
  public $tmpPrefix;
69
 
70
- /**
71
- * @var Helper
72
- */
73
- private $helper;
74
-
75
- /**
76
- * @var SearchReplaceService
77
- */
78
- private $searchReplaceService;
79
-
80
  /**
81
  * Initialize
82
  */
83
  public function initialize()
84
  {
85
  $this->initializeDbObjects();
86
- $this->helper = new Helper();
87
  $this->total = count($this->options->tables);
88
  $this->tmpPrefix = $this->options->prefix;
89
  $this->strings = new Strings();
90
  $this->sourceHostname = $this->getSourceHostname();
91
  $this->destinationHostname = $this->getDestinationHostname();
92
- $this->searchReplaceService = new SearchReplaceService();
93
  }
94
 
95
  public function start()
@@ -151,14 +142,6 @@ class SearchReplace extends CloningProcess
151
  return true;
152
  }
153
 
154
- private function getSourceHostname()
155
- {
156
- if ($this->isSubDir()) {
157
- return trailingslashit($this->helper->getHomeUrlWithoutScheme()) . $this->getSubDir();
158
- }
159
- return $this->helper->getHomeUrlWithoutScheme();
160
- }
161
-
162
  /**
163
  * Copy Tables
164
  * @param string $tableName
@@ -166,8 +149,8 @@ class SearchReplace extends CloningProcess
166
  */
167
  private function updateTable($tableName)
168
  {
169
- $strings = new Strings();
170
- $table = $strings->str_replace_first($this->productionDb->prefix, '', $tableName);
171
  $newTableName = $this->tmpPrefix . $table;
172
 
173
  // Save current job
@@ -295,10 +278,10 @@ class SearchReplace extends CloningProcess
295
  {
296
  $table = esc_sql($table);
297
 
298
- $args['search_for'] = $this->searchReplaceService->generateHostnamePatterns($this->sourceHostname);
299
  $args['search_for'][] = ABSPATH;
300
 
301
- $args['replace_with'] = $this->searchReplaceService->generateHostnamePatterns($this->destinationHostname);
302
  $args['replace_with'][] = $this->options->destinationDir;
303
 
304
  $this->debugLog("DB Search & Replace: Search: {$args['search_for'][0]}", Logger::TYPE_INFO);
@@ -323,7 +306,7 @@ class SearchReplace extends CloningProcess
323
 
324
  list($primary_key, $columns) = $primaryKeyAndColumns;
325
 
326
- if ($this->options->job->current != $table) {
327
  $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));
328
  }
329
 
@@ -352,7 +335,7 @@ class SearchReplace extends CloningProcess
352
  }
353
 
354
  // Filter certain rows (of other plugins)
355
- $filter = $this->searchReplaceService->excludedStrings();
356
 
357
  $filter = apply_filters('wpstg_clone_searchreplace_excl_rows', $filter);
358
 
@@ -408,7 +391,7 @@ class SearchReplace extends CloningProcess
408
  }
409
 
410
  // Skip primary key column
411
- if ($column == $primary_key) {
412
  $whereSql[] = $column . ' = "' . wpstg_mysql_escape_mimic($dataRow) . '"';
413
  continue;
414
  }
@@ -423,7 +406,7 @@ class SearchReplace extends CloningProcess
423
  $dataRow = $searchReplace->replace($dataRow);
424
 
425
  // Something was changed
426
- if ($row[$column] != $dataRow) {
427
  $updateSql[] = $column . ' = "' . wpstg_mysql_escape_mimic($dataRow) . '"';
428
  $doUpdate = true;
429
  }
@@ -447,7 +430,7 @@ class SearchReplace extends CloningProcess
447
  } // end row loop
448
 
449
  /// DEBUG
450
- $this->logDebug(
451
  sprintf(
452
  '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',
453
  $processed,
@@ -458,7 +441,7 @@ class SearchReplace extends CloningProcess
458
  $this->getRunningTime(),
459
  ($this->isThreshold() ? 'yes' : 'no')
460
  )
461
- );
462
  /// DEBUG
463
 
464
  unset($row,$updateSql,$whereSql,$sql,$currentRow);
@@ -511,7 +494,7 @@ class SearchReplace extends CloningProcess
511
  $this->options->job->failedAttempts = 0;
512
  }
513
 
514
- if ($this->options->job->start != 0) {
515
  // The job was attempted too many times and should be skipped now.
516
  return !($this->options->job->failedAttempts > $this->maxFailedAttempts);
517
  }
@@ -519,7 +502,7 @@ class SearchReplace extends CloningProcess
519
  $this->options->job->total = (int)$this->productionDb->get_var("SELECT COUNT(1) FROM {$oldTableName}");
520
  $this->options->job->failedAttempts = 0;
521
 
522
- if ($this->options->job->total == 0) {
523
  $this->finishStep();
524
  return false;
525
  }
@@ -564,53 +547,23 @@ class SearchReplace extends CloningProcess
564
  $this->options->clonedTables[] = $this->options->tables[$this->options->currentStep];
565
 
566
  // Reset job
567
- $this->options->job = new \stdClass();
568
 
569
  return true;
570
  }
571
 
572
- /**
573
- * Check if WP is installed in subdir
574
- * @return boolean
575
- */
576
- private function isSubDir()
577
- {
578
- // Compare names without scheme to bypass cases where siteurl and home have different schemes http / https
579
- // This is happening much more often than you would expect
580
- $siteurl = preg_replace('#^https?://#', '', rtrim(get_option('siteurl'), '/'));
581
- $home = preg_replace('#^https?://#', '', rtrim(get_option('home'), '/'));
582
-
583
- return $home !== $siteurl;
584
- }
585
-
586
- /**
587
- * Get the install sub directory if WP is installed in sub directory
588
- * @return string
589
- */
590
- private function getSubDir()
591
- {
592
- $home = get_option('home');
593
- $siteurl = get_option('siteurl');
594
-
595
- if (empty($home) || empty($siteurl)) {
596
- return '';
597
- }
598
-
599
- return str_replace([$home, '/'], '', $siteurl);
600
- }
601
-
602
  /**
603
  * Updates the (next) job start to reflect the number of actually processed rows.
604
  *
605
  * If nothing was processed, then the job start will be ticked by 1.
606
  *
607
  * @param int $processed The number of actually processed rows in this run.
608
- * @param \wpdb $db The wpdb instance being used to process.
609
  * @param string $table The table being processed.
610
  *
611
  * @return void The method does not return any value.
612
  */
613
- protected function updateJobStart($processed, \wpdb $db, $table)
614
  {
615
  $this->processed = absint($processed);
616
 
2
 
3
  namespace WPStaging\Backend\Modules\Jobs;
4
 
5
+ use stdClass;
6
+ use wpdb;
7
  use WPStaging\Core\Utils\Logger;
8
  use WPStaging\Core\Utils\Multisite;
9
+ use WPStaging\Framework\Traits\DatabaseSearchReplaceTrait;
10
+ use WPStaging\Core\WPStaging;
11
  use WPStaging\Framework\Traits\DbRowsGeneratorTrait;
12
  use WPStaging\Framework\Utils\Strings;
13
 
25
  {
26
  use TotalStepsAreNumberOfTables;
27
  use DbRowsGeneratorTrait;
28
+ use DatabaseSearchReplaceTrait;
29
 
30
  /**
31
  * The maximum number of failed attempts after which the Job should just move on.
70
  */
71
  public $tmpPrefix;
72
 
 
 
 
 
 
 
 
 
 
 
73
  /**
74
  * Initialize
75
  */
76
  public function initialize()
77
  {
78
  $this->initializeDbObjects();
 
79
  $this->total = count($this->options->tables);
80
  $this->tmpPrefix = $this->options->prefix;
81
  $this->strings = new Strings();
82
  $this->sourceHostname = $this->getSourceHostname();
83
  $this->destinationHostname = $this->getDestinationHostname();
 
84
  }
85
 
86
  public function start()
142
  return true;
143
  }
144
 
 
 
 
 
 
 
 
 
145
  /**
146
  * Copy Tables
147
  * @param string $tableName
149
  */
150
  private function updateTable($tableName)
151
  {
152
+ $strings = new Strings();
153
+ $table = $strings->str_replace_first(WPStaging::getTablePrefix(), '', $tableName);
154
  $newTableName = $this->tmpPrefix . $table;
155
 
156
  // Save current job
278
  {
279
  $table = esc_sql($table);
280
 
281
+ $args['search_for'] = $this->generateHostnamePatterns($this->sourceHostname);
282
  $args['search_for'][] = ABSPATH;
283
 
284
+ $args['replace_with'] = $this->generateHostnamePatterns($this->destinationHostname);
285
  $args['replace_with'][] = $this->options->destinationDir;
286
 
287
  $this->debugLog("DB Search & Replace: Search: {$args['search_for'][0]}", Logger::TYPE_INFO);
306
 
307
  list($primary_key, $columns) = $primaryKeyAndColumns;
308
 
309
+ if ($this->options->job->current !== $table) {
310
  $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));
311
  }
312
 
335
  }
336
 
337
  // Filter certain rows (of other plugins)
338
+ $filter = $this->excludedStrings();
339
 
340
  $filter = apply_filters('wpstg_clone_searchreplace_excl_rows', $filter);
341
 
391
  }
392
 
393
  // Skip primary key column
394
+ if ($column === $primary_key) {
395
  $whereSql[] = $column . ' = "' . wpstg_mysql_escape_mimic($dataRow) . '"';
396
  continue;
397
  }
406
  $dataRow = $searchReplace->replace($dataRow);
407
 
408
  // Something was changed
409
+ if ($row[$column] !== $dataRow) {
410
  $updateSql[] = $column . ' = "' . wpstg_mysql_escape_mimic($dataRow) . '"';
411
  $doUpdate = true;
412
  }
430
  } // end row loop
431
 
432
  /// DEBUG
433
+ /* $this->logDebug(
434
  sprintf(
435
  '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',
436
  $processed,
441
  $this->getRunningTime(),
442
  ($this->isThreshold() ? 'yes' : 'no')
443
  )
444
+ );*/
445
  /// DEBUG
446
 
447
  unset($row,$updateSql,$whereSql,$sql,$currentRow);
494
  $this->options->job->failedAttempts = 0;
495
  }
496
 
497
+ if ($this->options->job->start !== 0) {
498
  // The job was attempted too many times and should be skipped now.
499
  return !($this->options->job->failedAttempts > $this->maxFailedAttempts);
500
  }
502
  $this->options->job->total = (int)$this->productionDb->get_var("SELECT COUNT(1) FROM {$oldTableName}");
503
  $this->options->job->failedAttempts = 0;
504
 
505
+ if ($this->options->job->total === 0) {
506
  $this->finishStep();
507
  return false;
508
  }
547
  $this->options->clonedTables[] = $this->options->tables[$this->options->currentStep];
548
 
549
  // Reset job
550
+ $this->options->job = new stdClass();
551
 
552
  return true;
553
  }
554
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
555
  /**
556
  * Updates the (next) job start to reflect the number of actually processed rows.
557
  *
558
  * If nothing was processed, then the job start will be ticked by 1.
559
  *
560
  * @param int $processed The number of actually processed rows in this run.
561
+ * @param wpdb $db The wpdb instance being used to process.
562
  * @param string $table The table being processed.
563
  *
564
  * @return void The method does not return any value.
565
  */
566
+ protected function updateJobStart($processed, wpdb $db, $table)
567
  {
568
  $this->processed = absint($processed);
569
 
Backend/Modules/SystemInfo.php CHANGED
@@ -463,7 +463,7 @@ class SystemInfo
463
  *
464
  * @return string
465
  */
466
- private function getPHPUser()
467
  {
468
 
469
  $user = '';
463
  *
464
  * @return string
465
  */
466
+ public function getPHPUser()
467
  {
468
 
469
  $user = '';
Backend/Notices/DisabledItemsNotice.php CHANGED
@@ -9,7 +9,7 @@ use WPStaging\Framework\SiteInfo;
9
  *
10
  * This class is used to show notice about what WP Staging has disabled on the staging site
11
  *
12
- * @package WPStaging\Backend\Notices;
13
  */
14
  class DisabledItemsNotice extends BooleanNotice
15
  {
9
  *
10
  * This class is used to show notice about what WP Staging has disabled on the staging site
11
  *
12
+ * @see \WPStaging\Backend\Notices\Notices;
13
  */
14
  class DisabledItemsNotice extends BooleanNotice
15
  {
Backend/Notices/Notices.php CHANGED
@@ -6,6 +6,7 @@ namespace WPStaging\Backend\Notices;
6
  * Admin Notices | Warnings | Messages
7
  */
8
 
 
9
  use WPStaging\Backend\Pro\Notices\Notices as ProNotices;
10
  use WPStaging\Core\Utils\Cache;
11
  use WPStaging\Core\Utils\Logger;
@@ -33,6 +34,9 @@ class Notices
33
  */
34
  private $assets;
35
 
 
 
 
36
  /**
37
  * @var string The key that holds directory listing errors in the container.
38
  */
@@ -62,9 +66,9 @@ class Notices
62
  /**
63
  * check whether the plugin is pro version
64
  *
 
65
  * @todo Implement this in a separate class related to plugin. Then replace it with dependency injection. Add filters
66
  *
67
- * @return boolean
68
  */
69
  protected function isPro()
70
  {
@@ -110,6 +114,7 @@ class Notices
110
 
111
  return $days <= $difference;
112
  }
 
113
  /**
114
  * Get current page
115
  * @return string post, page
@@ -132,17 +137,15 @@ class Notices
132
  {
133
  $viewsNoticesPath = "{$this->path}views/notices/";
134
 
135
- // Show "rate the plugin". Free version only
136
- if (!$this->isPro()) {
137
- if ($this->canShow("wpstg_rating", 7) && $this->getCurrentScreen() !== 'page' && $this->getCurrentScreen() !== 'post') {
138
- require_once "{$viewsNoticesPath}rating.php";
139
- }
140
  }
141
 
142
- // Never show disable mail message if free version
143
  $outgoingMailsDisabled = false;
144
 
145
- // Show all pro version notices
146
  if ($this->isPro()) {
147
  $proNotices = new ProNotices($this);
148
  // TODO: inject CloneOptions using DI
@@ -152,7 +155,7 @@ class Notices
152
  }
153
 
154
  // Show notice about what disabled in the staging site. (Show only on staging site)
155
- if ((new DisabledItemsNotice())->isEnabled()) {
156
  // TODO: inject ExcludedPlugins using DI
157
  $excludedPlugins = (array)(new ExcludedPlugins())->getExcludedPlugins();
158
  // use require here instead of require_once otherwise unit tests will always fail,
@@ -160,72 +163,103 @@ class Notices
160
  require "{$viewsNoticesPath}disabled-items-notice.php";
161
  }
162
 
163
- // Display notices below in wp staging admin pages only
 
 
 
 
 
 
 
 
164
  if (!current_user_can("update_plugins") || !$this->isAdminPage()) {
165
  return;
166
  }
167
 
168
- // Cache directory is not writable
169
  /** @var Cache $cache */
170
  $cache = WPStaging::getInstance()->get("cache");
171
  $cacheDir = $cache->getCacheDir();
172
- if (!is_dir($cacheDir) || !is_writable($cacheDir)) {
173
  require_once "{$viewsNoticesPath}/cache-directory-permission-problem.php";
174
  }
175
 
176
- // Logger directory is not writable
177
  /** @var Logger $logger */
178
  $logger = WPStaging::getInstance()->get("logger");
179
  $logsDir = $logger->getLogDir();
180
- if (!is_dir($logsDir) || !is_writable($logsDir)) {
181
  require_once "{$viewsNoticesPath}/logs-directory-permission-problem.php";
182
  }
183
 
184
- // Staging directory is not writable
185
- if (!is_writable(ABSPATH)) {
186
  require_once "{$viewsNoticesPath}/staging-directory-permission-problem.php";
187
  }
188
 
189
- // WPSTAGING is not tested with current WordPress version
190
- if (!$this->isPro() && version_compare(WPStaging::getInstance()->get('WPSTG_COMPATIBLE'), get_bloginfo("version"), "<")) {
191
  require_once "{$viewsNoticesPath}wp-version-compatible-message.php";
192
  }
193
 
194
- // Different scheme in home and siteurl
195
- if ($this->isDifferentScheme()) {
196
  require_once "{$viewsNoticesPath}wrong-scheme.php";
197
  }
198
 
199
- // Outdated version of WP Staging Hooks
200
- if ($this->isUsingOutdatedWpstgHooksPlugin()) {
201
  require_once "{$viewsNoticesPath}outdated-wp-staging-hooks.php";
202
  }
203
 
 
204
  $this->showDirectoryListingWarningNotice($viewsNoticesPath);
205
  }
206
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
207
  /**
208
  * Displays the notice that we could not prevent
209
  * directory listing on a sensitive folder for some reason.
210
  *
 
211
  * @see \WPStaging\Framework\Filesystem\Filesystem::mkdir The place where all errors are enqueued
212
  * to be displayed as a single notice here.
213
  *
214
  * Note: When refactoring this, keep in mind this code should be
215
  * called only once, otherwise the message would be enqueued multiple times.
216
  *
217
- * @param string $viewsNoticesPath The path to the views folder.
218
  */
219
  private function showDirectoryListingWarningNotice($viewsNoticesPath)
220
  {
221
- $directoryListingErrors = WPStaging::getInstance()->getContainer()->getFromArray(static::$directoryListingErrors);
222
 
223
- // Early bail: No errors to show
224
- if (empty($directoryListingErrors)) {
 
 
225
  return;
226
  }
227
 
228
- // Early bail: These warnings were disabled by the user.
229
  if ((bool)apply_filters('wpstg.notices.hideDirectoryListingWarnings', false)) {
230
  return;
231
  }
@@ -240,7 +274,7 @@ class Notices
240
  private function isDifferentScheme()
241
  {
242
  $siteurlScheme = parse_url(get_option('siteurl'), PHP_URL_SCHEME);
243
- $homeScheme = parse_url(get_option('home'), PHP_URL_SCHEME);
244
 
245
  return !($siteurlScheme === $homeScheme);
246
  }
@@ -252,12 +286,12 @@ class Notices
252
  private function isUsingOutdatedWpstgHooksPlugin()
253
  {
254
  // Minimum version to check
255
- $versionToCheck = '0.0.2';
256
 
257
  // Path to WP Staging Hooks plugins in a directory
258
  $wpstgHooksPath = 'wp-staging-hooks/wp-staging-hooks.php';
259
 
260
- // Plugin doesn't exist, so no need to show notice
261
  if (file_exists(WP_PLUGIN_DIR . '/' . $wpstgHooksPath)) {
262
  $wpstgHooksData = get_plugin_data(WP_PLUGIN_DIR . '/' . $wpstgHooksPath);
263
  // Only show notice if current version is below required min version.
@@ -267,7 +301,7 @@ class Notices
267
  // Path to WP Staging Hooks plugins directly in plugins dir
268
  $wpstgHooksPath = 'wp-staging-hooks.php';
269
 
270
- // Plugin doesn't exist, so no need to show notice
271
  if (file_exists(WP_PLUGIN_DIR . '/' . $wpstgHooksPath)) {
272
  $wpstgHooksData = get_plugin_data(WP_PLUGIN_DIR . '/' . $wpstgHooksPath);
273
  // Only show notice if current version is below required min version.
6
  * Admin Notices | Warnings | Messages
7
  */
8
 
9
+ use wpdb;
10
  use WPStaging\Backend\Pro\Notices\Notices as ProNotices;
11
  use WPStaging\Core\Utils\Cache;
12
  use WPStaging\Core\Utils\Logger;
34
  */
35
  private $assets;
36
 
37
+ //** For testing all notices */
38
+ const SHOW_ALL_NOTICES = false;
39
+
40
  /**
41
  * @var string The key that holds directory listing errors in the container.
42
  */
66
  /**
67
  * check whether the plugin is pro version
68
  *
69
+ * @return boolean
70
  * @todo Implement this in a separate class related to plugin. Then replace it with dependency injection. Add filters
71
  *
 
72
  */
73
  protected function isPro()
74
  {
114
 
115
  return $days <= $difference;
116
  }
117
+
118
  /**
119
  * Get current page
120
  * @return string post, page
137
  {
138
  $viewsNoticesPath = "{$this->path}views/notices/";
139
 
140
+ // Show notice "rate the plugin". Free version only
141
+ if (self::SHOW_ALL_NOTICES || (!$this->isPro() && ($this->canShow("wpstg_rating", 7) && $this->getCurrentScreen() !== 'page' && $this->getCurrentScreen() !== 'post'))) {
142
+ require_once "{$viewsNoticesPath}rating.php";
 
 
143
  }
144
 
145
+ // Never show disable mail message if it's free version
146
  $outgoingMailsDisabled = false;
147
 
148
+ // Show all notices of the pro version
149
  if ($this->isPro()) {
150
  $proNotices = new ProNotices($this);
151
  // TODO: inject CloneOptions using DI
155
  }
156
 
157
  // Show notice about what disabled in the staging site. (Show only on staging site)
158
+ if (self::SHOW_ALL_NOTICES || ((new DisabledItemsNotice())->isEnabled())) {
159
  // TODO: inject ExcludedPlugins using DI
160
  $excludedPlugins = (array)(new ExcludedPlugins())->getExcludedPlugins();
161
  // use require here instead of require_once otherwise unit tests will always fail,
163
  require "{$viewsNoticesPath}disabled-items-notice.php";
164
  }
165
 
166
+ $db = WPStaging::getInstance()->get('wpdb');
167
+ $optionTable = $db->prefix . 'options';
168
+ if (self::SHOW_ALL_NOTICES || (current_user_can("manage_options") && $this->isOptionTablePrimaryKeyMissing($db, $optionTable))) {
169
+ require "{$viewsNoticesPath}wp-options-missing-pk.php";
170
+ }
171
+
172
+ /**
173
+ * Display all notices below this line in WP STAGING admin pages only and only to administrators!
174
+ */
175
  if (!current_user_can("update_plugins") || !$this->isAdminPage()) {
176
  return;
177
  }
178
 
179
+ // Show notice Cache directory is not writable
180
  /** @var Cache $cache */
181
  $cache = WPStaging::getInstance()->get("cache");
182
  $cacheDir = $cache->getCacheDir();
183
+ if (self::SHOW_ALL_NOTICES || (!is_dir($cacheDir) || !is_writable($cacheDir))) {
184
  require_once "{$viewsNoticesPath}/cache-directory-permission-problem.php";
185
  }
186
 
187
+ // Show notice Logger directory is not writable
188
  /** @var Logger $logger */
189
  $logger = WPStaging::getInstance()->get("logger");
190
  $logsDir = $logger->getLogDir();
191
+ if (self::SHOW_ALL_NOTICES || (!is_dir($logsDir) || !is_writable($logsDir))) {
192
  require_once "{$viewsNoticesPath}/logs-directory-permission-problem.php";
193
  }
194
 
195
+ // Show notice Staging directory is not writable
196
+ if (self::SHOW_ALL_NOTICES || (!is_writable(ABSPATH))) {
197
  require_once "{$viewsNoticesPath}/staging-directory-permission-problem.php";
198
  }
199
 
200
+ // Show notice WP STAGING is not tested with current WordPress version
201
+ if (self::SHOW_ALL_NOTICES || (!$this->isPro() && version_compare(WPStaging::getInstance()->get('WPSTG_COMPATIBLE'), get_bloginfo("version"), "<"))) {
202
  require_once "{$viewsNoticesPath}wp-version-compatible-message.php";
203
  }
204
 
205
+ // Show notice Different scheme in home and siteurl
206
+ if (self::SHOW_ALL_NOTICES || ($this->isDifferentScheme())) {
207
  require_once "{$viewsNoticesPath}wrong-scheme.php";
208
  }
209
 
210
+ // Show notice Outdated version of WP Staging Hooks
211
+ if (self::SHOW_ALL_NOTICES || ($this->isUsingOutdatedWpstgHooksPlugin())) {
212
  require_once "{$viewsNoticesPath}outdated-wp-staging-hooks.php";
213
  }
214
 
215
+ // Show notice Failed to prevent directory listing
216
  $this->showDirectoryListingWarningNotice($viewsNoticesPath);
217
  }
218
 
219
+ /**
220
+ * Check whether the wp_options table is missing primary key | auto increment
221
+ * @param wpdb $db
222
+ * @param string $optionTable
223
+ *
224
+ * @return boolean
225
+ */
226
+ private function isOptionTablePrimaryKeyMissing($db, $optionTable)
227
+ {
228
+ $result = $db->dbh->query("SELECT option_id FROM {$optionTable} LIMIT 1");
229
+ $fInfo = $result->fetch_field();
230
+ $result->free_result();
231
+
232
+ // Check whether the flag have primary key and auto increment flag
233
+ if (($fInfo->flags & MYSQLI_PRI_KEY_FLAG) && ($fInfo->flags & MYSQLI_AUTO_INCREMENT_FLAG)) {
234
+ return false;
235
+ }
236
+
237
+ return true;
238
+ }
239
+
240
  /**
241
  * Displays the notice that we could not prevent
242
  * directory listing on a sensitive folder for some reason.
243
  *
244
+ * @param string $viewsNoticesPath The path to the views folder.
245
  * @see \WPStaging\Framework\Filesystem\Filesystem::mkdir The place where all errors are enqueued
246
  * to be displayed as a single notice here.
247
  *
248
  * Note: When refactoring this, keep in mind this code should be
249
  * called only once, otherwise the message would be enqueued multiple times.
250
  *
 
251
  */
252
  private function showDirectoryListingWarningNotice($viewsNoticesPath)
253
  {
 
254
 
255
+ $directoryListingErrors = WPStaging::getInstance()->getContainer()->getFromArray(static::$directoryListingErrors);
256
+
257
+ // Early bail: No errors to show
258
+ if (!self::SHOW_ALL_NOTICES && empty($directoryListingErrors)) {
259
  return;
260
  }
261
 
262
+ // Early bail: These warnings were disabled by the user.
263
  if ((bool)apply_filters('wpstg.notices.hideDirectoryListingWarnings', false)) {
264
  return;
265
  }
274
  private function isDifferentScheme()
275
  {
276
  $siteurlScheme = parse_url(get_option('siteurl'), PHP_URL_SCHEME);
277
+ $homeScheme = parse_url(get_option('home'), PHP_URL_SCHEME);
278
 
279
  return !($siteurlScheme === $homeScheme);
280
  }
286
  private function isUsingOutdatedWpstgHooksPlugin()
287
  {
288
  // Minimum version to check
289
+ $versionToCheck = '0.0.4';
290
 
291
  // Path to WP Staging Hooks plugins in a directory
292
  $wpstgHooksPath = 'wp-staging-hooks/wp-staging-hooks.php';
293
 
294
+ // Only show notice if plugin exists for above path
295
  if (file_exists(WP_PLUGIN_DIR . '/' . $wpstgHooksPath)) {
296
  $wpstgHooksData = get_plugin_data(WP_PLUGIN_DIR . '/' . $wpstgHooksPath);
297
  // Only show notice if current version is below required min version.
301
  // Path to WP Staging Hooks plugins directly in plugins dir
302
  $wpstgHooksPath = 'wp-staging-hooks.php';
303
 
304
+ // Only show notice if plugin exists for above path
305
  if (file_exists(WP_PLUGIN_DIR . '/' . $wpstgHooksPath)) {
306
  $wpstgHooksData = get_plugin_data(WP_PLUGIN_DIR . '/' . $wpstgHooksPath);
307
  // Only show notice if current version is below required min version.
Backend/Optimizer/wp-staging-optimizer.php CHANGED
@@ -9,13 +9,13 @@
9
  * Do not use any of these methods in WP STAGING code base as this mu-plugin can be missing!
10
  *
11
  * Author: René Hermenau
12
- * Version: 1.4.1
13
  * Author URI: https://wp-staging.com
14
  */
15
 
16
  // Version number of this mu-plugin. Important for automatic updates
17
  if (!defined('WPSTG_OPTIMIZER_VERSION')) {
18
- define('WPSTG_OPTIMIZER_VERSION', '1.4.1');
19
  }
20
 
21
  /** @return string */
@@ -76,7 +76,7 @@ function wpstgIsExcludedPlugin($plugin)
76
  /**
77
  * Remove all plugins except wp-staging and wp-staging-pro from blog-active plugins
78
  *
79
- * @param array $plugins numerically keyed array of plugin names
80
  *
81
  * @return array
82
  */
@@ -121,11 +121,13 @@ function wpstgExcludeSitePlugins($plugins)
121
  return $plugins;
122
  }
123
 
124
- foreach ($plugins as $key => $plugin) {
125
  // Default filter. Must be at the beginning or wp staging plugin will be filtered and killed
126
  if (strpos($plugin, 'wp-staging') !== false || wpstgIsExcludedPlugin($plugin)) {
127
  continue;
128
  }
 
 
129
  }
130
 
131
  return $plugins;
@@ -172,11 +174,12 @@ add_filter('template_directory', 'wpstgDisableTheme');
172
  /**
173
  * Should the current request be processed by optimizer?
174
  *
 
 
175
  * @return bool
176
  */
177
  function wpstgIsOptimizerRequest()
178
  {
179
-
180
  if (!wpstgIsEnabledOptimizer()) {
181
  return false;
182
  }
@@ -184,9 +187,9 @@ function wpstgIsOptimizerRequest()
184
  if (
185
  defined('DOING_AJAX') &&
186
  DOING_AJAX &&
187
- isset($_POST['action']) &&
188
- strpos($_POST['action'], 'wpstg_send_report') === false &&
189
- strpos($_POST['action'], 'wpstg') === 0
190
  ) {
191
  return true;
192
  }
9
  * Do not use any of these methods in WP STAGING code base as this mu-plugin can be missing!
10
  *
11
  * Author: René Hermenau
12
+ * Version: 1.5.1
13
  * Author URI: https://wp-staging.com
14
  */
15
 
16
  // Version number of this mu-plugin. Important for automatic updates
17
  if (!defined('WPSTG_OPTIMIZER_VERSION')) {
18
+ define('WPSTG_OPTIMIZER_VERSION', '1.5.1');
19
  }
20
 
21
  /** @return string */
76
  /**
77
  * Remove all plugins except wp-staging and wp-staging-pro from blog-active plugins
78
  *
79
+ * @param array $plugins numerically keyed array of plugin names (index=>name)
80
  *
81
  * @return array
82
  */
121
  return $plugins;
122
  }
123
 
124
+ foreach ($plugins as $plugin => $timestamp) {
125
  // Default filter. Must be at the beginning or wp staging plugin will be filtered and killed
126
  if (strpos($plugin, 'wp-staging') !== false || wpstgIsExcludedPlugin($plugin)) {
127
  continue;
128
  }
129
+
130
+ unset($plugins[$plugin]);
131
  }
132
 
133
  return $plugins;
174
  /**
175
  * Should the current request be processed by optimizer?
176
  *
177
+ * For WP STAGING requests that require other plugins to be active, use raw_wpstg_{actionName}
178
+ *
179
  * @return bool
180
  */
181
  function wpstgIsOptimizerRequest()
182
  {
 
183
  if (!wpstgIsEnabledOptimizer()) {
184
  return false;
185
  }
187
  if (
188
  defined('DOING_AJAX') &&
189
  DOING_AJAX &&
190
+ isset($_REQUEST['action']) &&
191
+ strpos($_REQUEST['action'], 'wpstg_send_report') === false &&
192
+ strpos($_REQUEST['action'], 'wpstg') === 0
193
  ) {
194
  return true;
195
  }
Backend/views/_main/footer.php CHANGED
@@ -2,17 +2,34 @@
2
  <div id="wpstg-error-details"></div>
3
  </div>
4
  <div id='wpstg-footer'>
5
- <br/>
6
- <strong>&nbsp;&nbsp;<?php _e("FAQ", "wp-staging")?></strong><br/>
7
- - <a href="https://wp-staging.com/docs/staging-site-redirects-live-site/" target="_blank" rel="external"><?php _e("Can not login to staging site", "wp-staging")?></a> <br/>
8
- - <a href="https://wp-staging.com/docs/staging-site-redirects-live-site/" target="_blank" rel="external"><?php _e("Staging site redirects to production site", "wp-staging")?></a> <br/>
9
- - <a href="https://wp-staging.com/docs/fix-white-or-blank-page-after-pushing-fatal-error-500/" target="_blank" rel="external"><?php _e("Staging site returns blank white page", "wp-staging")?></a> <br/>
10
- - <a href="https://wp-staging.com/docs/css-layout-broken-after-push/" target="_blank" rel="external"><?php _e("CSS & layout broken after push", "wp-staging")?></a> <br/>
11
- - <a href="https://wp-staging.com/docs/skip-woocommerce-orders-and-products/" target="_blank" rel="external"><?php _e("Skip WooCommerce Orders and Products", "wp-staging")?></a> <br/>
12
- - <a href="https://wp-staging.com/docs/can-not-update-wp-staging-staging-site/" target="_blank" rel="external"><?php _e("Can not update WP Staging plugin", "wp-staging")?></a> <br/>
13
- - <a href="https://wp-staging.com/docs/page-not-found-error-404-after-pushing/" target="_blank" rel="external"><?php _e("Page not found – Error 404 after Pushing", "wp-staging")?></a> <br/>
14
- - <a href="https://wp-staging.com/docs/troubleshooting-try-this-first/" target="_blank" rel="external"><?php _e("More", "wp-staging")?></a><br/><br/>
15
- <?php echo __('Did not find a solution?', 'wp-staging');?>
16
  <br>
17
- <?php echo sprintf(__('Open a <a href="%s" target="_blank" rel="external nofollow">support ticket</a> and we will resolve it quickly.', 'wp-staging'), 'https://wp-staging.com/support');?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  </div>
2
  <div id="wpstg-error-details"></div>
3
  </div>
4
  <div id='wpstg-footer'>
5
+ <strong class="wpstg-footer--title"><?php _e("Knowledgebase", "wp-staging") ?></strong>
6
+ <ul>
7
+ <li><a href="https://wp-staging.com/docs/staging-site-redirects-live-site/" target="_blank" rel="external"><?php _e("Can not login to staging site", "wp-staging") ?></a></li>
8
+ <li><a href="https://wp-staging.com/docs/staging-site-redirects-live-site/" target="_blank" rel="external"><?php _e("Staging site redirects to production site", "wp-staging") ?></a></li>
9
+ <li><a href="https://wp-staging.com/docs/fix-white-or-blank-page-after-pushing-fatal-error-500/" target="_blank" rel="external"><?php _e("Staging site returns blank white page", "wp-staging") ?></a></li>
10
+ <li><a href="https://wp-staging.com/docs/css-layout-broken-after-push/" target="_blank" rel="external"><?php _e("CSS & layout broken after push", "wp-staging") ?></a></li>
11
+ <li><a href="https://wp-staging.com/docs/skip-woocommerce-orders-and-products/" target="_blank" rel="external"><?php _e("Skip WooCommerce Orders and Products", "wp-staging") ?></a></li>
12
+ <li><a href="https://wp-staging.com/docs/can-not-update-wp-staging-staging-site/" target="_blank" rel="external"><?php _e("Can not update WP STAGING plugin", "wp-staging") ?></a></li>
13
+ <li><a href="https://wp-staging.com/docs/page-not-found-error-404-after-pushing/" target="_blank" rel="external"><?php _e("Page not found – Error 404 after Pushing", "wp-staging") ?></a></li>
14
+ <li><a href="https://wp-staging.com/docs/troubleshooting-try-this-first/" target="_blank" rel="external"><?php _e("All articles", "wp-staging") ?></a></li>
15
+ </ul>
16
  <br>
17
+ <?php echo __('Still questions?', 'wp-staging'); ?><br>
18
+ <?php echo sprintf(__('Open a <a href="%s" target="_blank" rel="external nofollow">support ticket</a> and get in contact with us.', 'wp-staging'), 'https://wp-staging.com/support'); ?>
19
+ </div>
20
+ <div class='wpstg-share-button-container'>
21
+ <div class='wpstg-share-button wpstg-share-button-twitter' data-share-url="https://wordpress.org/plugins/wp-staging">
22
+ <div class='box'>
23
+ <a href="https://twitter.com/intent/tweet?button_hashtag=wpstaging&text=Check%20out%20this%20plugin%20for%20creating%20a%20one-click%20WordPress%20testing%20site&via=wpstg" target='_blank'>
24
+ <span class='wpstg-share'><?php echo __('Tweet #wpstaging', 'wp-staging'); ?></span>
25
+ </a>
26
+ </div>
27
+ </div>
28
+ <div class="wpstg-share-button wpstg-share-button-twitter">
29
+ <div class="box">
30
+ <a href="https://twitter.com/intent/follow?original_referer=http%3A%2F%2Fsrc.wordpress-develop.dev%2Fwp-admin%2Fadmin.php%3Fpage%3Dwpstg-settings&ref_src=twsrc%5Etfw&region=follow_link&screen_name=wpstg&tw_p=followbutton" target="_blank">
31
+ <span class='wpstg-share'><?php echo __('Follow @wpstg', 'wp-staging'); ?></span>
32
+ </a>
33
+ </div>
34
+ </div>
35
  </div>
Backend/views/_main/header.php CHANGED
@@ -1,43 +1,18 @@
 
 
 
1
  <span class="wpstg-logo">
2
- <img src="<?php echo $this->assets->getAssetsUrl("img/logo_clean_small_212_25.png") ?>">
3
  </span>
4
 
5
  <span class="wpstg-version">
6
  <?php if (defined('WPSTGPRO_VERSION')) {
7
- echo "Pro";
8
- } ?> Version <?php echo WPStaging\Core\WPStaging::getVersion() ?>
9
  </span>
10
-
11
  <div class="wpstg-header">
12
- <div class='wpstg-share-button-container'>
13
- <div class='wpstg-share-button wpstg-share-button-twitter' data-share-url="https://wordpress.org/plugins/wp-staging">
14
- <div class='box'>
15
- <a href="https://twitter.com/intent/tweet?button_hashtag=wpstaging&text=Check%20out%20this%20plugin%20for%20creating%20a%20one-click%20WordPress%20testing%20site&via=wpstg" target='_blank'>
16
- <span class='wpstg-share'><?php echo __('Tweet #wpstaging', 'wp-staging'); ?></span>
17
- </a>
18
- </div>
19
- </div>
20
- <div class="wpstg-share-button wpstg-share-button-twitter">
21
- <div class="box">
22
- <a href="https://twitter.com/intent/follow?original_referer=http%3A%2F%2Fsrc.wordpress-develop.dev%2Fwp-admin%2Fadmin.php%3Fpage%3Dwpstg-settings&ref_src=twsrc%5Etfw&region=follow_link&screen_name=wpstg&tw_p=followbutton" target="_blank">
23
- <span class='wpstg-share'><?php echo __('Follow @wpstg', 'wp-staging'); ?></span>
24
- </a>
25
- </div>
26
- </div>
27
- <div class="wpstg-share-button wpstg-share-button-facebook" data-share-url="https://wordpress.org/plugins/wp-staging">
28
- <div class="box">
29
- <a href="https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fwp-staging.com%2Fwow-cloning-wordpress-websites-has-never-been-easier%2F" target="_blank">
30
- <span class='wpstg-share'><?php echo __('Share on Facebook', 'wp-staging'); ?></span>
31
- </a>
32
- </div>
33
- </div>
34
- </div>
35
-
36
  <?php if ($_GET['page'] === 'wpstg_clone') { ?>
37
- <div class="wpstg-fs-14">
38
- <?php _e("Tutorial:", "wp-staging") ?> <a href="https://wp-staging.com/docs/copy-staging-site-to-live-site/" target="_blank"><?php _e("Push staging site to production website", "wp-staging") ?></a>
39
- </div>
40
-
41
  <?php
42
  $latestReleasedVersion = get_option('wpstg_version_latest');
43
  $display = 'none;';
@@ -50,8 +25,8 @@
50
  ?>
51
 
52
  <div id="wpstg-update-notify" style="display:<?php echo $display; ?>">
53
- <strong><?php echo sprintf(__("WP STAGING Pro %s is available!", 'wp-staging'), $latestReleasedVersion); ?></strong><br/>
54
- <?php echo sprintf(__('Important: Please update WP STAGING Pro before pushing the staging site to production site. <a href="%s" target="_blank">What\'s New?</a>', 'wp-staging'), 'https://wp-staging.com/wp-staging-pro-changelog'); ?>
55
  </div>
56
 
57
  <?php } ?>
1
+
2
+
3
+ <div>
4
  <span class="wpstg-logo">
5
+ <img src="<?php echo $this->assets->getAssetsUrl("img/logo-wp-staging-1468x230.png") ?>" width="212">
6
  </span>
7
 
8
  <span class="wpstg-version">
9
  <?php if (defined('WPSTGPRO_VERSION')) {
10
+ echo "PRO";
11
+ } ?> v. <?php echo WPStaging\Core\WPStaging::getVersion() ?>
12
  </span>
13
+ </div>
14
  <div class="wpstg-header">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  <?php if ($_GET['page'] === 'wpstg_clone') { ?>
 
 
 
 
16
  <?php
17
  $latestReleasedVersion = get_option('wpstg_version_latest');
18
  $display = 'none;';
25
  ?>
26
 
27
  <div id="wpstg-update-notify" style="display:<?php echo $display; ?>">
28
+ <strong><?php echo sprintf(__("New: WP STAGING PRO v. %s is available.", 'wp-staging'), $latestReleasedVersion); ?></strong><br/>
29
+ <?php echo sprintf(__('Important: Please update the plugin before pushing the staging site to production site. <a href="%s" target="_blank">What\'s New?</a>', 'wp-staging'), 'https://wp-staging.com/wp-staging-pro-changelog'); ?>
30
  </div>
31
 
32
  <?php } ?>
Backend/views/_main/report-issue.php CHANGED
@@ -1,4 +1,5 @@
1
  <div class="wpstg-report-issue-form">
 
2
  <div class="wpstg-field">
3
  <input placeholder="Your email address..." type="email" id="wpstg-report-email" class="wpstg-report-email">
4
  </div>
@@ -29,7 +30,7 @@
29
  <?php _e('Submit', 'wp-staging'); ?>
30
  </button>
31
  <span class="spinner"></span>
32
- <a href="#" id="wpstg-report-cancel" class="wpstg-report-cancel">Close</a>
33
  <div class="wpstg-clear"></div>
34
  </div>
35
  </div>
1
  <div class="wpstg-report-issue-form">
2
+ <div class="arrow-up"></div>
3
  <div class="wpstg-field">
4
  <input placeholder="Your email address..." type="email" id="wpstg-report-email" class="wpstg-report-email">
5
  </div>
30
  <?php _e('Submit', 'wp-staging'); ?>
31
  </button>
32
  <span class="spinner"></span>
33
+ <a href="#" id="wpstg-report-cancel" class="wpstg-report-cancel wpstg--red">CLOSE [X]</a>
34
  <div class="wpstg-clear"></div>
35
  </div>
36
  </div>
Backend/views/backup/free-version.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @see \WPStaging\Pro\Backup\Ajax\Listing::render
5
+ */
6
+
7
+ ?>
8
+
9
+ <div id="wpstg-free-version-backups">
10
+ <ul>
11
+ <li class="wpstg-clone wpstg-dark-alert">
12
+ <p><strong><?php esc_html_e('Backup & Migration is a PRO feature!', 'wp-staging'); ?></strong></p>
13
+ <p><?php _e('<a href="https://wp-staging.com/?utm_source=wp-admin&utm_medium=wp-admin&utm_campaign=backup-restore&utm_term=backup-restore" target="_blank" id="wpstg-button-backup-upgrade" class="wpstg-button--primary wpstg-button--cta-red wpstg-border--violet">Get Started</a>', 'wp-staging'); ?></p>
14
+ </li>
15
+ </ul>
16
+ </div>
Backend/views/backup/listing-backups-no-results.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @var WPStaging\Framework\TemplateEngine\TemplateEngine $this
4
+ * @var string $urlAssets
5
+ * @var string $isValidLicenseKey
6
+ * @see \WPStaging\Pro\Backup\Ajax\FileList::render()
7
+ */
8
+ ?>
9
+ <li id="wpstg-backup-no-results" class="wpstg-clone">
10
+ <img class="wpstg--dashicons" src="<?php echo $urlAssets; ?>svg/vendor/dashicons/cloud.svg" alt="cloud">
11
+ <div class="no-backups-found-text">
12
+ <?php if ($isValidLicenseKey) : ?>
13
+ <?php _e('No Backups found. Create your first Backup above!', 'wp-staging'); ?>
14
+ <?php else :?>
15
+ <strong id="wpstg-invalid-license-message" class="wpstg--red"><?php echo sprintf(__('Please<a href="%s">use a valid license key</a> to create and access your backups.', 'wp-staging'), admin_url() . 'admin.php?page=wpstg-license'); ?></strong>
16
+ <?php endif; ?>
17
+ </div>
18
+ </li>
Backend/views/backup/listing-single-backup.php CHANGED
@@ -1,19 +1,35 @@
1
  <?php
2
 
 
 
3
  /**
4
  * @var \WPStaging\Framework\TemplateEngine\TemplateEngine $this
5
  * @var \WPStaging\Pro\Backup\Entity\ListableBackup $backup
 
6
  */
7
  $name = $backup->backupName;
8
- $downloadUrl = $backup->downloadUrl;
9
  $notes = $backup->notes;
10
- $createdAt = $backup->dateCreatedFormatted;
 
11
  $size = $backup->size;
12
  $id = $backup->id;
13
  $automatedBackup = $backup->automatedBackup;
14
  $legacy = $backup->legacy;
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  ?>
16
- <li id="<?php echo esc_attr($id) ?>" class="wpstg-clone wpstg-backup">
17
 
18
  <div class="wpstg-clone-header">
19
  <span class="wpstg-clone-title">
@@ -23,24 +39,23 @@ $legacy = $backup->legacy;
23
  <div class="wpstg-dropdown wpstg-action-dropdown">
24
  <a href="#" class="wpstg-dropdown-toggler transparent">
25
  <?php _e("Actions", "wp-staging"); ?>
 
26
  </a>
27
  <div class="wpstg-dropdown-menu">
28
- <a href="#" class="wpstg-clone-action wpstg--backup--import"
29
- data-filePath="<?php echo esc_attr($backup->fullPath) ?>"
30
- data-title="<?php esc_attr_e('Import Backup', 'wp-staging') ?>"
31
- title="<?php esc_attr_e('Import Backup', 'wp-staging') ?>">
32
- <?php esc_html_e('Import', 'wp-staging') ?>
 
33
  </a>
34
- <a href="#" class="wpstg--backup--download wpstg-merge-clone wpstg-clone-action"
35
- data-md5="<?php echo esc_attr($backup->md5BaseName) ?>"
36
- data-url="<?php echo esc_url($downloadUrl ?: '') ?>"
37
- data-title="<?php esc_attr_e('Download Backup', 'wp-staging') ?>"
38
- data-title-export="<?php esc_attr_e('Exporting Database Tables...', 'wp-staging') ?>"
39
- data-btn-cancel-txt="<?php esc_attr_e('CANCEL', 'wp-staging') ?>"
40
- data-btn-download-txt="<?php esc_attr_e($downloadUrl ? 'Download' : 'Export & Download', 'wp-staging') ?>"
41
  title="<?php esc_attr_e('Download backup file on local system', 'wp-staging') ?>">
42
  <?php esc_html_e('Download', 'wp-staging') ?>
43
  </a>
 
44
  <a href="#" class="wpstg--backup--edit wpstg-clone-action"
45
  data-md5="<?php echo esc_attr($backup->md5BaseName); ?>"
46
  data-name="<?php echo esc_attr($name); ?>"
@@ -48,6 +63,7 @@ $legacy = $backup->legacy;
48
  title="<?php esc_attr_e('Edit backup name and / or notes', 'wp-staging') ?>">
49
  <?php esc_html_e('Edit', 'wp-staging') ?>
50
  </a>
 
51
  <a href="#" class="wpstg-remove-clone wpstg-clone-action wpstg-delete-backup"
52
  data-md5="<?php echo esc_attr($backup->md5BaseName) ?>"
53
  title="<?php esc_attr_e('Delete this backup. This action can not be undone!', 'wp-staging') ?>">
@@ -63,15 +79,27 @@ $legacy = $backup->legacy;
63
 
64
  <div class="wpstg-staging-info">
65
  <ul>
66
- <li><strong>Id:</strong> <?php esc_html_e($id); ?></li>
 
 
 
 
 
67
  <li>
68
  <strong><?php esc_html_e('Created on:', 'wp-staging') ?></strong>
69
- <?php echo esc_html($this->transformToWpFormat(new DateTime($createdAt))); ?>
 
 
 
 
70
  </li>
 
71
  <?php if ($notes) : ?>
72
  <li>
73
  <strong><?php esc_html_e('Notes:', 'wp-staging') ?></strong><br/>
74
- <?php echo esc_html(nl2br($notes)); ?>
 
 
75
  </li>
76
  <?php endif ?>
77
  <li>
@@ -82,33 +110,51 @@ $legacy = $backup->legacy;
82
  <strong><?php esc_html_e('Contains: ', 'wp-staging') ?></strong>
83
  <ul class="wpstg-import-backup-contains wpstg-listing-single-backup">
84
  <?php if ($backup->isExportingDatabase) : ?>
85
- <li><span class="dashicons dashicons-database wpstg--tooltip"><div class='wpstg--tooltiptext'>Database</div></span></li>
 
 
 
86
  <?php endif; ?>
87
  <?php if ($backup->isExportingPlugins) : ?>
88
- <li><span class="dashicons dashicons-admin-plugins wpstg--tooltip"><div class='wpstg--tooltiptext'>Plugins</div></span></li>
 
 
 
89
  <?php endif; ?>
90
  <?php if ($backup->isExportingMuPlugins) : ?>
91
- <li><span class="dashicons dashicons-plugins-checked wpstg--tooltip"><div class='wpstg--tooltiptext'>Mu-plugins</div></span></li>
 
 
 
92
  <?php endif; ?>
93
  <?php if ($backup->isExportingThemes) : ?>
94
- <li><span class="dashicons dashicons-layout wpstg--tooltip"><div class='wpstg--tooltiptext'>Themes</div></span></li>
 
 
 
95
  <?php endif; ?>
96
  <?php if ($backup->isExportingUploads) : ?>
97
- <li><span class="dashicons dashicons-images-alt wpstg--tooltip"><div class='wpstg--tooltiptext'>Uploads</div></span></li>
 
 
 
98
  <?php endif; ?>
99
  <?php if ($backup->isExportingOtherWpContentFiles) : ?>
100
- <li><span class="dashicons dashicons-admin-generic wpstg--tooltip"><div class='wpstg--tooltiptext'>Other files in wp-content</div></span></li>
 
 
 
101
  <?php endif; ?>
102
  </ul>
103
  </li>
104
  <?php if ($automatedBackup) : ?>
105
  <li style="font-style: italic">
106
- <span class="dashicons dashicons-database"></span> <?php esc_html_e('This database backup was automatically created before pushing a staging site to production.', 'wp-staging') ?>
107
  </li>
108
  <?php endif ?>
109
  <?php if ($legacy) : ?>
110
  <li style="font-style: italic">
111
- <span class="dashicons dashicons-hourglass"></span> <?php esc_html_e('This database backup was automatically converted from an existing legacy WPSTAGING Database export in the .SQL format.', 'wp-staging') ?>
112
  </li>
113
  <?php endif ?>
114
  </ul>
1
  <?php
2
 
3
+ use WPStaging\Pro\Backup\Task\Tasks\JobImport\RestoreRequirementsCheckTask;
4
+
5
  /**
6
  * @var \WPStaging\Framework\TemplateEngine\TemplateEngine $this
7
  * @var \WPStaging\Pro\Backup\Entity\ListableBackup $backup
8
+ * @var string $urlAssets
9
  */
10
  $name = $backup->backupName;
 
11
  $notes = $backup->notes;
12
+ $createdAt = $backup->dateCreatedTimestamp;
13
+ $uploadedAt = $backup->dateUploadedTimestamp;
14
  $size = $backup->size;
15
  $id = $backup->id;
16
  $automatedBackup = $backup->automatedBackup;
17
  $legacy = $backup->legacy;
18
+
19
+ $isUnsupported = version_compare($backup->generatedOnWPStagingVersion, RestoreRequirementsCheckTask::BETA_VERSION_LIMIT, '<');
20
+
21
+ if (defined('WPSTG_DOWNLOAD_BACKUP_USING_PHP') && WPSTG_DOWNLOAD_BACKUP_USING_PHP) {
22
+ // Download through PHP. Useful when the server mistakenly reads the .wpstg file as plain text instead of downloading it.
23
+ $downloadUrl = add_query_arg([
24
+ 'wpstgBackupDownloadNonce' => wp_create_nonce('wpstg_download_nonce'),
25
+ 'wpstgBackupDownloadMd5' => $backup->md5BaseName,
26
+ ], admin_url());
27
+ } else {
28
+ // Direct download of .wpstg file.
29
+ $downloadUrl = $backup->downloadUrl;
30
+ }
31
  ?>
32
+ <li id="<?php echo esc_attr($id) ?>" class="wpstg-clone wpstg-backup" data-md5="<?php echo esc_attr($backup->md5BaseName); ?>" data-name="<?php echo esc_attr($backup->backupName); ?>">
33
 
34
  <div class="wpstg-clone-header">
35
  <span class="wpstg-clone-title">
39
  <div class="wpstg-dropdown wpstg-action-dropdown">
40
  <a href="#" class="wpstg-dropdown-toggler transparent">
41
  <?php _e("Actions", "wp-staging"); ?>
42
+ <span class="wpstg-caret"></span>
43
  </a>
44
  <div class="wpstg-dropdown-menu">
45
+ <?php if (!$legacy) : ?>
46
+ <a href="#" class="wpstg-clone-action wpstg--backup--restore"
47
+ data-filePath="<?php echo esc_attr($backup->relativePath) ?>"
48
+ data-title="<?php esc_attr_e('Restore and overwrite current website according to the contents of this backup.', 'wp-staging') ?>"
49
+ title="<?php esc_attr_e('Restore and overwrite current website according to the contents of this backup.', 'wp-staging') ?>">
50
+ <?php esc_html_e('Restore', 'wp-staging') ?>
51
  </a>
52
+ <?php endif ?>
53
+ <a download
54
+ href="<?php echo esc_url($downloadUrl ?: '') ?>" class="wpstg--backup--download wpstg-merge-clone wpstg-clone-action"
 
 
 
 
55
  title="<?php esc_attr_e('Download backup file on local system', 'wp-staging') ?>">
56
  <?php esc_html_e('Download', 'wp-staging') ?>
57
  </a>
58
+ <?php if (!$legacy) : ?>
59
  <a href="#" class="wpstg--backup--edit wpstg-clone-action"
60
  data-md5="<?php echo esc_attr($backup->md5BaseName); ?>"
61
  data-name="<?php echo esc_attr($name); ?>"
63
  title="<?php esc_attr_e('Edit backup name and / or notes', 'wp-staging') ?>">
64
  <?php esc_html_e('Edit', 'wp-staging') ?>
65
  </a>
66
+ <?php endif ?>
67
  <a href="#" class="wpstg-remove-clone wpstg-clone-action wpstg-delete-backup"
68
  data-md5="<?php echo esc_attr($backup->md5BaseName) ?>"
69
  title="<?php esc_attr_e('Delete this backup. This action can not be undone!', 'wp-staging') ?>">
79
 
80
  <div class="wpstg-staging-info">
81
  <ul>
82
+ <?php if ($isUnsupported) : ?>
83
+ <li class="wpstg-unsupported-backup wpstg--red">
84
+ <div class="wpstg-exclamation">!</div><strong><?php esc_html_e('This backup was generated on the Beta version of WP STAGING and cannot be restored with the current version.', 'wp-staging') ?></strong><br/>
85
+ </li>
86
+ <?php endif ?>
87
+ <?php if ($createdAt) : ?>
88
  <li>
89
  <strong><?php esc_html_e('Created on:', 'wp-staging') ?></strong>
90
+ <?php
91
+ $date = new DateTime();
92
+ $date->setTimestamp($createdAt);
93
+ echo esc_html($this->transformToWpFormat($date));
94
+ ?>
95
  </li>
96
+ <?php endif ?>
97
  <?php if ($notes) : ?>
98
  <li>
99
  <strong><?php esc_html_e('Notes:', 'wp-staging') ?></strong><br/>
100
+ <div class="backup-notes">
101
+ <?php echo nl2br(esc_html($notes)); ?>
102
+ </div>
103
  </li>
104
  <?php endif ?>
105
  <li>
110
  <strong><?php esc_html_e('Contains: ', 'wp-staging') ?></strong>
111
  <ul class="wpstg-import-backup-contains wpstg-listing-single-backup">
112
  <?php if ($backup->isExportingDatabase) : ?>
113
+ <li><span class="wpstg--tooltip wpstg-backups-contains">
114
+ <img class="wpstg--dashicons" src="<?php echo $urlAssets; ?>svg/vendor/dashicons/database.svg" />
115
+ <div class='wpstg--tooltiptext'>Database</div>
116
+ </span></li>
117
  <?php endif; ?>
118
  <?php if ($backup->isExportingPlugins) : ?>
119
+ <li><span class="wpstg--tooltip wpstg-backups-contains">
120
+ <img class="wpstg--dashicons" src="<?php echo $urlAssets; ?>svg/vendor/dashicons/admin-plugins.svg" />
121
+ <div class='wpstg--tooltiptext'>Plugins</div>
122
+ </span></li>
123
  <?php endif; ?>
124
  <?php if ($backup->isExportingMuPlugins) : ?>
125
+ <li><span class="wpstg--tooltip wpstg-backups-contains">
126
+ <img class="wpstg--dashicons" src="<?php echo $urlAssets; ?>svg/vendor/dashicons/plugins-checked.svg" />
127
+ <div class='wpstg--tooltiptext'>Must-Use Plugins</div>
128
+ </span></li>
129
  <?php endif; ?>
130
  <?php if ($backup->isExportingThemes) : ?>
131
+ <li><span class="wpstg--tooltip wpstg-backups-contains">
132
+ <img class="wpstg--dashicons" src="<?php echo $urlAssets; ?>svg/vendor/dashicons/layout.svg" />
133
+ <div class='wpstg--tooltiptext'>Themes</div>
134
+ </span></li>
135
  <?php endif; ?>
136
  <?php if ($backup->isExportingUploads) : ?>
137
+ <li><span class="wpstg--tooltip wpstg-backups-contains">
138
+ <img class="wpstg--dashicons" src="<?php echo $urlAssets; ?>svg/vendor/dashicons/images-alt.svg" />
139
+ <div class='wpstg--tooltiptext'>Uploads</div>
140
+ </span></li>
141
  <?php endif; ?>
142
  <?php if ($backup->isExportingOtherWpContentFiles) : ?>
143
+ <li><span class="wpstg--tooltip wpstg-backups-contains">
144
+ <img class="wpstg--dashicons" src="<?php echo $urlAssets; ?>svg/vendor/dashicons/admin-generic.svg" />
145
+ <div class='wpstg--tooltiptext'>Other files in wp-content</div>
146
+ </span></li>
147
  <?php endif; ?>
148
  </ul>
149
  </li>
150
  <?php if ($automatedBackup) : ?>
151
  <li style="font-style: italic">
152
+ <img class="wpstg--dashicons wpstg-dashicons-19 wpstg-dashicons-grey" src="<?php echo $urlAssets; ?>svg/vendor/dashicons/database.svg" /> <?php esc_html_e('This database backup was automatically created before pushing a staging site to production.', 'wp-staging') ?>
153
  </li>
154
  <?php endif ?>
155
  <?php if ($legacy) : ?>
156
  <li style="font-style: italic">
157
+ <img class="wpstg--dashicons wpstg-dashicons-19 wpstg-dashicons-grey" src="<?php echo $urlAssets; ?>svg/vendor/dashicons/cloud-saved.svg" /> <?php esc_html_e('This database backup was generated from an existing legacy WP STAGING Database export in the .SQL format.', 'wp-staging') ?>
158
  </li>
159
  <?php endif ?>
160
  </ul>
Backend/views/backup/listing.php CHANGED
@@ -8,26 +8,43 @@ use WPStaging\Framework\Adapter\Directory;
8
  *
9
  * @var TemplateEngine $this
10
  * @var array $directories
11
- * @var string $urlPublic
12
  * @var Directory $directory
 
13
  */
 
 
14
  ?>
15
 
16
  <div id="wpstg-step-1">
17
- <button id="wpstg-new-backup" class="wpstg-next-step-link wpstg-link-btn wpstg-blue-primary wpstg-button"
18
- data-action="wpstg--backups--export">
19
- <?php esc_html_e('Backup & Export', 'wp-staging') ?>
20
  </button>
21
- <button id="wpstg-import-backup" class="wpstg-next-step-link wpstg-link-btn wpstg-blue-primary wpstg-button"
22
- data-action="wpstg--backups--import">
23
- <?php esc_html_e('Import', 'wp-staging') ?>
24
  </button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  </div>
26
 
27
  <div id="wpstg-existing-backups">
28
- <div style="display: flex; flex-direction: row; justify-content: space-between">
29
- <h3><?php _e('Your Backups:', 'wp-staging') ?></h3>
30
- </div>
31
  <div class="wpstg-backup-list">
32
  <ul>
33
  <li><?php _e('Searching for existing backups...', 'wp-staging') ?></li>
@@ -38,8 +55,11 @@ use WPStaging\Framework\Adapter\Directory;
38
  <?php include(__DIR__ . '/modal/export.php'); ?>
39
  <?php include(__DIR__ . '/modal/progress.php'); ?>
40
  <?php include(__DIR__ . '/modal/download.php'); ?>
 
41
  <?php include(__DIR__ . '/modal/import.php'); ?>
42
 
 
 
43
  <div
44
  id="wpstg--js--translations"
45
  style="display:none;"
8
  *
9
  * @var TemplateEngine $this
10
  * @var array $directories
11
+ * @var string $urlAssets
12
  * @var Directory $directory
13
+ * @var string $isValidLicense
14
  */
15
+
16
+ $disabledProperty = $isValidLicense ? '' : 'disabled';
17
  ?>
18
 
19
  <div id="wpstg-step-1">
20
+ <button id="wpstg-new-backup" class="wpstg-next-step-link wpstg-blue-primary wpstg-button" <?php echo $disabledProperty ?>>
21
+ <?php esc_html_e('Create New Backup', 'wp-staging') ?>
 
22
  </button>
23
+ <button id="wpstg-upload-backup" class="wpstg-next-step-link wpstg-blue-primary wpstg-button wpstg-ml-4" <?php echo $disabledProperty ?>>
24
+ <?php esc_html_e('Upload Backup', 'wp-staging') ?>
 
25
  </button>
26
+ <div class="wpstg--tooltip">
27
+ <img class="wpstg--dashicons wpstg-dashicons-21" src="<?php echo $urlAssets; ?>svg/vendor/dashicons/info-outline.svg"></img>
28
+ <p class="wpstg--tooltiptext wpstg--tooltiptext-backups">
29
+ <?php _e("Upload a WP STAGING backup file (*.wpstg) and restore your site to it at any time. This backup can have been created from this site, or even created on another website. So you can migrate the other site to this one.", "wp-staging")?>
30
+ <br><br>
31
+ <?php _e("Videos:", "wp-staging")?>
32
+ <br>
33
+ <?php echo sprintf(__('&#8226; <a href="%s" target="_blank">How to backup WordPress</a>', 'wp-staging'), 'https://www.youtube.com/watch?v=q352aYduOUY'); ?>
34
+ <br>
35
+ <?php echo sprintf(__('&#8226; <a href="%s" target="_blank">How to migrate WordPress</a>', 'wp-staging'), 'https://www.youtube.com/watch?v=DBaZQg1Efq4'); ?>
36
+ </p>
37
+ </div>
38
+ <div id="wpstg-report-issue-wrapper">
39
+ <button type="button" id="wpstg-report-issue-button" class="wpstg-button">
40
+ <i class="wpstg-icon-issue"></i><?php echo __("Report Issue", "wp-staging"); ?>
41
+ </button>
42
+ <?php require_once($this->views . '_main/report-issue.php'); ?>
43
+ </div>
44
  </div>
45
 
46
  <div id="wpstg-existing-backups">
47
+ <div id="backup-messages"></div>
 
 
48
  <div class="wpstg-backup-list">
49
  <ul>
50
  <li><?php _e('Searching for existing backups...', 'wp-staging') ?></li>
55
  <?php include(__DIR__ . '/modal/export.php'); ?>
56
  <?php include(__DIR__ . '/modal/progress.php'); ?>
57
  <?php include(__DIR__ . '/modal/download.php'); ?>
58
+ <?php include(__DIR__ . '/modal/upload.php'); ?>
59
  <?php include(__DIR__ . '/modal/import.php'); ?>
60
 
61
+ <?php include(__DIR__ . '/restore-wait.php'); ?>
62
+
63
  <div
64
  id="wpstg--js--translations"
65
  style="display:none;"
Backend/views/backup/{site/info.php → modal/confirm-restore.php} RENAMED
@@ -6,10 +6,17 @@ use WPStaging\Pro\Backup\Entity\BackupMetadata;
6
  * @var BackupMetadata $info
7
  */
8
 
 
 
 
 
 
 
 
9
  ?>
10
  <div id="wpstg-confirm-backup-restore-wrapper">
11
  <div class="wpstg-confirm-backup-restore-header">
12
- <h3 style="margin:0;"><?php _e('This will restore your website! </br> Are you sure?', 'wp-staging'); ?></h3>
13
  </div>
14
  <div id="wpstg-confirm-backup-restore-data">
15
  <ul>
@@ -32,7 +39,7 @@ use WPStaging\Pro\Backup\Entity\BackupMetadata;
32
  <li style="list-style-type: square;"><?php _e('Other files in wp-content folder will be added. ', 'wp-staging') ?></li>
33
  <?php endif; ?>
34
  </ul>
35
- <?php if (!empty($info->getTotalFiles())) : ?>
36
  <div class="wpstg-db-table" style="margin-top:5px;">
37
  <strong><?php _e('Total Files:', 'wp-staging') ?></strong>
38
  <span class=""><?php echo $info->getTotalFiles() ?></span>
6
  * @var BackupMetadata $info
7
  */
8
 
9
+ $isDatabaseOnlyBackup = $info->getIsExportingDatabase()
10
+ && !$info->getIsExportingPlugins()
11
+ && !$info->getIsExportingThemes()
12
+ && !$info->getIsExportingMuPlugins()
13
+ && !$info->getIsExportingUploads()
14
+ && !$info->getIsExportingOtherWpContentFiles();
15
+
16
  ?>
17
  <div id="wpstg-confirm-backup-restore-wrapper">
18
  <div class="wpstg-confirm-backup-restore-header">
19
+ <h3 class="swal2-title" style="text-align: center;"><?php _e('This will restore your website! </br> Are you sure?', 'wp-staging'); ?></h3>
20
  </div>
21
  <div id="wpstg-confirm-backup-restore-data">
22
  <ul>
39
  <li style="list-style-type: square;"><?php _e('Other files in wp-content folder will be added. ', 'wp-staging') ?></li>
40
  <?php endif; ?>
41
  </ul>
42
+ <?php if (!$isDatabaseOnlyBackup && !empty($info->getTotalFiles())) : ?>
43
  <div class="wpstg-db-table" style="margin-top:5px;">
44
  <strong><?php _e('Total Files:', 'wp-staging') ?></strong>
45
  <span class=""><?php echo $info->getTotalFiles() ?></span>
Backend/views/backup/modal/download.php CHANGED
@@ -1,7 +1,10 @@
1
  <div id="wpstg--modal--backup--download" style="display: none">
2
- <h2>{title}</h2>
3
- <div class="wpstg--modal--download--logs--wrapper" style="display:none">
4
- <button class="wpstg--modal--process--logs--tail">{btnTxtLog}</button>
5
- <div class="wpstg--modal--process--logs"></div>
 
 
 
6
  </div>
7
  </div>
1
  <div id="wpstg--modal--backup--download" style="display: none">
2
+ <div id="wpstg--modal--backup--download-inner">
3
+ <h2>{title}</h2>
4
+ <p class="wpstg-download-modal-text">{text}</p>
5
+ <div class="wpstg--modal--download--logs--wrapper" style="display:none">
6
+ <button class="wpstg--modal--process--logs--tail">{btnTxtLog}</button>
7
+ <div class="wpstg--modal--process--logs"></div>
8
+ </div>
9
  </div>
10
  </div>
Backend/views/backup/modal/export.php CHANGED
@@ -1,47 +1,46 @@
1
  <?php
2
  /**
3
  * @var \WPStaging\Framework\Adapter\Directory $directories
 
4
  */
5
  ?>
6
  <div id="wpstg--modal--backup--new" data-confirmButtonText="<?php esc_attr_e('Start Backup', 'wp-staging') ?>" style="display: none">
7
- <label for="wpstg-backup-name-input"><?php esc_html_e('Backup & Export', 'wp-staging') ?></label>
8
- <input id="wpstg-backup-name-input" name="backup_name" class="swal2-input" placeholder="<?php esc_attr_e('Name your backup for better distinction', 'wp-staging') ?>">
9
 
10
  <div class="wpstg-advanced-options" style="text-align: left;">
11
 
12
- <!-- EXPORT CHECKBOXES -->
13
- <div class="wpstg-advanced-options-site" style="padding-left: .75em;">
14
- <label style="display: block;margin: .5em 0;">
15
  <input type="checkbox" name="includedDirectories[]" id="includeMediaLibraryInBackup" value="<?php echo esc_attr($directories['uploads']); ?>" checked/>
16
- <?php esc_html_e('Export Media Library', 'wp-staging') ?>
17
  </label>
18
- <label style="display: block;margin: .5em 0;">
19
  <input type="checkbox" name="includedDirectories[]" id="includeThemesInBackup" value="<?php echo esc_attr($directories['themes']); ?>" checked/>
20
- <?php esc_html_e('Export Themes', 'wp-staging') ?>
21
  </label>
22
- <label style="display: block;margin: .5em 0;">
23
  <input type="checkbox" name="includedDirectories[]" id="includeMuPluginsInBackup" value="<?php echo esc_attr($directories['muPlugins']); ?>" checked/>
24
- <?php esc_html_e('Export Must-Use Plugins', 'wp-staging') ?>
25
  </label>
26
- <label style="display: block;margin: .5em 0;">
27
  <input type="checkbox" name="includedDirectories[]" id="includePluginsInBackup" value="<?php echo esc_attr($directories['plugins']); ?>" checked/>
28
- <?php esc_html_e('Export Plugins', 'wp-staging') ?>
29
  </label>
30
- <label style="display: block;margin: .5em 0;">
31
  <input type="checkbox" name="includeOtherFilesInWpContent" id="includeOtherFilesInWpContent" value="true" checked/>
32
- <?php esc_html_e('Export Other Files In wp-content', 'wp-staging') ?>
33
- <div class="wpstg--tooltip">
34
- <span class="dashicons dashicons-info-outline"></span>
35
  <span class="wpstg--tooltiptext wpstg--tooltiptext-backups">
36
- <p>
37
- <?php esc_html_e('Export files at wp-content that are not plugins, themes, mu-plugins or uploads. Eg: Cache and database drop-ins, etc. Recommended for full-site backups.', 'wp-staging') ?>
38
- </p>
39
  </span>
40
  </div>
41
  </label>
42
  <label style="display: block;margin: .5em 0;">
43
  <input type="checkbox" name="export_database" id="includeDatabaseInBackup" value="true" checked/>
44
- <?php esc_html_e('Export Database', 'wp-staging') ?>
45
  <div id="exportUploadsWithoutDatabaseWarning" style="display:none;">
46
  <?php esc_html_e('When exporting the Media Library without the Database, the attachments will be migrated but won\'t show up in the media library after import.', 'wp-staging'); ?>
47
  </div>
1
  <?php
2
  /**
3
  * @var \WPStaging\Framework\Adapter\Directory $directories
4
+ * @var string $urlAssets
5
  */
6
  ?>
7
  <div id="wpstg--modal--backup--new" data-confirmButtonText="<?php esc_attr_e('Start Backup', 'wp-staging') ?>" style="display: none">
8
+ <h3 class="swal2-title wpstg-w-100" for="wpstg-backup-name-input"><?php esc_html_e('Create Site Backup', 'wp-staging') ?></h3>
9
+ <input id="wpstg-backup-name-input" name="backup_name" class="swal2-input" placeholder="<?php esc_attr_e('Backup Name (Optional)', 'wp-staging') ?>">
10
 
11
  <div class="wpstg-advanced-options" style="text-align: left;">
12
 
13
+ <!-- BACKUP CHECKBOXES -->
14
+ <div class="wpstg-advanced-options-site">
15
+ <label>
16
  <input type="checkbox" name="includedDirectories[]" id="includeMediaLibraryInBackup" value="<?php echo esc_attr($directories['uploads']); ?>" checked/>
17
+ <?php esc_html_e('Backup Media Library', 'wp-staging') ?>
18
  </label>
19
+ <label>
20
  <input type="checkbox" name="includedDirectories[]" id="includeThemesInBackup" value="<?php echo esc_attr($directories['themes']); ?>" checked/>
21
+ <?php esc_html_e('Backup Themes', 'wp-staging') ?>
22
  </label>
23
+ <label>
24
  <input type="checkbox" name="includedDirectories[]" id="includeMuPluginsInBackup" value="<?php echo esc_attr($directories['muPlugins']); ?>" checked/>
25
+ <?php esc_html_e('Backup Must-Use Plugins', 'wp-staging') ?>
26
  </label>
27
+ <label>
28
  <input type="checkbox" name="includedDirectories[]" id="includePluginsInBackup" value="<?php echo esc_attr($directories['plugins']); ?>" checked/>
29
+ <?php esc_html_e('Backup Plugins', 'wp-staging') ?>
30
  </label>
31
+ <label>
32
  <input type="checkbox" name="includeOtherFilesInWpContent" id="includeOtherFilesInWpContent" value="true" checked/>
33
+ <?php esc_html_e('Backup Other Files In wp-content', 'wp-staging') ?>
34
+ <div class="wpstg--tooltip" style="position: absolute;">
35
+ <img class="wpstg--dashicons wpstg-dashicons-21" src="<?php echo $urlAssets; ?>svg/vendor/dashicons/info-outline.svg" alt="info" />
36
  <span class="wpstg--tooltiptext wpstg--tooltiptext-backups">
37
+ <?php esc_html_e('All files in folder wp-content that are not plugins, themes, mu-plugins and uploads. Recommended for full-site backups.', 'wp-staging') ?>
 
 
38
  </span>
39
  </div>
40
  </label>
41
  <label style="display: block;margin: .5em 0;">
42
  <input type="checkbox" name="export_database" id="includeDatabaseInBackup" value="true" checked/>
43
+ <?php esc_html_e('Backup Database', 'wp-staging') ?>
44
  <div id="exportUploadsWithoutDatabaseWarning" style="display:none;">
45
  <?php esc_html_e('When exporting the Media Library without the Database, the attachments will be migrated but won\'t show up in the media library after import.', 'wp-staging'); ?>
46
  </div>
Backend/views/backup/modal/import.php CHANGED
@@ -5,16 +5,15 @@
5
  ?>
6
  <div
7
  id="wpstg--modal--backup--import"
8
- data-confirmButtonText="<?php esc_attr_e('IMPORT', 'wp-staging'); ?>"
9
  data-nextButtonText="<?php esc_attr_e('NEXT', 'wp-staging'); ?>"
10
  data-cancelButtonText="<?php esc_attr_e('CANCEL', 'wp-staging'); ?>"
11
  data-baseDirectory="<?php echo esc_attr($directory->getPluginUploadsDirectory()); ?>"
12
  style="display: none"
13
  >
14
- <h2 class="wpstg--modal--backup--import--upload--title"><?php esc_html_e('Import Backup', 'wp-staging') ?></h2>
15
  <div style="padding: .75em; margin: 1em auto;">
16
- <?php include(__DIR__ . '/partials/import-upload.php'); ?>
17
- <?php include(__DIR__ . '/partials/import-filesystem.php'); ?>
18
- <?php include(__DIR__ . '/partials/import-configure.php'); ?>
19
  </div>
20
  </div>
5
  ?>
6
  <div
7
  id="wpstg--modal--backup--import"
8
+ data-confirmButtonText="<?php esc_attr_e('RESTORE', 'wp-staging'); ?>"
9
  data-nextButtonText="<?php esc_attr_e('NEXT', 'wp-staging'); ?>"
10
  data-cancelButtonText="<?php esc_attr_e('CANCEL', 'wp-staging'); ?>"
11
  data-baseDirectory="<?php echo esc_attr($directory->getPluginUploadsDirectory()); ?>"
12
  style="display: none"
13
  >
14
+ <h2 class="wpstg--modal--backup--import--upload--title wpstg--grey"><?php esc_html_e('Restore Backup', 'wp-staging') ?></h2>
15
  <div style="padding: .75em; margin: 1em auto;">
16
+ <?php include(__DIR__ . '/partials/import-introduction.php'); ?>
17
+ <?php include(__DIR__ . '/partials/import-database-search-replace.php'); ?>
 
18
  </div>
19
  </div>
Backend/views/backup/modal/partials/import-configure.php DELETED
@@ -1,33 +0,0 @@
1
- <?php
2
- /**
3
- * @var string $urlPublic
4
- */
5
- ?>
6
- <div class="wpstg--modal--backup--import--configure">
7
- <div class="wpstg--modal--backup--import--configure-review-backup">
8
- Reviewing backup.
9
- </div>
10
- <!-- DATABASE SEARCH AND REPLACE -->
11
- <div class="wpstg--modal--backup--import--search-replace--wrapper">
12
- <a href="#" class="wpstg--tab--toggle" data-target=".wpstg--import--database-search-and-replace" style="text-decoration: none;">
13
- <span style="margin-right: .25em">►</span>
14
- <?php esc_html_e('Database Search and Replace', 'wp-staging') ?>
15
- </a>
16
-
17
- <div class="wpstg--import--database-search-and-replace" style="display:none; padding-left: .75em;">
18
- <div class="wpstg--modal--backup--import--search-replace--info">
19
- <p><?php esc_html_e('You can do a search-and-replace of the values of the database being imported. This is optional, as WPSTAGING already takes care of replacing the Site URL and ABSPATH for you. You should avoid doing replacements of generic strings, as this could replace unwanted values and cause issues in the database.', 'wp-staging') ?></p>
20
- </div>
21
- <div class="wpstg--modal--backup--import--search-replace--input--container">
22
- <div class="wpstg--modal--backup--import--search-replace--input-group">
23
- <input name="wpstg__backup__import__search[{i}]" data-index="{i}" class="wpstg--backup--import--search" placeholder="Search"/>
24
- <input name="wpstg__backup__import__replace[{i}]" data-index="{i}" class="wpstg--backup--import--replace" placeholder="Replace"/>
25
- <button class="wpstg--import--advanced-options--button wpstg--modal--backup--import--search-replace--remove"><?php esc_html_e('-', 'wp-staging') ?></button>
26
- </div>
27
- </div>
28
- <div class="wpstg--modal--backup--import--search-replace--new--wrapper">
29
- <button class="wpstg--import--advanced-options--button wpstg--modal--backup--import--search-replace--new"><?php esc_html_e('+', 'wp-staging') ?></button>
30
- </div>
31
- </div>
32
- </div>
33
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Backend/views/backup/modal/partials/import-database-search-replace.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @var string $urlPublic
4
+ */
5
+ ?>
6
+ <div class="wpstg--modal--backup--import--database-search-replace" style="padding-left: .75em;">
7
+ <p><strong><?php esc_html_e('Database Search and Replace', 'wp-staging') ?></strong></p>
8
+ <div class="wpstg--modal--backup--import--search-replace--info">
9
+ <p><?php esc_html_e('You can do a search-and-replace of the values of the database being imported. This is optional, as WP STAGING already takes care of replacing the Site URL and ABSPATH for you. You should avoid doing replacements of generic strings, as this could replace unwanted values and cause issues in the database.', 'wp-staging') ?></p>
10
+ </div>
11
+ <div class="wpstg--modal--backup--import--search-replace--input--container">
12
+ <div class="wpstg--modal--backup--import--search-replace--input-group">
13
+ <input name="wpstg__backup__import__search[{i}]" data-index="{i}" class="wpstg--backup--import--search" placeholder="Search"/>
14
+ <input name="wpstg__backup__import__replace[{i}]" data-index="{i}" class="wpstg--backup--import--replace" placeholder="Replace"/>
15
+ <button class="wpstg--import--advanced-options--button wpstg--modal--backup--import--search-replace--remove"><?php esc_html_e('-', 'wp-staging') ?></button>
16
+ </div>
17
+ </div>
18
+ <div class="wpstg--modal--backup--import--search-replace--new--wrapper">
19
+ <button class="wpstg--import--advanced-options--button wpstg--modal--backup--import--search-replace--new"><?php esc_html_e('+', 'wp-staging') ?></button>
20
+ </div>
21
+ </div>
Backend/views/backup/modal/partials/import-filesystem.php DELETED
@@ -1,17 +0,0 @@
1
- <?php
2
- /**
3
- * @var \WPStaging\Framework\Adapter\Directory $directory
4
- */
5
- ?>
6
- <div class="wpstg--modal--backup--import--filesystem">
7
- <button class="wpstg--backup--import--option wpstg-blue-primary" data-option="upload">
8
- <?php esc_html_e('GO BACK', 'wp-staging') ?>
9
- </button>
10
- <div style="margin-top: .25em;font-size:14px;">
11
- <?php
12
- echo __('Upload import file to server directory:', 'wp-staging') . '<br>';
13
- echo esc_html($directory->getPluginUploadsDirectory());
14
- ?>
15
- </div>
16
- <ul></ul>
17
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Backend/views/backup/modal/partials/import-introduction.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @var string $urlPublic
4
+ */
5
+ ?>
6
+ <div class="wpstg--modal--backup--import--introduction">
7
+ <div class="wpstg--modal--backup--import--wrapper">
8
+ <div style="text-align: left; padding-left: 8px; padding-right: 8px;">
9
+ <h4 class="swal2-title"><strong><?php esc_html_e('Read First', 'wp-staging') ?></strong></h4>
10
+ <?php echo wp_kses_post(__(<<<HTML
11
+ <p>Restoring a Backup is a beta feature. Back up your current website first before proceeding.</p>
12
+ <p class="wpstg-backup-restore-contains-database">This site's database is going to be entirely replaced with the database from the backup, and you will be required to log in again with the user/password that exists in the backup.</p>
13
+ <p class="wpstg-backup-restore-contains-files">The restore process will add the files from the backup to the site, replacing the ones that exist both in the backup and in the site.</p>
14
+ HTML
15
+ , 'wp-staging')) ?>
16
+ </div>
17
+ </div>
18
+ </div>
Backend/views/backup/modal/partials/import-upload.php DELETED
@@ -1,59 +0,0 @@
1
- <?php
2
- /**
3
- * @var string $urlAssets
4
- */
5
- ?>
6
- <div class="wpstg--modal--backup--import--upload">
7
- <div class="wpstg--modal--backup--import--upload--container">
8
- <div class="wpstg--uploader">
9
- <input type="file" name="wpstg--backup--import--upload--file" accept=".wpstg"/>
10
- <img src="<?php echo esc_url($urlAssets . 'img/upload.svg'); ?>" alt="Upload Image"/>
11
- <span class="wpstg--backup--import--selected-file"></span>
12
- <span class="wpstg--drag-or-upload">
13
- <?php esc_html_e('Drag a new export file here or choose another option', 'wp-staging') ?>
14
- </span>
15
- <span class="wpstg--drag">
16
- <?php esc_html_e('Drag and Drop a WPSTAGING Backup file to start import', 'wp-staging') ?>
17
- <br>
18
- <small><?php esc_html_e('You can upload a file of any size here', 'wp-staging') ?></small>
19
- </span>
20
- <span class="wpstg--drop">
21
- <?php esc_html_e('Drop export file here', 'wp-staging') ?>
22
- </span>
23
- <div class="wpstg--backup--import--options">
24
- <button
25
- class="wpstg-blue-primary wpstg-button wpstg-link-btn wpstg--backup--import--choose-option"
26
- data-txtOther="<?php esc_attr_e('Import from', 'wp-staging') ?>"
27
- data-txtChoose="<?php esc_attr_e('Choose an Option', 'wp-staging') ?>"
28
- >
29
- <?php esc_html_e('Import from', 'wp-staging') ?>
30
- </button>
31
- <ul>
32
- <li>
33
- <button class="wpstg--backup--import--option wpstg-blue-primary" data-option="file">
34
- <?php esc_html_e('Local Computer', 'wp-staging') ?>
35
- </button>
36
- </li>
37
- <li>
38
- <button class="wpstg--backup--import--option wpstg-blue-primary" data-option="filesystem">
39
- <?php esc_html_e('Existing Backups', 'wp-staging') ?>
40
- </button>
41
- </li>
42
- </ul>
43
- </div>
44
- </div>
45
- <div class="wpstg--modal--import--upload--process">
46
- <div class="wpstg--modal--import--upload--progress"></div>
47
- <h4 class="wpstg--modal--import--upload--progress--title">
48
- <?php echo sprintf(esc_html__('Uploading %s%%...', 'wp-staging'), '<span></span>') ?>
49
- </h4>
50
- </div>
51
- </div>
52
- <div
53
- class="wpstg--modal--backup--import--upload--status"
54
- data-txt-uploading="<?php esc_html_e('Uploading...', 'wp-staging') ?>"
55
- data-txt-done="<?php esc_html_e('Uploaded Successfully', 'wp-staging') ?>"
56
- data-txt-error="<?php esc_html_e('Error! {message}', 'wp-staging') ?>"
57
- >
58
- </div>
59
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Backend/views/backup/modal/progress.php CHANGED
@@ -1,9 +1,9 @@
1
- <div id="wpstg--modal--backup--process" data-cancelButtonText="<?php esc_attr_e('CANCEL', 'wp-staging') ?>" style="display: none">
2
  <span class="wpstg-loader"></span>
3
- <h3 class="wpstg--modal--process--title" style="color: #a8a8a8;margin: .25em 0;">
4
  <?php esc_html_e('Processing...', 'wp-staging') ?>
5
  </h3>
6
- <div style="margin: .5em 0; color: #a8a8a8;">
7
  <?php
8
  echo sprintf(
9
  esc_html__('Progress %s - Elapsed time %s', 'wp-staging'),
1
+ <div id="wpstg--modal--backup--process" data-cancelButtonText="<?php esc_attr_e('Cancel', 'wp-staging') ?>" style="display: none">
2
  <span class="wpstg-loader"></span>
3
+ <h3 class="wpstg--modal--process--title">
4
  <?php esc_html_e('Processing...', 'wp-staging') ?>
5
  </h3>
6
+ <div class="wpstg--modal--process--subtitle">
7
  <?php
8
  echo sprintf(
9
  esc_html__('Progress %s - Elapsed time %s', 'wp-staging'),
Backend/views/backup/modal/upload.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @var \WPStaging\Framework\Adapter\Directory $directory
4
+ */
5
+ $uploadDirectory = str_replace(wp_normalize_path(ABSPATH), '', wp_normalize_path($directory->getPluginUploadsDirectory() . \WPStaging\Pro\Backup\Service\Compressor::EXPORT_DIR_NAME));
6
+ ?>
7
+ <div
8
+ id="wpstg--modal--backup--upload"
9
+ data-cancelButtonText="<?php esc_attr_e('CANCEL', 'wp-staging'); ?>"
10
+ style="display: none"
11
+ >
12
+ <h2 class="wpstg--modal--backup--import--upload--title wpstg--grey"><?php esc_html_e('Uploading Backup', 'wp-staging') ?></h2>
13
+ <div class="wpstg--modal--backup--import--upload--content">
14
+ <?php
15
+ /**
16
+ * @var string $urlAssets
17
+ */
18
+ ?>
19
+
20
+ <div class="wpstg-linear-loader">
21
+ <span class="wpstg-linear-loader-item"></span>
22
+ <span class="wpstg-linear-loader-item"></span>
23
+ <span class="wpstg-linear-loader-item"></span>
24
+ <span class="wpstg-linear-loader-item"></span>
25
+ <span class="wpstg-linear-loader-item"></span>
26
+ <span class="wpstg-linear-loader-item"></span>
27
+ </div>
28
+
29
+ <div class="wpstg--modal--backup--import--upload">
30
+
31
+ <div id="wpstg-upload-select">
32
+ <div class="wpstg--modal--backup--import--upload--container resumable-drop resumable-browse">
33
+ <img src="<?php echo esc_url($urlAssets . 'img/upload.svg'); ?>" alt="Upload Image"/>
34
+ <div class="upload-text">
35
+ <?php
36
+ echo wp_kses(
37
+ __(sprintf('Drop the backup file here to upload or <a>select from your computer</a>'), 'wp-staging'),
38
+ [
39
+ // Allowed HTML
40
+ 'a' => []
41
+ ]
42
+ ) ?>
43
+ </div>
44
+ <div class="dragover-text">
45
+ <strong><?php echo esc_html('Drop here to start the upload!') ?></strong>
46
+ </div>
47
+ </div>
48
+ <p class="wpstg-backup-direct-upload-notice">
49
+ <?php esc_html_e('Did you know? You can also upload backups directly to this directory:', 'wp-staging') ?><br>
50
+ <strong><?php echo esc_html($uploadDirectory) ?></strong>
51
+ </p>
52
+ </div>
53
+
54
+ <div id="wpstg-upload-progress">
55
+ <div class="wpstg--modal--import--upload--process">
56
+ <div class="wpstg--modal--import--upload--progress"></div>
57
+ <h4 class="wpstg--modal--import--upload--progress--title">
58
+ <span><small><?php esc_html_e('Discovering optimal upload speed... This might a little while...', 'wp-staging'); ?></small></span>
59
+ </h4>
60
+ </div>
61
+ <p class="wpstg-backup-upload-dont-close-notice"><?php esc_html_e('If you close this window your backup will be aborted.', 'wp-staging') ?></p>
62
+ </div>
63
+
64
+
65
+ </div>
66
+
67
+ </div>
68
+ </div>
Backend/views/backup/multisite-disabled.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @see \WPStaging\Pro\Backup\Ajax\Listing::render
5
+ */
6
+
7
+ ?>
8
+
9
+ <div id="wpstg-multisite-disabled">
10
+ <ul>
11
+ <li class="wpstg-clone">
12
+ <p><strong><?php esc_html_e('Coming soon!', 'wp-staging'); ?></strong></p>
13
+ <p><?php esc_html_e('The Backup feature is only available for single-sites for now.', 'wp-staging'); ?></p>
14
+ <p><?php esc_html_e('We are working hard to support multi-sites in the near future!', 'wp-staging'); ?></p>
15
+ </li>
16
+ </ul>
17
+ </div>
Backend/views/backup/restore-wait.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @see \WPStaging\Pro\Backup\Ajax\Listing::render
5
+ */
6
+
7
+ ?>
8
+
9
+ <div id="wpstg-restore-wait">
10
+ <div class="wpstg-logo"><img width="220" src="<?php echo WPSTG_PLUGIN_URL . "assets/img/logo-wp-staging-1468x230.png"; ?>"></div>
11
+ <div class="wpstg-title"><?php _e('Backup Restore Successful!', 'wp-staging') ?></div>
12
+ <div class="wpstg-text"><?php _e('You are being redirected to the login page...', 'wp-staging') ?></div>
13
+ </div>
Backend/views/clone/ajax/custom-directory.php CHANGED
@@ -1,46 +1,123 @@
1
  <?php
2
 
 
 
 
 
3
  /**
4
- * This file is currently being called only for the Free version:
5
- * src/Backend/views/clone/ajax/scan.php:113
 
 
 
 
6
  *
7
- * @file src/Backend/Pro/views/clone/ajax/custom-directory.php For the Pro counterpart.
8
  */
9
 
10
- ?>
11
- <fieldset disabled style="opacity:0.8;border-top: 1px solid white;margin-top: 20px;">
12
- <p>
13
- <strong style="font-size: 14px;"> <?php _e('Copy Staging Site to Custom Directory', 'wp-staging'); ?></strong>
14
- <br>
15
- <?php _e('Path must be writeable by PHP and an absolute path like <code>/www/public_html/dev</code>.', 'wp-staging'); ?>
16
- </p>
17
- <div class="wpstg-form-group wpstg-text-field">
18
- <label><?php _e('Target Directory: ', 'wp-staging') ?> </label>
19
- <input readonly type="text" name="wpstg_clone_dir" id="wpstg_clone_dir" value="" title="wpstg_clone_dir" placeholder="<?php echo \WPStaging\Core\WPStaging::getWPpath(); ?>" autocapitalize="off">
20
- <span class="wpstg-code-segment">
21
- <code><?php echo __('Default: ', 'wp-staging') . \WPStaging\Core\WPStaging::getWPpath(); ?></code>
22
- </span>
23
- </div>
24
- <div class="wpstg-form-group wpstg-text-field">
25
- <label><?php _e('Target Hostname: ') ?> </label>
26
- <input readonly type="text" name="wpstg_clone_hostname" id="wpstg_clone_hostname" value="" title="wpstg_clone_hostname" placeholder="<?php get_site_url(); ?>" autocapitalize="off">
27
- <span class="wpstg-code-segment">
28
- <code><?php echo __('Default: ', 'wp-staging') . get_site_url(); ?></code>
29
- </span>
30
- </div>
31
- </fieldset>
32
- <fieldset disabled class="wpstg-fieldset">
33
- <p>
34
- <strong class="wpstg-fs-14"> <?php _e('Symlink Upload Folder', 'wp-staging'); ?></strong>
35
- <br/>
36
- <p><?php _e('Activating will symlink the upload folder with the production site. All images and content on the production site uploads folder will be linked to the staging site folder. This will speed up the cloning and pushing process tremendously as no images and other data is copied between both sites.', 'wp-staging'); ?></p>
37
- <p><?php _e('Note: This feature will only work if the staging site is on the same hosting as the production site.', 'wp-staging'); ?></p>
38
- </p>
39
- <div class="wpstg-form-group">
40
- <label class="wpstg-checkbox" for="wpstg_symlink_upload">
41
- <?php _e('Symlink Upload Folder:', 'wp-staging'); ?>
42
- <input disabled type="checkbox" name="wpstg_symlink_upload" id="wpstg_symlink_upload" value="true" title="wpstg_symlink_upload">
43
- </label>
44
- </div>
45
- </fieldset>
46
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
2
 
3
+ use WPStaging\Core\WPStaging;
4
+ use WPStaging\Backend\Modules\SystemInfo;
5
+ use WPStaging\Backend\Modules\Jobs\Scan;
6
+
7
  /**
8
+ * This file is currently being called for the both FREE and PRO version:
9
+ * src/Backend/views/clone/ajax/scan.php:63
10
+ *
11
+ * @var Scan $scan
12
+ * @var stdClass $options
13
+ * @var boolean $isPro
14
  *
15
+ * @see \WPStaging\Backend\Modules\Jobs\Scan::start For details on $options.
16
  */
17
 
18
+ // For new clone settings are always enabled
19
+ $proSettingsDisabled = false;
20
+ // By default symlink option is unchecked
21
+ $uploadsSymlinked = false;
22
+
23
+ /**
24
+ * Used for overwriting the default target directory and target hostname via hook
25
+ */
26
+ $directory = WPStaging::getWPpath();
27
+ $customDir = $directory;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
 
29
+ if (is_multisite() && !SUBDOMAIN_INSTALL) {
30
+ $hostname = network_site_url();
31
+ } else {
32
+ $hostname = get_site_url();
33
+ }
34
+ $customHostname = $hostname;
35
+
36
+
37
+ // Apply Filters in only PRO version
38
+ if ($isPro) {
39
+ $hostname = apply_filters('wpstg_cloning_target_hostname', $hostname);
40
+ $customHostname = apply_filters('wpstg_cloning_target_hostname', '');
41
+ $directory = apply_filters('wpstg_cloning_target_dir', $directory);
42
+ $customDir = apply_filters('wpstg_cloning_target_dir', '');
43
+ } else {
44
+ // Disable pro settings when not PRO version
45
+ $customDir = '';
46
+ $customHostname = '';
47
+ $proSettingsDisabled = true;
48
+ }
49
+
50
+ if ($isPro && !empty($options->current) && $options->current !== null) {
51
+ $cloneDir = isset($options->existingClones[$options->current]['cloneDir']) ? $options->existingClones[$options->current]['cloneDir'] : '';
52
+ $hostname = isset($options->existingClones[$options->current]['url']) ? $options->existingClones[$options->current]['url'] : '';
53
+ $customHostname = $hostname;
54
+ $directory = isset($options->existingClones[$options->current]['path']) ? $options->existingClones[$options->current]['path'] : '';
55
+ $customDir = $directory;
56
+ $uploadsSymlinked = isset($options->existingClones[$options->current]['uploadsSymlinked']) && $options->existingClones[$options->current]['uploadsSymlinked'];
57
+ $proSettingsDisabled = true;
58
+ } ?>
59
+
60
+ <p class="wpstg--advance-settings--checkbox">
61
+ <label for="wpstg-change-dest"><?php _e('Change Destination'); ?></label>
62
+ <input type="checkbox" id="wpstg-change-dest" name="wpstg-change-dest" value="true" class="wpstg-toggle-advance-settings-section" data-id="wpstg-clone-directory" <?php echo $isPro === true ? '' : 'disabled' ?> >
63
+ <span class="wpstg--tooltip">
64
+ <img class="wpstg--dashicons" src="<?php echo $scan->getInfoIcon(); ?>" alt="info" />
65
+ <span class="wpstg--tooltiptext">
66
+ <strong> <?php _e('You can copy the staging site to a custom directory and can use a different hostname.', 'wp-staging'); ?></strong>
67
+ <br /> <br />
68
+ <?php echo sprintf(__('<strong>Target Directory:</strong> An absolute path like <code>/www/public_html/dev</code>. File permissions should be 755 and it must be writeable by php user <code>%s</code>', 'wp-staging'), (new SystemInfo())->getPHPUser()); ?>
69
+ <br /> <br />
70
+ <?php _e('<strong>Taget Hostname:</strong> The hostname of the target site, for instance <code>https://subdomain.example.com</code> or <code>https://example.com/staging</code>', 'wp-staging'); ?>
71
+ <br /> <br />
72
+ <?php _e('Make sure the hostname points to the target directory from above.', 'wp-staging'); ?>
73
+ </span>
74
+ </span>
75
+ </p>
76
+ <div id="wpstg-clone-directory" <?php echo $isPro === true ? 'style="display: none;"' : '' ?> >
77
+ <div class="wpstg-form-group wpstg-text-field">
78
+ <label><?php _e('Target Directory: ', 'wp-staging') ?> </label>
79
+ <input type="text" class="wpstg-textbox" name="wpstg_clone_dir" id="wpstg_clone_dir" value="<?php echo $customDir; ?>" title="wpstg_clone_dir" placeholder="<?php echo $directory; ?>" autocapitalize="off" <?php echo $proSettingsDisabled === true ? 'disabled' : '' ?> />
80
+ <?php if (!$proSettingsDisabled) : ?>
81
+ <span class="wpstg-code-segment">
82
+ <code>
83
+ <a id="wpstg-use-target-dir" data-base-path="<?php echo $directory ?>" data-path="<?php echo $directory ?>" class="wpstg-pointer">
84
+ <?php _e('Set Default: ', 'wp-staging') ?>
85
+ </a>
86
+ <span class="wpstg-use-target-dir--value"><?php echo $directory; ?></span>
87
+ </code>
88
+ </span>
89
+ <?php endif; ?>
90
+ </div>
91
+ <div class="wpstg-form-group wpstg-text-field">
92
+ <label><?php _e('Target Hostname: ') ?> </label>
93
+ <input type="text" class="wpstg-textbox" name="wpstg_clone_hostname" id="wpstg_clone_hostname" value="<?php echo $customHostname; ?>" title="wpstg_clone_hostname" placeholder="<?php echo $hostname; ?>" autocapitalize="off" <?php echo $proSettingsDisabled === true ? 'disabled' : '' ?> />
94
+ <?php if (!$proSettingsDisabled) : ?>
95
+ <span class="wpstg-code-segment">
96
+ <code>
97
+ <a id="wpstg-use-target-hostname" data-base-uri="<?php echo $hostname ?>" data-uri="<?php echo $hostname ?>" class="wpstg-pointer">
98
+ <?php _e('Set Default: ', 'wp-staging') ?>
99
+ </a>
100
+ <span class="wpstg-use-target-hostname--value"><?php echo get_site_url(); ?></span>
101
+ </code>
102
+ </span>
103
+ <?php endif; ?>
104
+ </div>
105
+ <hr/>
106
+ </div>
107
+
108
+ <p class="wpstg--advance-settings--checkbox">
109
+ <label for="wpstg_symlink_upload"><?php _e('Symlink Uploads Folder'); ?></label>
110
+ <input type="checkbox" id="wpstg_symlink_upload" name="wpstg_symlink_upload" value="true"
111
+ <?php echo $proSettingsDisabled === true ? 'disabled' : '' ?>
112
+ <?php echo $uploadsSymlinked === true ? 'checked' : '' ?> />
113
+ <span class="wpstg--tooltip">
114
+ <img class="wpstg--dashicons" src="<?php echo $scan->getInfoIcon(); ?>" alt="info" />
115
+ <span class="wpstg--tooltiptext">
116
+ <?php _e('Activate to symlink the folder <code>wp-content/uploads</code> to the production site. All images on the production site\'s uploads folder will be linked to the staging site uploads folder. This will speed up the cloning and pushing process tremendously as no images and other data is copied between both sites.', 'wp-staging'); ?>
117
+ <br/>
118
+ <br/>
119
+ <?php _e('<strong>This feature only works if the staging site is on the same hosting as the production site.</strong>', 'wp-staging'); ?>
120
+ <?php echo $proSettingsDisabled === true ? '<br/>' . __('(Create a new staging site if you want to change this setting.)', 'wp-staging') : '' ?>
121
+ </span>
122
+ </span>
123
+ </p>
Backend/views/clone/ajax/delete-confirmation.php CHANGED
@@ -2,26 +2,26 @@
2
  <div class="wpstg-notice-alert">
3
  <h3 class="wpstg-m-0 wpstg-pb-5px">
4
  <?php
5
- _e("Do you really want to delete the staging site? This can not be undone:", "wp-staging")
6
  ?>
7
  </h3>
8
 
9
  <p>
10
- <?php _e('Staging Site:', 'wp-staging'); ?>
11
- <span class="wpstg-confirmation-label">
12
  <?php
13
  echo $clone->directoryName;
14
  ?>
15
- </span>
16
  </p>
17
  <p>
18
- <?php _e('Database:', 'wp-staging'); ?>
19
- <span class="wpstg-confirmation-label">
20
  <?php
21
- $database = empty($clone->databaseDatabase) ? "{$dbname} / Main Database)" : $clone->databaseDatabase;
22
  echo $database;
23
  ?>
24
- </span>
25
  </p>
26
  </div>
27
  <?php } ?>
@@ -42,7 +42,7 @@
42
  <?php if ($isDatabaseConnected) { ?>
43
  <a href="#" class="wpstg-tab-header active" data-id="#wpstg-scanning-db">
44
  <span class="wpstg-tab-triangle">&#9658;</span>
45
- <?php echo __("Database tables to remove", "wp-staging")?>
46
  </a>
47
 
48
  <!-- Database -->
@@ -78,7 +78,7 @@
78
 
79
  <a href="#" class="wpstg-tab-header" data-id="#wpstg-scanning-files">
80
  <span class="wpstg-tab-triangle">&#9658;</span>
81
- <?php echo __("Files to remove", "wp-staging")?>
82
  </a>
83
 
84
  <!-- Files -->
@@ -98,10 +98,10 @@
98
  <!-- /Files -->
99
  </div>
100
 
101
- <a href="#" class="wpstg-link-btn button-primary" id="wpstg-cancel-removing">
102
  <?php _e("Cancel", "wp-staging")?>
103
  </a>
104
 
105
- <a href="#" class="wpstg-link-btn button-primary" id="wpstg-remove-clone" data-clone="<?php echo $clone->name?>">
106
- <?php echo __("Remove", "wp-staging")?>
107
  </a>
2
  <div class="wpstg-notice-alert">
3
  <h3 class="wpstg-m-0 wpstg-pb-5px">
4
  <?php
5
+ _e("Do you want to delete the staging site?", "wp-staging")
6
  ?>
7
  </h3>
8
 
9
  <p>
10
+ <?php _e('Staging Site Name:', 'wp-staging'); ?>
11
+ <code>
12
  <?php
13
  echo $clone->directoryName;
14
  ?>
15
+ </code>
16
  </p>
17
  <p>
18
+ <?php _e('Database Location:', 'wp-staging'); ?>
19
+ <code>
20
  <?php
21
+ $database = empty($clone->databaseDatabase) ? $dbname . "</code> (Production Database)" : $clone->databaseDatabase . "</code> (Separate Database)";
22
  echo $database;
23
  ?>
24
+
25
  </p>
26
  </div>
27
  <?php } ?>
42
  <?php if ($isDatabaseConnected) { ?>
43
  <a href="#" class="wpstg-tab-header active" data-id="#wpstg-scanning-db">
44
  <span class="wpstg-tab-triangle">&#9658;</span>
45
+ <?php echo __("Database tables to delete", "wp-staging")?>
46
  </a>
47
 
48
  <!-- Database -->
78
 
79
  <a href="#" class="wpstg-tab-header" data-id="#wpstg-scanning-files">
80
  <span class="wpstg-tab-triangle">&#9658;</span>
81
+ <?php echo __("Files to delete", "wp-staging")?>
82
  </a>
83
 
84
  <!-- Files -->
98
  <!-- /Files -->
99
  </div>
100
 
101
+ <a href="#" class="wpstg-button--primary" id="wpstg-cancel-removing">
102
  <?php _e("Cancel", "wp-staging")?>
103
  </a>
104
 
105
+ <a href="#" class="wpstg-button--primary wpstg-button--red" style="margin-left:5px;" id="wpstg-remove-clone" data-clone="<?php echo $clone->name?>">
106
+ <?php echo __("Delete", "wp-staging")?>
107
  </a>
Backend/views/clone/ajax/exclude-settings.php CHANGED
@@ -1,7 +1,7 @@
1
 
2
  <?php
3
  /**
4
- * @see \WPStaging\Backend\Administrator::ajaxCloneExcludeSettings Context where this is included.
5
  *
6
  * @var stdClass $options
7
  *
@@ -11,9 +11,10 @@
11
 
12
 
13
  <div>
14
- <h1 class="wpstg-m-0 wpstg-mt-10px"><?php _e('RESET CLONE'); ?></h1>
15
- <p><?php _e('Do you really want to reset this staging site with the current state of the production site? The original selection for tables and files have been preselected. You can adjust and verify them before starting the reset.', 'wp-staging'); ?></p>
16
- <p class="wpstg--modal--process--msg--critical"><?php _e('This will delete all your modifications!', 'wp-staging'); ?></p>
 
17
  <div class="wpstg-tabs-wrapper" style="text-align: left;">
18
  <a href="#" class="wpstg-tab-header wpstg-reset-exclude-tab" data-id="#wpstg-reset-excluded-tables" data-collapsed="true">
19
  <span class="wpstg-tab-triangle">&#9658;</span>
1
 
2
  <?php
3
  /**
4
+ * @see \WPStaging\Backend\Administrator::ajaxCloneExcludesSettings Context where this is included.
5
  *
6
  * @var stdClass $options
7
  *
11
 
12
 
13
  <div>
14
+ <h1 class="wpstg-m-0 wpstg-mt-10px swal2-title"><?php _e('Reset Staging Site'); ?></h1>
15
+ <p style="text-align: justify;"><?php _e('Do you really want to reset this staging site with the current state of the production site?', 'wp-staging'); ?></p>
16
+ <p style="color: #e01e5a; font-size: 18px;"><?php _e('This will delete your modifications!', 'wp-staging'); ?></p>
17
+ <p style="text-align: justify;"><?php _e('The original selection for tables and files have been preselected. You can adjust and verify them before starting the reset.', 'wp-staging'); ?></p>
18
  <div class="wpstg-tabs-wrapper" style="text-align: left;">
19
  <a href="#" class="wpstg-tab-header wpstg-reset-exclude-tab" data-id="#wpstg-reset-excluded-tables" data-collapsed="true">
20
  <span class="wpstg-tab-triangle">&#9658;</span>
Backend/views/clone/ajax/external-database.php CHANGED
@@ -1,43 +1,77 @@
1
  <?php
2
 
3
  /**
4
- * This file is currently being called only for the Free version:
5
- * src/Backend/views/clone/ajax/scan.php:113
6
  *
7
- * @file src/Backend/Pro/views/clone/ajax/external-database.php For the Pro counterpart.
 
 
 
 
 
8
  */
9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  ?>
11
- <fieldset disabled class="wpstg-opacity-80">
12
- <p><strong class="wpstg-fs-14">
13
- <?php _e('Copy Staging Site to Separate Database', 'wp-staging'); ?></strong>
14
- <br><?php _e('Database must be created manually in advance!', 'wp-staging'); ?>
 
15
  </p>
16
- <div id="wpstg-external-db">
17
- <div class="wpstg-form-group wpstg-text-field">
18
- <label><?php _e('Server: ', 'wp-staging'); ?> </label>
19
- <input type="text" name="wpstg_db_server" id="wpstg_db_server" value="" title="wpstg_db_server" placeholder="localhost" autocapitalize="off" readonly>
20
- </div>
21
- <div class="wpstg-form-group wpstg-text-field">
22
- <label><?php _e('User: ', 'wp-staging'); ?></label>
23
- <input type="text" name="wpstg_db_username" id="wpstg_db_username" value="" autocapitalize="off" class="" readonly>
24
- </div>
25
- <div class="wpstg-form-group wpstg-text-field">
26
- <label><?php _e('Password: ', 'wp-staging'); ?></label>
27
- <input type="password" name="wpstg_db_password" id="wpstg_db_password" class="" readonly>
28
- </div>
29
- <div class="wpstg-form-group wpstg-text-field">
30
- <label><?php _e('Database: ', 'wp-staging'); ?></label>
31
- <input type="text" name="wpstg_db_database" id="wpstg_db_database" value="" autocapitalize="off" readonly>
32
- </div>
33
- <div class="wpstg-form-group wpstg-text-field">
34
- <label><?php _e('Database Prefix: ', 'wp-staging'); ?></label>
35
- <input type="text" name="wpstg_db_prefix" id="wpstg_db_prefix" value="" placeholder="<?php echo $db->prefix; ?>" autocapitalize="off" readonly>
36
- </div>
37
- <div class="wpstg-form-group wpstg-text-field">
38
- <label>&nbsp;</label>
39
- <a href="#" id="wpstg-db-connect"><?php _e("Test Database Connection", "wp-staging"); ?></a>
40
- </div>
41
- </div>
42
- </fieldset>
43
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
2
 
3
  /**
4
+ * This file is currently being called for both FREE and PRO version:
5
+ * src/Backend/views/clone/ajax/scan.php:62
6
  *
7
+ * @var \WPStaging\Backend\Modules\Jobs\Scan $scan
8
+ * @var stdClass $options
9
+ * @var boolean $isPro
10
+ * @var \wpdb $db
11
+ *
12
+ * @see \WPStaging\Backend\Modules\Jobs\Scan::start For details on $options.
13
  */
14
 
15
+ $database = '';
16
+ $username = '';
17
+ $password = '';
18
+ $prefix = '';
19
+ $server = '';
20
+ $isDisabled = false;
21
+
22
+ if (!$isPro) {
23
+ $isDisabled = true;
24
+ }
25
+
26
+ if ($isPro && !empty($options->current) && $options->current !== null) {
27
+ $database = isset($options->existingClones[$options->current]['databaseDatabase']) ? $options->existingClones[$options->current]['databaseDatabase'] : '';
28
+ $username = isset($options->existingClones[$options->current]['databaseUser']) ? $options->existingClones[$options->current]['databaseUser'] : '';
29
+ $prefix = isset($options->existingClones[$options->current]['databasePrefix']) ? $options->existingClones[$options->current]['databasePrefix'] : '';
30
+ $server = isset($options->existingClones[$options->current]['databaseServer']) ? $options->existingClones[$options->current]['databaseServer'] : '';
31
+ $isDisabled = true;
32
+ $password = '*********';
33
+ }
34
  ?>
35
+ <p class="wpstg--advance-settings--checkbox">
36
+
37
+ <?php if (!$isPro) { // Show this on only FREE version ?>
38
+ <p class="wpstg-dark-alert"><?php _e('These are Pro Features ', 'wp-staging'); ?>
39
+ <a href="https://wp-staging.com/?utm_source=wp-admin&utm_medium=wp-admin&utm_campaign=db-external&utm_term=db-external" target="_blank" class="wpstg-button--primary wpstg-button--cta-red wpstg-border--violet"><?php _e("Get Started", "wp-staging"); ?></a>
40
  </p>
41
+ <?php } ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
 
43
+ <label for="wpstg-ext-db"><?php _e('Change Database'); ?></label>
44
+ <input type="checkbox" id="wpstg-ext-db" name="wpstg-ext-db" value="true" class="wpstg-toggle-advance-settings-section" data-id="wpstg-external-db-section" <?php echo $isPro === true ? '' : 'disabled' ?> >
45
+ <span class="wpstg--tooltip">
46
+ <img class="wpstg--dashicons" src="<?php echo $scan->getInfoIcon(); ?>" alt="info" />
47
+ <span class="wpstg--tooltiptext">
48
+ <?php _e('You can clone the staging site into a separate database. The Database must be created manually in advance before starting the cloning proccess.<br/><br/><strong>Note:</strong> If there are already tables with the same database prefix and name in this database, the cloning process will be aborted without any further asking!', 'wp-staging'); ?>
49
+ </span>
50
+ </span>
51
+ </p>
52
+ <div id="wpstg-external-db-section" <?php echo $isPro === true ? 'style="display: none;"' : '' ?> >
53
+ <div class="wpstg-form-group wpstg-text-field">
54
+ <label><?php _e('Server: ', 'wp-staging'); ?> </label>
55
+ <input type="text" class="wpstg-textbox" name="wpstg_db_server" id="wpstg_db_server" value="<?php echo $server; ?>" title="wpstg_db_server" placeholder="localhost" autocapitalize="off" <?php echo $isDisabled ? 'disabled' : '' ?> readonly>
56
+ </div>
57
+ <div class="wpstg-form-group wpstg-text-field">
58
+ <label for="wpstg_db_username"><?php _e('User: ', 'wp-staging'); ?></label>
59
+ <input type="text" class="wpstg-textbox" name="wpstg_db_username" id="wpstg_db_username" value="<?php echo $username; ?>" autocapitalize="off" <?php echo $isDisabled ? 'disabled' : '' ?> readonly />
60
+ </div>
61
+ <div class="wpstg-form-group wpstg-text-field">
62
+ <label for="wpstg_db_password"><?php _e('Password: ', 'wp-staging'); ?></label>
63
+ <input type="password" class="wpstg-textbox" name="wpstg_db_password" id="wpstg_db_password" value="<?php echo $password; ?>" <?php echo $isDisabled ? 'disabled' : '' ?> readonly />
64
+ </div>
65
+ <div class="wpstg-form-group wpstg-text-field">
66
+ <label for="wpstg_db_database"><?php _e('Database: ', 'wp-staging'); ?></label>
67
+ <input type="text" class="wpstg-textbox" name="wpstg_db_database" id="wpstg_db_database" value="<?php echo $database; ?>" autocapitalize="off" <?php echo $isDisabled ? 'disabled' : '' ?> readonly />
68
+ </div>
69
+ <div class="wpstg-form-group wpstg-text-field">
70
+ <label for="wpstg_db_prefix"><?php _e('Database Prefix: ', 'wp-staging'); ?></label>
71
+ <input type="text" class="wpstg-textbox" name="wpstg_db_prefix" id="wpstg_db_prefix" value="<?php echo $prefix; ?>" placeholder="<?php echo $db->prefix; ?>" autocapitalize="off" <?php echo $isDisabled ? 'disabled' : '' ?> readonly />
72
+ </div>
73
+ <div class="wpstg-form-group wpstg-text-field">
74
+ <a href="#" id="wpstg-db-connect"><?php _e("Test Database Connection", "wp-staging"); ?></a>
75
+ </div>
76
+ <hr />
77
+ </div>
Backend/views/clone/ajax/mail-setting.php CHANGED
@@ -1,14 +1,56 @@
1
- <fieldset disabled class="wpstg-fieldset">
2
- <p>
3
- <?php _e('Toggle emails sending for the staging site.', 'wp-staging'); ?>
4
- </p>
5
- <div class="wpstg-form-group">
6
- <label class="wpstg-checkbox" for="wpstg_allow_emails">
7
- <?php _e('Allow Emails Sending:', 'wp-staging'); ?> <input type="checkbox" id="wpstg_allow_emails" disabled checked>
8
- </label>
9
- </div>
10
- </fieldset>
11
- <p class="wpstg-light-alert"><?php _e('That\'s a Pro Feature', 'wp-staging'); ?>
12
- <br>
13
- <a href="https://wp-staging.com/?utm_source=wp-admin&utm_medium=wp-admin&utm_campaign=db-external&utm_term=db-external" target="_blank" class="quads-button green wpstg-button wpstg-bordered"><?php _e("Get WP STAGING Pro", "wp-staging"); ?></a>
14
- </p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * This file is currently being called for the both FREE and PRO version:
5
+ * src/Backend/views/clone/ajax/scan.php:64
6
+ *
7
+ * @var \WPStaging\Backend\Modules\Jobs\Scan $scan
8
+ * @var stdClass $options
9
+ * @var boolean $isPro
10
+ *
11
+ * @see \WPStaging\Backend\Modules\Jobs\Scan::start For details on $options.
12
+ */
13
+
14
+ // Settings Enabled by default
15
+ $settingsEnabled = true;
16
+ // New staging site. Mails Sending is checked by default.
17
+ $emailsAllowed = true;
18
+ // If plugin is not pro disable this Option
19
+ if (!$isPro) {
20
+ $settingsEnabled = false;
21
+ }
22
+ // Only change default check status when clone options exists plugin is PRO
23
+ if ($isPro && !empty($options->current)) {
24
+ /**
25
+ * Existing staging site.
26
+ * We read the site configuration. If none set, default to checked, since not having the setting
27
+ * to allow the email in the database means it was not disabled.
28
+ */
29
+ // To support staging site created with older version of this feature,
30
+ // Invert it's value if it is present
31
+ // Can be removed when we are sure that all staging sites have been updated.
32
+ $defaultEmailsSending = true;
33
+ if (isset($options->existingClones[$options->current]['emailsDisabled'])) {
34
+ $defaultEmailsSending = !((bool)$options->existingClones[$options->current]['emailsDisabled']);
35
+ }
36
+
37
+ $emailsAllowed = isset($options->existingClones[$options->current]['emailsAllowed']) ? (bool) $options->existingClones[$options->current]['emailsAllowed'] : $defaultEmailsSending;
38
+ } ?>
39
+ <p class="wpstg--advance-settings--checkbox">
40
+ <label for="wpstg_allow_emails"><?php _e('Allow Emails Sending'); ?></label>
41
+ <input type="checkbox" id="wpstg_allow_emails" name="wpstg_allow_emails" value="true" <?php echo $emailsAllowed === true ? 'checked' : '' ?> <?php echo $settingsEnabled === false ? 'disabled' : '' ?> />
42
+ <span class="wpstg--tooltip">
43
+ <img class="wpstg--dashicons" src="<?php echo $scan->getInfoIcon(); ?>" alt="info" />
44
+ <span class="wpstg--tooltiptext">
45
+ <?php _e('Disable emails sending for this staging site.', 'wp-staging'); ?>
46
+ <br /> <br />
47
+ <b><?php _e('Note', 'wp-staging') ?>: </b> <?php echo sprintf(__('Some plugins might still be able to send out mails if they don\'t depend upon %s.', 'wp-staging'), '<code>wp_mail()</code>'); ?>
48
+ </span>
49
+ </span>
50
+ </p>
51
+
52
+ <?php if (!$isPro) { // Show this on only FREE version ?>
53
+ <p class="wpstg-dark-alert"><?php _e('These are Pro Features ', 'wp-staging'); ?>
54
+ <a href="https://wp-staging.com/?utm_source=wp-admin&utm_medium=wp-admin&utm_campaign=db-external&utm_term=db-external" target="_blank" class="wpstg-button--primary wpstg-button--cta-red wpstg-border--violet"><?php _e("Get Started", "wp-staging"); ?></a>
55
+ </p>
56
+ <?php } ?>
Backend/views/clone/ajax/scan.php CHANGED
@@ -9,12 +9,16 @@
9
  *
10
  * @see \WPStaging\Backend\Modules\Jobs\Scan::start For details on $options.
11
  */
 
 
12
  ?>
13
  <label id="wpstg-clone-label" for="wpstg-new-clone">
14
- <?php echo __('Staging Site Name:', 'wp-staging') ?>
15
- <input type="text" id="wpstg-new-clone-id" value="<?php echo $options->current; ?>"<?php if ($options->current !== null) {
16
- echo " disabled='disabled'";
17
- } ?>>
 
 
18
  </label>
19
 
20
  <span class="wpstg-error-msg" id="wpstg-clone-id-error" style="display:none;">
@@ -49,62 +53,68 @@
49
  <a href="#" class="wpstg-tab-header" data-id="#wpstg-advanced-settings">
50
  <span class="wpstg-tab-triangle"><input type="checkbox" name="wpstg-advanced" value="true"></span>
51
  <?php
52
- $pro = defined('WPSTGPRO_VERSION') ? ' ' : ' / Pro';
53
  echo __("Advanced Settings " . $pro, "wp-staging"); ?>
54
  </a>
55
 
56
  <div class="wpstg-tab-section" id="wpstg-advanced-settings">
57
  <?php
58
- if (defined('WPSTGPRO_VERSION')) {
59
- require_once(WPSTG_PLUGIN_DIR . 'Backend/Pro/views/clone/ajax/external-database.php');
60
- require_once(WPSTG_PLUGIN_DIR . 'Backend/Pro/views/clone/ajax/custom-directory.php');
61
- } else {
62
- require_once(__DIR__ . DIRECTORY_SEPARATOR . 'external-database.php');
63
- require_once(__DIR__ . DIRECTORY_SEPARATOR . 'custom-directory.php');
64
- require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mail-setting.php');
65
- }
66
  ?>
67
  </div>
68
  </div>
69
 
70
  <?php
71
 
72
- if (defined('WPSTGPRO_VERSION')) {
73
- require_once(WPSTG_PLUGIN_DIR . 'Backend/Pro/views/clone/ajax/mail-setting.php');
74
- }
75
-
76
  if ($options->current !== null && $options->mainJob === 'updating') {
77
  $uploadsSymlinked = isset($options->existingClones[$options->current]['uploadsSymlinked']) ? (bool)$options->existingClones[$options->current]['uploadsSymlinked'] : false;
78
 
79
  ?>
80
- <p><label>
81
- <input type="checkbox" id="wpstg-clean-plugins-themes" name="wpstg-clean-plugins-themes">
82
- <?php echo __("Delete all plugins & themes on staging site before starting copy process.", "wp-staging"); ?>
83
- </label></p>
84
- <p><label> <?php echo ($uploadsSymlinked ? "<b>" . __("Note: This option is disabled as uploads directory is symlinked", "wp-staging") . "</b><br/>" : '') ?>
85
- <input type="checkbox" id="wpstg-clean-uploads" name="wpstg-clean-uploads" <?php echo ($uploadsSymlinked ? 'disabled' : '') ?>>
86
- <?php echo __("Delete entire folder wp-content/uploads on staging site including all images before starting copy process.", "wp-staging"); ?>
87
- </label></p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  <?php
89
  }
90
  ?>
91
- <strong>Important:</strong><a href="#" id="wpstg-check-space"><?php _e('Check required disk space', 'wp-staging'); ?></a>
92
- <p></p>
93
 
94
- <button type="button" class="wpstg-prev-step-link wpstg-link-btn wpstg-blue-primary wpstg-button">
95
  <?php _e("Back", "wp-staging") ?>
96
  </button>
97
 
98
  <?php
 
 
 
99
  if ($options->current !== null && $options->mainJob === 'updating') {
100
  $label = __("Update Clone", "wp-staging");
101
  $action = 'wpstg_update';
102
-
103
- echo '<button type="button" id="wpstg-start-updating" class="wpstg-next-step-link wpstg-link-btn wpstg-blue-primary wpstg-button" data-action="' . $action . '">' . $label . '</button>';
104
- } else {
105
- $label = __("Start Cloning", "wp-staging");
106
- $action = 'wpstg_cloning';
107
-
108
- echo '<button type="button" id="wpstg-start-cloning" class="wpstg-next-step-link wpstg-link-btn wpstg-blue-primary wpstg-button" data-action="' . $action . '">' . $label . '</button>';
109
  }
110
  ?>
 
 
 
 
9
  *
10
  * @see \WPStaging\Backend\Modules\Jobs\Scan::start For details on $options.
11
  */
12
+
13
+ $isPro = defined('WPSTGPRO_VERSION');
14
  ?>
15
  <label id="wpstg-clone-label" for="wpstg-new-clone">
16
+ <input type="text" id="wpstg-new-clone-id" class="wpstg-textbox"
17
+ placeholder="<?php _e('Enter Site Name (Optional)', 'wp-staging') ?>"
18
+ value="<?php echo $options->current; ?>"
19
+ <?php if ($options->current !== null) {
20
+ echo " disabled='disabled'";
21
+ } ?> />
22
  </label>
23
 
24
  <span class="wpstg-error-msg" id="wpstg-clone-id-error" style="display:none;">
53
  <a href="#" class="wpstg-tab-header" data-id="#wpstg-advanced-settings">
54
  <span class="wpstg-tab-triangle"><input type="checkbox" name="wpstg-advanced" value="true"></span>
55
  <?php
56
+ $pro = $isPro ? ' ' : ' (Requires Pro Version)';
57
  echo __("Advanced Settings " . $pro, "wp-staging"); ?>
58
  </a>
59
 
60
  <div class="wpstg-tab-section" id="wpstg-advanced-settings">
61
  <?php
62
+ require_once(__DIR__ . DIRECTORY_SEPARATOR . 'external-database.php');
63
+ require_once(__DIR__ . DIRECTORY_SEPARATOR . 'custom-directory.php');
64
+ require_once(__DIR__ . DIRECTORY_SEPARATOR . 'mail-setting.php');
 
 
 
 
 
65
  ?>
66
  </div>
67
  </div>
68
 
69
  <?php
70
 
 
 
 
 
71
  if ($options->current !== null && $options->mainJob === 'updating') {
72
  $uploadsSymlinked = isset($options->existingClones[$options->current]['uploadsSymlinked']) ? (bool)$options->existingClones[$options->current]['uploadsSymlinked'] : false;
73
 
74
  ?>
75
+ <fieldset class="wpstg-fieldset" style="margin-left: 16px;">
76
+ <p class="wpstg--advance-settings--checkbox">
77
+ <label for="wpstg-clean-plugins-themes"><?php _e('Clean Plugins/Themes'); ?></label>
78
+ <input type="checkbox" id="wpstg-clean-plugins-themes" name="wpstg-clean-plugins-themes" value="true">
79
+ <span class="wpstg--tooltip">
80
+ <img class="wpstg--dashicons" src="<?php echo $scan->getInfoIcon(); ?>" alt="info" />
81
+ <span class="wpstg--tooltiptext">
82
+ <?php _e('Delete all plugins & themes on staging site before starting copy process.', 'wp-staging'); ?>
83
+ </span>
84
+ </span>
85
+ </p>
86
+ <p class="wpstg--advance-settings--checkbox">
87
+ <label for="wpstg-clean-uploads"><?php _e('Clean Uploads'); ?></label>
88
+ <input type="checkbox" id="wpstg-clean-uploads" name="wpstg-clean-uploads" value="true">
89
+ <span class="wpstg--tooltip">
90
+ <img class="wpstg--dashicons" src="<?php echo $scan->getInfoIcon(); ?>" alt="info" />
91
+ <span class="wpstg--tooltiptext">
92
+ <?php _e('Delete entire folder wp-content/uploads on staging site including all images before starting copy process.', 'wp-staging'); ?>
93
+ <?php echo ($uploadsSymlinked ? "<br/><br/><b>" . __("Note: This option is disabled as uploads directory is symlinked", "wp-staging") . "</b>" : '') ?>
94
+ </span>
95
+ </span>
96
+ </p>
97
+ </fieldset>
98
+ <hr/>
99
  <?php
100
  }
101
  ?>
 
 
102
 
103
+ <button type="button" class="wpstg-prev-step-link wpstg-button--primary">
104
  <?php _e("Back", "wp-staging") ?>
105
  </button>
106
 
107
  <?php
108
+ $label = __("Start Cloning", "wp-staging");
109
+ $action = 'wpstg_cloning';
110
+ $btnId = 'wpstg-start-cloning';
111
  if ($options->current !== null && $options->mainJob === 'updating') {
112
  $label = __("Update Clone", "wp-staging");
113
  $action = 'wpstg_update';
114
+ $btnId = 'wpstg-start-updating';
 
 
 
 
 
 
115
  }
116
  ?>
117
+
118
+ <button type="button" id="<?php echo $btnId; ?>" class="wpstg-next-step-link wpstg-button--primary wpstg-button--blue" data-action="<?php echo $action; ?>"><?php echo $label; ?></button>
119
+
120
+ <a href="#" id="wpstg-check-space"><?php _e('Check required disk space', 'wp-staging'); ?></a>
Backend/views/clone/ajax/single-overview.php CHANGED
@@ -1,12 +1,14 @@
1
  <?php
2
  /**
3
  * @see \WPStaging\Backend\Administrator::ajaxOverview
4
- * @var array availableClones
5
- * @var $license
 
 
6
  */
7
  ?>
8
  <div id="wpstg-step-1">
9
- <button id="wpstg-new-clone" class="wpstg-next-step-link wpstg-link-btn wpstg-blue-primary wpstg-button" data-action="wpstg_scanning">
10
  <?php echo __("Create new staging site", "wp-staging") ?>
11
  </button>
12
  </div>
@@ -28,6 +30,7 @@
28
  <div class="wpstg-dropdown wpstg-action-dropdown">
29
  <a href="#" class="wpstg-dropdown-toggler transparent">
30
  <?php _e("Actions", "wp-staging"); ?>
 
31
  </a>
32
  <div class="wpstg-dropdown-menu">
33
  <?php
@@ -81,7 +84,7 @@
81
  $url = ! empty($data['url']) ? sprintf('<a href="%1$s" target="_blank">%1$s</a>', $data['url']) : '';
82
  $datetime = ! empty($data['datetime']) ? date("D, d M Y H:i:s T", $data['datetime']) : '&nbsp;&nbsp;&nbsp;';
83
  $owner = ! empty($data['ownerId']) ? get_userdata($data['ownerId']) : null;
84
- $ownerName = ($owner !== null) ? $owner->user_login : 'N/A';
85
  $statusTooltip = "This clone is incomplete and does not work. Clone or update it again! \n\n" .
86
  "Important: Keep the browser open until the cloning is finished. \n" .
87
  "It will not proceed if your browser is not open.\n\n" .
@@ -91,7 +94,7 @@
91
 
92
  if (!empty($data['status']) && $data['status'] !== 'finished') {
93
  $status = sprintf(
94
- __('Status: <span class="wpstg-bold" style="color:#ffc2c2;" title="%s">%s</span>', 'wp-staging'),
95
  $statusTooltip,
96
  $data['status']
97
  );
@@ -123,10 +126,20 @@
123
  </div>
124
  </div>
125
  <?php endforeach ?>
 
 
 
126
  </div>
127
  <!-- /Existing Clones -->
128
  <?php endif ?>
129
 
 
 
 
 
 
 
 
130
  <!-- Remove Clone -->
131
  <div id="wpstg-removing-clone">
132
 
1
  <?php
2
  /**
3
  * @see \WPStaging\Backend\Administrator::ajaxOverview
4
+ *
5
+ * @var array $availableClones
6
+ * @var string $iconPath
7
+ * @var $license
8
  */
9
  ?>
10
  <div id="wpstg-step-1">
11
+ <button id="wpstg-new-clone" class="wpstg-next-step-link wpstg-blue-primary wpstg-button" data-action="wpstg_scanning">
12
  <?php echo __("Create new staging site", "wp-staging") ?>
13
  </button>
14
  </div>
30
  <div class="wpstg-dropdown wpstg-action-dropdown">
31
  <a href="#" class="wpstg-dropdown-toggler transparent">
32
  <?php _e("Actions", "wp-staging"); ?>
33
+ <span class="wpstg-caret"></span>
34
  </a>
35
  <div class="wpstg-dropdown-menu">
36
  <?php
84
  $url = ! empty($data['url']) ? sprintf('<a href="%1$s" target="_blank">%1$s</a>', $data['url']) : '';
85
  $datetime = ! empty($data['datetime']) ? date("D, d M Y H:i:s T", $data['datetime']) : '&nbsp;&nbsp;&nbsp;';
86
  $owner = ! empty($data['ownerId']) ? get_userdata($data['ownerId']) : null;
87
+ $ownerName = ! empty($owner->user_login) ? $owner->user_login : 'N/A';
88
  $statusTooltip = "This clone is incomplete and does not work. Clone or update it again! \n\n" .
89
  "Important: Keep the browser open until the cloning is finished. \n" .
90
  "It will not proceed if your browser is not open.\n\n" .
94
 
95
  if (!empty($data['status']) && $data['status'] !== 'finished') {
96
  $status = sprintf(
97
+ __('Status: <span class="wpstg-staging-status wpstg-bold" title="%s">%s</span>', 'wp-staging'),
98
  $statusTooltip,
99
  $data['status']
100
  );
126
  </div>
127
  </div>
128
  <?php endforeach ?>
129
+ <div class="wpstg-fs-14">
130
+ <?php _e("How to:", "wp-staging") ?> <a href="https://wp-staging.com/docs/copy-staging-site-to-live-site/" target="_blank"><?php _e("Push staging site to production", "wp-staging") ?></a>
131
+ </div>
132
  </div>
133
  <!-- /Existing Clones -->
134
  <?php endif ?>
135
 
136
+ <div id="wpstg-no-staging-site-results" class="wpstg-clone" <?php echo $availableClones !== [] ? 'style="display: none;"' : '' ?> >
137
+ <img class="wpstg--dashicons" src="<?php echo $iconPath; ?>" alt="cloud">
138
+ <div class="no-staging-site-found-text">
139
+ <?php _e('No Staging Site found. Create your first Staging Site above!', 'wp-staging'); ?>
140
+ </div>
141
+ </div>
142
+
143
  <!-- Remove Clone -->
144
  <div id="wpstg-removing-clone">
145
 
Backend/views/clone/ajax/start.php CHANGED
@@ -4,7 +4,7 @@
4
  * @var \WPStaging\Backend\Modules\Jobs\Cloning $cloning
5
  */
6
  ?>
7
- <div class=successfullying-section">
8
  <h2 id="wpstg-processing-header"><?php echo __("Processing, please wait...", "wp-staging")?></h2>
9
  <div class="wpstg-progress-bar">
10
  <div class="wpstg-progress" id="wpstg-progress-db"></div>
@@ -19,11 +19,11 @@
19
  <div class="wpstg-clear-both"></div>
20
  </div>
21
 
22
- <button type="button" id="wpstg-cancel-cloning" class="wpstg-button wpstg-link-btn wpstg-blue-primary">
23
  <?php echo __("Cancel", "wp-staging")?>
24
  </button>
25
 
26
- <button type="button" id="wpstg-resume-cloning" class="wpstg-link-btn button-primary">
27
  <?php echo __("Resume", "wp-staging")?>
28
  </button>
29
 
@@ -35,18 +35,17 @@
35
  <span id="wpstg-cloning-result"></span>
36
  </div>
37
 
38
- <div id="wpstg-finished-result">
39
- <h3>Congratulations
40
- </h3>
41
  <?php
42
  $subDirectory = str_replace(get_home_path(), '', ABSPATH);
43
  $helper = new \WPStaging\Core\Utils\Helper();
44
  $url = $helper->getHomeUrl() . str_replace('/', '', $subDirectory);
45
- echo sprintf(__('WP Staging successfully created a staging site in a sub-directory of your main site accessable from:<br><strong><a href="%1$s" target="_blank" id="wpstg-clone-url-1">%1$s</a></strong>', 'wp-staging'), $url);
46
  ?>
47
  <br>
48
  <br>
49
- <a href="" class="wpstg-link-btn wpstg-blue-primary" id="wpstg-home-link">
50
  <?php echo __("BACK", "wp-staging")?>
51
  </a>
52
  <a href="<?php echo $url; ?>" id="wpstg-clone-url" target="_blank" class="wpstg-link-btn wpstg-blue-primary">
@@ -58,33 +57,31 @@
58
  </h3>
59
  <ul>
60
  <li>
61
- <strong>1. Post name permalinks on your <span class="wpstg-font-italic">staging site</span> have been disabled for technical reasons. </strong>
62
  <br>
63
- Usually this will not affect your staging website. In 99% of all cases you do not need to activate permalinks.
64
  <br>
65
  <p>
66
- If Apache is the webserver there is a good chance that permalinks can be activated without further modifications. Try to activate them from <br/>
67
  <br>
68
  <strong>Staging Site > wp-admin > Settings > Permalinks</strong></a>
69
  <br/><br/>
70
- If this does not work or Nginx webserver is used there might be some modifications needed in the files .htaccess (Apache) or *.conf (Nginx).
71
  </p>
72
  <p>
73
- <strong><a href="https://wp-staging.com/docs/activate-permalinks-staging-site/?utm_source=wpstg_admin&utm_medium=finish_screen&utm_campaign=tutorial" target="_blank">Read this tutorial</a> to learn how to enable permalinks on the staging site.</strong>
74
  </p>
75
  </li>
76
  <li>
77
- <strong>2. Verify that you are REALLY working on your staging site and NOT on your production site if you are not 100% sure! </strong>
78
  <br>
79
- Your main and your staging site are both reachable under the same domain so
80
- <br>
81
- this can be confusing.
82
  <p>
83
- To make it more clear when you work on the staging site WP Staging changed the color of the admin bar:
84
  <br><br>
85
  <img src="<?php echo $this->assets->getAssetsUrl("img/admin_dashboard.png") ?>">
86
  <br>
87
- On the fronpage the site name also changed to <br>
88
  <strong class="wpstg-font-italic">
89
  "STAGING - <span class="wpstg-clone-name"><?php echo get_bloginfo("name")?></span>"
90
  </strong>.
4
  * @var \WPStaging\Backend\Modules\Jobs\Cloning $cloning
5
  */
6
  ?>
7
+ <div class="successfullying-section">
8
  <h2 id="wpstg-processing-header"><?php echo __("Processing, please wait...", "wp-staging")?></h2>
9
  <div class="wpstg-progress-bar">
10
  <div class="wpstg-progress" id="wpstg-progress-db"></div>
19
  <div class="wpstg-clear-both"></div>
20
  </div>
21
 
22
+ <button type="button" id="wpstg-cancel-cloning" class="wpstg-button--primary wpstg-button--red">
23
  <?php echo __("Cancel", "wp-staging")?>
24
  </button>
25
 
26
+ <button type="button" id="wpstg-resume-cloning" class="wpstg-link-btn wpstg-button--primary wpstg-button--blue">
27
  <?php echo __("Resume", "wp-staging")?>
28
  </button>
29
 
35
  <span id="wpstg-cloning-result"></span>
36
  </div>
37
 
38
+ <div id="wpstg-finished-result" class="wpstg--grey">
39
+ <h3><?php _e('Congratulations', 'wp-staing') ?></h3>
 
40
  <?php
41
  $subDirectory = str_replace(get_home_path(), '', ABSPATH);
42
  $helper = new \WPStaging\Core\Utils\Helper();
43
  $url = $helper->getHomeUrl() . str_replace('/', '', $subDirectory);
44
+ echo sprintf(__('WP STAGING successfully created a staging site in a sub-directory of your main site accessable from:<br><strong><a href="%1$s" target="_blank" id="wpstg-clone-url-1">%1$s</a></strong>', 'wp-staging'), $url);
45
  ?>
46
  <br>
47
  <br>
48
+ <a href="" class="wpstg-button--primary" id="wpstg-home-link">
49
  <?php echo __("BACK", "wp-staging")?>
50
  </a>
51
  <a href="<?php echo $url; ?>" id="wpstg-clone-url" target="_blank" class="wpstg-link-btn wpstg-blue-primary">
57
  </h3>
58
  <ul>
59
  <li>
60
+ <strong><?php echo sprintf(__('1. Post name permalinks on your %s have been disabled for technical reasons. ', 'wp-staging'), '<span class="wpstg-font-italic">' . __('staging site', 'wp-staging') . '</span>') ?></strong>
61
  <br>
62
+ <?php _e('Usually this will not affect your staging website. In 99% of all cases you do not need to activate permalinks.', 'wp-staging') ?>
63
  <br>
64
  <p>
65
+ <?php _e('If Apache is the webserver there is a good chance that permalinks can be activated without further modifications. Try to activate them from', 'wp-staging') ?> <br/>
66
  <br>
67
  <strong>Staging Site > wp-admin > Settings > Permalinks</strong></a>
68
  <br/><br/>
69
+ <?php _e('If this does not work or Nginx webserver is used there might be some modifications needed in the files .htaccess (Apache) or *.conf (Nginx).', 'wp-staging') ?>
70
  </p>
71
  <p>
72
+ <strong><?php echo sprintf(__('<a href="%s" target="_blank">Read this tutorial</a> to learn how to enable permalinks on the staging site.', 'wp-staging'), 'https://wp-staging.com/docs/activate-permalinks-staging-site/?utm_source=wpstg_admin&utm_medium=finish_screen&utm_campaign=tutorial') ?></strong>
73
  </p>
74
  </li>
75
  <li>
76
+ <strong><?php _e('2. Verify that you are REALLY working on your staging site and NOT on your production site if you are not 100% sure!', 'wp-staging') ?> </strong>
77
  <br>
78
+ <?php _e('Your main and your staging site are both reachable under the same domain so <br> this can be confusing.', 'wp-staging') ?>
 
 
79
  <p>
80
+ <?php _e('To make it more clear when you work on the staging site WP Staging changed the color of the admin bar:', 'wp-staging') ?>
81
  <br><br>
82
  <img src="<?php echo $this->assets->getAssetsUrl("img/admin_dashboard.png") ?>">
83
  <br>
84
+ <?php _e('On the front page the site name also changed to', 'wp-staging') ?> <br>
85
  <strong class="wpstg-font-italic">
86
  "STAGING - <span class="wpstg-clone-name"><?php echo get_bloginfo("name")?></span>"
87
  </strong>.
Backend/views/clone/ajax/update.php CHANGED
@@ -20,7 +20,7 @@
20
  <div class="wpstg-clear-both"></div>
21
  </div>
22
 
23
- <button type="button" id="wpstg-cancel-cloning-update" data-job="<?php echo $cloning->getOptions()->mainJob; ?>" class="wpstg-link-btn button-primary">
24
  <?php
25
  if ($cloning->getOptions()->mainJob === 'resetting') {
26
  _e("Cancel Reset", "wp-staging");
20
  <div class="wpstg-clear-both"></div>
21
  </div>
22
 
23
+ <button type="button" id="wpstg-cancel-cloning-update" data-job="<?php echo $cloning->getOptions()->mainJob; ?>" class="wpstg-link-btn wpstg-button--primary wpstg-button--red">
24
  <?php
25
  if ($cloning->getOptions()->mainJob === 'resetting') {
26
  _e("Cancel Reset", "wp-staging");
Backend/views/clone/index.php CHANGED
@@ -1,42 +1,48 @@
 
 
 
 
 
 
 
 
 
 
1
  <div id="wpstg-clonepage-wrapper">
2
  <?php
3
  require_once($this->path . 'views/_main/header.php');
4
- require_once($this->path . 'views/_main/report-issue.php');
5
  do_action('wpstg_notifications');
6
 
7
- $display = '';
8
- if (!defined('WPSTGPRO_VERSION')) {
9
- $display = 'display:none;';
 
 
 
 
10
  }
 
11
  ?>
12
  <div class="wpstg--tab--wrapper">
13
  <div class="wpstg--tab--header">
14
  <ul>
15
- <li style="<?php echo $display ?>">
16
- <a class="wpstg--tab--content wpstg--tab--active wpstg-button" data-target="#wpstg--tab--staging">
17
  <?php _e('Staging', 'wp-staging') ?>
18
  </a>
19
  </li>
20
- <?php if(class_exists('\WPStaging\Pro\Backup\BackupServiceProvider') && \WPStaging\Pro\Backup\BackupServiceProvider::isEnabled()): ?>
21
- <li style="<?php echo $display ?>">
22
- <a class="wpstg-button" data-target="#wpstg--tab--backup">
23
- <?php _e('Backup & Migrate', 'wp-staging') ?>
24
- </a>
25
- </li>
26
- <?php else: ?>
27
- <li style="<?php echo $display ?>">
28
- <a class="wpstg-button" data-target="#wpstg--tab--database-backups">
29
- <?php _e('Backups', 'wp-staging') ?>
30
  </a>
31
  </li>
32
- <?php endif; ?>
33
  <li>
34
  <span class="wpstg-loader"></span>
35
  </li>
36
  </ul>
37
  </div>
38
  <div class="wpstg--tab--contents">
39
- <div id="wpstg--tab--staging" class="wpstg--tab--content wpstg--tab--active">
40
  <?php
41
  if (!$this->siteInfo->isCloneable()) {
42
  // Staging site but not cloneable
@@ -49,11 +55,14 @@
49
  }
50
  ?>
51
  </div>
52
- <div id="wpstg--tab--backup" class="wpstg--tab--content">
53
- <?php _e('Loading...', 'wp-staging') ?>
54
- </div>
55
- <div id="wpstg--tab--database-backups" class="wpstg--tab--content">
56
- <?php _e('Loading...', 'wp-staging') ?>
 
 
 
57
  </div>
58
  </div>
59
  </div>
1
+ <?php
2
+
3
+ /**
4
+ * @see \WPStaging\Backend\Administrator::getClonePage()
5
+ * @see \WPStaging\Backend\Administrator::getBackupPage()
6
+ * @var bool $openBackupPage
7
+ */
8
+
9
+ ?>
10
+
11
  <div id="wpstg-clonepage-wrapper">
12
  <?php
13
  require_once($this->path . 'views/_main/header.php');
 
14
  do_action('wpstg_notifications');
15
 
16
+ if (isset($openBackupPage)){
17
+ echo "<script>window.addEventListener('DOMContentLoaded', function() {window.dispatchEvent(new Event('backups-tab'));});</script>";
18
+ $classStagingPageActive = '';
19
+ $classBackupPageActive = 'wpstg--tab--active';
20
+ } else {
21
+ $classStagingPageActive = 'wpstg--tab--active';
22
+ $classBackupPageActive = '';
23
  }
24
+
25
  ?>
26
  <div class="wpstg--tab--wrapper">
27
  <div class="wpstg--tab--header">
28
  <ul>
29
+ <li>
30
+ <a class="wpstg--tab--content <?php echo $classStagingPageActive; ?> wpstg-button" data-target="#wpstg--tab--staging">
31
  <?php _e('Staging', 'wp-staging') ?>
32
  </a>
33
  </li>
34
+ <li>
35
+ <a class="wpstg-button <?php echo $classBackupPageActive; ?>" data-target="#wpstg--tab--backup" id="wpstg--tab--toggle--backup">
36
+ <?php _e('Backup & Migration', 'wp-staging') ?>
 
 
 
 
 
 
 
37
  </a>
38
  </li>
 
39
  <li>
40
  <span class="wpstg-loader"></span>
41
  </li>
42
  </ul>
43
  </div>
44
  <div class="wpstg--tab--contents">
45
+ <div id="wpstg--tab--staging" class="wpstg--tab--content <?php echo $classStagingPageActive; ?>">
46
  <?php
47
  if (!$this->siteInfo->isCloneable()) {
48
  // Staging site but not cloneable
55
  }
56
  ?>
57
  </div>
58
+ <div id="wpstg--tab--backup" class="wpstg--tab--content <?php echo $classBackupPageActive; ?>">
59
+ <?php
60
+ if (defined('WPSTGPRO_VERSION')) {
61
+ _e('Loading...', 'wp-staging');
62
+ } else {
63
+ require_once($this->path . "views/backup/free-version.php");
64
+ }
65
+ ?>
66
  </div>
67
  </div>
68
  </div>
Backend/views/clone/single-site/index.php CHANGED
@@ -16,9 +16,12 @@
16
  <?php echo __("Pushing", "wp-staging") ?>
17
  </li>
18
  <li>
19
- <button type="button" id="wpstg-report-issue-button" class="wpstg-button">
20
- <i class="wpstg-icon-issue"></i><?php echo __("Report Issue", "wp-staging"); ?>
21
- </button>
 
 
 
22
  </li>
23
  </ul>
24
 
@@ -28,11 +31,11 @@
28
  <div id="wpstg-sidebar">
29
  <div class="wpstg-text-center">
30
  <span class="wpstg-feedback-span">
31
- <a class="wpstg-feedback-link" href="https://wordpress.org/support/plugin/wp-staging/reviews/?filter=5" target="_blank" rel="external noopener">Give Feedback ★★★</a>
32
  </span>
33
  </div>
34
  <a href="https://wp-staging.com/?utm_source=tryout&utm_medium=plugin&utm_campaign=tryout&utm_term=tryout" target="_new">
35
- <img src="<?php echo $this->assets->getAssetsUrl('img/wpstaging-banner200x400-tryout.gif'); ?>">
36
  </a>
37
  </div>
38
  <?php } ?>
16
  <?php echo __("Pushing", "wp-staging") ?>
17
  </li>
18
  <li>
19
+ <div id="wpstg-report-issue-wrapper">
20
+ <button type="button" id="wpstg-report-issue-button" class="wpstg-button">
21
+ <i class="wpstg-icon-issue"></i><?php echo __("Report Issue", "wp-staging"); ?>
22
+ </button>
23
+ <?php require_once($this->path . 'views/_main/report-issue.php'); ?>
24
+ </div>
25
  </li>
26
  </ul>
27
 
31
  <div id="wpstg-sidebar">
32
  <div class="wpstg-text-center">
33
  <span class="wpstg-feedback-span">
34
+ <a class="wpstg-feedback-link wpstg--blue" href="https://wordpress.org/support/plugin/wp-staging/reviews/?filter=5" target="_blank" rel="external noopener">Rate Plugin ★★★</a>
35
  </span>
36
  </div>
37
  <a href="https://wp-staging.com/?utm_source=tryout&utm_medium=plugin&utm_campaign=tryout&utm_term=tryout" target="_new">
38
+ <img id="wpstg-sidebar--banner" src="<?php echo $this->assets->getAssetsUrl('img/wp-staging274x463-1.png'); ?>">
39
  </a>
40
  </div>
41
  <?php } ?>
Backend/views/clone/staging-site/index.php CHANGED
@@ -1,12 +1,18 @@
1
- <span class="wpstg-notice-alert wpstg-mt-20px">
2
- <?php echo __("This staging site can be pushed and modified with WP STAGING Pro plugin installed on your production site! Open WP Staging Pro on your production site and start the pushing process from there!", "wp-staging")?>
 
 
 
 
 
 
 
 
 
3
  <br/>
4
- <?php echo sprintf(__("<a href='%s' target='_new'>Open WP STAGING Pro on Live Site</a>", 'wp-staging'), wpstg_get_production_hostname() . '/wp-admin/admin.php?page=wpstg_clone'); ?>
5
- <br/>
6
- <br/>
7
- <br/>
8
- <button class='wpstg-button wpstg-button-light' id="wpstg-enable-staging-cloning"><?php _e('Click here', 'wp-staging') ?></button> <?php _e(' to make this staging site cloneable.', 'wp-staging') ?>
9
- <br/>
10
- <br/>
11
- <?php echo sprintf(__("If you would like to know more about cloning staging sites check out <a href='%s' target='_new'>this article</a>.", 'wp-staging'), 'https://wp-staging.com/docs/cloning-a-staging-site-testing-push-method/'); ?>
12
- </span>
1
+ <?php
2
+
3
+ /**
4
+ * This file is called on the staging site in
5
+ * @see /Backend/views/clone/index.php
6
+ */
7
+
8
+ ?>
9
+
10
+ <span class="wpstg-notice--white wpstg-mt-20px">
11
+ <?php echo __("If you want to transfer this staging site to the production site,", "wp-staging") ?>
12
  <br/>
13
+ <?php echo sprintf(__("<a href='%s' target='_new'>Open WP STAGING on Live Site</a> and start the push process from there.", 'wp-staging'), (new WPStaging\Framework\Utils\Urls())->getProductionHostname() . '/wp-admin/admin.php?page=wpstg_clone'); ?>
14
+ <br/> <br/>
15
+ <?php _e("If you want to clone this staging site, you can <a href='#' id='wpstg-enable-staging-cloning'>click here</a>!", 'wp-staging'); ?>
16
+ <br/> <br/>
17
+ <?php echo sprintf(__("<a href='%s' target='_new'>Read this article</a> if you would like to know more about cloning a staging site.", 'wp-staging'), 'https://wp-staging.com/docs/cloning-a-staging-site-testing-push-method/'); ?>
18
+ </span>
 
 
 
Backend/views/database/legacy/confirm-delete.php DELETED
@@ -1,31 +0,0 @@
1
- <?php
2
-
3
- use WPStaging\Framework\TemplateEngine\TemplateEngine;
4
- use WPStaging\Pro\Database\Legacy\Entity\Backup;
5
-
6
- /** @var TemplateEngine $this */
7
- /** @var Backup $backup */
8
- ?>
9
- <div class="wpstg-notice-alert wpstg-failed">
10
- <h4 style="margin:0;">
11
- <?php _e('This backup will be deleted.', 'wp-staging') ?>
12
- </h4>
13
- <?php _e('Are you sure that you want to delete the site backup? This action can not be undone!', 'wp-staging') ?>
14
- </div>
15
-
16
- <div class="wpstg-box">
17
- <div class="wpstg-db-table">
18
- <?php if (!empty($size = $backup->getFileSize())) : ?>
19
- <label><?php _e('File Size', 'wp-staging')?></label>
20
- <span class="wpstg-size-info"><?php echo esc_html($size); ?></span>
21
- <?php endif; ?>
22
- </div>
23
- </div>
24
-
25
- <a href="#" class="wpstg-link-btn button-primary" id="wpstg-cancel-backup-delete">
26
- <?php _e('Cancel', 'wp-staging')?>
27
- </a>
28
-
29
- <a href="#" class="wpstg-link-btn button-primary" id="wpstg-delete-backup" data-id="<?php echo $backup->getId()?>">
30
- <?php _e('Delete', 'wp-staging')?>
31
- </a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Backend/views/database/legacy/confirm-restore.php DELETED
@@ -1,114 +0,0 @@
1
- <?php
2
-
3
- use WPStaging\Framework\Database\TableDto;
4
- use WPStaging\Framework\Collection\Collection;
5
- use WPStaging\Framework\TemplateEngine\TemplateEngine;
6
- use WPStaging\Pro\Database\Legacy\Entity\Backup;
7
-
8
- /** @var TemplateEngine $this */
9
- /** @var Backup $backup */
10
- /** @var TableDto[]|Collection $backupTables */
11
- /** @var TableDto[]|Collection $prodTables */
12
- /** @var Closure $isTableChanged */
13
- ?>
14
- <div class="wpstg-beta-notice" style="display:none;">
15
- <?php _e('WP STAGING backup restoring works well but is a new feature in beta status. Please use it on your own risk and have a backup of your site before using it. <br>If you experience an issue or you have a feature request <a href="#" id="wpstg-backups-report-issue-button">please give us some feedback.</a>', 'wp-staging') ?>
16
- </div>
17
- <div class="wpstg-notice-alert wpstg-failed">
18
- <h4 style="margin:0;">
19
- <?php _e('Take care: This will overwrite your database!', 'wp-staging') ?>
20
- </h4>
21
-
22
- <p>
23
- <?php _e('Are you sure that you want to restore the WordPress database with this backup created at ' . $this->transformToWpFormat($backup->getCreatedAt()) . '?', 'wp-staging') ?>
24
- </p>
25
- <?php _e('The production tables will be overwritten with the backup and the WordPress database will be restored to another point in time.', 'wp-staging') ?>
26
- <br><br>
27
- <?php _e('This will not delete any tables that are existing on the production site but not in the backup. If you want to remove them you will need to delete them manually.', 'wp-staging') ?>
28
- <br><br>
29
- <?php _e('Do not interrupt the process. Restoring can not be undone!', 'wp-staging') ?>
30
- </div>
31
-
32
- <div class="wpstg-box">
33
- <div class="wpstg-float-left">
34
-
35
- <h3><?php _e('Tables below will be overwritten:', 'wp-staging') ?></h3>
36
- <table class="wpstg--snaphot-restore-table">
37
- <?php foreach ($prodTables as $prodTable) : ?>
38
- <tr>
39
- <?php
40
- $lastUpdate = $this->transformToWpFormat($prodTable->getUpdatedAt() ?: $prodTable->getCreatedAt());
41
- $textBoldDanger = $isTableChanged($prodTable, $backupTables) ? ' wpstg--text--strong wpstg--text--danger' : '';
42
- $title = empty($textBoldDanger) ? '' : __('This table is different compared to its backup equivalent.', 'wp-staging');
43
- ?>
44
- <td>
45
- <span class="wpstg-db-table<?php echo $textBoldDanger ?>" title="<?php echo $title ?>"><?php echo $prodTable->getName() ?></span>
46
- </td>
47
- <td>
48
- <span class="wpstg-size-info <?php echo $textBoldDanger ?>"><?php echo $prodTable->getHumanReadableSize() ?></span>
49
- <span class="wpstg-size-info <?php echo $textBoldDanger ?>" title="Last updated: <?php echo $lastUpdate ?>"> - <?php echo $lastUpdate; ?></span>
50
- </td>
51
- </tr>
52
- <?php endforeach ?>
53
- </table>
54
- </div>
55
- <div class="wpstg-float-left" style="margin-left:10px;">
56
- <h3><?php _e('Tables below will be restored:', 'wp-staging') ?></h3>
57
- <table class="wpstg--snaphot-restore-table">
58
- <?php foreach ($backupTables as $backupTable) : ?>
59
- <tr>
60
- <?php
61
- $lastUpdate = $this->transformToWpFormat($backupTable->getUpdatedAt() ?: $backupTable->getCreatedAt());
62
- $textBold = $isTableChanged($backupTable, $prodTables) ? ' wpstg--text--strong' : '';
63
- $title = empty($textBold) ? '' : __('This table is different compared to its production equivalent.', 'wp-staging');
64
- ?>
65
- <td>
66
- <span class="wpstg-db-table<?php echo $textBold ?>" title="<?php echo $title ?>"><?php echo $backupTable->getName() ?></span>
67
- </td>
68
- <td>
69
- <span class="wpstg-size-info <?php echo $textBold ?>"><?php echo $backupTable->getHumanReadableSize() ?></span>
70
- <span class="wpstg-size-info <?php echo $textBold ?>" title="Last updated: <?php echo $lastUpdate ?>"> - <?php echo $lastUpdate ?></span>
71
- </td>
72
- </tr>
73
- <?php endforeach ?>
74
- </table>
75
- </div>
76
- </div>
77
-
78
- <a href="#" class="wpstg-link-btn wpstg-blue-primary" id="wpstg--backup--restore--cancel">
79
- <?php _e('Cancel', 'wp-staging') ?>
80
- </a>
81
-
82
- <a href="#" class="wpstg-link-btn wpstg-blue-primary" id="wpstg--backup--restore"
83
- data-id="<?php echo $backup->getId() ?>">
84
- <?php _e('Restore Backup', 'wp-staging') ?>
85
- </a>
86
-
87
- <!-- TODO RPoC -->
88
- <div id="wpstg--modal--backup--process" data-cancelButtonText="<?php _e('CANCEL', 'wp-staging') ?>" style="display: none">
89
- <span class="wpstg-loader"></span>
90
- <h3 class="wpstg--modal--process--title" style="color: #a8a8a8;margin: .25em 0;">
91
- <?php _e('Processing...', 'wp-staging') ?>
92
- </h3>
93
- <div style="margin: .5em 0; color: #a8a8a8;">
94
- <?php
95
- echo sprintf(
96
- __('Progress %s - Elapsed time %s', 'wp-staging'),
97
- '<span class="wpstg--modal--process--percent">0</span>%',
98
- '<span class="wpstg--modal--process--elapsed-time">0:00</span>'
99
- )
100
- ?>
101
- </div>
102
- <button
103
- class="wpstg--modal--process--logs--tail"
104
- data-txt-bad="<?php echo sprintf(
105
- __('(%s) Critical, (%s) Errors, (%s) Warnings. Show Logs', 'wp-staging'),
106
- '<span class=\'wpstg--modal--logs--critical-count\'>0</span>',
107
- '<span class=\'wpstg--modal--logs--error-count\'>0</span>',
108
- '<span class=\'wpstg--modal--logs--warning-count\'>0</span>'
109
- ) ?>"
110
- >
111
- <?php _e('Show Logs', 'wp-staging') ?>
112
- </button>
113
- <div class="wpstg--modal--process--logs"></div>
114
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Backend/views/database/legacy/listing.php DELETED
@@ -1,331 +0,0 @@
1
- <?php
2
-
3
- /**
4
- * @todo See if we can unify this file with src/template/Component/Backend/Backup/listing.php:8
5
- */
6
-
7
- use WPStaging\Pro\Database\Legacy\Entity\Backup;
8
- use WPStaging\Pro\Database\Legacy\Collection\OptionCollection;
9
- use WPStaging\Framework\TemplateEngine\TemplateEngine;
10
- use WPStaging\Framework\Adapter\Directory;
11
-
12
- /** @var TemplateEngine $this */
13
- /** @var Backup[]|OptionCollection $backups */
14
- /** @var array $directories */
15
- /** @var string $urlAssets */
16
- /** @var Directory $directory */
17
-
18
- ?>
19
-
20
- <div id="wpstg-step-1">
21
- <button id="wpstg-new-database-backup" class="wpstg-next-step-link wpstg-link-btn wpstg-blue-primary wpstg-button"
22
- data-action="wpstg--backups--create">
23
- <?php _e('Backup & Export Database', 'wp-staging') ?>
24
- </button>
25
- <div class="wpstg--tooltip"> <?php _e('What is this?', 'wp-staging'); ?>
26
-
27
- <span class="wpstg--tooltiptext wpstg--tooltiptext-backups">
28
- <?php _e('This can create a backup of the WordPress database tables at a particular point in time.
29
- You can restore WordPress and roll back the database to another state.<br><br>
30
- This is useful if you need to reset WordPress to the state before you\'ve pushed a staging site to live or if you want to revert other database changes
31
- like activating a new theme or updating its settings.<br><br>
32
- This backup include all WordPress core tables and custom ones created by other plugins.
33
- Restoring a backup will not affect other staging sites or existing backups. <br><br>
34
- No files are included in backups! This is a quick way to roll back your site in time. For a full site backup it is recommended to use a dedicated backup plugin!
35
- ', 'wp-staging') ?>
36
- <p></p>
37
- <?php if (is_multisite()) {
38
- echo '<strong>' . __('Multisite Users Only: ', 'wp-staging') . '</strong>';
39
- echo '<p></p>';
40
- echo __("- If you run the backup function on a multisite network site the backup will contain only the tables belonging to the particular network site. <p></p>It will not save all database tables of all network sites. So you are able to restore all network sites independently. <p></p>- If you create a backup on a multisite main site it will create a backup of <strong>all database tables</strong>.</p></p><strong>Take care:</strong> Restoring a multisite main backup will <strong>restore all children sites including the mainsite.</strong>", 'wp-staging');
41
- } ?>
42
- </span>
43
- </div>
44
- </div>
45
-
46
- <div id="wpstg-existing-database-backups">
47
-
48
- &nbsp;
49
- <?php
50
-
51
- if (!empty($backups)) {
52
- echo '<h3>' . __('Available Backups', 'wp-staging') . '</h3>';
53
- }
54
-
55
-
56
- foreach ($backups as $backup) : ?>
57
- <div id="<?php echo $backup->getId() ?>" class="wpstg-clone wpstg-backup" data-type="<?php echo $backup->getType() ?>">
58
- <div class="wpstg-clone-header">
59
- <span class="wpstg-clone-title" data-title="<?php echo esc_attr($backup->getName()) ?>"><?php echo $backup->getName() ?></span>
60
- <div class="wpstg-clone-actions">
61
- <div class="wpstg-dropdown wpstg-action-dropdown">
62
- <a href="#" class="wpstg-dropdown-toggler transparent">Actions</a>
63
- <div class="wpstg-dropdown-menu">
64
-
65
- <a href="#" class="wpstg--backup--download wpstg-merge-clone wpstg-clone-action"
66
- data-id="<?php echo $backup->getId() ?>"
67
- data-url="<?php echo $backup->getUrlDownload() ?: null ?>"
68
- data-title="<?php _e('Download Backup', 'wp-staging') ?>"
69
- data-title-export="<?php _e('Exporting Database Tables...', 'wp-staging') ?>"
70
- data-btn-cancel-txt="<?php _e('CANCEL', 'wp-staging') ?>"
71
- data-btn-download-txt="<?php _e($backup->getUrlDownload() ? 'Download' : 'Export & Download', 'wp-staging') ?>"
72
- title="<?php _e('Download backup file on local system', 'wp-staging') ?>">
73
- <?php _e('Download', 'wp-staging') ?>
74
- </a>
75
-
76
- <a href="#" class="wpstg--backup--restore wpstg-merge-clone wpstg-clone-action"
77
- data-id="<?php echo $backup->getId() ?>"
78
- title="<?php _e('Restore this backup to your live website!', 'wp-staging') ?>">
79
- <?php _e('Restore', 'wp-staging') ?>
80
- </a>
81
-
82
- <a href="#" class="wpstg-remove-clone wpstg-clone-action wpstg-delete-backup"
83
- data-id="<?php echo $backup->getId() ?>"
84
- title="<?php _e('Delete this backup. This action can not be undone!', 'wp-staging') ?>">
85
- <?php _e('Delete', 'wp-staging') ?>
86
- </a>
87
-
88
- <a href="#" class="wpstg--backup--edit wpstg-clone-action"
89
- data-id="<?php echo $backup->getId() ?>"
90
- data-name="<?php echo $backup->getName() ?>"
91
- data-notes="<?php echo $backup->getNotes() ?>"
92
- title="<?php _e('Edit backup name and / or notes', 'wp-staging') ?>">
93
- <?php _e('Edit', 'wp-staging') ?>
94
- </a>
95
- </div>
96
- </div>
97
- </div>
98
- </div>
99
-
100
- <div class="wpstg-staging-info">
101
- <ul>
102
- <li>
103
- <strong>
104
- <?php
105
- _e(
106
- $backup->getType() === Backup::TYPE_DATABASE ? 'Table Prefix:' : 'Id:',
107
- 'wp-staging'
108
- )
109
- ?>
110
- </strong>
111
- <?php echo $backup->getId() ?>
112
- </li>
113
- <li>
114
- <strong><?php _e('Created on:', 'wp-staging') ?></strong>
115
- <?php echo $this->transformToWpFormat($backup->getCreatedAt()) ?>
116
- <?php if ($backup->getUpdatedAt()) : ?>
117
- &nbsp; | &nbsp;<strong><?php _e('Updated on:', 'wp-staging') ?></strong>
118
- <?php echo $this->transformToWpFormat($backup->getUpdatedAt()) ?>
119
- <?php endif ?>
120
- </li>
121
- <?php if ($backup->getNotes()) : ?>
122
- <li>
123
- <strong><?php _e('Notes:', 'wp-staging') ?></strong><br/>
124
- <?php echo nl2br($backup->getNotes()) ?>
125
- </li>
126
- <?php endif ?>
127
- <?php if (!empty($size = $backup->getFileSize())) : ?>
128
- <li>
129
- <strong><?php _e('Size:', 'wp-staging') ?></strong><br/>
130
- <?php echo esc_html($size); ?>
131
- </li>
132
- <?php endif ?>
133
- </ul>
134
- </div>
135
- </div>
136
- <?php endforeach ?>
137
- </div>
138
-
139
- <div id="wpstg--modal--database--new" data-confirmButtonText="<?php _e('Take New Database Backup', 'wp-staging') ?>" style="display: none">
140
- <label for="backup_type_database" style="display:none;"><?php _e('Backup Type', 'wp-staging') ?></label>
141
- <div style="padding: .75em; margin: 1em auto;display:none;">
142
- <label style="margin-right: .5em;">
143
- <input type="radio" name="backup_type" id="backup_type_database" value="database" checked/>
144
- <?php _e('Database Only', 'wp-staging') ?>
145
- </label>
146
- <label>
147
- <input type="radio" name="backup_type" id="backup_type_site" value="site"/>
148
- <?php _e('Files and Database', 'wp-staging') ?>
149
- </label>
150
- </div>
151
- <label for="wpstg-backup-name-input"><?php _e('Backup Name', 'wp-staging') ?></label>
152
- <input id="wpstg-backup-name-input" name="backup_name" class="swal2-input" placeholder="<?php _e('Name your backup for better distinction', 'wp-staging') ?>">
153
- <label for="wpstg-backup-notes-textarea"><?php _e('Additional Notes', 'wp-staging') ?></label>
154
- <textarea id="wpstg-backup-notes-textarea" name="backup_note" class="swal2-textarea" placeholder="<?php _e("Add an optional description e.g.: 'before push of staging site', 'before updating plugin XY'", 'wp-staging') ?>"></textarea>
155
-
156
- <div class="wpstg-advanced-options" style="text-align: left; display: none">
157
- <a href="#" class="wpstg--tab--toggle" data-target=".wpstg-advanced-options-site" style="text-decoration: none;">
158
- <span style="margin-right: .25em">►</span>
159
- <?php _e('Advanced Options', 'wp-staging') ?>
160
- </a>
161
- <?php _e('(click to expand)', 'wp-staging') ?>
162
-
163
- <div class="wpstg-advanced-options-site" style="display: none; padding-left: .75em;">
164
- <label style="display: block;margin: .5em 0;">
165
- <input type="checkbox" name="includedDirectories[]" value="<?php echo $directories['uploads'] ?>" checked/>
166
- <?php _e('Export Media Library', 'wp-staging') ?>
167
- </label>
168
- <label style="display: block;margin: .5em 0;">
169
- <input type="checkbox" name="includedDirectories[]" value="<?php echo $directories['themes'] ?>" checked/>
170
- <?php _e('Export Themes', 'wp-staging') ?>
171
- </label>
172
- <label style="display: block;margin: .5em 0;">
173
- <input type="checkbox" name="includedDirectories[]" value="<?php echo $directories['muPlugins'] ?>" checked/>
174
- <?php _e('Export Must-Use Plugins', 'wp-staging') ?>
175
- </label>
176
- <label style="display: block;margin: .5em 0;">
177
- <input type="checkbox" name="includedDirectories[]" value="<?php echo $directories['plugins'] ?>" checked/>
178
- <?php _e('Export Plugins', 'wp-staging') ?>
179
- </label>
180
- <label style="display: block;margin: .5em 0;">
181
- <input type="checkbox" name="export_database" value="true" checked/>
182
- <?php _e('Exporting Database', 'wp-staging') ?>
183
- </label>
184
- <input type="hidden" name="wpContentDir" value="<?php echo $directories['wpContent'] ?>"/>
185
- <input type="hidden" name="wpStagingDir" value="<?php echo $directories['wpStaging'] ?>"/>
186
- <?php unset($directories['wpContent'], $directories['wpStaging']) ?>
187
- <input type="hidden" name="availableDirectories" value="<?php echo implode('|', $directories) ?>"/>
188
- </div>
189
- </div>
190
- </div>
191
- <div id="wpstg--modal--backup--process" data-cancelButtonText="<?php _e('CANCEL', 'wp-staging') ?>" style="display: none">
192
- <span class="wpstg-loader"></span>
193
- <h3 class="wpstg--modal--process--title" style="color: #a8a8a8;margin: .25em 0;">
194
- <?php _e('Processing...', 'wp-staging') ?>
195
- </h3>
196
- <div style="margin: .5em 0; color: #a8a8a8;">
197
- <?php
198
- echo sprintf(
199
- __('Progress %s - Elapsed time %s', 'wp-staging'),
200
- '<span class="wpstg--modal--process--percent">0</span>%',
201
- '<span class="wpstg--modal--process--elapsed-time">0:00</span>'
202
- )
203
- ?>
204
- </div>
205
- <div class="wpstg--modal--process--generic-problem"></div>
206
- <button
207
- class="wpstg--modal--process--logs--tail"
208
- data-txt-bad="<?php echo sprintf(
209
- __('(%s) Critical, (%s) Errors, (%s) Warnings. Show Logs', 'wp-staging'),
210
- '<span class=\'wpstg--modal--logs--critical-count\'>0</span>',
211
- '<span class=\'wpstg--modal--logs--error-count\'>0</span>',
212
- '<span class=\'wpstg--modal--logs--warning-count\'>0</span>'
213
- ) ?>"
214
- >
215
- <?php _e('Show Logs', 'wp-staging') ?>
216
- </button>
217
- <div class="wpstg--modal--process--logs"></div>
218
- </div>
219
- <div id="wpstg--modal--backup--download" style="display: none">
220
- <h2>{title}</h2>
221
- <div class="wpstg--modal--download--logs--wrapper" style="display:none">
222
- <button class="wpstg--modal--process--logs--tail">{btnTxtLog}</button>
223
- <div class="wpstg--modal--process--logs"></div>
224
- </div>
225
- </div>
226
- <div
227
- id="wpstg--modal--backup--import"
228
- data-confirmButtonText="<?php _e('IMPORT', 'wp-staging') ?>"
229
- data-nextButtonText="<?php _e('NEXT', 'wp-staging') ?>"
230
- data-cancelButtonText="<?php _e('CANCEL', 'wp-staging') ?>"
231
- data-baseDirectory="<?php echo $directory->getPluginUploadsDirectory() ?>"
232
- style="display: none"
233
- >
234
- <h2 class="wpstg--modal--backup--import--upload--title"><?php _e('Import Backup', 'wp-staging') ?></h2>
235
- <div style="padding: .75em; margin: 1em auto;">
236
- <div class="wpstg--modal--backup--import--upload">
237
- <div class="wpstg--modal--backup--import--upload--container">
238
- <div class="wpstg--uploader">
239
- <input type="file" name="wpstg--backup--import--upload--file"/>
240
- <img src="<?php echo $urlAssets . 'img/upload.svg' ?>" alt="Upload Image"/>
241
- <span class="wpstg--backup--import--selected-file"></span>
242
- <span class="wpstg--drag-or-upload">
243
- <?php _e('Drag a new export file here or choose another option', 'wp-staging') ?>
244
- </span>
245
- <span class="wpstg--drag">
246
- <?php _e('Drag and Drop a backup file to start import', 'wp-staging') ?>
247
- </span>
248
- <span class="wpstg--drop">
249
- <?php _e('Drop export file here', 'wp-staging') ?>
250
- </span>
251
- <div class="wpstg--backup--import--options">
252
- <button
253
- class="wpstg-blue-primary wpstg-button wpstg-link-btn wpstg--backup--import--choose-option"
254
- data-txtOther="<?php _e('Import from', 'wp-staging') ?>"
255
- data-txtChoose="<?php _e('Choose an Option', 'wp-staging') ?>"
256
- >
257
- <?php _e('Import from', 'wp-staging') ?>
258
- </button>
259
- <ul>
260
- <li>
261
- <button class="wpstg--backup--import--option wpstg-blue-primary" data-option="file">
262
- <?php _e('Local Computer', 'wp-staging') ?>
263
- </button>
264
- </li>
265
- <li>
266
- <button class="wpstg--backup--import--option wpstg-blue-primary" data-option="filesystem">
267
- <?php _e('Upload Directory', 'wp-staging') ?>
268
- </button>
269
- </li>
270
- </ul>
271
- </div>
272
- </div>
273
- <div class="wpstg--modal--import--upload--process">
274
- <div class="wpstg--modal--import--upload--progress"></div>
275
- <h4 class="wpstg--modal--import--upload--progress--title">
276
- <?php echo sprintf(__('Uploading %s%%...', 'wp-staging'), '<span></span>') ?>
277
- </h4>
278
- </div>
279
- </div>
280
- <div
281
- class="wpstg--modal--backup--import--upload--status"
282
- data-txt-uploading="<?php _e('Uploading...', 'wp-staging') ?>"
283
- data-txt-done="<?php _e('Uploaded Successfully', 'wp-staging') ?>"
284
- data-txt-error="<?php _e('Error! {message}', 'wp-staging') ?>"
285
- >
286
- </div>
287
- </div>
288
- <div class="wpstg--modal--backup--import--filesystem">
289
- <button class="wpstg--backup--import--option wpstg-blue-primary" data-option="upload">
290
- <?php _e('GO BACK', 'wp-staging') ?>
291
- </button>
292
- <div style="margin-top: .25em;font-size:14px;">
293
- <?php
294
- echo __('Upload import file to server directory:', 'wp-staging') . '<br>';
295
- echo $directory->getPluginUploadsDirectory();
296
- ?>
297
- </div>
298
- <ul></ul>
299
- </div>
300
- <div class="wpstg--modal--backup--import--search-replace--wrapper">
301
- <div class="wpstg--modal--backup--import--search-replace--info">
302
- <p><?php _e('Search & Replace strings in the database. (Fully optional).', 'wp-staging') ?></p>
303
- <p><?php _e('Leave empty and WP Staging handles this automatically.', 'wp-staging') ?></p>
304
- </div>
305
- <div class="wpstg--modal--backup--import--search-replace--input--container">
306
- <div class="wpstg--modal--backup--import--search-replace--input-group">
307
- <input name="wpstg__backup__import__search[{i}]" data-index="{i}" class="wpstg--backup--import--search" placeholder="Search"/>
308
- <input name="wpstg__backup__import__replace[{i}]" data-index="{i}" class="wpstg--backup--import--replace" placeholder="Replace"/>
309
- </div>
310
- </div>
311
- <button class="wpstg--modal--backup--import--search-replace--new"><?php _e('+', 'wp-staging') ?></button>
312
- </div>
313
- </div>
314
- </div>
315
-
316
- <div
317
- id="wpstg--js--translations"
318
- style="display:none;"
319
- data-modal-txt-critical="<?php _e('Critical', 'wp-staging') ?>"
320
- data-modal-txt-errors="<?php _e('Error(s)', 'wp-staging') ?>"
321
- data-modal-txt-warnings="<?php _e('Warning(s)', 'wp-staging') ?>"
322
- data-modal-txt-and="<?php _e('and', 'wp-staging') ?>"
323
- data-modal-txt-found="<?php _e('Found', 'wp-staging') ?>"
324
- data-modal-txt-show-logs="<?php _e('Show Logs', 'wp-staging') ?>"
325
- data-modal-logs-title="<?php _e(
326
- '{critical} Critical, {errors} Error(s) and {warnings} Warning(s) Found',
327
- 'wp-staging'
328
- ) ?>"
329
- ></div>
330
-
331
- <div id="wpstg-delete-confirmation"></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Backend/views/notices/cache-directory-permission-problem.php CHANGED
@@ -4,10 +4,11 @@
4
  * @see \WPStaging\Backend\Notices\Notices::messages
5
  */
6
  ?>
7
- <div class="wpstg-error">
8
- <p>
9
- <strong>WP Staging Folder Permission error: </strong> <?php echo $cacheDir; ?> is not write and/or readable.
10
  <br>
11
- Check if the folder <strong><?php echo $cacheDir; ?></strong> exists! Folder permissions should be chmod 755 or higher.
 
 
12
  </p>
13
  </div>
4
  * @see \WPStaging\Backend\Notices\Notices::messages
5
  */
6
  ?>
7
+ <div class="notice notice-error">
8
+ <p><strong>WP STAGING - Folder Permission error. </strong>
 
9
  <br>
10
+ The folder <code><?php echo $cacheDir; ?></code> is not write and/or readable.
11
+ <br>
12
+ Check if this folder exists! Folder permissions should be chmod 755 or higher.
13
  </p>
14
  </div>
Backend/views/notices/directory-listing-could-not-be-prevented.php CHANGED
@@ -6,9 +6,10 @@
6
  ?>
7
 
8
  <div class='notice-warning notice is-dismissible'>
9
- <p style='font-weight: bold;'><?php _e('WPSTAGING - Failed to prevent directory listing', 'wp-staging'); ?></p>
10
- <p><?php _e('Following the best development practices, WPSTAGING tries to prevent directory listing on it\'s own directories
 
11
  that might contain sensitive data. This warning tells you that we could not prevent directory listing on one
12
- of the directories.'); ?></p>
13
- <p><?php echo implode('<br>', esc_html($directoryListingErrors)); ?></p>
14
  </div>
6
  ?>
7
 
8
  <div class='notice-warning notice is-dismissible'>
9
+ <p><strong><?php _e('WP STAGING - Failed to prevent directory listing', 'wp-staging'); ?></strong>
10
+ <br>
11
+ <?php _e('Following the best development practices, WP STAGING tries to prevent directory listing on it\'s own directories
12
  that might contain sensitive data. This warning tells you that we could not prevent directory listing on one
13
+ of the directories.'); ?>
14
+ <?php echo !empty($directoryListingErrors) ? implode('<br>', esc_html($directoryListingErrors)) : ''; ?></p>
15
  </div>
Backend/views/notices/disabled-items-notice.php CHANGED
@@ -1,13 +1,15 @@
1
  <?php
2
  /**
3
  * @var $this \WPStaging\Backend\Notices\Notices
4
- * @see \WPStaging\Backend\Notices\Notices::showNotices
 
 
5
  */
6
  ?>
7
- <div class="notice wpstg-disabled-items-notice" style="border-left: 4px solid #ffba00; padding: 8px; padding-left: 16px; padding-top: 12px;">
8
- <strong style="margin-bottom: 10px;"><?php _e('WP STAGING Notes:', 'wp-staging'); ?></strong> <br/>
9
  <ol style="margin-left: 12px;">
10
- <li> <?php echo sprintf(__('Disabled the cache by setting the constant WP_CACHE to FALSE in the wp-config.php and excluding wp-content/cache. <a href="%s" target="_blank">How to activate caching</a>', 'wp-staging'), 'https://wp-staging.com/docs/how-to-activate-caching-on-staging-site/') ?></li>
11
  <?php if ($outgoingMailsDisabled) : ?>
12
  <li> <?php echo sprintf(__('Disabled outgoing emails. <a href="%s" target="_blank">How to activate mails</a>', 'wp-staging'), 'https://wp-staging.com/docs/how-to-activate-email-sending-on-the-staging-site/')?></li>
13
  <?php endif; ?>
1
  <?php
2
  /**
3
  * @var $this \WPStaging\Backend\Notices\Notices
4
+ * @see \WPStaging\Backend\Notices\Notices::messages
5
+ * @var bool $outgoingMailsDisabled
6
+ * @var array $excludedPlugins
7
  */
8
  ?>
9
+ <div class="notice notice-warning wpstg-disabled-items-notice">
10
+ <p><strong><?php _e('WP STAGING - Notes:', 'wp-staging'); ?></strong></p>
11
  <ol style="margin-left: 12px;">
12
+ <li> <?php echo sprintf(__('WP STAGING Disabled the cache by setting the constant <code>WP_CACHE</code> to <code>FALSE</code>in the file <code>wp-config.php</code>. <a href="%s" target="_blank"> You can revert this easily</a>', 'wp-staging'), 'https://wp-staging.com/docs/how-to-activate-caching-on-staging-site/') ?></li>
13
  <?php if ($outgoingMailsDisabled) : ?>
14
  <li> <?php echo sprintf(__('Disabled outgoing emails. <a href="%s" target="_blank">How to activate mails</a>', 'wp-staging'), 'https://wp-staging.com/docs/how-to-activate-email-sending-on-the-staging-site/')?></li>
15
  <?php endif; ?>
Backend/views/notices/logs-directory-permission-problem.php CHANGED
@@ -4,10 +4,12 @@
4
  * @see \WPStaging\Backend\Notices\Notices::messages
5
  */
6
  ?>
7
- <div class="wpstg-error">
8
  <p>
9
- <strong>WP Staging Folder Permission error: </strong> <?php echo $logsDir; ?> is not write and/or readable.
10
  <br>
11
- Check if the folder <strong><?php echo $logsDir; ?></strong> exists! Folder permissions should be chmod 755 or higher.
 
 
12
  </p>
13
  </div>
4
  * @see \WPStaging\Backend\Notices\Notices::messages
5
  */
6
  ?>
7
+ <div class="notice notice-error">
8
  <p>
9
+ <strong>WP STAGING - Folder Permission error.</strong>
10
  <br>
11
+ The folder <code><?php echo $logsDir; ?></code> is not write and/or readable.
12
+ <br>
13
+ Check if this folder exists! Folder permissions should be chmod 755 or higher.
14
  </p>
15
  </div>
Backend/views/notices/low-memory-limit.php CHANGED
@@ -1,3 +1,3 @@
1
- <div class="wpstg-warning">
2
  <?php echo sprintf(__('It\'s recommended to increase the memory limit to 256M or more! If cloning/pushing <strong>fails</strong> <a href="%s" target="_blank">increase the memory limit</a>.', 'wp-staging'), 'https://wp-staging.com/docs/php-fatal-error-allowed-memory-size-of-134217728-bytes-exhausted/'); ?>
3
  </div>
1
+ <div class="notice notice-warning">
2
  <?php echo sprintf(__('It\'s recommended to increase the memory limit to 256M or more! If cloning/pushing <strong>fails</strong> <a href="%s" target="_blank">increase the memory limit</a>.', 'wp-staging'), 'https://wp-staging.com/docs/php-fatal-error-allowed-memory-size-of-134217728-bytes-exhausted/'); ?>
3
  </div>
Backend/views/notices/no-license-key.php DELETED
@@ -1,11 +0,0 @@
1
- <div class="error">
2
- <p>
3
- <?php
4
- echo sprintf(__(
5
- 'You have no license key entered. WP STAGING Pro needs a valid license key to be activated. You can purchase the license from here:' .
6
- '<br/> <a href="%1$s" target="_blank">%1$s</a>',
7
- 'wp-staging'
8
- ), 'https://wp-staging.com');
9
- ?>
10
- </p>
11
- </div>
 
 
 
 
 
 
 
 
 
 
 
Backend/views/notices/outdated-wp-staging-hooks.php CHANGED
@@ -1,12 +1,12 @@
1
  <?php
2
  /**
3
  * @var $this \WPStaging\Backend\Notices\Notices
4
- * @see \WPStaging\Backend\Notices\Notices::showNotices
5
  */
6
  ?>
7
- <div class="notice wpstg-hooks-outdated-notice notice notice-error wpstg-error">
8
  <p>
9
- <strong style="margin-bottom: 10px;"><?php _e('WP Staging Hooks Outdated!', 'wp-staging'); ?></strong> <br/>
10
  <?php echo sprintf(__('You are using an outdated version of the WP STAGING hooks plugin. The filters for <code>wpstg_clone_excl_folders</code> and <code>wpstg_clone_mu_excl_folders</code> have been changed. Download the latest version from <a href="%s" target="_blank">here</a> and adjust your filters.', 'wp-staging'), 'https://github.com/wp-staging/wp-staging-hooks'); ?>
11
  </p>
12
  </div>
1
  <?php
2
  /**
3
  * @var $this \WPStaging\Backend\Notices\Notices
4
+ * @see \WPStaging\Backend\Notices\Notices::messages
5
  */
6
  ?>
7
+ <div class="wpstg-hooks-outdated-notice notice notice-error">
8
  <p>
9
+ <strong><?php _e('WP STAGING - Hooks Outdated.', 'wp-staging'); ?></strong> <br/>
10
  <?php echo sprintf(__('You are using an outdated version of the WP STAGING hooks plugin. The filters for <code>wpstg_clone_excl_folders</code> and <code>wpstg_clone_mu_excl_folders</code> have been changed. Download the latest version from <a href="%s" target="_blank">here</a> and adjust your filters.', 'wp-staging'), 'https://github.com/wp-staging/wp-staging-hooks'); ?>
11
  </p>
12
  </div>
Backend/views/notices/rating.php CHANGED
@@ -1,15 +1,15 @@
1
  <?php
2
  /**
3
  * @var $this \WPStaging\Backend\Notices\Notices
4
- * @see \WPStaging\Backend\Notices\Notices::showNotices
5
  */
6
  ?>
7
- <div class="wpstg_fivestar" style="display:none;box-shadow: 0 1px 1px 0 rgba(0,0,0,.1); border-left:none; background-color:#59a7f7; color:white; padding: 10px; margin: 10px; margin-left: 0px;">
8
  <div class="wpstg-welcome-box" style="display: flex; width: 100%; align-items: center;">
9
- <div class="wpstg-welcome-video-container" style="width: 375px; height: 210px;">
10
  <div style="width: 100%; height: 100%; display: flex; background: #000; position: relative; align-items: center; justify-content: center; z-index: 0;">
11
  <div class="wpstg-yt-thumbnail-container" style="display: flex; width: 100%; height: 100%; z-index: 100; cursor: pointer; justify-content: center; align-items: center;" id="welcomeNoticeFree">
12
- <img style="width: 100%; object-fit: fill; z-index: 0; cursor: pointer;" alt="WP Staging Welcome Video Thumbnail" src="<?php echo esc_url(plugins_url('/assets/img/thumbnail.jpg', dirname(dirname(__DIR__)))) ?>" />
13
  <button style="cursor: pointer; position: absolute; width: 68px; height: 48px; background: transparent; border: 0px solid transparent; -moz-transition: opacity .25s cubic-bezier(0.0,0.0,0.2,1); -webkit-transition: opacity .25s cubic-bezier(0.0,0.0,0.2,1); transition: opacity .25s cubic-bezier(0.0,0.0,0.2,1); z-index: 63;">
14
  <svg height="100%" version="1.1" viewBox="0 0 68 48" width="100%"><path class="wpstg-yt-button-svg" style="-moz-transition: fill .1s cubic-bezier(0.4,0.0,1,1),fill-opacity .1s cubic-bezier(0.4,0.0,1,1); -webkit-transition: fill .1s cubic-bezier(0.4,0.0,1,1),fill-opacity .1s cubic-bezier(0.4,0.0,1,1); transition: fill .1s cubic-bezier(0.4,0.0,1,1),fill-opacity .1s cubic-bezier(0.4,0.0,1,1); fill: #212121; fill-opacity: .8; height: 100%; left: 0; position: absolute; top: 0; width: 100%;" d="M66.52,7.74c-0.78-2.93-2.49-5.41-5.42-6.19C55.79,.13,34,0,34,0S12.21,.13,6.9,1.55 C3.97,2.33,2.27,4.81,1.48,7.74C0.06,13.05,0,24,0,24s0.06,10.95,1.48,16.26c0.78,2.93,2.49,5.41,5.42,6.19 C12.21,47.87,34,48,34,48s21.79-0.13,27.1-1.55c2.93-0.78,4.64-3.26,5.42-6.19C67.94,34.95,68,24,68,24S67.94,13.05,66.52,7.74z" fill="#f00"></path><path d="M 45,24 27,14 27,34" fill="#fff"></path></svg>
15
  </button>
@@ -20,43 +20,39 @@
20
  </div>
21
  </div>
22
  <div class="wpstg-welcome-text" style="padding: 0px; padding-left: 20px; padding-right: 8px;">
23
- <p><?php _e('Thanks for using <strong>WP Staging </strong> for more than 1 week.
24
- May I ask you to give it a <strong>5-star</strong> rating on wordpress.org?', 'wp-staging'); ?>
25
  <?php if (!defined('WPSTGPRO_VERSION')) { ?>
26
  <br><br>
27
- <?php echo sprintf(__('P.S. Do you want to migrate this staging site from staging to live site?<br/>
28
  Try out <a href="%1$s" target="_blank" style="color:white;font-weight:bold;">WP STAGING PRO</a>
29
  ', 'wp-staging'), 'https://wp-staging.com/?utm_source=wpstg_admin&utm_medium=rating_screen&utm_campaign=admin_notice'); ?>
30
  <br>
31
  <?php } ?>
32
  </p>
33
- <p>
34
- Cheers,<br>René Hermenau
35
- </p>
36
-
37
  <ul>
38
  <li>
39
  <a href="https://wordpress.org/support/plugin/wp-staging/reviews/?filter=5#new-post" target="_blank" style="background-color:#35e6be;border-color:transparent;margin-bottom:10px;color:white;font-weight:bold;-webkit-box-shadow: 1px 1px 8px -7px rgba(0,0,0,0.75);-moz-box-shadow: 1px 1px 8px -7px rgba(0,0,0,0.75);box-shadow: 1px 1px 8px -7px rgba(0,0,0,0.75);" id="wpstg_clicked_deserved_it" class="thankyou button"
40
- title="Sure, I like Your Plugin and Work" style="font-weight:bold;">
41
- <?php _e('Yes, I like Your Plugin', 'wp-staging') ?>
42
  </a>
43
  </li>
44
  <li>
45
  <a href="javascript:void(0);" class="wpstg_hide_rating" title="I already did"
46
- style="font-weight:normal;color:white;">
47
- <?php _e('I already did', 'wp-staging') ?>
48
  </a>
49
  </li>
50
  <li>
51
  <a href="javascript:void(0);" class="wpstg_hide_rating" title="No, not good enough"
52
  style="font-weight:normal;color:white;">
53
- <?php _e('No, not good enough', 'wp-staging') ?>
54
  </a>
55
  </li>
56
  <li>
57
  <a href="javascript:void(0);" class="wpstg_rate_later" title="Ask me again in a week"
58
- style="font-weight:normal;color:white;">
59
- <?php _e('I want to rate later - Ask me again in a week', 'wp-staging') ?>
60
  </a>
61
  </li>
62
  </ul>
@@ -68,7 +64,7 @@
68
  <script>
69
  var wpstgYouTubeConfig = {
70
  'accepted': false,
71
- 'message': "<?php _e("Please click on the OK button to play this video. We don't load any data from YouTube without your explicit consent.") ?>",
72
  'regards': "<?php _e("Your WP STAGING Team") ?>"
73
  };
74
  </script>
1
  <?php
2
  /**
3
  * @var $this \WPStaging\Backend\Notices\Notices
4
+ * @see \WPStaging\Backend\Notices\Notices::messages
5
  */
6
  ?>
7
+ <div class="wpstg_fivestar" style="display:none;box-shadow: 0 1px 1px 0 rgba(0,0,0,.1); border-left:none; background-color:#0a8ee2; color:white; padding: 10px; margin:20px 20px 20px 0px;">
8
  <div class="wpstg-welcome-box" style="display: flex; width: 100%; align-items: center;">
9
+ <div class="wpstg-welcome-video-container" style="width: 375px; height: 210px;display:none;">
10
  <div style="width: 100%; height: 100%; display: flex; background: #000; position: relative; align-items: center; justify-content: center; z-index: 0;">
11
  <div class="wpstg-yt-thumbnail-container" style="display: flex; width: 100%; height: 100%; z-index: 100; cursor: pointer; justify-content: center; align-items: center;" id="welcomeNoticeFree">
12
+ <img style="width: 100%; object-fit: fill; z-index: 0; cursor: pointer;" alt="WP STAGING Welcome Video Thumbnail" src="<?php echo esc_url(plugins_url('/assets/img/thumbnail.jpg', dirname(dirname(__DIR__)))) ?>" />
13
  <button style="cursor: pointer; position: absolute; width: 68px; height: 48px; background: transparent; border: 0px solid transparent; -moz-transition: opacity .25s cubic-bezier(0.0,0.0,0.2,1); -webkit-transition: opacity .25s cubic-bezier(0.0,0.0,0.2,1); transition: opacity .25s cubic-bezier(0.0,0.0,0.2,1); z-index: 63;">
14
  <svg height="100%" version="1.1" viewBox="0 0 68 48" width="100%"><path class="wpstg-yt-button-svg" style="-moz-transition: fill .1s cubic-bezier(0.4,0.0,1,1),fill-opacity .1s cubic-bezier(0.4,0.0,1,1); -webkit-transition: fill .1s cubic-bezier(0.4,0.0,1,1),fill-opacity .1s cubic-bezier(0.4,0.0,1,1); transition: fill .1s cubic-bezier(0.4,0.0,1,1),fill-opacity .1s cubic-bezier(0.4,0.0,1,1); fill: #212121; fill-opacity: .8; height: 100%; left: 0; position: absolute; top: 0; width: 100%;" d="M66.52,7.74c-0.78-2.93-2.49-5.41-5.42-6.19C55.79,.13,34,0,34,0S12.21,.13,6.9,1.55 C3.97,2.33,2.27,4.81,1.48,7.74C0.06,13.05,0,24,0,24s0.06,10.95,1.48,16.26c0.78,2.93,2.49,5.41,5.42,6.19 C12.21,47.87,34,48,34,48s21.79-0.13,27.1-1.55c2.93-0.78,4.64-3.26,5.42-6.19C67.94,34.95,68,24,68,24S67.94,13.05,66.52,7.74z" fill="#f00"></path><path d="M 45,24 27,14 27,34" fill="#fff"></path></svg>
15
  </button>
20
  </div>
21
  </div>
22
  <div class="wpstg-welcome-text" style="padding: 0px; padding-left: 20px; padding-right: 8px;">
23
+ <p><?php _e('You are using <strong>WP STAGING </strong> for more than 1 week.
24
+ May we ask you to give it a <strong>5-star</strong> rating on wordpress.org?', 'wp-staging'); ?>
25
  <?php if (!defined('WPSTGPRO_VERSION')) { ?>
26
  <br><br>
27
+ <?php echo sprintf(__('P.S. Do you like to migrate this staging site to production site?
28
  Try out <a href="%1$s" target="_blank" style="color:white;font-weight:bold;">WP STAGING PRO</a>
29
  ', 'wp-staging'), 'https://wp-staging.com/?utm_source=wpstg_admin&utm_medium=rating_screen&utm_campaign=admin_notice'); ?>
30
  <br>
31
  <?php } ?>
32
  </p>
 
 
 
 
33
  <ul>
34
  <li>
35
  <a href="https://wordpress.org/support/plugin/wp-staging/reviews/?filter=5#new-post" target="_blank" style="background-color:#35e6be;border-color:transparent;margin-bottom:10px;color:white;font-weight:bold;-webkit-box-shadow: 1px 1px 8px -7px rgba(0,0,0,0.75);-moz-box-shadow: 1px 1px 8px -7px rgba(0,0,0,0.75);box-shadow: 1px 1px 8px -7px rgba(0,0,0,0.75);" id="wpstg_clicked_deserved_it" class="thankyou button"
36
+ title="Sure, I like your plugin" style="font-weight:bold;">
37
+ <?php _e('- Yes, I like WP STAGING - Rate & Close', 'wp-staging') ?>
38
  </a>
39
  </li>
40
  <li>
41
  <a href="javascript:void(0);" class="wpstg_hide_rating" title="I already did"
42
+ style="font-weight:normal;color:white;text-decoration: none;">
43
+ <?php _e('- I already did - Close ', 'wp-staging') ?>
44
  </a>
45
  </li>
46
  <li>
47
  <a href="javascript:void(0);" class="wpstg_hide_rating" title="No, not good enough"
48
  style="font-weight:normal;color:white;">
49
+ <?php _e('', 'wp-staging') ?>
50
  </a>
51
  </li>
52
  <li>
53
  <a href="javascript:void(0);" class="wpstg_rate_later" title="Ask me again in a week"
54
+ style="font-weight:normal;color:white;text-decoration: none;">
55
+ <?php _e('- Ask me again in a week - Close', 'wp-staging') ?>
56
  </a>
57
  </li>
58
  </ul>
64
  <script>
65
  var wpstgYouTubeConfig = {
66
  'accepted': false,
67
+ 'message': "<?php _e("This video is hosted on YouTube. Please click on the OK button to play this video. We don't load any external data without your explicit consent.") ?>",
68
  'regards': "<?php _e("Your WP STAGING Team") ?>"
69
  };
70
  </script>
Backend/views/notices/staging-directory-permission-problem.php CHANGED
@@ -1,11 +1,13 @@
1
- <div class="wpstg-error">
2
  <p>
3
  <strong>
4
- <?php echo sprintf(__('WP Staging Folder Permission error:</strong>
5
- %1$s is not write and/or readable.
6
  <br>
7
- Check if the folder <strong>%1$s</strong> is writeable by php user %2$s or www-data .
 
 
8
  File permissions should be chmod 755 or 777.', 'wp-staging'), ABSPATH, getenv('USERNAME') ?: getenv('USER'));
9
- ?>
10
  </p>
11
  </div>
1
+ <div class="notice notice-error">
2
  <p>
3
  <strong>
4
+ <?php
5
+ echo sprintf(__('WP STAGING - Folder Permission error.</strong>
6
  <br>
7
+ The folder <code>%1$s</code> is not write and/or readable.
8
+ <br>
9
+ Check if this folder is writeable by php user %2$s or www-data .
10
  File permissions should be chmod 755 or 777.', 'wp-staging'), ABSPATH, getenv('USERNAME') ?: getenv('USER'));
11
+ ?>
12
  </p>
13
  </div>
Backend/views/notices/transient.php CHANGED
@@ -1,4 +1,4 @@
1
- <div class="updated notice is-dismissible wpstg-warning">
2
  <p>
3
  <?php
4
  echo esc_html(
1
+ <div class="updated notice is-dismissible">
2
  <p>
3
  <?php
4
  echo esc_html(
Backend/views/notices/vars-directory-permission-problem.php CHANGED
@@ -1,7 +1,9 @@
1
- <div class="wpstg-error">
2
  <p>
3
- <strong>WP Staging Folder Permission error: </strong> <?php echo "{$varsDirectory}"?> is not write and/or readable.
4
  <br>
5
- Check if the folder <strong><?php echo "{$varsDirectory}"?></strong> exists! Folder permissions should be chmod 755 or 777.
 
 
6
  </p>
7
  </div>
1
+ <div class="notice notice-error">
2
  <p>
3
+ <strong>WP STAGING - Folder Permission error. </strong>
4
  <br>
5
+ The folder <code><?php echo "{$varsDirectory}"?></code> is not write and/or readable.
6
+ <br>
7
+ Check if this folder exists! Folder permissions should be chmod 755 or 777.
8
  </p>
9
  </div>
Backend/views/notices/wp-options-missing-pk.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @var string $optionTable
4
+ * @see \WPStaging\Backend\Notices\Notices::messages
5
+ */
6
+ ?>
7
+ <div class="notice notice-error">
8
+ <p>
9
+ <strong><?php echo sprintf(__('WP STAGING - Your table %s has no primary key index.', 'wp-staging'), $optionTable)?></strong>
10
+ <br>
11
+ <?php _e('This is a serious issue and needs to be fixed as soon as possible. The longer you wait, the harder it gets to repair it and can make your site inaccessible at worst. We recommend fixing it right now! This error has either been caused by a person with access to the database or by another plugin. You should not do any changes to your site until this is fixed.', 'wp-staging') ?>
12
+ </p>
13
+ <p><a href="https://wp-staging.com/docs/missing-primary-key-in-table-wp-options" target="_blank"><strong><?php _e('How to fix this.', 'wp-staging') ?></strong></a></p>
14
+ </div>
Backend/views/notices/wp-version-compatible-message.php CHANGED
@@ -1,10 +1,10 @@
1
- <div class="wpstg-error">
2
  <p>
3
  <?php
4
  echo sprintf(__(
5
- 'Your version of WP STAGING has not been tested with WordPress %2$s.' .
6
  '<br/><br/>WP STAGING has an enterprise-level quality control that performs a compatibility audit on every new WordPress release.' .
7
- '<br/>We prioritize testing the Pro version of the plugin first, which receives the compatibility audit earlier than the Free version. If you are in a rush, upgrade to Pro today to get the latest version of WPSTAGING.' .
8
  '<p><a href="%1$s" target="_blank"><strong>Get the latest version Now</strong></a>.',
9
  'wp-staging'
10
  ), 'https://wp-staging.com', get_bloginfo('version'));
1
+ <div class="notice notice-warning">
2
  <p>
3
  <?php
4
  echo sprintf(__(
5
+ '<strong>Your version of WP STAGING has not been tested with WordPress %2$s.</strong>' .
6
  '<br/><br/>WP STAGING has an enterprise-level quality control that performs a compatibility audit on every new WordPress release.' .
7
+ '<br/>We prioritize testing the Pro version of the plugin first, which receives the compatibility audit earlier than the Free version. If you are in a rush, upgrade to Pro today to get the latest version of WP STAGING.' .
8
  '<p><a href="%1$s" target="_blank"><strong>Get the latest version Now</strong></a>.',
9
  'wp-staging'
10
  ), 'https://wp-staging.com', get_bloginfo('version'));
Backend/views/notices/wrong-scheme.php CHANGED
@@ -1,7 +1,8 @@
1
- <div class="wpstg-error">
2
  <p>
3
- <strong><?php _e('WP Staging HTTP/HTTPS Scheme Error:', 'wp-staging'); ?></strong>
4
- <?php echo sprintf(__('Go to <a href="%s" target="_blank">Settings > General</a> and make sure that WordPress Address (URL) and Site Address (URL) do both contain the same http / https scheme.', 'wp-staging'), admin_url() . 'options-general.php'); ?>
 
5
  <br>
6
  <?php _e('Otherwise your staging site will not be reachable after creation.', 'wp-staging'); ?></p>
7
  </div>
1
+ <div class="notice notice-error">
2
  <p>
3
+ <strong><?php _e('WP STAGING - HTTP/HTTPS Scheme Error.', 'wp-staging'); ?></strong>
4
+ <br>
5
+ <?php echo sprintf(__('Go to <a href="%s" target="_blank">Settings > General</a> and make sure that WordPress Address (URL) and Site Address (URL) both start wth either http or https scheme.', 'wp-staging'), admin_url() . 'options-general.php'); ?>
6
  <br>
7
  <?php _e('Otherwise your staging site will not be reachable after creation.', 'wp-staging'); ?></p>
8
  </div>
Backend/views/selections/database-tables.php CHANGED
@@ -9,11 +9,13 @@
9
  do_action("wpstg_scanning_db");
10
  $dbPrefix = WPStaging\Core\WPStaging::getTablePrefix();
11
  ?>
12
- <h4 class="wpstg-m-0">
13
- <?php printf(__("Select the tables to copy. Tables beginning with the prefix '%s' have been preselected.", "wp-staging"), $dbPrefix); ?>
14
- </h4>
15
  <p>
16
- <?php _e("All selected tables will be copied/replaced with the tables from the production site.", "wp-staging"); ?>
 
 
 
 
 
17
  </p>
18
  <div class="wpstg-my-10px">
19
  <a href="#" class="wpstg-button-unselect button"><?php _e('Unselect All', 'wp-staging'); ?></a>
@@ -39,5 +41,5 @@
39
  <a href="#" class="wpstg-button-select button"> <?php echo $dbPrefix; ?> </a>
40
  </div>
41
  <p>
42
- <?php _e("You can select multiple tables by pressing left mouse button and moving or by pressing STRG+Left Mouse button. (Mac ⌘+Left Mouse Button)", "wp-staging"); ?>
43
  </p>
9
  do_action("wpstg_scanning_db");
10
  $dbPrefix = WPStaging\Core\WPStaging::getTablePrefix();
11
  ?>
 
 
 
12
  <p>
13
+ <strong><?php _e("Select Tables to Copy", "wp-staging"); ?></strong>
14
+ <br>
15
+ <?php printf(__("Tables with the production prefix <code>%s</code> have been selected.", "wp-staging"), $dbPrefix); ?>
16
+ </p>
17
+ <p style="display: none;">
18
+ <?php _e("Selected tables will be copied/replaced with the tables from the production site.", "wp-staging"); ?>
19
  </p>
20
  <div class="wpstg-my-10px">
21
  <a href="#" class="wpstg-button-unselect button"><?php _e('Unselect All', 'wp-staging'); ?></a>
41
  <a href="#" class="wpstg-button-select button"> <?php echo $dbPrefix; ?> </a>
42
  </div>
43
  <p>
44
+ <?php _e("You can select multiple tables. Press left mouse button & move or press STRG+Left mouse button. (Apple: ⌘+Left Mouse Button)", "wp-staging"); ?>
45
  </p>
Backend/views/selections/files.php CHANGED
@@ -5,9 +5,11 @@
5
  * @see \WPStaging\Backend\Modules\Jobs\Scan::start For details on $options.
6
  */
7
  ?>
8
- <h4>
9
- <?php _e("Select folders to copy. Click on a folder to expand subfolders!", "wp-staging") ?>
10
- </h4>
 
 
11
  <div id="wpstg-directories-listing" data-existing-excludes="<?php echo (($options->mainJob === 'updating' || $options->mainJob === 'resetting') && isset($options->currentClone['excludedDirectories'])) ? esc_html(implode(',', $options->currentClone['excludedDirectories'])) : '' ?>">
12
  <div class="wpstg-mb-8px">
13
  <button type="button" class="wpstg-unselect-dirs button"><?php _e('Unselect All', 'wp-staging'); ?></button>
@@ -36,8 +38,8 @@
36
  <p <?php echo !$hasRules ? 'style="display: none;"' : '' ?> class="wpstg-has-exclude-rules"><b><?php _e('Note', 'wp-staging'); ?>:</b> <?php _e('These rules will not affect wp-admin and wp-includes directories!', 'wp-staging')?></p>
37
  <div class="wpstg-exclude-filters-foot">
38
  <div class="wpstg-dropdown wpstg-exclude-filter-dropdown">
39
- <button class="wpstg-dropdown-toggler transparent">
40
- <?php _e("Add Exclude Rule", "wp-staging"); ?> <span class="wpstg-dropdown-symbol">+</span>
41
  </button>
42
  <div class="wpstg-dropdown-menu wpstg-menu-dropup">
43
  <button class="wpstg-dropdown-action wpstg-file-size-rule"><?php _e('File Size', 'wp-staging'); ?></button>
@@ -46,7 +48,7 @@
46
  <button class="wpstg-dropdown-action wpstg-dir-name-rule"><?php _e('Folder Name', 'wp-staging'); ?></button>
47
  </div>
48
  </div>
49
- <button <?php echo !$hasRules ? 'style="display: none;"' : '' ?> class="wpstg-ml-8px wpstg-button wpstg-clear-all-rules danger wpstg-has-exclude-rules">
50
  <?php _e("Clear All Rules", "wp-staging"); ?>
51
  </button>
52
  </div>
@@ -97,7 +99,7 @@ if ($options->current !== null && $options->mainJob === 'updating') {
97
  <span>
98
  <?php
99
  if (isset($options->clone)) {
100
- echo __("All files will be copied to: ", "wp-staging") . $options->root . $options->clone;
101
  }
102
  ?>
103
  </span>
5
  * @see \WPStaging\Backend\Modules\Jobs\Scan::start For details on $options.
6
  */
7
  ?>
8
+ <p>
9
+ <strong><?php _e("Select Folders to Copy", "wp-staging") ?></strong>
10
+ <br>
11
+ <?php _e("Click on a folder name to expand it.", "wp-staging") ?>
12
+ </p>
13
  <div id="wpstg-directories-listing" data-existing-excludes="<?php echo (($options->mainJob === 'updating' || $options->mainJob === 'resetting') && isset($options->currentClone['excludedDirectories'])) ? esc_html(implode(',', $options->currentClone['excludedDirectories'])) : '' ?>">
14
  <div class="wpstg-mb-8px">
15
  <button type="button" class="wpstg-unselect-dirs button"><?php _e('Unselect All', 'wp-staging'); ?></button>
38
  <p <?php echo !$hasRules ? 'style="display: none;"' : '' ?> class="wpstg-has-exclude-rules"><b><?php _e('Note', 'wp-staging'); ?>:</b> <?php _e('These rules will not affect wp-admin and wp-includes directories!', 'wp-staging')?></p>
39
  <div class="wpstg-exclude-filters-foot">
40
  <div class="wpstg-dropdown wpstg-exclude-filter-dropdown">
41
+ <button class="wpstg-dropdown-toggler wpstg-button--secondary wpstg-button--blue">
42
+ <?php _e("Add Exclude Rule + ", "wp-staging"); ?>
43
  </button>
44
  <div class="wpstg-dropdown-menu wpstg-menu-dropup">
45
  <button class="wpstg-dropdown-action wpstg-file-size-rule"><?php _e('File Size', 'wp-staging'); ?></button>
48
  <button class="wpstg-dropdown-action wpstg-dir-name-rule"><?php _e('Folder Name', 'wp-staging'); ?></button>
49
  </div>
50
  </div>
51
+ <button <?php echo !$hasRules ? 'style="display: none;"' : '' ?> class="wpstg-ml-8px wpstg-button--secondary wpstg-clear-all-rules wpstg-has-exclude-rules wpstg-button--red">
52
  <?php _e("Clear All Rules", "wp-staging"); ?>
53
  </button>
54
  </div>
99
  <span>
100
  <?php
101
  if (isset($options->clone)) {
102
+ echo __("All files will be copied to: ", "wp-staging") . "<code>" . $options->root . $options->clone . "</code>";
103
  }
104
  ?>
105
  </span>
Backend/views/settings/tabs/mail-settings.php CHANGED
@@ -11,7 +11,7 @@
11
  </label>
12
  </div>
13
  <p>
14
- <b><?php _e('Note', 'wp-staging') ?>: </b> <?php echo sprintf(__('Some plugins might still be able to send out mails if they don\'t depend upon %s.', 'wp-staging'), '<code>wp_mail()</code>', '<code>wp_mail()</code>', '<strong>WP STAGING</strong>'); ?>
15
  </p>
16
  <button type="button" id="wpstg-update-mail-settings" class="wpstg-link-btn wpstg-blue-primary"><?php _e("Update Settings", "wp-staging") ?></button>
17
  </form>
11
  </label>
12
  </div>
13
  <p>
14
+ <b><?php _e('Note', 'wp-staging') ?>: </b> <?php echo sprintf(__('Some plugins might still be able to send out mails if they don\'t depend upon %s.', 'wp-staging'), '<code>wp_mail()</code>'); ?>
15
  </p>
16
  <button type="button" id="wpstg-update-mail-settings" class="wpstg-link-btn wpstg-blue-primary"><?php _e("Update Settings", "wp-staging") ?></button>
17
  </form>
Backend/views/templates/exclude-filters/dir-name-exclude-filter.php CHANGED
@@ -19,9 +19,9 @@ use WPStaging\Framework\Filesystem\Filters\ExcludeFilter;
19
  <option value="<?php echo ExcludeFilter::NAME_CONTAINS ?>" <?php echo isset($rule) && $rule === ExcludeFilter::NAME_CONTAINS ? 'selected' : '' ?>><?php _e('CONTAINS', 'wp-staging') ?></option>
20
  </select>
21
  <input type="text" class="wpstg-exclude-rule-input" name="wpstgDirNameExcludeRulePath[]" value="<?php echo isset($name) ? $name : '' ?>" />
22
- <div class="wpstg-popover">
23
  <button class="wpstg-exclusion-rule-info" type="button">i</button>
24
- <p class="wpstg-code-block wpstg-rule-info"><?php echo sprintf(__('Exclude folders by name. For example to exclude all folder with name node_modules, select %s and type %s in the input box.', 'wp-staging'), '<code class="wpstg-code">' . __('EXACT MATCHES', 'wp-staging') . '</code>', '<code class="wpstg-code">node_modules</code>') ?>
25
  </p>
26
  </div>
27
  </td>
19
  <option value="<?php echo ExcludeFilter::NAME_CONTAINS ?>" <?php echo isset($rule) && $rule === ExcludeFilter::NAME_CONTAINS ? 'selected' : '' ?>><?php _e('CONTAINS', 'wp-staging') ?></option>
20
  </select>
21
  <input type="text" class="wpstg-exclude-rule-input" name="wpstgDirNameExcludeRulePath[]" value="<?php echo isset($name) ? $name : '' ?>" />
22
+ <div class="wpstg--tooltip wpstg--exclude-rules--tooltip">
23
  <button class="wpstg-exclusion-rule-info" type="button">i</button>
24
+ <p class="wpstg--tooltiptext has-top-arrow"><?php echo sprintf(__('Exclude folders by name. For example to exclude all folder with name node_modules, select %s and type %s in the input box.', 'wp-staging'), '<code class="wpstg-code">' . __('EXACT MATCHES', 'wp-staging') . '</code>', '<code class="wpstg-code">node_modules</code>') ?>
25
  </p>
26
  </div>
27
  </td>
Backend/views/templates/exclude-filters/file-ext-exclude-filter.php CHANGED
@@ -9,9 +9,9 @@
9
  <td class="wpstg-exclude-filter-name-column"><?php _e('File Extension', 'wp-staging') ?></td>
10
  <td class="wpstg-exclude-filter-exclusion-column">
11
  <input type="text" name='wpstgFileExtExcludeRule[]' class="wpstg-exclude-rule-input file-ext" value="<?php echo isset($extension) ? $extension : '' ?>" />
12
- <div class="wpstg-popover">
13
  <button class="wpstg-exclusion-rule-info" type="button">i</button>
14
- <p class="wpstg-code-block wpstg-rule-info"><?php echo sprintf(__('Exclude files by extension. For example to exclude zip files, type %s to exclude all zip files.', 'wp-staging'), '<code class="wpstg-code">zip</code>') ?> </p>
15
  </div>
16
  </td>
17
  <td class="wpstg-exclude-filter-action-column"><button class="wpstg-remove-exclude-rule">×</button></td>
9
  <td class="wpstg-exclude-filter-name-column"><?php _e('File Extension', 'wp-staging') ?></td>
10
  <td class="wpstg-exclude-filter-exclusion-column">
11
  <input type="text" name='wpstgFileExtExcludeRule[]' class="wpstg-exclude-rule-input file-ext" value="<?php echo isset($extension) ? $extension : '' ?>" />
12
+ <div class="wpstg--tooltip wpstg--exclude-rules--tooltip">
13
  <button class="wpstg-exclusion-rule-info" type="button">i</button>
14
+ <p class="wpstg--tooltiptext has-top-arrow"><?php echo sprintf(__('Exclude files by extension. For example to exclude zip files, type %s to exclude all zip files.', 'wp-staging'), '<code class="wpstg-code">zip</code>') ?> </p>
15
  </div>
16
  </td>
17
  <td class="wpstg-exclude-filter-action-column"><button class="wpstg-remove-exclude-rule">×</button></td>
Backend/views/templates/exclude-filters/file-name-exclude-filter.php CHANGED
@@ -19,9 +19,9 @@ use WPStaging\Framework\Filesystem\Filters\ExcludeFilter;
19
  <option value="<?php echo ExcludeFilter::NAME_CONTAINS ?>" <?php echo isset($rule) && $rule === ExcludeFilter::NAME_CONTAINS ? 'selected' : '' ?>><?php _e('CONTAINS', 'wp-staging') ?></option>
20
  </select>
21
  <input type="text" class="wpstg-exclude-rule-input" name="wpstgFileNameExcludeRulePath[]" value="<?php echo isset($name) ? $name : '' ?>" />
22
- <div class="wpstg-popover">
23
  <button class="wpstg-exclusion-rule-info" type="button">i</button>
24
- <p class="wpstg-code-block wpstg-rule-info"><?php echo sprintf(__('Exclude files by name. For example to exclude all files which have %s at the end of the name, select %s and type %s in the input box.', 'wp-staging'), '<code class="wpstg-code">-class</code>', '<code class="wpstg-code">' . __('ENDS WITH', 'wp-staging') . '</code>', '<code class="wpstg-code">-class</code>') ?>
25
  </p>
26
  </div>
27
  </td>
19
  <option value="<?php echo ExcludeFilter::NAME_CONTAINS ?>" <?php echo isset($rule) && $rule === ExcludeFilter::NAME_CONTAINS ? 'selected' : '' ?>><?php _e('CONTAINS', 'wp-staging') ?></option>
20
  </select>
21
  <input type="text" class="wpstg-exclude-rule-input" name="wpstgFileNameExcludeRulePath[]" value="<?php echo isset($name) ? $name : '' ?>" />
22
+ <div class="wpstg--tooltip wpstg--exclude-rules--tooltip">
23
  <button class="wpstg-exclusion-rule-info" type="button">i</button>
24
+ <p class="wpstg--tooltiptext has-top-arrow"><?php echo sprintf(__('Exclude files by name. For example to exclude all files which have %s at the end of the name, select %s and type %s in the input box.', 'wp-staging'), '<code class="wpstg-code">-class</code>', '<code class="wpstg-code">' . __('ENDS WITH', 'wp-staging') . '</code>', '<code class="wpstg-code">-class</code>') ?>
25
  </p>
26
  </div>
27
  </td>
Backend/views/templates/exclude-filters/file-size-exclude-filter.php CHANGED
@@ -24,9 +24,9 @@ use WPStaging\Framework\Filesystem\Filters\ExcludeFilter;
24
  <option value="<?php echo ExcludeFilter::SIZE_MB ?>" <?php echo isset($size) && strpos($size, ExcludeFilter::SIZE_MB) !== false ? "selected" : '' ?>>MB</option>
25
  <option value="<?php echo ExcludeFilter::SIZE_GB ?>" <?php echo isset($size) && strpos($size, ExcludeFilter::SIZE_GB) !== false ? "selected" : '' ?>>GB</option>
26
  </select>
27
- <div class="wpstg-popover">
28
  <button class="wpstg-exclusion-rule-info" type="button">i</button>
29
- <p class="wpstg-code-block wpstg-rule-info"><?php echo sprintf(__('Exclude files by size. For example to exclude files greater than 10 MB, select %s and type %s in next input box and select %s.', 'wp-staging'), '<code class="wpstg-code">' . __('GREATER THAN', 'wp-staging') . '</code>', '<code class="wpstg-code">10</code>', '<code class="wpstg-code">MB</code>') ?>
30
  </p>
31
  </div>
32
  </td>
24
  <option value="<?php echo ExcludeFilter::SIZE_MB ?>" <?php echo isset($size) && strpos($size, ExcludeFilter::SIZE_MB) !== false ? "selected" : '' ?>>MB</option>
25
  <option value="<?php echo ExcludeFilter::SIZE_GB ?>" <?php echo isset($size) && strpos($size, ExcludeFilter::SIZE_GB) !== false ? "selected" : '' ?>>GB</option>
26
  </select>
27
+ <div class="wpstg--tooltip wpstg--exclude-rules--tooltip">
28
  <button class="wpstg-exclusion-rule-info" type="button">i</button>
29
+ <p class="wpstg--tooltiptext has-top-arrow"><?php echo sprintf(__('Exclude files by size. For example to exclude files greater than 10 MB, select %s and type %s in next input box and select %s.', 'wp-staging'), '<code class="wpstg-code">' . __('GREATER THAN', 'wp-staging') . '</code>', '<code class="wpstg-code">10</code>', '<code class="wpstg-code">MB</code>') ?>
30
  </p>
31
  </div>
32
  </td>
Backend/views/welcome/welcome.php CHANGED
@@ -1,16 +1,21 @@
1
  <div class="" id="wpstg-welcome">
2
- <div class="wpstg-welcome-container">
3
- <h2 class="wpstg-h2">
4
- <span class="wpstg-heading-pro"><?php _e('WP STAGING Pro', 'wp-staging'); ?></span><?php _e(' - Copy Themes & Plugins from Staging to Live Site', 'wp-staging'); ?>
5
  </h2>
6
- <li><strong>Cloning</strong> - <?php _e('Create a clone of your website with a simple click', 'wp-staging'); ?></li>
7
- <li><strong>Push Changes</strong> - <?php _e('Copy plugin and theme files from staging to live site', 'wp-staging'); ?></li>
8
- <li><strong>Authentication</strong> - <?php _e('Staging Site is available to authenticated users only', 'wp-staging'); ?></li>
9
- <li><strong>High Performance</strong> - <?php _e('Cloning process is fast and does not slow down website loading', 'wp-staging'); ?></li>
10
- <li><strong>Secure</strong> - <?php _e('WP Staging is coded well for protection of your data', 'wp-staging'); ?></li>
11
- <li><strong>Multisites</strong> - <?php _e('WP STAGING Pro allows to clone and push Multisites, (main site & sub sites)', 'wp-staging'); ?></li>
12
- <a href="http://wp-staging.com/?utm_source=wpstg&utm_medium=addon_page&utm_term=click-wpstaging-pro&utm_campaign=wpstaging" target="_blank" class="wpstg-button green">Buy WP STAGING Pro</a>
13
- <a href="<?php echo admin_url(); ?>admin.php?page=wpstg_clone" target="_self" class="wpstg-ml-30px">Skip - Start Cloning</a>
 
 
 
 
 
14
  <div class="wpstg-footer"> <?php _e('Comes with our 30-day money back guarantee * You need to give us chance to resolve your issue first.', 'wp-staging'); ?></div>
15
  </div>
16
  </div>
1
  <div class="" id="wpstg-welcome">
2
+ <div class="wpstg-welcome-container wpstg--grey">
3
+ <h2 class="wpstg-h2 wpstg--grey">
4
+ <span class="wpstg-heading-pro wpstg--blue"><?php _e('WP STAGING | PRO', 'wp-staging'); ?></span><?php _e(' - Enterprise Level Backup, Cloning & Migration Tool', 'wp-staging'); ?>
5
  </h2>
6
+ <h3 class="wpstg--grey">Is this the best backup & migration plugin?</h3>
7
+ <li><strong>Enterprise Reliability</strong> - <?php echo sprintf(__('Your data is crucial so we run <a href="%s" target="_blank" style="text-decoration: underline;">thousands</a> of automated tests before every release.', 'wp-staging'), 'https://www.youtube.com/watch?v=Tf9C9Pgu7Bs&t=5s'); ?></li>
8
+ <li><strong>German Engineering</strong> - <?php _e('Our headquarter is located in Germany with a small team of highly skilled developers.', 'wp-staging'); ?></li>
9
+ <li><strong>Cloning</strong> - <?php _e('Clone your entire website with one click.', 'wp-staging'); ?></li>
10
+ <li><strong>Push Changes</strong> - <?php _e('Push a staging site to the production site. (Pro)', 'wp-staging'); ?></li>
11
+ <li><strong>Backup & Restore</strong> - <?php _e('Backup and Restore WordPress. Easy, fast, and secure. (Pro)', 'wp-staging'); ?></li>
12
+ <li><strong>Move WordPress</strong> - <?php _e('Migrate & move your website from one domain to another, even to a separate server. (Pro)', 'wp-staging'); ?></li>
13
+ <li><strong>Support Multisites</strong> - <?php _e('Clone and push Multisites. (Pro)', 'wp-staging'); ?></li>
14
+ <li><strong>Authentication</strong> - <?php _e('Cloned sites are available to authenticated users only.', 'wp-staging'); ?></li>
15
+ <li><strong>High Performance</strong> - <?php _e('WP STAGING is one of the fastest backup and migration plugins. Compare yourself.', 'wp-staging'); ?></li>
16
+ <li><strong>Secure</strong> - <?php _e('WP STAGING is no cloud service. Your data belongs to you only.', 'wp-staging'); ?></li>
17
+ <a href="http://wp-staging.com/?utm_source=wpstg&utm_medium=addon_page&utm_term=click-wpstaging-pro&utm_campaign=wpstaging" target="_blank" class="wpstg-button--big wpstg-button--blue">Buy WP STAGING Pro</a>
18
+ <a href="<?php echo admin_url(); ?>admin.php?page=wpstg_clone" target="_self" class="wpstg-ml-30px">Skip & Start Cloning</a>
19
  <div class="wpstg-footer"> <?php _e('Comes with our 30-day money back guarantee * You need to give us chance to resolve your issue first.', 'wp-staging'); ?></div>
20
  </div>
21
  </div>
Core/Utils/Directories.php CHANGED
@@ -2,11 +2,10 @@
2
 
3
  namespace WPStaging\Core\Utils;
4
 
5
- // No Direct Access
6
- if (!defined("WPINC")) {
7
- die;
8
- }
9
-
10
  use WPStaging\Core\WPStaging;
11
 
12
  /**
@@ -65,22 +64,26 @@ class Directories
65
  */
66
  private function sizeWithPHP($path)
67
  {
68
- // Iterator
69
- $iterator = new \RecursiveIteratorIterator(
70
- new \RecursiveDirectoryIterator($path, \FilesystemIterator::SKIP_DOTS)
71
- );
72
-
73
  $totalBytes = 0;
74
 
75
- // Loop & add file size
76
- foreach ($iterator as $file) {
77
- try {
78
- $totalBytes += $file->getSize();
79
- }
80
- // Some invalid symbolik links can cause issues in *nix systems
81
- catch (\Exception $e) {
82
- $this->log->add("{$file} is a symbolic link or for some reason its size is invalid");
 
 
 
 
 
 
 
83
  }
 
 
84
  }
85
 
86
  return $totalBytes;
2
 
3
  namespace WPStaging\Core\Utils;
4
 
5
+ use Exception;
6
+ use FilesystemIterator;
7
+ use RecursiveDirectoryIterator;
8
+ use RecursiveIteratorIterator;
 
9
  use WPStaging\Core\WPStaging;
10
 
11
  /**
64
  */
65
  private function sizeWithPHP($path)
66
  {
 
 
 
 
 
67
  $totalBytes = 0;
68
 
69
+ try {
70
+ // Iterator
71
+ $iterator = new RecursiveIteratorIterator(
72
+ new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS)
73
+ );
74
+
75
+ // Loop & add file size
76
+ foreach ($iterator as $file) {
77
+ try {
78
+ $totalBytes += $file->getSize();
79
+ }
80
+ // Some invalid symbolik links can cause issues in *nix systems
81
+ catch (Exception $e) {
82
+ $this->log->add("{$file} is a symbolic link or for some reason its size is invalid");
83
+ }
84
  }
85
+ } catch (Exception $e) {
86
+ $this->log->add("System Error: " . $e->getMessage());
87
  }
88
 
89
  return $totalBytes;
Core/Utils/Helper.php CHANGED
@@ -2,10 +2,12 @@
2
 
3
  namespace WPStaging\Core\Utils;
4
 
5
- // No Direct Access
6
- if (!defined("WPINC")) {
7
- die;
8
- }
 
 
9
 
10
  class Helper
11
  {
2
 
3
  namespace WPStaging\Core\Utils;
4
 
5
+ /**
6
+ * Class Helper
7
+ * @package WPStaging\Core\Utils
8
+ * @todo replace with Framework\Utils\Urls
9
+ * @deprecated
10
+ */
11
 
12
  class Helper
13
  {
Core/Utils/Logger.php CHANGED
@@ -154,7 +154,6 @@ class Logger implements LoggerInterface, ShutdownableInterface
154
  return true;
155
  }
156
 
157
- //return (@file_put_contents($this->getLogFile(), $messageString, FILE_APPEND | LOCK_EX));
158
  return (@file_put_contents($this->getLogFile(), $messageString, FILE_APPEND));
159
  }
160
 
@@ -232,17 +231,7 @@ class Logger implements LoggerInterface, ShutdownableInterface
232
  return $this->messages[] = array_pop($this->messages);
233
  }
234
  }
235
-
236
- /**
237
- * Get running time in seconds
238
- * @return int
239
- */
240
- public function getRunningTime()
241
- {
242
- $str_time = $this->messages[0]["date"];
243
- return $str_time;
244
- }
245
-
246
  /**
247
  * @inheritDoc
248
  */
154
  return true;
155
  }
156
 
 
157
  return (@file_put_contents($this->getLogFile(), $messageString, FILE_APPEND));
158
  }
159
 
231
  return $this->messages[] = array_pop($this->messages);
232
  }
233
  }
234
+
 
 
 
 
 
 
 
 
 
 
235
  /**
236
  * @inheritDoc
237
  */
Core/Utils/functions.php CHANGED
@@ -6,10 +6,13 @@
6
  * Yeah, evil in terms of some best "dogmatic" practices and made by laziness... but effective.
7
  * As they are prefixed we can easily find and refactor them over time.
8
  *
9
- * @todo refactor - Split this file into classes for strings, database, filesystem and so on
10
  *
11
  */
12
 
 
 
 
13
  /**
14
  * PHP setup environment
15
  *
@@ -145,38 +148,7 @@ function wpstg_urldecode($data)
145
  */
146
  function wpstg_is_stagingsite()
147
  {
148
- return (new \WPStaging\Framework\SiteInfo())->isStaging();
149
- }
150
-
151
- /**
152
- * @param string $memory
153
- * @return int
154
- */
155
- function wpstg_get_memory_in_bytes($memory)
156
- {
157
- // Handle unlimited ones
158
- if ((int)$memory < 1) {
159
- //return (int) $memory;
160
- // 128 MB default value
161
- return (int)134217728;
162
- }
163
-
164
- $bytes = (int)$memory; // grab only the number
165
- $size = trim(str_replace($bytes, null, strtolower($memory))); // strip away number and lower-case it
166
- // Actual calculation
167
- switch ($size) {
168
- case 'k':
169
- $bytes *= 1024;
170
- break;
171
- case 'm':
172
- $bytes *= (1024 * 1024);
173
- break;
174
- case 'g':
175
- $bytes *= (1024 * 1024 * 1024);
176
- break;
177
- }
178
-
179
- return $bytes;
180
  }
181
 
182
  /**
@@ -194,27 +166,6 @@ function wpstg_unique_constraint($query)
194
  return $query;
195
  }
196
 
197
- /**
198
- * Get root relative path to the uploads folder, can be a custom folder e.g 'assets' or default folder 'wp-content/uploads'
199
- * @return string
200
- * @todo delete
201
- */
202
- /*function wpstg_get_rel_upload_dir()
203
- {
204
- // Get upload directory information. Default is ABSPATH . 'wp-content/uploads'
205
- // Can be customized by populating the db option upload_path or the constant UPLOADS
206
- // If both are defined WordPress will uses the value of the UPLOADS constant
207
- $uploads = wp_upload_dir();
208
-
209
- // Get absolute path to wordpress uploads directory e.g srv/www/htdocs/sitename/wp-content/uploads
210
- $uploadsAbsPath = trailingslashit($uploads['basedir']);
211
-
212
- // Get relative path to the uploads folder, e.g assets
213
- $relPath = str_replace(ABSPATH, null, $uploadsAbsPath);
214
-
215
- return $relPath;
216
- }*/
217
-
218
  /**
219
  * Get relative path to the uploads folder, can be a custom folder e.g assets or default folder wp-content/uploads
220
  *
@@ -226,27 +177,7 @@ function wpstg_unique_constraint($query)
226
  */
227
  function wpstg_get_abs_upload_dir()
228
  {
229
- return (new \WPStaging\Framework\Utils\WpDefaultDirectories())->getUploadsPath();
230
- }
231
-
232
- /**
233
- * Get hostname of production site including scheme
234
- * @return string
235
- */
236
- function wpstg_get_production_hostname()
237
- {
238
-
239
- $connection = get_option('wpstg_connection');
240
-
241
- // Get the stored hostname
242
- if (!empty($connection['prodHostname'])) {
243
- return $connection['prodHostname'];
244
- }
245
-
246
- // Default. Try to get the hostname from the main domain (Workaround for WP Staging Pro older < 2.9.1)
247
- $siteurl = get_site_url();
248
- $result = parse_url($siteurl);
249
- return $result['scheme'] . "://" . $result['host'];
250
  }
251
 
252
  /**
@@ -271,7 +202,7 @@ function wpstg_is_empty_dir($dir)
271
  if (!is_dir($dir)) {
272
  return true;
273
  }
274
- $iterator = new \FilesystemIterator($dir);
275
  if ($iterator->valid()) {
276
  return false;
277
  }
@@ -311,14 +242,12 @@ function wpstg_get_upload_dir()
311
 
312
  /**
313
  * Get the base of a string
314
- * @param type $input
315
- * @return type
316
  */
317
  function wpstg_base($input)
318
  {
319
  $keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
320
- $chr1 = $chr2 = $chr3 = "";
321
- $enc1 = $enc2 = $enc3 = $enc4 = "";
322
  $i = 0;
323
  $output = "";
324
  $input = preg_replace("[^A-Za-z0-9\+\/\=]", "", $input);
@@ -337,8 +266,6 @@ function wpstg_base($input)
337
  if ($enc4 != 64) {
338
  $output = $output . chr((int)$chr3);
339
  }
340
- $chr1 = $chr2 = $chr3 = "";
341
- $enc1 = $enc2 = $enc3 = $enc4 = "";
342
  } while ($i < strlen($input));
343
  return urldecode($output);
344
  }
@@ -383,7 +310,6 @@ function wpstg_put_contents($file, $contents, $mode = false)
383
  * Change chmod of file or folder
384
  * @param string $file path to file
385
  * @param mixed $mode false or specific octal value like 0755
386
- * @param type $recursive
387
  * @return boolean
388
  */
389
  function wpstg_chmod($file, $mode = false)
@@ -413,28 +339,6 @@ function wpstg_chmod($file, $mode = false)
413
  return true;
414
  }
415
 
416
- /**
417
- * Changes the owner of a file or directory.
418
- *
419
- *
420
- * @param string $file Path to the file or directory.
421
- * @param string|int $owner A user name or number.
422
- * @param bool $recursive Optional. If set to true, changes file owner recursively.
423
- * Default false.
424
- * @return bool True on success, false on failure.
425
- */
426
- function wpstg_chown($file, $owner)
427
- {
428
- if (!@file_exists($file)) {
429
- return false;
430
- }
431
-
432
- if (!@is_dir($file)) {
433
- return @chown($file, $owner);
434
- }
435
- return true;
436
- }
437
-
438
  /*
439
  * Check if website is installed locally
440
  * @return boolean
6
  * Yeah, evil in terms of some best "dogmatic" practices and made by laziness... but effective.
7
  * As they are prefixed we can easily find and refactor them over time.
8
  *
9
+ * @todo refactor! Split this file into classes for strings, database, filesystem and so on. Move everything under /Frameworks
10
  *
11
  */
12
 
13
+ use WPStaging\Framework\SiteInfo;
14
+ use WPStaging\Framework\Utils\WpDefaultDirectories;
15
+
16
  /**
17
  * PHP setup environment
18
  *
148
  */
149
  function wpstg_is_stagingsite()
150
  {
151
+ return (new SiteInfo())->isStaging();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
  }
153
 
154
  /**
166
  return $query;
167
  }
168
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  /**
170
  * Get relative path to the uploads folder, can be a custom folder e.g assets or default folder wp-content/uploads
171
  *
177
  */
178
  function wpstg_get_abs_upload_dir()
179
  {
180
+ return (new WpDefaultDirectories())->getUploadsPath();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
181
  }
182
 
183
  /**
202
  if (!is_dir($dir)) {
203
  return true;
204
  }
205
+ $iterator = new FilesystemIterator($dir);
206
  if ($iterator->valid()) {
207
  return false;
208
  }
242
 
243
  /**
244
  * Get the base of a string
245
+ * @param string $input
246
+ * @return string
247
  */
248
  function wpstg_base($input)
249
  {
250
  $keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
 
 
251
  $i = 0;
252
  $output = "";
253
  $input = preg_replace("[^A-Za-z0-9\+\/\=]", "", $input);
266
  if ($enc4 != 64) {
267
  $output = $output . chr((int)$chr3);
268
  }
 
 
269
  } while ($i < strlen($input));
270
  return urldecode($output);
271
  }
310
  * Change chmod of file or folder
311
  * @param string $file path to file
312
  * @param mixed $mode false or specific octal value like 0755
 
313
  * @return boolean
314
  */
315
  function wpstg_chmod($file, $mode = false)
339
  return true;
340
  }
341
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
342
  /*
343
  * Check if website is installed locally
344
  * @return boolean
Core/WPStaging.php CHANGED
@@ -6,14 +6,16 @@ use WPStaging\Backend\Administrator;
6
  use WPStaging\Core\Cron\Cron;
7
  use WPStaging\Core\Utils\Cache;
8
  use WPStaging\Core\Utils\Logger;
 
9
  use WPStaging\Framework\AssetServiceProvider;
 
10
  use WPStaging\Framework\DI\Container;
11
  use WPStaging\Framework\Filesystem\DirectoryListing;
12
  use WPStaging\Framework\Filesystem\Filesystem;
13
  use WPStaging\Framework\Permalinks\PermalinksPurge;
14
  use WPStaging\Framework\Staging\FirstRun;
15
  use WPStaging\Frontend\Frontend;
16
- use WPStaging\Vendor\Psr\Log\LoggerInterface;
17
 
18
  /**
19
  * Class WPStaging
@@ -40,7 +42,7 @@ final class WPStaging
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.
@@ -54,7 +56,7 @@ final class WPStaging
54
  {
55
  $this->isBootstrapped = true;
56
 
57
- $this->startTime = microtime(true);
58
 
59
  $this->container->register(CoreServiceProvider::class);
60
 
@@ -63,6 +65,7 @@ final class WPStaging
63
  // Boot the container after dependencies are loaded.
64
  $this->container->boot();
65
 
 
66
  $this->container->register(AssetServiceProvider::class);
67
  $this->initCron();
68
  $this->cloneSiteFirstRun();
@@ -71,15 +74,14 @@ final class WPStaging
71
  $this->container->register(\WPStaging\Pro\ProServiceProvider::class);
72
  }
73
 
 
 
 
 
74
  $this->handleCacheIssues();
75
  $this->preventDirectoryListing();
76
  }
77
 
78
- public function getStartTime()
79
- {
80
- return $this->startTime;
81
- }
82
-
83
  /**
84
  * Initialize cron jobs
85
  */
@@ -101,11 +103,32 @@ final class WPStaging
101
 
102
  /**
103
  * Get table prefix of the current site
 
104
  * @return string
105
  */
106
  public static function getTablePrefix()
107
  {
108
- return WPStaging::getInstance()->get("wpdb")->prefix;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  }
110
 
111
  /**
@@ -153,6 +176,16 @@ final class WPStaging
153
  }
154
  }
155
 
 
 
 
 
 
 
 
 
 
 
156
  /**
157
  * Load Dependencies
158
  */
@@ -234,6 +267,28 @@ final class WPStaging
234
  return $this->container->_get($name);
235
  }
236
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
237
  /**
238
  * Get given name index from DI
239
  *
@@ -309,7 +364,8 @@ final class WPStaging
309
  */
310
  private function preventDirectoryListing()
311
  {
312
- if (is_admin() && !wp_doing_ajax()) {
 
313
  /** @var DirectoryListing $directoryListing */
314
  $directoryListing = $this->getContainer()->make(DirectoryListing::class);
315
  $directoryListing->protectPluginUploadDirectory();
6
  use WPStaging\Core\Cron\Cron;
7
  use WPStaging\Core\Utils\Cache;
8
  use WPStaging\Core\Utils\Logger;
9
+ use WPStaging\Framework\Adapter\WpAdapter;
10
  use WPStaging\Framework\AssetServiceProvider;
11
+ use WPStaging\Framework\CommonServiceProvider;
12
  use WPStaging\Framework\DI\Container;
13
  use WPStaging\Framework\Filesystem\DirectoryListing;
14
  use WPStaging\Framework\Filesystem\Filesystem;
15
  use WPStaging\Framework\Permalinks\PermalinksPurge;
16
  use WPStaging\Framework\Staging\FirstRun;
17
  use WPStaging\Frontend\Frontend;
18
+ use WPStaging\Frontend\FrontendServiceProvider;
19
 
20
  /**
21
  * Class WPStaging
42
  /**
43
  * @var int The microtime where the Container was bootstraped. Used to identify the time where the application started running.
44
  */
45
+ public static $startTime;
46
 
47
  /**
48
  * WPStaging constructor.
56
  {
57
  $this->isBootstrapped = true;
58
 
59
+ WPStaging::$startTime = microtime(true);
60
 
61
  $this->container->register(CoreServiceProvider::class);
62
 
65
  // Boot the container after dependencies are loaded.
66
  $this->container->boot();
67
 
68
+ $this->container->register(CommonServiceProvider::class);
69
  $this->container->register(AssetServiceProvider::class);
70
  $this->initCron();
71
  $this->cloneSiteFirstRun();
74
  $this->container->register(\WPStaging\Pro\ProServiceProvider::class);
75
  }
76
 
77
+ if (!is_admin()) {
78
+ $this->container->register(FrontendServiceProvider::class);
79
+ }
80
+
81
  $this->handleCacheIssues();
82
  $this->preventDirectoryListing();
83
  }
84
 
 
 
 
 
 
85
  /**
86
  * Initialize cron jobs
87
  */
103
 
104
  /**
105
  * Get table prefix of the current site
106
+ * Always use lowercase on Windows
107
  * @return string
108
  */
109
  public static function getTablePrefix()
110
  {
111
+ $db = WPStaging::getInstance()->get("wpdb");
112
+ if (self::isWindowsOs()) {
113
+ return strtolower($db->prefix);
114
+ }
115
+
116
+ return $db->prefix;
117
+ }
118
+
119
+ /**
120
+ * Get base prefix of the current wordpress
121
+ * Always use lowercase on Windows
122
+ * @return string
123
+ */
124
+ public static function getTableBasePrefix()
125
+ {
126
+ $db = WPStaging::getInstance()->get("wpdb");
127
+ if (self::isWindowsOs()) {
128
+ return strtolower($db->base_prefix);
129
+ }
130
+
131
+ return $db->base_prefix;
132
  }
133
 
134
  /**
176
  }
177
  }
178
 
179
+ /**
180
+ * Is the current PHP OS Windows?
181
+ *
182
+ * @return boolean
183
+ */
184
+ public static function isWindowsOs()
185
+ {
186
+ return strncasecmp(PHP_OS, 'WIN', 3) === 0;
187
+ }
188
+
189
  /**
190
  * Load Dependencies
191
  */
267
  return $this->container->_get($name);
268
  }
269
 
270
+ /**
271
+ * Get given name index from DI
272
+ *
273
+ * USE THIS WISELY. Most of the time the dependencies should be injected through the __construct!
274
+ * Google for "service locator vs dependency injection"
275
+ *
276
+ * @param string $id The bound service identifier, or a class name to build and return.
277
+ *
278
+ * @return mixed The built object bound to the id, the requested
279
+ * class instance.
280
+ */
281
+ public static function make($id)
282
+ {
283
+ static $container;
284
+
285
+ if ($container === null) {
286
+ $container = self::getInstance()->getContainer();
287
+ }
288
+
289
+ return $container->make($id);
290
+ }
291
+
292
  /**
293
  * Get given name index from DI
294
  *
364
  */
365
  private function preventDirectoryListing()
366
  {
367
+ // TODO: inject WpAdapter using DI
368
+ if (is_admin() && !(new WpAdapter())->doingAjax()) {
369
  /** @var DirectoryListing $directoryListing */
370
  $directoryListing = $this->getContainer()->make(DirectoryListing::class);
371
  $directoryListing->protectPluginUploadDirectory();
Deactivate.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WPStaging;
4
+
5
+ /**
6
+ * Actions to perform when we deactivate WP Staging Plugin
7
+ */
8
+ class Deactivate
9
+ {
10
+ /**
11
+ * @var string
12
+ */
13
+ private $currentPluginFile;
14
+
15
+ public function __construct($currentPluginFile)
16
+ {
17
+ $this->currentPluginFile = $currentPluginFile;
18
+
19
+ // Early bail
20
+ // This filter hook is for internal use only
21
+ if (apply_filters('wpstg.deactivation_hook.skip_mu_delete', false)) {
22
+ return;
23
+ }
24
+
25
+ // Only delete MU plugin when no other wp staging plugin is activated
26
+ if (!$this->isOtherWPStagingPluginActivated()) {
27
+ $this->deleteMuPlugin();
28
+ }
29
+ }
30
+
31
+ /**
32
+ * Check if any other WP Staging Plugin is activated other than current one
33
+ *
34
+ * @return boolean
35
+ */
36
+ private function isOtherWPStagingPluginActivated()
37
+ {
38
+ foreach (wp_get_active_and_valid_plugins() as $activePlugin) {
39
+ if ($activePlugin === $this->currentPluginFile) {
40
+ continue;
41
+ }
42
+
43
+ if (strpos($activePlugin, 'wp-staging.php') !== false || strpos($activePlugin, 'wp-staging-pro.php') !== false) {
44
+ return true;
45
+ }
46
+ }
47
+
48
+ return false;
49
+ }
50
+
51
+ /**
52
+ * delete MuPlugin
53
+ */
54
+ private function deleteMuPlugin()
55
+ {
56
+ $muDir = (defined('WPMU_PLUGIN_DIR')) ? WPMU_PLUGIN_DIR : trailingslashit(WP_CONTENT_DIR) . 'mu-plugins';
57
+ $dest = trailingslashit($muDir) . 'wp-staging-optimizer.php';
58
+
59
+ if (file_exists($dest) && !unlink($dest)) {
60
+ return false;
61
+ }
62
+
63
+ return true;
64
+ }
65
+ }
Framework/Adapter/Database.php CHANGED
@@ -10,6 +10,7 @@ namespace WPStaging\Framework\Adapter;
10
 
11
  use RuntimeException;
12
  use wpdb;
 
13
  use WPStaging\Framework\Adapter\Database\InterfaceDatabase;
14
  use WPStaging\Framework\Adapter\Database\InterfaceDatabaseClient;
15
  use WPStaging\Framework\Adapter\Database\MysqlAdapter;
@@ -65,10 +66,17 @@ class Database
65
  }
66
 
67
  /**
 
 
 
68
  * @return string
69
  */
70
  public function getPrefix()
71
  {
 
 
 
 
72
  return $this->wpdb->prefix;
73
  }
74
 
@@ -90,10 +98,14 @@ class Database
90
 
91
  /**
92
  * Return escaped prefix to use it in sql queries like 'wp\_'
 
 
 
 
93
  * @param string|null $prefix
94
  * @return string|string[]
95
  */
96
- public function provideSqlPrefix($prefix = null)
97
  {
98
  if (!$prefix) {
99
  $prefix = $this->getPrefix();
10
 
11
  use RuntimeException;
12
  use wpdb;
13
+ use WPStaging\Core\WPStaging;
14
  use WPStaging\Framework\Adapter\Database\InterfaceDatabase;
15
  use WPStaging\Framework\Adapter\Database\InterfaceDatabaseClient;
16
  use WPStaging\Framework\Adapter\Database\MysqlAdapter;
66
  }
67
 
68
  /**
69
+ * Will always return prefix in the lowercase for Windows.
70
+ * In *nix it will return prefix in whatever the case it was written in wp-config.
71
+ *
72
  * @return string
73
  */
74
  public function getPrefix()
75
  {
76
+ if (WPStaging::isWindowsOs()) {
77
+ return strtolower($this->wpdb->prefix);
78
+ }
79
+
80
  return $this->wpdb->prefix;
81
  }
82
 
98
 
99
  /**
100
  * Return escaped prefix to use it in sql queries like 'wp\_'
101
+ *
102
+ * _ is interpreted as a single-character wildcard when
103
+ * executed in a LIKE SQL statement.
104
+ *
105
  * @param string|null $prefix
106
  * @return string|string[]
107
  */
108
+ public function escapeSqlPrefixForLIKE($prefix = null)
109
  {
110
  if (!$prefix) {
111
  $prefix = $this->getPrefix();
Framework/Adapter/Database/InterfaceDatabaseClient.php CHANGED
@@ -8,13 +8,20 @@ use mysqli_result;
8
 
9
  interface InterfaceDatabaseClient
10
  {
 
 
 
 
 
 
 
11
  /**
12
  * Runs given MySQL query
13
  * @param string $query
14
  * @param bool $isExecOnly
15
  * @return resource
16
  */
17
- public function query($query, $isExecOnly = false);
18
 
19
  /**
20
  * Escapes given input for mysql query
@@ -55,6 +62,13 @@ interface InterfaceDatabaseClient
55
  */
56
  public function fetchRow($result);
57
 
 
 
 
 
 
 
 
58
  /**
59
  * Returns the number for rows from MySQL results
60
  * @param resource|mysqli_result $result
8
 
9
  interface InterfaceDatabaseClient
10
  {
11
+ /**
12
+ * Runs given MySQL query
13
+ * @param string $query
14
+ * @return resource
15
+ */
16
+ public function query($query);
17
+
18
  /**
19
  * Runs given MySQL query
20
  * @param string $query
21
  * @param bool $isExecOnly
22
  * @return resource
23
  */
24
+ public function realQuery($query, $isExecOnly = false);
25
 
26
  /**
27
  * Escapes given input for mysql query
62
  */
63
  public function fetchRow($result);
64
 
65
+ /**
66
+ * Returns the result from MySQL query resource as an object
67
+ * @param resource|mysqli_result $result
68
+ * @return array
69
+ */
70
+ public function fetchObject($result);
71
+
72
  /**
73
  * Returns the number for rows from MySQL results
74
  * @param resource|mysqli_result $result
Framework/Adapter/Database/MysqlAdapter.php CHANGED
@@ -4,6 +4,8 @@
4
 
5
  namespace WPStaging\Framework\Adapter\Database;
6
 
 
 
7
  /**
8
  * Class MysqlAdapter
9
  *
@@ -35,6 +37,15 @@ class MysqlAdapter implements InterfaceDatabaseClient
35
  return mysql_query($query, $this->link);
36
  }
37
 
 
 
 
 
 
 
 
 
 
38
  /**
39
  * @inheritDoc
40
  */
@@ -89,6 +100,12 @@ class MysqlAdapter implements InterfaceDatabaseClient
89
  return mysql_fetch_row($result);
90
  }
91
 
 
 
 
 
 
 
92
  /**
93
  * @inheritDoc
94
  */
4
 
5
  namespace WPStaging\Framework\Adapter\Database;
6
 
7
+ use mysqli_result;
8
+
9
  /**
10
  * Class MysqlAdapter
11
  *
37
  return mysql_query($query, $this->link);
38
  }
39
 
40
+ public function realQuery($query, $isExecOnly = false)
41
+ {
42
+ if (defined('WPSTG_DEBUG') && WPSTG_DEBUG) {
43
+ error_log('mysql_real_query() doesn\'t exist in PHP. However, mysqli_real_query() exists.');
44
+ }
45
+
46
+ return $this->query($query, $isExecOnly);
47
+ }
48
+
49
  /**
50
  * @inheritDoc
51
  */
100
  return mysql_fetch_row($result);
101
  }
102
 
103
+ public function fetchObject($result)
104
+ {
105
+ // phpcs:ignore PHPCompatibility.Extensions.RemovedExtensions.mysql_DeprecatedRemoved
106
+ return mysql_fetch_object($result);
107
+ }
108
+
109
  /**
110
  * @inheritDoc
111
  */
Framework/Adapter/Database/MysqliAdapter.php CHANGED
@@ -13,6 +13,7 @@ class MysqliAdapter implements InterfaceDatabaseClient
13
 
14
  /**
15
  * MysqlAdapter constructor.
 
16
  * @param mysqli|null $link
17
  */
18
  public function __construct($link = null)
@@ -23,7 +24,15 @@ class MysqliAdapter implements InterfaceDatabaseClient
23
  /**
24
  * @inheritDoc
25
  */
26
- public function query($query, $isExecOnly = false)
 
 
 
 
 
 
 
 
27
  {
28
  if ($isExecOnly) {
29
  return mysqli_real_query($this->link, $query);
@@ -89,6 +98,14 @@ class MysqliAdapter implements InterfaceDatabaseClient
89
  return mysqli_fetch_row($result);
90
  }
91
 
 
 
 
 
 
 
 
 
92
  /**
93
  * @inheritDoc
94
  */
13
 
14
  /**
15
  * MysqlAdapter constructor.
16
+ *
17
  * @param mysqli|null $link
18
  */
19
  public function __construct($link = null)
24
  /**
25
  * @inheritDoc
26
  */
27
+ public function query($query)
28
+ {
29
+ return mysqli_query($this->link, $query);
30
+ }
31
+
32
+ /**
33
+ * @inheritDoc
34
+ */
35
+ public function realQuery($query, $isExecOnly = false)
36
  {
37
  if ($isExecOnly) {
38
  return mysqli_real_query($this->link, $query);
98
  return mysqli_fetch_row($result);
99
  }
100
 
101
+ /**
102
+ * @inheritDoc
103
+ */
104
+ public function fetchObject($result)
105
+ {
106
+ return mysqli_fetch_object($result);
107
+ }
108
+
109
  /**
110
  * @inheritDoc
111
  */
Framework/Adapter/Directory.php CHANGED
@@ -2,10 +2,62 @@
2
 
3
  namespace WPStaging\Framework\Adapter;
4
 
 
 
 
 
5
  class Directory
6
  {
7
- /** @var string|null */
8
- private $uploadDir;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
 
10
  /**
11
  * @noinspection PhpUnused
@@ -13,21 +65,57 @@ class Directory
13
  */
14
  public function getCacheDirectory()
15
  {
16
- return $this->getPluginUploadsDirectory() . 'cache/';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  }
18
 
19
  /**
20
- * @noinspection PhpUnused
21
  * @return string
22
  */
23
  public function getLogDirectory()
24
  {
25
- return $this->getPluginUploadsDirectory() . $this->getDomain() . 'logs/';
 
 
 
 
 
 
26
  }
27
 
 
 
 
28
  public function getPluginUploadsDirectory()
29
  {
30
- return trailingslashit($this->getUploadsDirectory() . $this->getDomain());
 
 
 
 
 
 
31
  }
32
 
33
  /**
@@ -43,20 +131,173 @@ class Directory
43
  // Get absolute path to wordpress uploads directory e.g /var/www/wp-content/uploads/
44
  // Default is ABSPATH . 'wp-content/uploads', but it can be customized by the db option upload_path or the constant UPLOADS
45
  $uploadDir = wp_upload_dir(null, false, null)['basedir'];
46
- $uploadDir = trim(trailingslashit($uploadDir));
47
 
48
- $this->uploadDir = $uploadDir;
49
 
50
  return $this->uploadDir;
51
  }
52
 
53
- public function getDomain()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  {
55
- return WPSTG_PLUGIN_DOMAIN;
 
 
 
 
56
  }
57
 
58
- public function getSlug()
 
 
 
59
  {
60
- return WPSTG_PLUGIN_SLUG;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  }
62
  }
2
 
3
  namespace WPStaging\Framework\Adapter;
4
 
5
+ use WPStaging\Framework\Filesystem\Filesystem;
6
+ use WPStaging\Pro\Backup\Job\Jobs\JobImport;
7
+ use WPStaging\Framework\Utils\Strings;
8
+
9
  class Directory
10
  {
11
+ /** @var string The directory that holds the uploads, usually wp-content/uploads */
12
+ protected $uploadDir;
13
+
14
+ /** @var string The directory that holds the WPSTAGING cache directory, usually wp-content/uploads/wp-staging/cache */
15
+ protected $cacheDirectory;
16
+
17
+ /** @var string The directory that holds the WPSTAGING tmp directory, usually wp-content/uploads/wp-staging/tmp */
18
+ protected $tmpDirectory;
19
+
20
+ /** @var string The directory that holds the WPSTAGING logs directory, usually wp-content/uploads/wp-staging/logs */
21
+ protected $logDirectory;
22
+
23
+ /** @var string The directory that holds the WPSTAGING data directory, usually wp-content/uploads/wp-staging */
24
+ protected $pluginUploadsDirectory;
25
+
26
+ /** @var string The directory that holds the plugins, usually wp-content/plugins */
27
+ protected $pluginsDir;
28
+
29
+ /** @var string The directory that holds the mu-plugins, usually wp-content/mu-plugins */
30
+ protected $muPluginsDir;
31
+
32
+ /** @var array An array of directories that holds themes, usually ['wp-content/themes'] */
33
+ protected $themesDirs;
34
+
35
+ /** @var string The directory that holds the currently active theme, usually wp-content/themes */
36
+ protected $activeThemeParentDir;
37
+
38
+ /** @var array An array of default directories, such as ['wp-content/themes/', 'wp-content/plugins/', 'wp-content/mu-plugins/', 'wp-content/uploads/'] */
39
+ protected $defaultWordPressFolders;
40
+
41
+ /** @var string The directory that points to the wp-content folder, usually wp-content/ */
42
+ protected $wpContentDirectory;
43
+
44
+ /** @var string The directory that points to the languages folder, usually wp-content/languages/ */
45
+ protected $langDir;
46
+
47
+ /** @var string The directory that points to the ABSPATH folder */
48
+ protected $absPath;
49
+
50
+ /** @var Filesystem */
51
+ protected $filesystem;
52
+
53
+ /** @var Strings */
54
+ protected $strUtils;
55
+
56
+ public function __construct(Filesystem $filesystem, Strings $strings)
57
+ {
58
+ $this->filesystem = $filesystem;
59
+ $this->strUtils = $strings;
60
+ }
61
 
62
  /**
63
  * @noinspection PhpUnused
65
  */
66
  public function getCacheDirectory()
67
  {
68
+ if (isset($this->cacheDirectory)) {
69
+ return $this->cacheDirectory;
70
+ }
71
+
72
+ $this->cacheDirectory = trailingslashit(wp_normalize_path($this->getPluginUploadsDirectory() . 'cache'));
73
+
74
+ return $this->cacheDirectory;
75
+ }
76
+
77
+ /**
78
+ * @return string
79
+ */
80
+ public function getTmpDirectory()
81
+ {
82
+ if (isset($this->tmpDirectory)) {
83
+ return $this->tmpDirectory;
84
+ }
85
+
86
+ $this->tmpDirectory = trailingslashit(wp_normalize_path($this->getPluginUploadsDirectory() . JobImport::TMP_DIRECTORY));
87
+
88
+ wp_mkdir_p($this->tmpDirectory);
89
+
90
+ return $this->tmpDirectory;
91
  }
92
 
93
  /**
 
94
  * @return string
95
  */
96
  public function getLogDirectory()
97
  {
98
+ if (isset($this->logDirectory)) {
99
+ return $this->logDirectory;
100
+ }
101
+
102
+ $this->logDirectory = trailingslashit(wp_normalize_path($this->getPluginUploadsDirectory() . WPSTG_PLUGIN_DOMAIN . 'logs'));
103
+
104
+ return $this->logDirectory;
105
  }
106
 
107
+ /**
108
+ * @return string
109
+ */
110
  public function getPluginUploadsDirectory()
111
  {
112
+ if (isset($this->pluginUploadsDirectory)) {
113
+ return $this->pluginUploadsDirectory;
114
+ }
115
+
116
+ $this->pluginUploadsDirectory = trailingslashit(wp_normalize_path($this->getUploadsDirectory() . WPSTG_PLUGIN_DOMAIN));
117
+
118
+ return $this->pluginUploadsDirectory;
119
  }
120
 
121
  /**
131
  // Get absolute path to wordpress uploads directory e.g /var/www/wp-content/uploads/
132
  // Default is ABSPATH . 'wp-content/uploads', but it can be customized by the db option upload_path or the constant UPLOADS
133
  $uploadDir = wp_upload_dir(null, false, null)['basedir'];
 
134
 
135
+ $this->uploadDir = trim(trailingslashit(wp_normalize_path($uploadDir)));
136
 
137
  return $this->uploadDir;
138
  }
139
 
140
+ public function getDefaultWordPressFolders()
141
+ {
142
+ if (!isset($this->defaultWordPressFolders)) {
143
+ $this->defaultWordPressFolders = array_merge(
144
+ [
145
+ $this->getPluginsDirectory(),
146
+ $this->getMuPluginsDirectory(),
147
+ $this->getUploadsDirectory(),
148
+ ],
149
+ $this->getAllThemesDirectories()
150
+ );
151
+ }
152
+
153
+ return $this->defaultWordPressFolders;
154
+ }
155
+
156
+ /**
157
+ * @return string
158
+ */
159
+ public function getPluginsDirectory()
160
+ {
161
+ if (!isset($this->pluginsDir)) {
162
+ $this->pluginsDir = $this->filesystem->normalizePath(WP_PLUGIN_DIR);
163
+ }
164
+
165
+ return $this->pluginsDir;
166
+ }
167
+
168
+ /**
169
+ * @return string
170
+ */
171
+ public function getMuPluginsDirectory()
172
+ {
173
+ if (!isset($this->muPluginsDir)) {
174
+ $this->muPluginsDir = $this->filesystem->normalizePath(WPMU_PLUGIN_DIR);
175
+ }
176
+
177
+ return $this->muPluginsDir;
178
+ }
179
+
180
+ /**
181
+ * @throws \RuntimeException
182
+ *
183
+ * @return array
184
+ */
185
+ public function getAllThemesDirectories()
186
+ {
187
+ if (!isset($this->themesDirs)) {
188
+ $this->themesDirs = array_map(function ($directory) {
189
+ return $this->filesystem->normalizePath($directory['theme_root']);
190
+ }, search_theme_directories(true));
191
+
192
+ if (!is_array($this->themesDirs)) {
193
+ throw new \RuntimeException('Could not get the themes directories.');
194
+ }
195
+
196
+ /*
197
+ * [
198
+ * 'foo' => '/var/www/single/wp-content/themes',
199
+ * 'bar' => '/var/www/single/wp-content/themes',
200
+ * 'baz' => '/var/themes'
201
+ * ]
202
+ *
203
+ * Becomes:
204
+ *
205
+ * [
206
+ * '/var/www/single/wp-content/themes',
207
+ * '/var/themes',
208
+ * ]
209
+ */
210
+ $this->themesDirs = array_unique($this->themesDirs);
211
+ $this->themesDirs = array_values($this->themesDirs);
212
+ }
213
+
214
+ return $this->themesDirs;
215
+ }
216
+
217
+ /**
218
+ * @return string
219
+ */
220
+ public function getActiveThemeParentDirectory()
221
+ {
222
+ if (!isset($this->activeThemeParentDir)) {
223
+ $this->activeThemeParentDir = $this->filesystem->normalizePath(get_theme_root(get_template()));
224
+ }
225
+
226
+ return $this->activeThemeParentDir;
227
+ }
228
+
229
+ /**
230
+ * @return string
231
+ */
232
+ public function getLangsDirectory()
233
+ {
234
+ if (!isset($this->langDir)) {
235
+ $this->langDir = $this->filesystem->normalizePath(WP_LANG_DIR);
236
+ }
237
+
238
+ return $this->langDir;
239
+ }
240
+
241
+ /**
242
+ * @return string
243
+ */
244
+ public function getAbsPath()
245
  {
246
+ if (!isset($this->absPath)) {
247
+ $this->absPath = $this->filesystem->normalizePath(ABSPATH);
248
+ }
249
+
250
+ return $this->absPath;
251
  }
252
 
253
+ /**
254
+ * @return string
255
+ */
256
+ public function getWpContentDirectory()
257
  {
258
+ if (!isset($this->wpContentDirectory)) {
259
+ $this->wpContentDirectory = $this->filesystem->normalizePath(WP_CONTENT_DIR);
260
+ }
261
+
262
+ return $this->wpContentDirectory;
263
+ }
264
+
265
+ /**
266
+ * Check whether the path exists in the list.
267
+ * If the isRelative flag is checked it will ignore ABSPATH (root path of WP Installation),
268
+ * from both the paths during checking
269
+ *
270
+ * @param string $path The path to check
271
+ * @param array $list List of path to check against
272
+ * @param boolean $isRelative Should the ABSPATH be ignored when checking. Default false
273
+ *
274
+ * @return boolean
275
+ */
276
+ public function isPathInPathsList($path, $list, $isRelative = false)
277
+ {
278
+ $path = $this->strUtils->sanitizeDirectorySeparator($path);
279
+ // remove ABSPATH and add leading slash if not present
280
+ if ($isRelative) {
281
+ $path = '/' . ltrim(str_replace($this->getAbsPath(), '', $path), '/');
282
+ }
283
+
284
+ foreach ($list as $pathItem) {
285
+ $pathItem = $this->strUtils->sanitizeDirectorySeparator($pathItem);
286
+ // remove ABSPATH and add leading slash if not present
287
+ if ($isRelative) {
288
+ $pathItem = '/' . ltrim(str_replace($this->getAbsPath(), '', $pathItem), '/');
289
+ }
290
+
291
+ if ($path === $pathItem) {
292
+ return true;
293
+ }
294
+
295
+ // Check whether directory a child of any excluded directories
296
+ if ($this->strUtils->startsWith($path, $pathItem . '/')) {
297
+ return true;
298
+ }
299
+ }
300
+
301
+ return false;
302
  }
303
  }
Framework/Adapter/WpAdapter.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WPStaging\Framework\Adapter;
4
+
5
+ /**
6
+ * Class WP
7
+ * Adapter to maintain wordpress core function for WP backward compatibility support and deprecated functions
8
+ *
9
+ * @package WPStaging\Framework\Adapter
10
+ */
11
+ class WpAdapter
12
+ {
13
+ /**
14
+ * Is the current request doing some ajax
15
+ * Alternative to wp_doing_ajax() as it is not available for WP < 4.7
16
+ * This implementation is without hooks
17
+ *
18
+ * @return boolean
19
+ */
20
+ public function doingAjax()
21
+ {
22
+ return defined('DOING_AJAX') && DOING_AJAX;
23
+ }
24
+ }
Framework/Assets/Assets.php CHANGED
@@ -5,12 +5,14 @@ namespace WPStaging\Framework\Assets;
5
  use WPStaging\Core\DTO\Settings;
6
  use WPStaging\Core\WPStaging;
7
  use WPStaging\Framework\Filesystem\Scanning\ScanConst;
8
- use WPStaging\Framework\Filesystem\Filters\ExcludeFilter;
9
  use WPStaging\Framework\Security\AccessToken;
10
  use WPStaging\Framework\Security\Nonce;
 
11
 
12
  class Assets
13
  {
 
 
14
  /**
15
  * Default admin bar background color for staging site
16
  * @var string
@@ -129,13 +131,9 @@ class Assets
129
  }
130
 
131
  // Load admin js files
132
- $asset = 'js/dist/wpstg-admin.min.js';
133
- if ($this->isDebugOrDevMode()) {
134
- $asset = 'js/dist/wpstg-admin.js';
135
- }
136
-
137
  wp_enqueue_script(
138
- "wpstg-admin-script",
139
  $this->getAssetsUrl($asset),
140
  ["jquery"],
141
  $this->getAssetsVersion($asset),
@@ -143,18 +141,18 @@ class Assets
143
  );
144
 
145
  // Load admin js files
146
- $asset = 'js/dist/wpstg-legacy-database.min.js';
147
  if ($this->isDebugOrDevMode()) {
148
- $asset = 'js/dist/wpstg-legacy-database.js';
149
  }
150
-
151
  wp_enqueue_script(
152
- "wpstg-legacy-database",
153
  $this->getAssetsUrl($asset),
154
- ["wpstg-admin-script"],
155
  $this->getAssetsVersion($asset),
156
  false
157
  );
 
158
  // Sweet Alert
159
  $asset = 'js/vendor/sweetalert2.all.min.js';
160
  wp_enqueue_script(
@@ -193,6 +191,28 @@ class Assets
193
 
194
  // Load admin js pro files
195
  if (defined('WPSTGPRO_VERSION')) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
196
  $asset = 'js/dist/pro/wpstg-admin-pro.min.js';
197
  if ($this->isDebugOrDevMode()) {
198
  $asset = 'js/dist/pro/wpstg-admin-pro.js';
@@ -201,7 +221,7 @@ class Assets
201
  wp_enqueue_script(
202
  "wpstg-admin-pro-script",
203
  $this->getAssetsUrl($asset),
204
- ["jquery"],
205
  $this->getAssetsVersion($asset),
206
  false
207
  );
@@ -220,9 +240,6 @@ class Assets
220
  $this->getAssetsVersion($asset)
221
  );
222
 
223
- // Add ability to import/export modules to wpstg-admin.js and wpstg-admin-pro.js
224
- add_filter('script_loader_tag', [$this, 'makeScriptsES6'], 10, 3);
225
-
226
  wp_localize_script("wpstg-admin-script", "wpstg", [
227
  "delayReq" => $this->getDelay(),
228
  // TODO: move directorySeparator to consts?
@@ -233,8 +250,10 @@ class Assets
233
  "isMultisite" => is_multisite(),
234
  AccessToken::REQUEST_KEY => (string)$this->accessToken->getToken() ?: (string)$this->accessToken->generateNewToken(),
235
  'nonce' => wp_create_nonce(Nonce::WPSTG_NONCE),
 
236
  'ajaxUrl' => admin_url('admin-ajax.php'),
237
  'wpstgIcon' => $this->getAssetsUrl('img/wpstaging-icon.png'),
 
238
  // TODO: handle i18n translations through Class/Service Provider?
239
  'i18n' => [
240
  'dbConnectionSuccess' => esc_html__('Database Connection - Success', 'wp-staging'),
@@ -242,14 +261,39 @@ class Assets
242
  'somethingWentWrong' => esc_html__('Something went wrong.', 'wp-staging'),
243
  'noImportFileFound' => esc_html__('No import file found.', 'wp-staging'),
244
  'selectFileToImport' => esc_html__('Select file to import.', 'wp-staging'),
245
- 'cloneResetComplete' => esc_html__('Clone Reset Complete!', 'wp-staging'),
246
- 'cloneUpdateComplete' => esc_html__('Clone Update Complete!', 'wp-staging'),
247
  'success' => esc_html__('Success', 'wp-staging'),
248
- 'resetClone' => esc_html__('Reset Clone', 'wp-staging'),
 
 
249
  ],
250
  ]);
251
  }
252
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253
  /**
254
  * Load css and js files only on wp staging admin pages
255
  *
@@ -262,6 +306,7 @@ class Assets
262
  if (defined('WPSTGPRO_VERSION')) {
263
  $availablePages = [
264
  "toplevel_page_wpstg_clone",
 
265
  "wp-staging-pro_page_wpstg-settings",
266
  "wp-staging-pro_page_wpstg-tools",
267
  "wp-staging-pro_page_wpstg-license",
@@ -269,6 +314,7 @@ class Assets
269
  } else {
270
  $availablePages = [
271
  "toplevel_page_wpstg_clone",
 
272
  "wp-staging_page_wpstg-settings",
273
  "wp-staging_page_wpstg-tools",
274
  "wp-staging_page_wpstg-welcome",
@@ -345,20 +391,6 @@ class Assets
345
  return $delay;
346
  }
347
 
348
- /**
349
- * @param string $tag
350
- * @param string $handle
351
- * @param string $source
352
- */
353
- public function makeScriptsES6($tag, $handle, $source)
354
- {
355
- if ($handle === 'wpstg-admin-pro-script' || $handle === 'wpstg-admin-script') {
356
- $tag = '<script src="' . $source . '" type="module"></script>';
357
- }
358
-
359
- return $tag;
360
- }
361
-
362
  /**
363
  * @return string
364
  */
5
  use WPStaging\Core\DTO\Settings;
6
  use WPStaging\Core\WPStaging;
7
  use WPStaging\Framework\Filesystem\Scanning\ScanConst;
 
8
  use WPStaging\Framework\Security\AccessToken;
9
  use WPStaging\Framework\Security\Nonce;
10
+ use WPStaging\Framework\Traits\ResourceTrait;
11
 
12
  class Assets
13
  {
14
+ use ResourceTrait;
15
+
16
  /**
17
  * Default admin bar background color for staging site
18
  * @var string
131
  }
132
 
133
  // Load admin js files
134
+ $asset = 'js/dist/wpstg.js';
 
 
 
 
135
  wp_enqueue_script(
136
+ "wpstg-common",
137
  $this->getAssetsUrl($asset),
138
  ["jquery"],
139
  $this->getAssetsVersion($asset),
141
  );
142
 
143
  // Load admin js files
144
+ $asset = 'js/dist/wpstg-admin.min.js';
145
  if ($this->isDebugOrDevMode()) {
146
+ $asset = 'js/dist/wpstg-admin.js';
147
  }
 
148
  wp_enqueue_script(
149
+ "wpstg-admin-script",
150
  $this->getAssetsUrl($asset),
151
+ ["wpstg-common", "wpstg-admin-notyf", "wpstg-admin-sweetalerts"],
152
  $this->getAssetsVersion($asset),
153
  false
154
  );
155
+
156
  // Sweet Alert
157
  $asset = 'js/vendor/sweetalert2.all.min.js';
158
  wp_enqueue_script(
191
 
192
  // Load admin js pro files
193
  if (defined('WPSTGPRO_VERSION')) {
194
+ $asset = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? 'js/vendor/resumable.js' : 'js/vendor/resumable.min.js';
195
+ wp_enqueue_script(
196
+ "wpstg-resumable",
197
+ $this->getAssetsUrl($asset),
198
+ ["wpstg-common"],
199
+ $this->getAssetsVersion($asset),
200
+ false
201
+ );
202
+
203
+ $asset = 'js/dist/pro/wpstg-backup.min.js';
204
+ if ($this->isDebugOrDevMode()) {
205
+ $asset = 'js/dist/pro/wpstg-backup.js';
206
+ }
207
+
208
+ wp_enqueue_script(
209
+ "wpstg-backup",
210
+ $this->getAssetsUrl($asset),
211
+ ["wpstg-resumable"],
212
+ $this->getAssetsVersion($asset),
213
+ false
214
+ );
215
+
216
  $asset = 'js/dist/pro/wpstg-admin-pro.min.js';
217
  if ($this->isDebugOrDevMode()) {
218
  $asset = 'js/dist/pro/wpstg-admin-pro.js';
221
  wp_enqueue_script(
222
  "wpstg-admin-pro-script",
223
  $this->getAssetsUrl($asset),
224
+ ["jquery", "wpstg-admin-notyf", "wpstg-admin-sweetalerts"],
225
  $this->getAssetsVersion($asset),
226
  false
227
  );
240
  $this->getAssetsVersion($asset)
241
  );
242
 
 
 
 
243
  wp_localize_script("wpstg-admin-script", "wpstg", [
244
  "delayReq" => $this->getDelay(),
245
  // TODO: move directorySeparator to consts?
250
  "isMultisite" => is_multisite(),
251
  AccessToken::REQUEST_KEY => (string)$this->accessToken->getToken() ?: (string)$this->accessToken->generateNewToken(),
252
  'nonce' => wp_create_nonce(Nonce::WPSTG_NONCE),
253
+ 'assetsUrl' => $this->getAssetsUrl(),
254
  'ajaxUrl' => admin_url('admin-ajax.php'),
255
  'wpstgIcon' => $this->getAssetsUrl('img/wpstaging-icon.png'),
256
+ 'maxUploadChunkSize' => $this->getMaxUploadChunkSize(),
257
  // TODO: handle i18n translations through Class/Service Provider?
258
  'i18n' => [
259
  'dbConnectionSuccess' => esc_html__('Database Connection - Success', 'wp-staging'),
261
  'somethingWentWrong' => esc_html__('Something went wrong.', 'wp-staging'),
262
  'noImportFileFound' => esc_html__('No import file found.', 'wp-staging'),
263
  'selectFileToImport' => esc_html__('Select file to import.', 'wp-staging'),
264
+ 'cloneResetComplete' => esc_html__('Reset Complete!', 'wp-staging'),
265
+ 'cloneUpdateComplete' => esc_html__('Update Complete!', 'wp-staging'),
266
  'success' => esc_html__('Success', 'wp-staging'),
267
+ 'resetClone' => esc_html__('Reset Staging Site', 'wp-staging'),
268
+ 'showLogs' => esc_html__('Show Logs', 'wp-staging'),
269
+ 'hideLogs' => esc_html__('Hide Logs', 'wp-staging'),
270
  ],
271
  ]);
272
  }
273
 
274
+ /**
275
+ * @return int The max upload size for a file.
276
+ */
277
+ protected function getMaxUploadChunkSize()
278
+ {
279
+ $lowerLimit = 64 * KB_IN_BYTES;
280
+ $upperLimit = 16 * MB_IN_BYTES;
281
+
282
+ $maxPostSize = wp_convert_hr_to_bytes(ini_get('post_max_size'));
283
+ $uploadMaxFileSize = wp_convert_hr_to_bytes(ini_get('upload_max_filesize'));
284
+
285
+ // The real limit, read from the PHP context.
286
+ $limit = min($maxPostSize, $uploadMaxFileSize) * 0.90;
287
+
288
+ // Do not allow to go over upper limit.
289
+ $limit = min($limit, $upperLimit);
290
+
291
+ // Do not allow to go under lower limit.
292
+ $limit = max($lowerLimit, $limit);
293
+
294
+ return (int)$limit;
295
+ }
296
+
297
  /**
298
  * Load css and js files only on wp staging admin pages
299
  *
306
  if (defined('WPSTGPRO_VERSION')) {
307
  $availablePages = [
308
  "toplevel_page_wpstg_clone",
309
+ "wp-staging-pro_page_wpstg_backup",
310
  "wp-staging-pro_page_wpstg-settings",
311
  "wp-staging-pro_page_wpstg-tools",
312
  "wp-staging-pro_page_wpstg-license",
314
  } else {
315
  $availablePages = [
316
  "toplevel_page_wpstg_clone",
317
+ "wp-staging_page_wpstg_backup",
318
  "wp-staging_page_wpstg-settings",
319
  "wp-staging_page_wpstg-tools",
320
  "wp-staging_page_wpstg-welcome",
391
  return $delay;
392
  }
393
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
394
  /**
395
  * @return string
396
  */
Framework/BackgroundProcessing/FeatureDetection.php CHANGED
@@ -9,6 +9,7 @@
9
  namespace WPStaging\Framework\BackgroundProcessing;
10
 
11
  use WP_Error;
 
12
 
13
  /**
14
  * Class FeatureDetection
@@ -39,7 +40,8 @@ class FeatureDetection
39
  {
40
  if ($this->isAjaxAvailableCache === null) {
41
  // Run this check only on Admin UI and on PHP initial state.
42
- $notRightContext = wp_installing() || (defined('REST_REQUEST') && REST_REQUEST) || wp_doing_ajax()
 
43
  || wp_doing_cron() || !is_admin();
44
 
45
  if ($notRightContext) {
9
  namespace WPStaging\Framework\BackgroundProcessing;
10
 
11
  use WP_Error;
12
+ use WPStaging\Framework\Adapter\WpAdapter;
13
 
14
  /**
15
  * Class FeatureDetection
40
  {
41
  if ($this->isAjaxAvailableCache === null) {
42
  // Run this check only on Admin UI and on PHP initial state.
43
+ // TODO: inject WpAdapter using DI
44
+ $notRightContext = wp_installing() || (defined('REST_REQUEST') && REST_REQUEST) || (new WpAdapter())->doingAjax()
45
  || wp_doing_cron() || !is_admin();
46
 
47
  if ($notRightContext) {
Framework/CloningProcess/Database/CompareExternalDatabase.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WPStaging\Framework\CloningProcess\Database;
4
+
5
+ use WPStaging\Framework\Database\DbInfo;
6
+ use WPStaging\Framework\Database\WpDbInfo;
7
+ use WPStaging\Core\WPStaging;
8
+
9
+ class CompareExternalDatabase
10
+ {
11
+ /*
12
+ * @var \WPStaging\Framework\Database\DbInfo
13
+ */
14
+ protected $stagingDbInfo;
15
+
16
+ /*
17
+ * @var \WPStaging\Framework\Database\DbInfo
18
+ */
19
+ protected $productionDbInfo;
20
+
21
+ /*
22
+ * @var bool
23
+ */
24
+ protected $isProductionDbConnected;
25
+
26
+ /*
27
+ * @param string $hostServer
28
+ * @param string $user
29
+ * @param string $password
30
+ * @param string $database
31
+ */
32
+ public function __construct($hostServer, $user, $password, $database)
33
+ {
34
+ $this->stagingDbInfo = new DbInfo($hostServer, $user, $password, $database);
35
+ $this->productionDbInfo = new WpDbInfo(WPStaging::getInstance()->get("wpdb"));
36
+ }
37
+
38
+ /*
39
+ * @return array
40
+ */
41
+ public function maybeGetComparison()
42
+ {
43
+ $stagingDbError = $this->stagingDbInfo->getError();
44
+ if ($stagingDbError !== null) {
45
+ return [
46
+ "success" => false,
47
+ 'error_type' => 'connection',
48
+ "message" => $stagingDbError
49
+ ];
50
+ }
51
+
52
+ // DB properties are equal. Do nothing
53
+ if ($this->productionDbInfo->toArray() === $this->stagingDbInfo->toArray()) {
54
+ return [
55
+ "success" => true
56
+ ];
57
+ }
58
+
59
+ // DB Properties are different. Get comparison table
60
+ return [
61
+ "success" => false,
62
+ 'error_type' => 'comparison',
63
+ "checks" => [
64
+ [
65
+ "name" => __('DB Collation'),
66
+ "production" => $this->productionDbInfo->getDbCollation(),
67
+ "staging" => $this->stagingDbInfo->getDbCollation(),
68
+ ],
69
+ [
70
+ "name" => __('DB Storage Engine'),
71
+ "production" => $this->productionDbInfo->getDbEngine(),
72
+ "staging" => $this->stagingDbInfo->getDbEngine(),
73
+ ],
74
+ [
75
+ "name" => __('MySQL Server Version'),
76
+ "production" => $this->productionDbInfo->getMySqlServerVersion(),
77
+ "staging" => $this->stagingDbInfo->getMySqlServerVersion(),
78
+ ]
79
+ ]
80
+ ];
81
+ }
82
+ }
Framework/CloningProcess/Database/DatabaseCloningService.php CHANGED
@@ -3,8 +3,9 @@
3
  namespace WPStaging\Framework\CloningProcess\Database;
4
 
5
  use WPStaging\Backend\Modules\Jobs\Exceptions\FatalException;
6
- use WPStaging\Framework\CloningProcess\CloningDto;
7
  use WPStaging\Core\Utils\Logger;
 
 
8
  use WPStaging\Framework\Utils\Strings;
9
 
10
  class DatabaseCloningService
@@ -84,7 +85,9 @@ class DatabaseCloningService
84
  }
85
 
86
  /**
87
- * @param $tableName
 
 
88
  */
89
  public function tableIsMissing($tableName)
90
  {
@@ -93,6 +96,7 @@ class DatabaseCloningService
93
  $this->log("Table {$this->dto->getExternalDatabaseName()}.{$tableName} doesn't exist. Skipping");
94
  return true;
95
  }
 
96
  return false;
97
  }
98
 
@@ -144,7 +148,7 @@ class DatabaseCloningService
144
  */
145
  public function removeDBPrefix($tableName)
146
  {
147
- return (new Strings())->str_replace_first($this->dto->getProductionDb()->prefix, null, $tableName);
148
  }
149
 
150
  /**
@@ -153,7 +157,7 @@ class DatabaseCloningService
153
  */
154
  public function removeDBBasePrefix($tableName)
155
  {
156
- return (new Strings())->str_replace_first($this->dto->getProductionDb()->base_prefix, null, $tableName);
157
  }
158
 
159
  /**
@@ -200,7 +204,7 @@ class DatabaseCloningService
200
  * Get MySQL create-table query statement.
201
  * Only used by external databases
202
  *
203
- * @param string $table_name Table name
204
  * @return array
205
  */
206
  private function getTableCreateStatement($tableName)
3
  namespace WPStaging\Framework\CloningProcess\Database;
4
 
5
  use WPStaging\Backend\Modules\Jobs\Exceptions\FatalException;
 
6
  use WPStaging\Core\Utils\Logger;
7
+ use WPStaging\Core\WPStaging;
8
+ use WPStaging\Framework\CloningProcess\CloningDto;
9
  use WPStaging\Framework\Utils\Strings;
10
 
11
  class DatabaseCloningService
85
  }
86
 
87
  /**
88
+ * @param string $tableName
89
+ *
90
+ * @return boolean
91
  */
92
  public function tableIsMissing($tableName)
93
  {
96
  $this->log("Table {$this->dto->getExternalDatabaseName()}.{$tableName} doesn't exist. Skipping");
97
  return true;
98
  }
99
+
100
  return false;
101
  }
102
 
148
  */
149
  public function removeDBPrefix($tableName)
150
  {
151
+ return (new Strings())->str_replace_first(WPStaging::getTablePrefix(), null, $tableName);
152
  }
153
 
154
  /**
157
  */
158
  public function removeDBBasePrefix($tableName)
159
  {
160
+ return (new Strings())->str_replace_first(WPStaging::getTableBasePrefix(), null, $tableName);
161
  }
162
 
163
  /**
204
  * Get MySQL create-table query statement.
205
  * Only used by external databases
206
  *
207
+ * @param string $tableName Table name
208
  * @return array
209
  */
210
  private function getTableCreateStatement($tableName)
Framework/CloningProcess/SearchReplace/SearchReplaceService.php DELETED
@@ -1,45 +0,0 @@
1
- <?php
2
-
3
- namespace WPStaging\Framework\CloningProcess\SearchReplace;
4
-
5
- class SearchReplaceService
6
- {
7
- private $excludedStrings = [
8
- 'Admin_custome_login_Slidshow',
9
- 'Admin_custome_login_Social',
10
- 'Admin_custome_login_logo',
11
- 'Admin_custome_login_text',
12
- 'Admin_custome_login_login',
13
- 'Admin_custome_login_top',
14
- 'Admin_custome_login_dashboard',
15
- 'Admin_custome_login_Version',
16
- 'upload_path',
17
- 'wpstg_existing_clones_beta',
18
- 'wpstg_existing_clones',
19
- 'wpstg_settings',
20
- 'wpstg_license_status',
21
- 'wpstg_tmp_data',
22
- 'siteurl',
23
- 'home'
24
- ];
25
-
26
- public function excludedStrings()
27
- {
28
- return $this->excludedStrings;
29
- }
30
-
31
- /**
32
- * Prepend the following characters to string: %2F%2F, \/\/, //
33
- * This is to make sure that only valid hostnames are replaced
34
- * @param $string
35
- * @return string[]
36
- */
37
- public function generateHostnamePatterns($string)
38
- {
39
- return [
40
- '%2F%2F' . str_replace('/', '%2F', $string), // HTML entity for WP Backery Page Builder Plugin
41
- '\/\/' . str_replace('/', '\/', $string), // Escaped \/ used by revslider and several visual editors
42
- '//' . $string // //example.com
43
- ];
44
- }
45
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Framework/CommonServiceProvider.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WPStaging\Framework;
4
+
5
+ use WPStaging\Framework\DI\ServiceProvider;
6
+ use WPStaging\Framework\Filesystem\DiskWriteCheck;
7
+
8
+ /**
9
+ * Class CommonServiceProvider
10
+ *
11
+ * A Service Provider for binds common to both Free and Pro.
12
+ *
13
+ * @package WPStaging\Framework
14
+ */
15
+ class CommonServiceProvider extends ServiceProvider
16
+ {
17
+ protected function registerClasses()
18
+ {
19
+ $this->container->singleton(DiskWriteCheck::class);
20
+ }
21
+ }
Framework/Component/AbstractTemplateComponent.php CHANGED
@@ -5,6 +5,7 @@
5
 
6
  namespace WPStaging\Framework\Component;
7
 
 
8
  use WPStaging\Framework\Security\AccessToken;
9
  use WPStaging\Framework\Security\Capabilities;
10
  use WPStaging\Framework\Security\Nonce;
@@ -17,6 +18,7 @@ abstract class AbstractTemplateComponent
17
 
18
  private $accessToken;
19
  private $nonce;
 
20
 
21
  public function __construct(TemplateEngine $templateEngine)
22
  {
@@ -25,6 +27,7 @@ abstract class AbstractTemplateComponent
25
  // Todo: Inject using DI
26
  $this->accessToken = new AccessToken();
27
  $this->nonce = new Nonce();
 
28
  }
29
 
30
  /**
@@ -43,7 +46,7 @@ abstract class AbstractTemplateComponent
43
  */
44
  protected function canRenderAjax()
45
  {
46
- $isAjax = wp_doing_ajax();
47
  $hasToken = $this->accessToken->requestHasValidToken();
48
  $isAuthenticated = current_user_can((new Capabilities())->manageWPSTG()) && $this->nonce->requestHasValidNonce(Nonce::WPSTG_NONCE);
49
 
5
 
6
  namespace WPStaging\Framework\Component;
7
 
8
+ use WPStaging\Framework\Adapter\WpAdapter;
9
  use WPStaging\Framework\Security\AccessToken;
10
  use WPStaging\Framework\Security\Capabilities;
11
  use WPStaging\Framework\Security\Nonce;
18
 
19
  private $accessToken;
20
  private $nonce;
21
+ private $wpAdapter;
22
 
23
  public function __construct(TemplateEngine $templateEngine)
24
  {
27
  // Todo: Inject using DI
28
  $this->accessToken = new AccessToken();
29
  $this->nonce = new Nonce();
30
+ $this->wpAdapter = new WpAdapter();
31
  }
32
 
33
  /**
46
  */
47
  protected function canRenderAjax()
48
  {
49
+ $isAjax = $this->wpAdapter->doingAjax();
50
  $hasToken = $this->accessToken->requestHasValidToken();
51
  $isAuthenticated = current_user_can((new Capabilities())->manageWPSTG()) && $this->nonce->requestHasValidNonce(Nonce::WPSTG_NONCE);
52
 
Framework/Database/LegacyDatabaseInfo.php DELETED
@@ -1,24 +0,0 @@
1
- <?php
2
-
3
- namespace WPStaging\Framework\Database;
4
-
5
- class LegacyDatabaseInfo
6
- {
7
- const PREFIX_AUTOMATIC = 'wpsa';
8
- const PREFIX_MANUAL = 'wpsm';
9
- const PREFIX_TMP = 'wpstgtmp';
10
-
11
- /**
12
- * Returns whether a prefixed table name matches the name used for backup tables or not.
13
- *
14
- * @param string $prefixedTableName The prefixed table name.
15
- *
16
- * @return bool Whether a prefixed table name matches the name used for backup tables or not.
17
- */
18
- public static function isBackupTable($prefixedTableName)
19
- {
20
- $pattern = '#^(' . static::PREFIX_AUTOMATIC . '|' . static::PREFIX_MANUAL . ')\\d+_#';
21
-
22
- return (bool)preg_match($pattern, $prefixedTableName);
23
- }
24
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Framework/Database/SearchReplace.php CHANGED
@@ -24,6 +24,8 @@ class SearchReplace
24
  /** @var string */
25
  private $currentReplace;
26
 
 
 
27
  public function __construct(array $search = [], array $replace = [], $caseSensitive = true, array $exclude = [])
28
  {
29
  $this->search = $search;
@@ -32,6 +34,21 @@ class SearchReplace
32
  $this->exclude = $exclude;
33
  }
34
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  /**
36
  * @param array|object|string $data
37
  * @return array|object|string
@@ -166,9 +183,6 @@ class SearchReplace
166
 
167
  private function strReplace($data)
168
  {
169
- // TODO: This filter doesn't really belong in a universally-used class, but usages of the class may need to be checked on whether they need to apply it
170
- // $excludes = apply_filters('wpstg_clone_searchreplace_excl', []);
171
-
172
  $regexExclude = '';
173
  foreach ($this->exclude as $excludeString) {
174
  //TODO: I changed (FAIL) to (*FAIL) because that's what tutorials say is the right syntax. This may need testing
24
  /** @var string */
25
  private $currentReplace;
26
 
27
+ protected $smallerReplacement = PHP_INT_MAX;
28
+
29
  public function __construct(array $search = [], array $replace = [], $caseSensitive = true, array $exclude = [])
30
  {
31
  $this->search = $search;
34
  $this->exclude = $exclude;
35
  }
36
 
37
+ public function getSmallerSearchLength()
38
+ {
39
+ if ($this->smallerReplacement < PHP_INT_MAX) {
40
+ return $this->smallerReplacement;
41
+ }
42
+
43
+ foreach ($this->search as $search) {
44
+ if (strlen($search) < $this->smallerReplacement) {
45
+ $this->smallerReplacement = strlen($search);
46
+ }
47
+ }
48
+
49
+ return $this->smallerReplacement;
50
+ }
51
+
52
  /**
53
  * @param array|object|string $data
54
  * @return array|object|string
183
 
184
  private function strReplace($data)
185
  {
 
 
 
186
  $regexExclude = '';
187
  foreach ($this->exclude as $excludeString) {
188
  //TODO: I changed (FAIL) to (*FAIL) because that's what tutorials say is the right syntax. This may need testing
Framework/Database/TableService.php CHANGED
@@ -64,7 +64,7 @@ class TableService
64
  public function findTableStatusStartsWith($prefix = null)
65
  {
66
  // eg: SHOW TABLE STATUS LIKE 'wp\_%';
67
- $tables = $this->database->find("SHOW TABLE STATUS LIKE '{$this->provideSqlPrefix($prefix)}%'");
68
  if (!$tables) {
69
  return null;
70
  }
@@ -117,12 +117,15 @@ class TableService
117
  return $tables;
118
  }
119
 
120
- return $this->getFilteredResult($tables, $prefix);
121
  }
122
 
123
 
124
  /**
125
  * Get all table views starting with a certain prefix
 
 
 
126
  * @return array|null
127
  */
128
  public function findViewsNamesStartWith($prefix = null)
@@ -145,18 +148,30 @@ class TableService
145
  return $views;
146
  }
147
 
148
- return $this->getFilteredResult($views, $prefix);
149
  }
150
 
151
  /**
152
  * Delete all the tables or views that starts with $startsWith
153
- * @param string $startsWith
154
- * @param array $excludedTables
 
 
155
  * @return bool
156
  */
157
- public function deleteTablesStartWith($startsWith = null, $excludedTables = [])
158
  {
159
- $prefix = $this->provideSqlPrefix($startsWith);
 
 
 
 
 
 
 
 
 
 
160
  $tables = $this->findTableStatusStartsWith($prefix);
161
  if ($tables === null) {
162
  return true;
@@ -190,18 +205,36 @@ class TableService
190
  // TODO: inject class Strings using DI
191
  if (!$this->database->isExternal() && (new Strings())->startsWith($table, $this->database->getProductionPrefix())) {
192
  $this->errors[] = sprintf(__("Fatal Error: Trying to delete table %s of main WP installation!", 'wp-staging'), $table);
 
193
  return false;
194
  }
195
 
196
- $this->database->getWpdba()->exec("DROP TABLE {$table}");
 
197
 
198
- if (!is_callable($this->shouldStop)) {
199
- continue;
200
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
201
 
202
- if (call_user_func($this->shouldStop)) {
203
  return false;
204
  }
 
 
205
  }
206
 
207
  return true;
@@ -209,19 +242,22 @@ class TableService
209
 
210
  /**
211
  * Get all elements starting with a specific string from an array
212
- * @param array $data
 
213
  * @param string $startsWith
 
214
  * @return array
215
  */
216
- private function getFilteredResult($data, $startsWith)
217
  {
218
- $result = [];
219
- foreach ($data as $value) {
220
- if (strpos($value, $startsWith) === 0) {
221
- $result[] = $value;
222
- }
223
- }
224
- return $result;
 
225
  }
226
 
227
  /**
@@ -231,13 +267,4 @@ class TableService
231
  {
232
  return $this->database;
233
  }
234
-
235
- /**
236
- * @param string|null $prefix
237
- * @return string
238
- */
239
- private function provideSqlPrefix($prefix = null)
240
- {
241
- return $this->database->provideSqlPrefix($prefix);
242
- }
243
  }
64
  public function findTableStatusStartsWith($prefix = null)
65
  {
66
  // eg: SHOW TABLE STATUS LIKE 'wp\_%';
67
+ $tables = $this->database->find("SHOW TABLE STATUS LIKE '{$this->database->escapeSqlPrefixForLIKE($prefix)}%'");
68
  if (!$tables) {
69
  return null;
70
  }
117
  return $tables;
118
  }
119
 
120
+ return $this->filterByPrefix($tables, $prefix);
121
  }
122
 
123
 
124
  /**
125
  * Get all table views starting with a certain prefix
126
+ *
127
+ * @param string|null $prefix
128
+ *
129
  * @return array|null
130
  */
131
  public function findViewsNamesStartWith($prefix = null)
148
  return $views;
149
  }
150
 
151
+ return $this->filterByPrefix($views, $prefix);
152
  }
153
 
154
  /**
155
  * Delete all the tables or views that starts with $startsWith
156
+ *
157
+ * @param string $prefix
158
+ * @param array $excludedTables
159
+ *
160
  * @return bool
161
  */
162
+ public function deleteTablesStartWith($prefix, $excludedTables = [], $deleteViews = false)
163
  {
164
+ if ($deleteViews) {
165
+ // Delete VIEWS first
166
+ $views = $this->findViewsNamesStartWith($prefix);
167
+ if (is_array($views) && !empty($views)) {
168
+ $viewsToRemove = array_diff($views, $excludedTables);
169
+ if (!$this->deleteViews($viewsToRemove)) {
170
+ return false;
171
+ }
172
+ }
173
+ }
174
+
175
  $tables = $this->findTableStatusStartsWith($prefix);
176
  if ($tables === null) {
177
  return true;
205
  // TODO: inject class Strings using DI
206
  if (!$this->database->isExternal() && (new Strings())->startsWith($table, $this->database->getProductionPrefix())) {
207
  $this->errors[] = sprintf(__("Fatal Error: Trying to delete table %s of main WP installation!", 'wp-staging'), $table);
208
+
209
  return false;
210
  }
211
 
212
+ $this->database->getWpdba()->exec("DROP TABLE {$table};");
213
+ }
214
 
215
+ return true;
216
+ }
217
+
218
+ /**
219
+ * Delete Views
220
+ *
221
+ * @param array $views
222
+ * @param string $prefix
223
+ *
224
+ * @return bool
225
+ */
226
+ public function deleteViews($views)
227
+ {
228
+ foreach ($views as $view) {
229
+ // PROTECTION: Never delete any table that beginns with wp prefix of live site
230
+ // TODO: inject class Strings using DI
231
+ if (!$this->database->isExternal() && (new Strings())->startsWith($view, $this->database->getProductionPrefix())) {
232
+ $this->errors[] = sprintf(__("Fatal Error: Trying to delete view %s of main WP installation!", 'wp-staging'), $view);
233
 
 
234
  return false;
235
  }
236
+
237
+ $this->database->getWpdba()->exec("DROP VIEW {$view};");
238
  }
239
 
240
  return true;
242
 
243
  /**
244
  * Get all elements starting with a specific string from an array
245
+ *
246
+ * @param array $data
247
  * @param string $startsWith
248
+ *
249
  * @return array
250
  */
251
+ private function filterByPrefix($tablesOrViews, $prefix)
252
  {
253
+ $filteredArray = array_filter($tablesOrViews, function ($tableOrView) use ($prefix) {
254
+ return strpos($tableOrView, $prefix) === 0;
255
+ });
256
+
257
+ // Re-orders the array eliminating the "key" gaps for filtered out values.
258
+ $reorderedArray = array_values($filteredArray);
259
+
260
+ return $reorderedArray;
261
  }
262
 
263
  /**
267
  {
268
  return $this->database;
269
  }
 
 
 
 
 
 
 
 
 
270
  }
Framework/Exceptions/WPStagingException.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WPStaging\Framework\Exceptions;
4
+
5
+ use Exception;
6
+
7
+ class WPStagingException extends Exception
8
+ {
9
+
10
+ }
Framework/Filesystem/DirectoryScanner.php DELETED
@@ -1,57 +0,0 @@
1
- <?php
2
-
3
- // TODO PHP7.x; declare(strict_types=1);
4
- // TODO PHP7.x; return types && type-hints
5
-
6
- namespace WPStaging\Framework\Filesystem;
7
-
8
- use WPStaging\Vendor\Psr\Log\LoggerInterface;
9
-
10
- class DirectoryScanner
11
- {
12
- private $logger;
13
-
14
- public function __construct(LoggerInterface $logger)
15
- {
16
- $this->logger = $logger;
17
- }
18
-
19
- /**
20
- * @param string $directory
21
- * @param array $excludedDirectories
22
- *
23
- * @return array
24
- */
25
- public function scan($directory, array $excludedDirectories = [])
26
- {
27
- try {
28
- $it = new \DirectoryIterator($directory);
29
- } catch (\Exception $e) {
30
- return [];
31
- }
32
-
33
- $excludedDirectories = array_map(function ($item) {
34
- return trailingslashit($item);
35
- }, $excludedDirectories);
36
-
37
- $dirs = [];
38
-
39
- /** @var \SplFileInfo $item */
40
- foreach ($it as $item) {
41
- if ($item->isDir() && $item->getFilename() != "." && $item->getFilename() != "..") {
42
- if (in_array(trailingslashit($item->getRealPath()), $excludedDirectories)) {
43
- // Early bail: Directory is ignored
44
- $this->logger->info(sprintf(
45
- __('%s: Ignored directory "%s" because it\'s in the ignored directories list.', 'wp-staging'),
46
- __('Directory Scanner', 'wp-staging'),
47
- $item->getRealPath()
48
- ));
49
- continue;
50
- }
51
- $dirs[] = $item->getRealPath();
52
- }
53
- }
54
-
55
- return $dirs;
56
- }
57
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Framework/Filesystem/DirectoryScannerControl.php DELETED
@@ -1,147 +0,0 @@
1
- <?php
2
-
3
- // TODO PHP7.x; declare(strict_type=1);
4
- // TODO PHP7.x; type hints & return types
5
- // TODO PHP7.1; constant visibility
6
-
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;
14
- use WPStaging\Framework\Queue\Queue;
15
- use WPStaging\Framework\Queue\Storage\BufferedCacheStorage;
16
- use WPStaging\Framework\Utils\Cache\BufferedCache;
17
-
18
- /**
19
- * Class DirectoryScannerControl
20
- *
21
- * @see DirectoryScannerTask
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';
29
-
30
- /** @var BufferedCache */
31
- private $cache;
32
-
33
- /** @var BufferedCacheStorage */
34
- private $storage;
35
-
36
- /** @var DirectoryScanner */
37
- private $scanner;
38
-
39
- /** @var Queue|null */
40
- private $queue;
41
-
42
- /** @var array */
43
- private $newQueueItems;
44
-
45
- /** @var Directory */
46
- private $directory;
47
-
48
- public function __construct(BufferedCache $cache, BufferedCacheStorage $storage, DirectoryScanner $scanner, Directory $directory)
49
- {
50
- $this->newQueueItems = [];
51
- $this->cache = clone $cache;
52
- $this->storage = clone $storage;
53
- $this->scanner = $scanner;
54
- $this->directory = $directory;
55
- }
56
-
57
- public function onWpShutdown()
58
- {
59
- if ($this->newQueueItems && $this->queue) {
60
- $this->queue->pushAsArray($this->newQueueItems);
61
- }
62
- }
63
-
64
- /**
65
- * @param string $name
66
- */
67
- public function setQueueByName($name = self::QUEUE_CACHE_FILE)
68
- {
69
- $this->queue = new Queue();
70
- $this->queue->setName($name);
71
- $this->queue->setStorage($this->storage);
72
- }
73
-
74
- /**
75
- * @param array $excluded
76
- *
77
- * @return array
78
- */
79
- public function scanCurrentPath(array $excluded = [])
80
- {
81
- $path = $this->getPathFromQueue();
82
- if ($path === null) {
83
- throw new FinishedQueueException('Directory Scanner Queue is Finished');
84
- }
85
-
86
- $path = ABSPATH . $path;
87
-
88
- return $this->scanner->scan($path, $excluded);
89
- }
90
-
91
- /**
92
- * @return string|null
93
- */
94
- public function getPathFromQueue()
95
- {
96
- if ($this->queue->count() > 0) {
97
- return $this->queue->pop();
98
- }
99
-
100
- if ($this->newQueueItems) {
101
- return array_shift($this->newQueueItems);
102
- }
103
-
104
- return null;
105
- }
106
-
107
- /**
108
- * @param string $item
109
- */
110
- public function addToNewQueue($item)
111
- {
112
- $this->newQueueItems[] = $item;
113
- }
114
-
115
- /**
116
- * @return BufferedCache
117
- */
118
- public function getCache()
119
- {
120
- return $this->cache;
121
- }
122
-
123
- /**
124
- * @return Queue
125
- */
126
- public function getQueue()
127
- {
128
- if (!$this->queue) {
129
- // TODO Custom Exception
130
- throw new RuntimeException('DirectoryScannerControl Queue is not set');
131
- }
132
- return $this->queue;
133
- }
134
-
135
- public function setNewQueueItems(array $items = null)
136
- {
137
- $this->newQueueItems = $items;
138
- }
139
-
140
- /**
141
- * @return Directory
142
- */
143
- public function getDirectory()
144
- {
145
- return $this->directory;
146
- }
147
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Framework/Filesystem/DiskFullException.php DELETED
@@ -1,16 +0,0 @@
1
- <?php
2
-
3
- // TODO PHP7.x; declare(strict_types=1);
4
- // TODO PHP7.x; return types && type-hints
5
-
6
- namespace WPStaging\Framework\Filesystem;
7
-
8
- use RuntimeException;
9
-
10
- class DiskFullException extends RuntimeException
11
- {
12
- public function __construct($message = 'Failed to write to disk. Disk probably is full')
13
- {
14
- parent::__construct($message);
15
- }
16
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Framework/Filesystem/DiskWriteCheck.php ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WPStaging\Framework\Filesystem;
4
+
5
+ use WPStaging\Framework\Adapter\Directory;
6
+ use WPStaging\Pro\Backup\Exceptions\DiskNotWritableException;
7
+
8
+ class DiskWriteCheck
9
+ {
10
+ protected $directory;
11
+ protected $filesystem;
12
+ protected $reservedMemory;
13
+
14
+ const OPTION_DISK_WRITABLE_FAILED = 'wpstg_disk_writable_check_failed';
15
+
16
+ public function __construct(Filesystem $filesystem, Directory $directory)
17
+ {
18
+ $this->directory = $directory;
19
+ $this->filesystem = $filesystem;
20
+ // 1kb
21
+ $this->reservedMemory = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
22
+ }
23
+
24
+ /**
25
+ * @param string $path An absolute path to check for free disk space.
26
+ * @param int|float $bytesToStore The number of bytes intended to be written.
27
+ *
28
+ * @throws \RuntimeException When something happened that prevented us from checking if there's enough free disk space.
29
+ * @throws DiskNotWritableException When disk_free_space reports there's not enough disk space to store this amount of bytes.
30
+ */
31
+ public function checkPathCanStoreEnoughBytes($path, $bytesToStore)
32
+ {
33
+ // Early bail: Disabled by filter
34
+ if (apply_filters('wpstg.filesystem.disableDiskFreeSpaceCheck', false)) {
35
+ throw new \RuntimeException();
36
+ }
37
+
38
+ // Early bail: disk_free_space might have been disabled using php.ini "disable_functions"
39
+ if (!function_exists('disk_free_space')) {
40
+ throw new \RuntimeException('The disk_free_space function is not available.');
41
+ }
42
+
43
+ $path = untrailingslashit($path);
44
+
45
+ clearstatcache();
46
+ if (!file_exists($path)) {
47
+ throw new \RuntimeException('The given path does not exist.');
48
+ }
49
+
50
+ if (is_link($path)) {
51
+ throw new \RuntimeException('The given path must be a directory.');
52
+ }
53
+
54
+ if (!is_dir($path)) {
55
+ throw new \RuntimeException('The path must be a directory.');
56
+ }
57
+
58
+ set_error_handler(function () {
59
+ throw new \RuntimeException();
60
+ });
61
+ $freeSpaceInBytes = @disk_free_space($path);
62
+ restore_error_handler();
63
+
64
+ if ($freeSpaceInBytes === false) {
65
+ throw new \RuntimeException(error_get_last());
66
+ }
67
+
68
+ if (!is_numeric($freeSpaceInBytes)) {
69
+ throw new \RuntimeException('disk_free_space returned an unexpected result');
70
+ }
71
+
72
+ $freeSpaceInBytes = (int)$freeSpaceInBytes;
73
+
74
+ if ($freeSpaceInBytes - $bytesToStore < 0) {
75
+ throw DiskNotWritableException::willExceedFreeDiskSpace(abs($freeSpaceInBytes - $bytesToStore));
76
+ }
77
+ }
78
+
79
+ /**
80
+ * @throws DiskNotWritableException If a previous disk write test has failed.
81
+ */
82
+ public function hasDiskWriteTestFailed()
83
+ {
84
+ if (get_option(self::OPTION_DISK_WRITABLE_FAILED) === 'fail') {
85
+ throw DiskNotWritableException::diskNotWritable();
86
+ }
87
+ }
88
+
89
+ public function testDiskIsWriteable()
90
+ {
91
+ $destination = $this->directory->getPluginUploadsDirectory() . '.wpstgDiskWriteCheck';
92
+
93
+ if (file_exists($destination)) {
94
+ unlink($destination);
95
+ }
96
+
97
+ // Early bail: Disk writeable check pass
98
+ if (@file_put_contents($destination, $this->reservedMemory)) {
99
+ unlink($destination);
100
+
101
+ delete_option(self::OPTION_DISK_WRITABLE_FAILED);
102
+
103
+ return true;
104
+ }
105
+
106
+ // First try, this might fail as the disk is full.
107
+ $result = $this->setLowLevelDiskFullFlag();
108
+
109
+ $this->filesystem->delete($this->directory->getCacheDirectory());
110
+
111
+ // Second try, this might succeed if the first failed as we freed up a few kb of data.
112
+ if (!$result) {
113
+ $result = $this->setLowLevelDiskFullFlag();
114
+ }
115
+
116
+ $this->filesystem->delete($this->directory->getTmpDirectory());
117
+
118
+ // Third try, this should succeed if the second failed, but it's the tmp directory can be very big and the request might timeout before getting here.
119
+ if (!$result) {
120
+ $result = $this->setLowLevelDiskFullFlag();
121
+
122
+ if (!$result) {
123
+ error_log('WPSTGAGING DiskWriteCheck failed and could not update the option in the database.');
124
+ }
125
+ }
126
+
127
+ throw DiskNotWritableException::diskNotWritable();
128
+ }
129
+
130
+ protected function setLowLevelDiskFullFlag()
131
+ {
132
+ global $wpdb;
133
+
134
+ return $wpdb->query($wpdb->prepare("INSERT INTO `$wpdb->options` (`option_name`, `option_value`, `autoload`) VALUES (%s, %s, %s) ON DUPLICATE KEY UPDATE `option_name` = VALUES(`option_name`), `option_value` = VALUES(`option_value`), `autoload` = VALUES(`autoload`)", self::OPTION_DISK_WRITABLE_FAILED, 'fail', 'no'));
135
+ }
136
+ }
Framework/Filesystem/File.php CHANGED
@@ -7,26 +7,38 @@ namespace WPStaging\Framework\Filesystem;
7
 
8
  use LimitIterator;
9
  use SplFileObject;
 
10
 
11
  class File extends SplFileObject
12
  {
13
  const MODE_READ = 'rb'; // read only, binary
14
  const MODE_WRITE = 'wb'; // write only, binary
15
  const MODE_APPEND = 'ab'; // append with create, binary
 
16
  const MODE_WRITE_SAFE = 'xb'; // write if exists E_WARNING & return false, binary
17
  const MODE_WRITE_UNSAFE = 'cb'; // append, if exists cursor to top, binary
18
 
19
  const AVERAGE_LINE_LENGTH = 4096;
20
- const MAX_LENGTH_PER_IOP = 512000; // Max Length Per Input Output Operations
 
21
 
22
  public function __construct($fullPath, $openMode = self::MODE_READ)
23
  {
 
24
 
25
  if (!file_exists($fullPath)) {
26
  (new Filesystem())->mkdir(dirname($fullPath));
27
  }
28
 
29
- parent::__construct($fullPath, $openMode);
 
 
 
 
 
 
 
 
30
  }
31
 
32
  // Not sure if we need this, if not, delete it as we already open file with binary mode.
@@ -61,6 +73,42 @@ class File extends SplFileObject
61
  return array_reverse(array_values(iterator_to_array($allLines)));
62
  }
63
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  public function totalLines()
65
  {
66
  $currentKey = $this->key();
7
 
8
  use LimitIterator;
9
  use SplFileObject;
10
+ use WPStaging\Core\WPStaging;
11
 
12
  class File extends SplFileObject
13
  {
14
  const MODE_READ = 'rb'; // read only, binary
15
  const MODE_WRITE = 'wb'; // write only, binary
16
  const MODE_APPEND = 'ab'; // append with create, binary
17
+ const MODE_APPEND_AND_READ = 'ab+'; // append with read and create if not exists, binary
18
  const MODE_WRITE_SAFE = 'xb'; // write if exists E_WARNING & return false, binary
19
  const MODE_WRITE_UNSAFE = 'cb'; // append, if exists cursor to top, binary
20
 
21
  const AVERAGE_LINE_LENGTH = 4096;
22
+
23
+ private $existingMetadataPosition;
24
 
25
  public function __construct($fullPath, $openMode = self::MODE_READ)
26
  {
27
+ $fullPath = untrailingslashit($fullPath);
28
 
29
  if (!file_exists($fullPath)) {
30
  (new Filesystem())->mkdir(dirname($fullPath));
31
  }
32
 
33
+ try {
34
+ parent::__construct($fullPath, $openMode);
35
+ } catch (\Exception $e) {
36
+ // If this fails, it will throw an exception.
37
+ WPStaging::make(DiskWriteCheck::class)->testDiskIsWriteable();
38
+
39
+ // If it didn't fail due to disk, re-throw
40
+ throw $e;
41
+ }
42
  }
43
 
44
  // Not sure if we need this, if not, delete it as we already open file with binary mode.
73
  return array_reverse(array_values(iterator_to_array($allLines)));
74
  }
75
 
76
+ /**
77
+ * @return array The backup metadata array
78
+ */
79
+ public function readBackupMetadata()
80
+ {
81
+ $negativeOffset = 16 * KB_IN_BYTES;
82
+
83
+ // Set the pointer to the end of the file, minus the negative offset for which to start looking for the backup metadata.
84
+ $this->fseek(max($this->getSize() - $negativeOffset, 0), SEEK_SET);
85
+
86
+ $backupMetadata = null;
87
+
88
+ do {
89
+ $this->existingMetadataPosition = $this->ftell();
90
+ $line = trim($this->fgets());
91
+ if (substr($line, 0, 1) === '{') {
92
+ $backupMetadata = json_decode($line, true);
93
+ }
94
+ } while ($this->valid() && !is_array($backupMetadata));
95
+
96
+ if (!is_array($backupMetadata)) {
97
+ throw new \RuntimeException('Could not find metadata in the backup.');
98
+ }
99
+
100
+ return $backupMetadata;
101
+ }
102
+
103
+ public function getExistingMetadataPosition()
104
+ {
105
+ if ($this->existingMetadataPosition === null) {
106
+ $this->readBackupMetadata();
107
+ }
108
+
109
+ return $this->existingMetadataPosition;
110
+ }
111
+
112
  public function totalLines()
113
  {
114
  $currentKey = $this->key();
Framework/Filesystem/FileScanner.php DELETED
@@ -1,154 +0,0 @@
1
- <?php
2
-
3
- // TODO PHP7.x; declare(strict_type=1);
4
- // TODO PHP7.x; type hints & return types
5
- // TODO PHP7.1; constant visibility
6
-
7
- namespace WPStaging\Framework\Filesystem;
8
-
9
- use WPStaging\Framework\Adapter\Directory;
10
- use WPStaging\Vendor\Psr\Log\LoggerInterface;
11
-
12
- class FileScanner
13
- {
14
- private $directory;
15
- private $filesystem;
16
- private $logger;
17
-
18
- public function __construct(Directory $directory, Filesystem $filesystem, LoggerInterface $logger)
19
- {
20
- $this->directory = $directory;
21
- $this->filesystem = $filesystem;
22
- $this->logger = $logger;
23
- }
24
-
25
- /**
26
- * @param string $directory
27
- * @param bool $includeOtherFilesInWpContent
28
- * @param array $excludedDirectories
29
- *
30
- * @return array
31
- */
32
- public function scan($directory, $includeOtherFilesInWpContent, $excludedDirectories = [])
33
- {
34
- try {
35
- $it = new \DirectoryIterator($directory);
36
- } catch (\Exception $e) {
37
- return [];
38
- }
39
-
40
- /**
41
- * Allow user to exclude certain file extensions from being exported.
42
- */
43
- $ignoreFileExtensions = (array)apply_filters('wpstg.export.site.ignore.file_extension', [
44
- 'log',
45
- ]);
46
-
47
- /**
48
- * Allow user to exclude files larger than given size from being exported.
49
- */
50
- $ignoreFileBiggerThan = (int)apply_filters('wpstg.export.site.ignore.max_size_in_bytes', 200 * MB_IN_BYTES);
51
-
52
- /**
53
- * Allow user to exclude files with extension larger than given size from being exported.
54
- */
55
- $ignoreFileExtensionFilesBiggerThan = (array)apply_filters('wpstg.export.site.ignore.file_extension_max_size_in_bytes', [
56
- 'zip' => 10 * MB_IN_BYTES,
57
- ]);
58
-
59
- /*
60
- * If "Include Other Files in WP Content" is false, only the files inside
61
- * these folders will be added to the export.
62
- */
63
- $defaultWpContentFolders = [
64
- WP_PLUGIN_DIR,
65
- $this->directory->getUploadsDirectory(),
66
- get_theme_root(),
67
- WPMU_PLUGIN_DIR,
68
- ];
69
-
70
- $files = [];
71
-
72
- /** @var \SplFileInfo $item */
73
- foreach ($it as $item) {
74
- $shouldScan = $item->isFile() &&
75
- !$item->isLink() &&
76
- $item->getFilename() != "." &&
77
- $item->getFilename() != "..";
78
-
79
- if ($shouldScan) {
80
- if (in_array($item->getExtension(), $ignoreFileExtensions)) {
81
- // Early bail: File has an ignored extension
82
- $this->logger->info(sprintf(
83
- __('%s: Ignored file "%s" because the extension "%s" is ignored.', 'wp-staging'),
84
- /*
85
- * We can't use FileScanerTask::TASK_NAME due to an architectural problem.
86
- * It's not a trully static method. It uses sprintf that relies on the state of the class,
87
- * thus it can only be used inside the context of the task itself.
88
- */
89
- __('File Scanner', 'wp-staging'),
90
- $item->getPathname(),
91
- $item->getExtension()
92
- ));
93
- continue;
94
- }
95
-
96
- if ($item->getSize() > $ignoreFileBiggerThan) {
97
- // Early bail: File is larger than max allowed size.
98
- $this->logger->info(sprintf(
99
- __('%s: Ignored file "%s" because it exceeds the maximum file size for exporting (%s).', 'wp-staging'),
100
- __('File Scanner', 'wp-staging'),
101
- $item->getPathname(),
102
- size_format($item->getSize())
103
- ));
104
- continue;
105
- }
106
-
107
- if (
108
- array_key_exists($item->getExtension(), $ignoreFileExtensionFilesBiggerThan) &&
109
- $item->getSize() > $ignoreFileExtensionFilesBiggerThan[$item->getExtension()]
110
- ) {
111
- // Early bail: File bigger than expected for given extension
112
- $this->logger->info(sprintf(
113
- __('%s: Ignored file "%s" because it exceeds the maximum file size for exporting (%s) for files with the "%s" extension.', 'wp-staging'),
114
- __('File Scanner', 'wp-staging'),
115
- $item->getPathname(),
116
- size_format($item->getSize()),
117
- $item->getExtension()
118
- ));
119
- continue;
120
- }
121
-
122
- $path = $this->filesystem->safePath($item->getPathname());
123
-
124
- foreach ($excludedDirectories as $excludedDirectory) {
125
- if (strpos($path, trailingslashit($excludedDirectory)) === 0) {
126
- // Early bail: File is inside an ignored folder
127
- $this->logger->info(sprintf(
128
- __('%s: Ignored file "%s" because it is inside an ignored directory (%s).', 'wp-staging'),
129
- __('File Scanner', 'wp-staging'),
130
- $item->getPathname(),
131
- $excludedDirectory
132
- ));
133
- continue;
134
- }
135
- }
136
-
137
- if (!$includeOtherFilesInWpContent) {
138
- foreach ($defaultWpContentFolders as $defaultFolder) {
139
- /*
140
- * Only include files that are inside allowed folders.
141
- */
142
- if (strpos($path, trailingslashit($defaultFolder)) === 0) {
143
- $files[] = $path;
144
- }
145
- }
146
- } else {
147
- $files[] = $path;
148
- }
149
- }
150
- }
151
-
152
- return $files;
153
- }
154
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Framework/Filesystem/FileScannerControl.php DELETED
@@ -1,129 +0,0 @@
1
- <?php
2
-
3
- // TODO PHP7.x; declare(strict_type=1);
4
- // TODO PHP7.x; type hints & return types
5
- // TODO PHP7.1; constant visibility
6
-
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';
21
-
22
- /** @var BufferedCache */
23
- private $cache;
24
-
25
- /** @var BufferedCacheStorage */
26
- private $storage;
27
-
28
- /** @var FileScanner */
29
- private $scanner;
30
-
31
- /** @var Queue|null */
32
- private $queue;
33
-
34
- /** @var array */
35
- private $newQueueItems;
36
-
37
- public function __construct(BufferedCache $cache, BufferedCacheStorage $storage, FileScanner $scanner)
38
- {
39
- $this->newQueueItems = [];
40
- $this->cache = clone $cache;
41
- $this->storage = clone $storage;
42
- $this->scanner = $scanner;
43
- }
44
-
45
- public function onWpShutdown()
46
- {
47
- if ($this->newQueueItems && $this->queue) {
48
- $this->queue->pushAsArray($this->newQueueItems);
49
- }
50
- }
51
-
52
- /**
53
- * @param string $name
54
- */
55
- public function setQueueByName($name = self::QUEUE_CACHE_FILE)
56
- {
57
- $this->queue = new Queue();
58
- $this->queue->setName($name);
59
- $this->queue->setStorage($this->storage);
60
- }
61
-
62
- /**
63
- * @param bool $includeOtherFilesInWpContent
64
- * @param array $excludedDirectories
65
- *
66
- * @return array
67
- */
68
- public function scanCurrentPath($includeOtherFilesInWpContent, $excludedDirectories = [])
69
- {
70
- $path = $this->getPathFromQueue();
71
- if ($path === null) {
72
- throw new FinishedQueueException('File Scanner Queue is Finished');
73
- }
74
-
75
- $path = ABSPATH . $path;
76
-
77
- return $this->scanner->scan($path, $includeOtherFilesInWpContent, $excludedDirectories);
78
- }
79
-
80
- /**
81
- * @return string|null
82
- */
83
- public function getPathFromQueue()
84
- {
85
- if ($this->queue->count() > 0) {
86
- return $this->queue->pop();
87
- }
88
-
89
- if ($this->newQueueItems) {
90
- return array_shift($this->newQueueItems);
91
- }
92
-
93
- return null;
94
- }
95
-
96
- /**
97
- * @param string $item
98
- */
99
- public function addToNewQueue($item)
100
- {
101
- $this->newQueueItems[] = $item;
102
- }
103
-
104
- /**
105
- * @return BufferedCache
106
- */
107
- public function getCache()
108
- {
109
- return $this->cache;
110
- }
111
-
112
- /**
113
- * @return Queue
114
- */
115
- public function getQueue()
116
- {
117
- if (!$this->queue) {
118
- // TODO Custom Exception
119
- throw new RuntimeException('FileScannerControl Queue is not set');
120
- }
121
-
122
- return $this->queue;
123
- }
124
-
125
- public function setNewQueueItems(array $items = null)
126
- {
127
- $this->newQueueItems = $items;
128
- }
129
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Framework/Filesystem/Filesystem.php CHANGED
@@ -267,6 +267,8 @@ class Filesystem extends FilterableDirectoryIterator
267
  throw new RuntimeException('You can not delete WP Root directory');
268
  }
269
 
 
 
270
  // if $path is link or file, delete it and stop execution
271
  if (is_link($path) || is_file($path)) {
272
  if (!unlink($path)) {
@@ -324,7 +326,18 @@ class Filesystem extends FilterableDirectoryIterator
324
  }
325
 
326
  foreach ($iterator as $item) {
327
- $result = $this->deleteItem($item);
 
 
 
 
 
 
 
 
 
 
 
328
  if (!$result || !is_callable($this->shouldStop)) {
329
  continue;
330
  }
@@ -567,9 +580,6 @@ class Filesystem extends FilterableDirectoryIterator
567
  {
568
  $path = $item->getPathname();
569
 
570
- $perms = substr(sprintf('%o', fileperms($path)), -4);
571
- $this->log('Permission Error: Can not delete link ' . $perms);
572
-
573
  if ($item->isLink()) {
574
  if (!$this->removeSymlink($path)) {
575
  $this->log('Permission Error: Can not delete link ' . $path);
@@ -671,4 +681,21 @@ class Filesystem extends FilterableDirectoryIterator
671
  {
672
  return @insert_with_markers($path, $marker, $content);
673
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
674
  }
267
  throw new RuntimeException('You can not delete WP Root directory');
268
  }
269
 
270
+ clearstatcache();
271
+
272
  // if $path is link or file, delete it and stop execution
273
  if (is_link($path) || is_file($path)) {
274
  if (!unlink($path)) {
326
  }
327
 
328
  foreach ($iterator as $item) {
329
+ $result = false;
330
+
331
+ try {
332
+ $result = $this->deleteItem($item);
333
+ } catch (RuntimeException $e) {
334
+ if ($throw) {
335
+ $this->setRecursive($originalIsRecursive);
336
+
337
+ throw $e;
338
+ }
339
+ }
340
+
341
  if (!$result || !is_callable($this->shouldStop)) {
342
  continue;
343
  }
580
  {
581
  $path = $item->getPathname();
582
 
 
 
 
583
  if ($item->isLink()) {
584
  if (!$this->removeSymlink($path)) {
585
  $this->log('Permission Error: Can not delete link ' . $path);
681
  {
682
  return @insert_with_markers($path, $marker, $content);
683
  }
684
+
685
+ /**
686
+ * This normalizes the given path in a specific way,
687
+ * aiming to compare paths with precision.
688
+ *
689
+ * @param $path
690
+ *
691
+ * @return string
692
+ */
693
+ public function normalizePath($path)
694
+ {
695
+ $path = trim($path);
696
+ $path = wp_normalize_path($path);
697
+ $path = trailingslashit($path);
698
+
699
+ return $path;
700
+ }
701
  }
Framework/Filesystem/FilterableDirectoryIterator.php CHANGED
@@ -3,6 +3,7 @@
3
  namespace WPStaging\Framework\Filesystem;
4
 
5
  use DirectoryIterator;
 
6
  use FilesystemIterator;
7
  use IteratorIterator;
8
  use RecursiveDirectoryIterator;
@@ -225,11 +226,15 @@ class FilterableDirectoryIterator
225
  throw new FilesystemExceptions(sprintf(__('Directory not found on the given path: %s.', 'wp-staging'), $this->directory));
226
  }
227
 
228
- if ($this->isRecursive) {
229
- return $this->getRecursiveIterator();
230
- }
 
231
 
232
- return $this->getIterator();
 
 
 
233
  }
234
 
235
  /**
3
  namespace WPStaging\Framework\Filesystem;
4
 
5
  use DirectoryIterator;
6
+ use Exception;
7
  use FilesystemIterator;
8
  use IteratorIterator;
9
  use RecursiveDirectoryIterator;
226
  throw new FilesystemExceptions(sprintf(__('Directory not found on the given path: %s.', 'wp-staging'), $this->directory));
227
  }
228
 
229
+ try {
230
+ if ($this->isRecursive) {
231
+ return $this->getRecursiveIterator();
232
+ }
233
 
234
+ return $this->getIterator();
235
+ } catch (Exception $e) {
236
+ throw new FilesystemExceptions($e->getMessage());
237
+ }
238
  }
239
 
240
  /**
Framework/Filesystem/LogCleanup.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WPStaging\Framework\Filesystem;
4
+
5
+ use WPStaging\Core\Utils\Logger;
6
+
7
+ class LogCleanup
8
+ {
9
+ protected $logger;
10
+
11
+ public function __construct(Logger $logger)
12
+ {
13
+ $this->logger = $logger;
14
+ }
15
+
16
+ public function cleanOldLogs()
17
+ {
18
+ try {
19
+ $it = new \DirectoryIterator($this->logger->getLogDir());
20
+ } catch (\Exception $e) {
21
+ // Early bail: Couldn't open directory.
22
+ return;
23
+ }
24
+
25
+ // Delete logs older than 7 days by default
26
+ $deleteOlderThanDays = absint(apply_filters('wpstg.logs.deleteOlderThanDays', 7));
27
+
28
+ /** @var \SplFileInfo $splFileInfo */
29
+ foreach ($it as $splFileInfo) {
30
+ if ($splFileInfo->isFile() && !$splFileInfo->isLink() && $splFileInfo->getExtension() === 'log') {
31
+ if ($splFileInfo->getMTime() < strtotime("-$deleteOlderThanDays days")) {
32
+ // Not silenced nor logged
33
+ unlink($splFileInfo->getPathname());
34
+ }
35
+ }
36
+ }
37
+ }
38
+ }
Framework/Filesystem/PathIdentifier.php ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WPStaging\Framework\Filesystem;
4
+
5
+ use WPStaging\Framework\Adapter\Directory;
6
+
7
+ class PathIdentifier
8
+ {
9
+ const IDENTIFIER_WP_CONTENT = 'wpstg_c_';
10
+ const IDENTIFIER_PLUGINS = 'wpstg_p_';
11
+ const IDENTIFIER_THEMES = 'wpstg_t_';
12
+ const IDENTIFIER_MUPLUGINS = 'wpstg_m_';
13
+ const IDENTIFIER_UPLOADS = 'wpstg_u_';
14
+ const IDENTIFIER_LANG = 'wpstg_l_';
15
+
16
+ /**
17
+ * @var string The identifier of the last match.
18
+ * We will try to match the path/identifier of the next item starting from this one. It's a form of cache,
19
+ * making it more efficient to transform long lists of similar paths.
20
+ */
21
+ protected $lastIdentifier;
22
+
23
+ /** @var Directory */
24
+ protected $directory;
25
+
26
+ public function __construct(Directory $directory)
27
+ {
28
+ $this->directory = $directory;
29
+ }
30
+
31
+ /**
32
+ * @param string $path /var/www/single/wp-content/plugins/index.php
33
+ *
34
+ * @return string wpstg_p_index.php
35
+ */
36
+ public function transformPathToIdentifiable($path)
37
+ {
38
+ // Start looking from the same placeholder as the last item, unless it was wp-content, which would cause false-positives.
39
+ if (isset($this->lastIdentifier) && $this->lastIdentifier !== self::IDENTIFIER_WP_CONTENT) {
40
+ $basePath = $this->getIdentifierPath($this->lastIdentifier);
41
+
42
+ // Early bail: This item has the same type as the previous one.
43
+ if (strpos($path, $basePath) === 0) {
44
+ return $this->lastIdentifier . substr($path, strlen($basePath));
45
+ }
46
+ }
47
+
48
+ // Uploads are usually the largest folders, so let's start with them.
49
+ if (strpos($path, $this->directory->getUploadsDirectory()) === 0) {
50
+ $this->lastIdentifier = self::IDENTIFIER_UPLOADS;
51
+
52
+ return $this->lastIdentifier . substr($path, strlen($this->directory->getUploadsDirectory()));
53
+ }
54
+
55
+ if (strpos($path, $this->directory->getPluginsDirectory()) === 0) {
56
+ $this->lastIdentifier = self::IDENTIFIER_PLUGINS;
57
+
58
+ return $this->lastIdentifier . substr($path, strlen($this->directory->getPluginsDirectory()));
59
+ }
60
+
61
+ foreach ($this->directory->getAllThemesDirectories() as $themesDirectory) {
62
+ if (strpos($path, $themesDirectory) === 0) {
63
+ $this->lastIdentifier = self::IDENTIFIER_THEMES;
64
+
65
+ return $this->lastIdentifier . substr($path, strlen($themesDirectory));
66
+ }
67
+ }
68
+
69
+ if (strpos($path, $this->directory->getMuPluginsDirectory()) === 0) {
70
+ $this->lastIdentifier = self::IDENTIFIER_MUPLUGINS;
71
+
72
+ return $this->lastIdentifier . substr($path, strlen($this->directory->getMuPluginsDirectory()));
73
+ }
74
+
75
+ if (strpos($path, $this->directory->getLangsDirectory()) === 0) {
76
+ $this->lastIdentifier = self::IDENTIFIER_LANG;
77
+
78
+ return $this->lastIdentifier . substr($path, strlen($this->directory->getLangsDirectory()));
79
+ }
80
+
81
+ if (strpos($path, $this->directory->getWpContentDirectory()) === 0) {
82
+ $this->lastIdentifier = self::IDENTIFIER_WP_CONTENT;
83
+
84
+ return $this->lastIdentifier . substr($path, strlen($this->directory->getWpContentDirectory()));
85
+ }
86
+
87
+ // This should never happen on Backups, as we only scan the folders above explicitly and don't follow links.
88
+ throw new \RuntimeException("Unknown entity type for path: $path");
89
+ }
90
+
91
+ /**
92
+ * @param string $path wpstg_p_index.php
93
+ *
94
+ * @return string /var/www/single/wp-content/plugins/index.php
95
+ */
96
+ public function transformIdentifiableToPath($path)
97
+ {
98
+ $identifier = $this->getIdentifierFromPath($path);
99
+ $pathWithoutIdentifier = $this->getPathWithoutIdentifier($path);
100
+
101
+ return $this->getIdentifierPath($identifier) . $pathWithoutIdentifier;
102
+ }
103
+
104
+ /**
105
+ * @param string $path wpstg_p_index.php
106
+ *
107
+ * @return string index.php
108
+ */
109
+ public function getPathWithoutIdentifier($path)
110
+ {
111
+ return substr($path, 8);
112
+ }
113
+
114
+ /**
115
+ * @param string $path wpstg_p_index.php
116
+ *
117
+ * @return string wpstg_p_
118
+ */
119
+ public function getIdentifierFromPath($path)
120
+ {
121
+ return substr($path, 0, 8);
122
+ }
123
+
124
+ /**
125
+ * @param string $identifier wpstg_p_
126
+ *
127
+ * @return string /var/www/single/wp-content/plugins/
128
+ */
129
+ protected function getIdentifierPath($identifier)
130
+ {
131
+ // It is crucial that generic paths are placed last in this list. Eg: wp-content directory must be last.
132
+ switch ($identifier) :
133
+ case self::IDENTIFIER_UPLOADS:
134
+ return $this->directory->getUploadsDirectory();
135
+ case self::IDENTIFIER_PLUGINS:
136
+ return $this->directory->getPluginsDirectory();
137
+ case self::IDENTIFIER_THEMES:
138
+ return $this->directory->getActiveThemeParentDirectory();
139
+ case self::IDENTIFIER_MUPLUGINS:
140
+ return $this->directory->getMuPluginsDirectory();
141
+ case self::IDENTIFIER_LANG:
142
+ return $this->directory->getLangsDirectory();
143
+ case self::IDENTIFIER_WP_CONTENT:
144
+ return $this->directory->getWpContentDirectory();
145
+ default:
146
+ throw new \UnexpectedValueException("Could not find a path for the placeholder: $identifier");
147
+ endswitch;
148
+ }
149
+ }
Framework/Filesystem/WpUploadsFolderSymlinker.php CHANGED
@@ -88,7 +88,7 @@ class WpUploadsFolderSymlinker
88
  private function linkWithExec($source, $destination)
89
  {
90
  try {
91
- exec('ln -s ' . $source . ' ' . $destination);
92
  return true;
93
  } catch (FatalException $ex) {
94
  $this->error = sprintf(__("Can not symlink %s. Error: ", 'wp-staging'), $destination, $ex->getMessage());
88
  private function linkWithExec($source, $destination)
89
  {
90
  try {
91
+ exec('mklink /D "' . $destination . '" "' . $source . '"');
92
  return true;
93
  } catch (FatalException $ex) {
94
  $this->error = sprintf(__("Can not symlink %s. Error: ", 'wp-staging'), $destination, $ex->getMessage());
Framework/Mails/Report/Report.php CHANGED
@@ -81,7 +81,7 @@ class Report
81
  $errors[] = [
82
  "status" => 'already_submitted',
83
  "message" => __("You've already submitted a ticket.<br/>" .
84
- "Do you really want to send another one?", 'wp-staging')
85
  ];
86
  return $errors;
87
  }
81
  $errors[] = [
82
  "status" => 'already_submitted',
83
  "message" => __("You've already submitted a ticket.<br/>" .
84
+ "Do you want to send another one?", 'wp-staging')
85
  ];
86
  return $errors;
87
  }
Framework/Queue/FileSeekableQueue.php ADDED
@@ -0,0 +1,207 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WPStaging\Framework\Queue;
4
+
5
+ use SplFileObject;
6
+ use WPStaging\Framework\Adapter\Directory;
7
+ use WPStaging\Framework\Filesystem\Filesystem;
8
+
9
+ class FileSeekableQueue implements SeekableQueueInterface, \SeekableIterator
10
+ {
11
+ /** @var string The string identifier of this task */
12
+ protected $taskName;
13
+
14
+ /** @var SplFileObject The file resource that persists this queue */
15
+ protected $handle;
16
+
17
+ /** @var \Generator */
18
+ protected $fileGenerator;
19
+
20
+ /** @var Directory */
21
+ protected $directory;
22
+
23
+ /** @var Filesystem */
24
+ protected $filesystem;
25
+
26
+ /** @var int */
27
+ protected $offsetBefore;
28
+
29
+ /** @var bool */
30
+ protected $needsUnlock = false;
31
+
32
+ /** @var bool Whether the Queue is in write-only mode. */
33
+ protected $isWriteOnly;
34
+
35
+ public function __construct(Directory $directory, Filesystem $filesystem)
36
+ {
37
+ $this->directory = $directory;
38
+ $this->filesystem = $filesystem;
39
+ }
40
+
41
+ public function __destruct()
42
+ {
43
+ if ($this->needsUnlock && $this->handle instanceof \SplFileObject) {
44
+ try {
45
+ $this->handle->flock(LOCK_UN);
46
+ } catch (\Exception $e) {
47
+ // no-op
48
+ }
49
+ }
50
+ }
51
+
52
+ /**
53
+ * @param $taskName
54
+ * @param string $queueMode Either opens the Queue for read and write, or optimized to write-only.
55
+ */
56
+ public function setup($taskName, $queueMode = SeekableQueueInterface::MODE_READ_WRITE)
57
+ {
58
+ $this->taskName = $taskName;
59
+
60
+ $path = "{$this->directory->getCacheDirectory()}$taskName.cache";
61
+
62
+ $this->filesystem->mkdir(dirname($path), true);
63
+
64
+ if (!file_exists($path)) {
65
+ touch($path);
66
+ }
67
+
68
+ // Developer exception
69
+ if ($queueMode !== SeekableQueueInterface::MODE_WRITE && $queueMode !== SeekableQueueInterface::MODE_READ_WRITE) {
70
+ throw new \BadMethodCallException();
71
+ }
72
+
73
+ $this->handle = new SplFileObject($path, $queueMode);
74
+ $this->handle->setFlags(SplFileObject::DROP_NEW_LINE);
75
+ $this->fileGenerator = $this->initializeGenerator();
76
+
77
+ $this->isWriteOnly = $queueMode === SeekableQueueInterface::MODE_WRITE;
78
+
79
+ if ($this->isWriteOnly) {
80
+ $waitedTimes = 0;
81
+ do {
82
+ $wouldBlock = false;
83
+
84
+ /*
85
+ * Windows does not support LOCK_NB (Advisory locking), so we read from the return of flock.
86
+ * Unix supports LOCK_NB, so we read from the second parameter of flock.
87
+ */
88
+ $locked = $this->handle->flock(LOCK_EX | LOCK_NB, $wouldBlock) || (bool)!$wouldBlock;
89
+
90
+ if (!$locked) {
91
+ usleep(250000); // 0.25s
92
+ $waitedTimes++;
93
+ if ($waitedTimes > 5) {
94
+ throw new \RuntimeException('Could not acquire exclusive lock for writing to Queue file.');
95
+ }
96
+ }
97
+ } while (!$locked);
98
+
99
+ $this->needsUnlock = true;
100
+ }
101
+ }
102
+
103
+ protected function initializeGenerator()
104
+ {
105
+ while ($this->handle->valid()) {
106
+ $this->offsetBefore = $this->handle->ftell();
107
+ yield $this->handle->fgets();
108
+ }
109
+ }
110
+
111
+ public function current()
112
+ {
113
+ return $this->fileGenerator->current();
114
+ }
115
+
116
+ public function next()
117
+ {
118
+ $this->fileGenerator->next();
119
+ }
120
+
121
+ public function key()
122
+ {
123
+ return $this->fileGenerator->key();
124
+ }
125
+
126
+ public function valid()
127
+ {
128
+ return $this->fileGenerator->valid();
129
+ }
130
+
131
+ public function rewind()
132
+ {
133
+ $this->handle->fseek(0);
134
+ }
135
+
136
+ public function seek($offset)
137
+ {
138
+ $this->handle->fseek($offset);
139
+ }
140
+
141
+ public function isFinished()
142
+ {
143
+ return $this->handle->eof();
144
+ }
145
+
146
+ public function retry($dequeue = true)
147
+ {
148
+ $this->seek($this->offsetBefore);
149
+
150
+ if ($dequeue) {
151
+ return $this->dequeue();
152
+ }
153
+ }
154
+
155
+ public function enqueue($data)
156
+ {
157
+ // Early bail: Write-only optimization
158
+ if ($this->isWriteOnly) {
159
+ $this->handle->fwrite(trim($data) . PHP_EOL);
160
+
161
+ return $this->handle->ftell();
162
+ }
163
+
164
+ $this->handle->fseek(0, SEEK_END);
165
+ $this->handle->flock(LOCK_EX);
166
+ $this->handle->fwrite(trim($data) . PHP_EOL);
167
+ $this->handle->flock(LOCK_UN);
168
+
169
+ return $this->handle->ftell();
170
+ }
171
+
172
+ public function dequeue()
173
+ {
174
+ if ($this->isWriteOnly) {
175
+ throw new \BadMethodCallException('Trying to read from read-only Queue');
176
+ }
177
+
178
+ $first = is_null($this->offsetBefore);
179
+
180
+ if (!$first) {
181
+ $this->next();
182
+ }
183
+
184
+ return $this->current();
185
+ }
186
+
187
+ public function enqueueMany(array $data = [])
188
+ {
189
+ foreach ($data as $item) {
190
+ if (is_scalar($item)) {
191
+ $this->enqueue((string)$item);
192
+ }
193
+ }
194
+
195
+ return $this->handle->ftell();
196
+ }
197
+
198
+ public function reset()
199
+ {
200
+ $this->handle->ftruncate(0);
201
+ }
202
+
203
+ public function getOffset()
204
+ {
205
+ return $this->handle->ftell();
206
+ }
207
+ }
Framework/Queue/Queue.php CHANGED
@@ -5,14 +5,16 @@
5
 
6
  namespace WPStaging\Framework\Queue;
7
 
 
8
  use WPStaging\Framework\Queue\Storage\StorageInterface;
 
9
 
10
  class Queue implements QueueInterface
11
  {
12
  /** @var string */
13
  private $name;
14
 
15
- /** @var StorageInterface */
16
  private $storage;
17
 
18
  /**
@@ -59,6 +61,16 @@ class Queue implements QueueInterface
59
  return $this->storage->count();
60
  }
61
 
 
 
 
 
 
 
 
 
 
 
62
  /**
63
  * @inheritDoc
64
  */
@@ -113,4 +125,12 @@ class Queue implements QueueInterface
113
  {
114
  $this->storage->reset();
115
  }
 
 
 
 
 
 
 
 
116
  }
5
 
6
  namespace WPStaging\Framework\Queue;
7
 
8
+ use WPStaging\Framework\Queue\Storage\CacheStorage;
9
  use WPStaging\Framework\Queue\Storage\StorageInterface;
10
+ use WPStaging\Pro\Backup\Task\AbstractTask;
11
 
12
  class Queue implements QueueInterface
13
  {
14
  /** @var string */
15
  private $name;
16
 
17
+ /** @var StorageInterface|CacheStorage */
18
  private $storage;
19
 
20
  /**
61
  return $this->storage->count();
62
  }
63
 
64
+ /**
65
+ * Returns the first element of the storage, without advancing the pointer.
66
+ *
67
+ * @return mixed|AbstractTask|null
68
+ */
69
+ public function current()
70
+ {
71
+ return $this->storage->current();
72
+ }
73
+
74
  /**
75
  * @inheritDoc
76
  */
125
  {
126
  $this->storage->reset();
127
  }
128
+
129
+ /**
130
+ * @inheritDoc
131
+ */
132
+ public function reverse()
133
+ {
134
+ $this->storage->reverse();
135
+ }
136
  }
Framework/Queue/SeekableQueueInterface.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WPStaging\Framework\Queue;
4
+
5
+ interface SeekableQueueInterface
6
+ {
7
+ /** @var string Write-only queue. Optimized for writing. */
8
+ const MODE_WRITE = 'ab';
9
+
10
+ /** @var string Read/write queue. Versatile, but a little bit slower. */
11
+ const MODE_READ_WRITE = 'rb+';
12
+
13
+ public function setup($queueName, $queueMode = SeekableQueueInterface::MODE_READ_WRITE);
14
+
15
+ /**
16
+ * Whether the Queue has more items.
17
+ *
18
+ * @return bool
19
+ */
20
+ public function isFinished();
21
+
22
+ /**
23
+ * Returns the current element in the Queue and move the pointer to the next.
24
+ *
25
+ * @return mixed
26
+ */
27
+ public function dequeue();
28
+
29
+ /**
30
+ * Append item to the end of the queue
31
+ *
32
+ * @param mixed $data
33
+ */
34
+ public function enqueue($data);
35
+
36
+ /**
37
+ * Push array of items to the end of the queue
38
+ *
39
+ * @param array $data
40
+ */
41
+ public function enqueueMany(array $data = []);
42
+
43
+ /**
44
+ * Rollback the pointer to repeat the item that was just returned.
45
+ *
46
+ * @return mixed
47
+ */
48
+ public function retry($dequeue = true);
49
+
50
+ /**
51
+ * Removes all the items from the queue
52
+ */
53
+ public function reset();
54
+
55
+ /**
56
+ * Seek the Queue to given offset
57
+ */
58
+ public function seek($offset);
59
+
60
+ /**
61
+ * Returns the Queue offset
62
+ */
63
+ public function getOffset();
64
+ }
Framework/Queue/Storage/ArrayStorage.php CHANGED
@@ -83,4 +83,15 @@ class ArrayStorage implements StorageInterface
83
  {
84
  return null;
85
  }
 
 
 
 
 
 
 
 
 
 
 
86
  }
83
  {
84
  return null;
85
  }
86
+ public function reverse()
87
+ {
88
+ $this->items = array_reverse($this->items);
89
+
90
+ return $this->items;
91
+ }
92
+
93
+ public function current()
94
+ {
95
+ return current($this->items);
96
+ }
97
  }
Framework/Queue/Storage/BufferedCacheStorage.php CHANGED
@@ -173,4 +173,16 @@ class BufferedCacheStorage implements StorageInterface, ShutdownableInterface
173
  {
174
  return $this->cache;
175
  }
 
 
 
 
 
 
 
 
 
 
 
 
176
  }
173
  {
174
  return $this->cache;
175
  }
176
+
177
+ public function reverse()
178
+ {
179
+ $this->items = array_reverse($this->items);
180
+
181
+ return $this->items;
182
+ }
183
+
184
+ public function current()
185
+ {
186
+ return current($this->items);
187
+ }
188
  }
Framework/Queue/Storage/CacheStorage.php CHANGED
@@ -86,6 +86,14 @@ class CacheStorage implements StorageInterface, ShutdownableInterface
86
  array_unshift($this->items, $value);
87
  }
88
 
 
 
 
 
 
 
 
 
89
  /**
90
  * @inheritDoc
91
  */
@@ -123,4 +131,11 @@ class CacheStorage implements StorageInterface, ShutdownableInterface
123
  {
124
  return $this->cache;
125
  }
 
 
 
 
 
 
 
126
  }
86
  array_unshift($this->items, $value);
87
  }
88
 
89
+ /**
90
+ * @inheritDoc
91
+ */
92
+ public function current()
93
+ {
94
+ return current($this->items);
95
+ }
96
+
97
  /**
98
  * @inheritDoc
99
  */
131
  {
132
  return $this->cache;
133
  }
134
+
135
+ public function reverse()
136
+ {
137
+ $this->items = array_reverse($this->items);
138
+
139
+ return $this->items;
140
+ }
141
  }
Framework/Queue/Storage/ObjectCacheStorage.php ADDED
@@ -0,0 +1,277 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WPStaging\Framework\Queue\Storage;
4
+
5
+ use WPStaging\Framework\Interfaces\ShutdownableInterface;
6
+ use WPStaging\Framework\Queue\Storage\SPL\JsonDoublyLinkedList;
7
+ use WPStaging\Framework\Traits\ResourceTrait;
8
+
9
+ class ObjectCacheStorage implements StorageInterface, ShutdownableInterface
10
+ {
11
+ use ResourceTrait;
12
+
13
+ /**
14
+ * @var int When this value is hit, a new cache rotation starts,
15
+ * to make sure we don't try to bite more than we can chew.
16
+ */
17
+ protected $maxCacheSize;
18
+
19
+ /**
20
+ * @var int The current cache size, that should be smaller than max.
21
+ */
22
+ protected $currentCacheSize = 0;
23
+
24
+ /**
25
+ * @var string The identifier of this cache instance.
26
+ */
27
+ protected $key;
28
+
29
+ /**
30
+ * Everytime the Cache gets bigger than maxCacheSize,
31
+ * this value increases by 1.
32
+ *
33
+ * @var int
34
+ */
35
+ protected $cacheRotation = 0;
36
+
37
+ /**
38
+ * The total items across all cache rotations.
39
+ *
40
+ * @var int
41
+ */
42
+ protected $totalCount = 0;
43
+
44
+ /**
45
+ * @var array The current data this storage stores.
46
+ */
47
+ protected $data;
48
+
49
+ const GROUP = 'wpstg.objectCacheStorage';
50
+
51
+ /**
52
+ * @var JsonDoublyLinkedList
53
+ */
54
+ protected $linkedList;
55
+
56
+ public function __construct()
57
+ {
58
+ // 1MB, or 10% of available memory
59
+ $this->maxCacheSize = 1 * MB_IN_BYTES;
60
+ }
61
+
62
+ public function onWpShutdown()
63
+ {
64
+ if (!$this->linkedList->isEmpty()) {
65
+ $this->commit();
66
+ }
67
+ }
68
+
69
+ protected function baseCacheKey()
70
+ {
71
+ return "wpstg.storage.objectCache.{$this->key}";
72
+ }
73
+
74
+ protected function cacheKeyThisRotation()
75
+ {
76
+ return "{$this->baseCacheKey()}.{$this->cacheRotation}";
77
+ }
78
+
79
+ protected function cacheKeyPreviousRotation()
80
+ {
81
+ $previousCacheRotation = $this->cacheRotation - 1;
82
+
83
+ return "{$this->baseCacheKey()}.{$previousCacheRotation}";
84
+ }
85
+
86
+ public function commit()
87
+ {
88
+ // json_encode removes items from the linkedList
89
+ $count = $this->linkedList->count();
90
+
91
+ wp_cache_add($this->cacheKeyThisRotation(), json_encode($this->linkedList), self::GROUP, 1 * DAY_IN_SECONDS);
92
+ $this->currentCacheSize = 0;
93
+ $this->updateCacheInfo($this->cacheRotation + 1);
94
+ }
95
+
96
+ /**
97
+ * This is the entry-point of this cache.
98
+ * It must be set.
99
+ *
100
+ * @param string $key
101
+ *
102
+ * @return void|StorageInterface
103
+ */
104
+ public function setKey($key)
105
+ {
106
+ if (!is_null($this->key)) {
107
+ throw new \BadMethodCallException();
108
+ }
109
+
110
+ $this->key = $key;
111
+ $this->initializeLinkedList();
112
+ $this->updateCacheInfo(1);
113
+ $this->linkedList->hydrate(wp_cache_get($this->cacheKeyThisRotation(), self::GROUP) ?: '[]');
114
+ }
115
+
116
+ protected function getCacheInfo()
117
+ {
118
+ if (!$cacheInfo = wp_cache_get($this->baseCacheKey(), self::GROUP)) {
119
+ return [
120
+ 'currentRotation' => 1,
121
+ 'totalCount' => 0,
122
+ 'highestRotation' => 0,
123
+ ];
124
+ }
125
+
126
+ return json_decode($cacheInfo, true);
127
+ }
128
+
129
+ protected function updateCacheInfo($newCacheRotation)
130
+ {
131
+ $this->cacheRotation = $newCacheRotation;
132
+
133
+ $cacheInfo = [
134
+ 'currentRotation' => $newCacheRotation,
135
+ 'totalCount' => $this->totalCount,
136
+ 'highestRotation' => max($this->cacheRotation, $this->getCacheInfo()['highestRotation']),
137
+ ];
138
+
139
+ wp_cache_add($this->baseCacheKey(), json_encode($cacheInfo), self::GROUP, 1 * DAY_IN_SECONDS);
140
+ }
141
+
142
+ public function count()
143
+ {
144
+ return $this->totalCount;
145
+ }
146
+
147
+ public function append($value)
148
+ {
149
+ if (empty($this->key)) {
150
+ throw new \BadMethodCallException();
151
+ }
152
+
153
+ if (!is_scalar($value)) {
154
+ throw new \BadMethodCallException();
155
+ }
156
+
157
+ $this->totalCount++;
158
+ $this->currentCacheSize += strlen(strval($value));
159
+ $this->linkedList->push($value);
160
+
161
+ if ($this->currentCacheSize >= $this->maxCacheSize) {
162
+ $this->commit();
163
+ }
164
+ }
165
+
166
+ public function prepend($value)
167
+ {
168
+ if (empty($this->key)) {
169
+ throw new \BadMethodCallException();
170
+ }
171
+
172
+ if (!is_scalar($value)) {
173
+ throw new \BadMethodCallException();
174
+ }
175
+
176
+ $this->totalCount++;
177
+ $this->currentCacheSize += strlen(strval($value));
178
+ $this->linkedList->unshift($value);
179
+
180
+ if ($this->currentCacheSize >= $this->maxCacheSize) {
181
+ $this->commit();
182
+ }
183
+ }
184
+
185
+ public function first()
186
+ {
187
+ if (empty($this->key)) {
188
+ throw new \BadMethodCallException();
189
+ }
190
+
191
+ try {
192
+ $this->maybeDecreaseCacheRotation();
193
+ } catch (\OutOfBoundsException $e) {
194
+ return null;
195
+ }
196
+
197
+ $data = $this->linkedList->shift();
198
+ $this->currentCacheSize -= max(0, strlen(strval($data)));
199
+ $this->totalCount--;
200
+
201
+ return $data;
202
+ }
203
+
204
+ public function last()
205
+ {
206
+ if (empty($this->key)) {
207
+ throw new \BadMethodCallException();
208
+ }
209
+
210
+ try {
211
+ $this->maybeDecreaseCacheRotation();
212
+ } catch (\OutOfBoundsException $e) {
213
+ return null;
214
+ }
215
+
216
+ $data = $this->linkedList->pop();
217
+ $this->currentCacheSize -= max(0, strlen(strval($data)));
218
+ $this->totalCount--;
219
+
220
+ return $data;
221
+ }
222
+
223
+ public function current()
224
+ {
225
+ return $this->linkedList->current();
226
+ }
227
+
228
+ protected function maybeDecreaseCacheRotation()
229
+ {
230
+ if ($this->linkedList->isEmpty()) {
231
+ try {
232
+ $data = wp_cache_get($this->cacheKeyPreviousRotation(), self::GROUP);
233
+
234
+ if (empty($data)) {
235
+ throw new \OutOfBoundsException();
236
+ }
237
+
238
+ $this->updateCacheInfo($this->cacheRotation - 1);
239
+ $this->linkedList->hydrate($data);
240
+ } catch (\OutOfBoundsException $e) {
241
+ throw $e;
242
+ }
243
+ }
244
+ }
245
+
246
+ public function reset()
247
+ {
248
+ if (empty($this->key)) {
249
+ throw new \BadMethodCallException();
250
+ }
251
+
252
+ for ($i = $this->getCacheInfo()['highestRotation']; $i > 0; $i--) {
253
+ wp_cache_delete($this->cacheKeyThisRotation());
254
+ }
255
+
256
+ wp_cache_delete($this->baseCacheKey());
257
+ $this->initializeLinkedList();
258
+ }
259
+
260
+ protected function initializeLinkedList()
261
+ {
262
+ $this->linkedList = new JsonDoublyLinkedList();
263
+
264
+ // Free up memory as it reads through the contents.
265
+ $this->linkedList->setIteratorMode(JsonDoublyLinkedList::IT_MODE_DELETE);
266
+ }
267
+
268
+ public function getCache()
269
+ {
270
+ // no-op
271
+ }
272
+
273
+ public function reverse()
274
+ {
275
+ // no-op
276
+ }
277
+ }
Framework/Queue/Storage/SPL/JsonDoublyLinkedList.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WPStaging\Framework\Queue\Storage\SPL;
4
+
5
+ use WPStaging\Framework\Interfaces\ArrayableInterface;
6
+
7
+ class JsonDoublyLinkedList extends \SplDoublyLinkedList implements \JsonSerializable, ArrayableInterface
8
+ {
9
+ /**
10
+ * @param string $jsonData A JSON string previously returned by jsonSerialize.
11
+ */
12
+ public function hydrate($jsonData)
13
+ {
14
+ foreach (json_decode($jsonData, true) as &$item) {
15
+ $this->push($item);
16
+ unset($item);
17
+ }
18
+ }
19
+
20
+ public function toArray()
21
+ {
22
+ $data = [];
23
+
24
+ while (!$this->isEmpty()) {
25
+ $data[] = $this->shift();
26
+ }
27
+
28
+ return $data;
29
+ }
30
+
31
+ public function jsonSerialize()
32
+ {
33
+ return $this->toArray();
34
+ }
35
+ }
Framework/Queue/Storage/StorageInterface.php CHANGED
@@ -55,6 +55,12 @@ interface StorageInterface
55
  */
56
  public function first();
57
 
 
 
 
 
 
 
58
  /**
59
  * Removes and returns the last item from the queue
60
  * @return mixed
@@ -66,6 +72,11 @@ interface StorageInterface
66
  */
67
  public function reset();
68
 
 
 
 
 
 
69
  /**
70
  * @return AbstractCache|null
71
  */
55
  */
56
  public function first();
57
 
58
+ /**
59
+ * Returns the first item of the queue without removing it
60
+ * @return mixed
61
+ */
62
+ public function current();
63
+
64
  /**
65
  * Removes and returns the last item from the queue
66
  * @return mixed
72
  */
73
  public function reset();
74
 
75
+ /**
76
+ * Reverse the items in the queue
77
+ */
78
+ public function reverse();
79
+
80
  /**
81
  * @return AbstractCache|null
82
  */
Framework/Security/AccessToken.php CHANGED
@@ -55,6 +55,28 @@ class AccessToken
55
  return $newToken;
56
  }
57
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  /**
59
  * Gets the token. Requires user to be logged-in.
60
  *
55
  return $newToken;
56
  }
57
 
58
+ /**
59
+ * @param string $newToken The new token, a 64-char string.
60
+ *
61
+ * @return false|mixed
62
+ */
63
+ public function setToken($newToken)
64
+ {
65
+ // Early bail: Not enough privilege to generate a token.
66
+ if (! current_user_can((new Capabilities())->manageWPSTG())) {
67
+ return false;
68
+ }
69
+
70
+ // Early bail: A token is always a 64-character random string.
71
+ if (strlen($newToken) !== 64) {
72
+ return false;
73
+ }
74
+
75
+ update_option(static::OPTION_NAME, $newToken);
76
+
77
+ return $newToken;
78
+ }
79
+
80
  /**
81
  * Gets the token. Requires user to be logged-in.
82
  *
Framework/SiteInfo.php CHANGED
@@ -147,4 +147,36 @@ class SiteInfo
147
  // So now try disabling through new way
148
  return (!file_exists($cloneableFile) && $this->cloneOptions->delete(self::IS_CLONEABLE_KEY));
149
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
150
  }
147
  // So now try disabling through new way
148
  return (!file_exists($cloneableFile) && $this->cloneOptions->delete(self::IS_CLONEABLE_KEY));
149
  }
150
+
151
+ /**
152
+ * Ports wp_timezone_string function for compatibility with WordPress < 5.3
153
+ *
154
+ * @see wp_timezone_string()
155
+ *
156
+ * @return mixed|string|void
157
+ */
158
+ public function getSiteTimezone()
159
+ {
160
+ // Early bail: Let's use WordPress core function, as it is available.
161
+ if (function_exists('wp_timezone_string')) {
162
+ return wp_timezone_string();
163
+ }
164
+
165
+ $timezone_string = get_option('timezone_string');
166
+
167
+ if ($timezone_string) {
168
+ return $timezone_string;
169
+ }
170
+
171
+ $offset = (float)get_option('gmt_offset');
172
+ $hours = (int)$offset;
173
+ $minutes = ($offset - $hours);
174
+
175
+ $sign = ($offset < 0) ? '-' : '+';
176
+ $abs_hour = abs($hours);
177
+ $abs_mins = abs($minutes * 60);
178
+ $tz_offset = sprintf('%s%02d:%02d', $sign, $abs_hour, $abs_mins);
179
+
180
+ return $tz_offset;
181
+ }
182
  }
Framework/TemplateEngine/TemplateEngine.php CHANGED
@@ -10,6 +10,9 @@ use WPStaging\Framework\Adapter\DateTimeAdapter;
10
 
11
  class TemplateEngine implements TemplateEngineInterface
12
  {
 
 
 
13
  /**
14
  * @param string $path
15
  * @param array $params
@@ -18,6 +21,10 @@ class TemplateEngine implements TemplateEngineInterface
18
  */
19
  public function render($path, array $params = [])
20
  {
 
 
 
 
21
  $fullPath = WPSTG_PLUGIN_DIR . $path;
22
  if (!file_exists($fullPath)) {
23
  throw new TemplateEngineException('Template not found: ' . $fullPath);
10
 
11
  class TemplateEngine implements TemplateEngineInterface
12
  {
13
+ /** @var string Absolute path to the views directory. */
14
+ protected $views;
15
+
16
  /**
17
  * @param string $path
18
  * @param array $params
21
  */
22
  public function render($path, array $params = [])
23
  {
24
+ if (!isset($this->views)) {
25
+ $this->views = WPSTG_PLUGIN_DIR . 'Backend/views/';
26
+ }
27
+
28
  $fullPath = WPSTG_PLUGIN_DIR . $path;
29
  if (!file_exists($fullPath)) {
30
  throw new TemplateEngineException('Template not found: ' . $fullPath);
Framework/Traits/DatabaseSearchReplaceTrait.php ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WPStaging\Framework\Traits;
4
+
5
+ use WPStaging\Core\Utils\Helper;
6
+ use WPStaging\Core\WPStaging;
7
+
8
+ /**
9
+ * Trait DatabaseSearchReplaceTrait
10
+ *
11
+ * This trait puts together some common functionality for database search and replace
12
+ * used both by Cloning and Backups. This is not ideal, and should be refactored in the future
13
+ * for a more robust and proper architecture.
14
+ *
15
+ * @package WPStaging\Framework\Traits
16
+ */
17
+ trait DatabaseSearchReplaceTrait
18
+ {
19
+ private $excludedStrings = [
20
+ 'Admin_custome_login_Slidshow',
21
+ 'Admin_custome_login_Social',
22
+ 'Admin_custome_login_logo',
23
+ 'Admin_custome_login_text',
24
+ 'Admin_custome_login_login',
25
+ 'Admin_custome_login_top',
26
+ 'Admin_custome_login_dashboard',
27
+ 'Admin_custome_login_Version',
28
+ 'upload_path',
29
+ 'wpstg_existing_clones_beta',
30
+ 'wpstg_existing_clones',
31
+ 'wpstg_settings',
32
+ 'wpstg_license_status',
33
+ 'wpstg_tmp_data',
34
+ 'siteurl',
35
+ 'home'
36
+ ];
37
+
38
+ public function excludedStrings()
39
+ {
40
+ return $this->excludedStrings;
41
+ }
42
+
43
+ /**
44
+ * Prepend the following characters to string: %2F%2F, \/\/, //
45
+ * This is to make sure that only valid hostnames are replaced
46
+ * @param $string
47
+ * @return string[]
48
+ */
49
+ public function generateHostnamePatterns($string)
50
+ {
51
+ return [
52
+ '%2F%2F' . str_replace('/', '%2F', $string), // HTML entity for WP Backery Page Builder Plugin
53
+ '\/\/' . str_replace('/', '\/', $string), // Escaped \/ used by revslider and several visual editors
54
+ '//' . $string // //example.com
55
+ ];
56
+ }
57
+
58
+ private function getSourceHostname()
59
+ {
60
+ $helper = WPStaging::getInstance()->getContainer()->make(Helper::class);
61
+
62
+ if ($this->isSubDir()) {
63
+ return trailingslashit($helper->getHomeUrlWithoutScheme()) . $this->getSubDir();
64
+ }
65
+
66
+ return $helper->getHomeUrlWithoutScheme();
67
+ }
68
+
69
+ /**
70
+ * Check if WP is installed in subdir
71
+ * @return boolean
72
+ */
73
+ private function isSubDir()
74
+ {
75
+ // Compare names without scheme to bypass cases where siteurl and home have different schemes http / https
76
+ // This is happening much more often than you would expect
77
+ $siteurl = preg_replace('#^https?://#', '', rtrim(get_option('siteurl'), '/'));
78
+ $home = preg_replace('#^https?://#', '', rtrim(get_option('home'), '/'));
79
+
80
+ return $home !== $siteurl;
81
+ }
82
+
83
+ /**
84
+ * Get the install sub directory if WP is installed in sub directory
85
+ * @return string
86
+ */
87
+ private function getSubDir()
88
+ {
89
+ $home = get_option('home');
90
+ $siteurl = get_option('siteurl');
91
+
92
+ if (empty($home) || empty($siteurl)) {
93
+ return '';
94
+ }
95
+
96
+ return str_replace([$home, '/'], '', $siteurl);
97
+ }
98
+ }
Framework/Traits/DeveloperTimerTrait.php ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Provides methods to fetch potentially unlimited rows from a database table
5
+ * with resource-usage awareness using raw MySQL(i) queries.
6
+ *
7
+ * @package WPStaging\Framework\Traits
8
+ */
9
+
10
+ namespace WPStaging\Framework\Traits;
11
+
12
+ /**
13
+ * Trait DeveloperTimerTrait
14
+ *
15
+ * This trait should be used ONLY FOR DEBUGGING DURING DEVELOPMENT.
16
+ *
17
+ * This is NOT a substitute to real Profiling, but it proved to be
18
+ * useful to gather data in a way that the developer would like to profile.
19
+ *
20
+ * No production code should call methods from this trait.
21
+ * Feel free to commit code that uses this while the PR is under progress,
22
+ * but it should be removed before the PR is approved.
23
+ *
24
+ * @todo Add a PHPCS rule that looks for these methods and fail CI.
25
+ *
26
+ * @package WPStaging\Framework\Traits
27
+ */
28
+ trait DeveloperTimerTrait
29
+ {
30
+ use ResourceTrait;
31
+
32
+ protected $debugTimingIteration = 0;
33
+
34
+ protected $eventsStart = [];
35
+
36
+ protected $timings = [];
37
+
38
+ protected $eventStart;
39
+
40
+ protected function startEventTimer($event)
41
+ {
42
+ if (!defined('WPSTG_DEBUG') || !WPSTG_DEBUG) {
43
+ return;
44
+ }
45
+
46
+ $this->eventsStart[$event] = microtime(true);
47
+ }
48
+
49
+ public function __destruct()
50
+ {
51
+ if (!defined('WPSTG_DEBUG') || !WPSTG_DEBUG) {
52
+ return;
53
+ }
54
+
55
+ error_log(json_encode($this->timings, JSON_PRETTY_PRINT));
56
+ }
57
+
58
+ protected function finishEventTimer($event, $context = [])
59
+ {
60
+ if (!defined('WPSTG_DEBUG') || !WPSTG_DEBUG) {
61
+ return;
62
+ }
63
+
64
+ if (!array_key_exists($event, $this->eventsStart)) {
65
+ throw new \BadMethodCallException('You should initiate the event timer with startEventTimer("Name of the event")');
66
+ }
67
+
68
+ if (!array_key_exists($this->debugTimingIteration, $this->timings)) {
69
+ $this->timings[$this->debugTimingIteration] = [];
70
+ }
71
+
72
+ if (!array_key_exists($event, $this->timings[$this->debugTimingIteration])) {
73
+ $this->timings[$this->debugTimingIteration][$event] = [];
74
+ $this->timings[$this->debugTimingIteration][$event]['accumulatedTime'] = 0;
75
+ }
76
+
77
+ if (count($this->timings[$this->debugTimingIteration][$event]) > 100) {
78
+ return;
79
+ }
80
+
81
+ $this->timings[$this->debugTimingIteration][$event]['accumulatedTime'] += microtime(true) - $this->eventsStart[$event];
82
+
83
+ $this->timings[$this->debugTimingIteration][$event][] = [
84
+ 'completedIn' => number_format(microtime(true) - $this->eventsStart[$event]) . ' seconds',
85
+ 'memoryUsage' => size_format($this->getMemoryUsage()),
86
+ 'runningTime' => $this->getRunningTime(),
87
+ 'context' => $context,
88
+ ];
89
+ }
90
+
91
+ protected function incrementTimerIteration()
92
+ {
93
+ if (!defined('WPSTG_DEBUG') || !WPSTG_DEBUG) {
94
+ return;
95
+ }
96
+
97
+ $this->debugTimingIteration++;
98
+ }
99
+ }
Framework/Traits/FileScanToCacheTrait.php CHANGED
@@ -3,6 +3,7 @@
3
  namespace WPStaging\Framework\Traits;
4
 
5
  use Exception;
 
6
  use stdClass;
7
  use WPStaging\Framework\Filesystem\Scanning\ScanConst;
8
  use WPStaging\Framework\Filesystem\FilterableDirectoryIterator;
@@ -34,10 +35,6 @@ trait FileScanToCacheTrait
34
  */
35
  public function scanToCacheFile($filesHandle, $path, $isRecursive = false, $excludePaths = [], $excludeSizeRules = [], $wpRootPath = ABSPATH)
36
  {
37
- if (is_link($path)) {
38
- return 0;
39
- }
40
-
41
  $strUtil = new Strings();
42
  if (is_file($path)) {
43
  $file = str_replace($strUtil->sanitizeDirectorySeparator($wpRootPath), '', $strUtil->sanitizeDirectorySeparator($path)) . PHP_EOL;
@@ -49,32 +46,44 @@ trait FileScanToCacheTrait
49
  }
50
 
51
  $filesWrittenToCache = 0;
52
- $iterator = (new FilterableDirectoryIterator())
53
- ->setDirectory(trailingslashit($path))
54
- ->setRecursive(false)
55
- ->setDotSkip()
56
- ->setExcludePaths($excludePaths)
57
- ->setExcludeSizeRules($excludeSizeRules)
58
- ->setWpRootPath($wpRootPath)
59
- ->get();
60
 
61
- $strUtil = new Strings();
62
- foreach ($iterator as $item) {
63
- // Always check link first otherwise it may be treated as directory
64
- if ($item->isLink()) {
65
- continue;
66
- }
 
 
 
67
 
68
- if ($isRecursive && $item->isDir()) {
69
- $filesWrittenToCache += $this->scanToCacheFile($filesHandle, $item->getPathname(), $isRecursive, $excludePaths, $excludeSizeRules, $wpRootPath);
70
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
 
72
- if ($item->isFile()) {
73
- $file = str_replace($strUtil->sanitizeDirectorySeparator($wpRootPath), '', $strUtil->sanitizeDirectorySeparator($item->getPathname())) . PHP_EOL;
74
- if ($this->write($filesHandle, $file)) {
75
- $filesWrittenToCache++;
 
76
  }
77
  }
 
 
78
  }
79
 
80
  return $filesWrittenToCache;
3
  namespace WPStaging\Framework\Traits;
4
 
5
  use Exception;
6
+ use RuntimeException;
7
  use stdClass;
8
  use WPStaging\Framework\Filesystem\Scanning\ScanConst;
9
  use WPStaging\Framework\Filesystem\FilterableDirectoryIterator;
35
  */
36
  public function scanToCacheFile($filesHandle, $path, $isRecursive = false, $excludePaths = [], $excludeSizeRules = [], $wpRootPath = ABSPATH)
37
  {
 
 
 
 
38
  $strUtil = new Strings();
39
  if (is_file($path)) {
40
  $file = str_replace($strUtil->sanitizeDirectorySeparator($wpRootPath), '', $strUtil->sanitizeDirectorySeparator($path)) . PHP_EOL;
46
  }
47
 
48
  $filesWrittenToCache = 0;
 
 
 
 
 
 
 
 
49
 
50
+ try {
51
+ $iterator = (new FilterableDirectoryIterator())
52
+ ->setDirectory(trailingslashit($path))
53
+ ->setRecursive(false)
54
+ ->setDotSkip()
55
+ ->setExcludePaths($excludePaths)
56
+ ->setExcludeSizeRules($excludeSizeRules)
57
+ ->setWpRootPath($wpRootPath)
58
+ ->get();
59
 
60
+ $strUtil = new Strings();
61
+ foreach ($iterator as $item) {
62
+ // Always check link first otherwise it may be treated as directory
63
+ $path = $item->getPathname();
64
+ if ($item->isLink()) {
65
+ // Allow copying of link if the link's source is a directory
66
+ if (is_dir($item->getRealPath())) {
67
+ $filesWrittenToCache += $this->scanToCacheFile($filesHandle, $path, $isRecursive, $excludePaths, $excludeSizeRules, $wpRootPath);
68
+ }
69
+
70
+ continue;
71
+ }
72
+
73
+ if ($isRecursive && $item->isDir()) {
74
+ $filesWrittenToCache += $this->scanToCacheFile($filesHandle, $path, $isRecursive, $excludePaths, $excludeSizeRules, $wpRootPath);
75
+ continue;
76
+ }
77
 
78
+ if ($item->isFile()) {
79
+ $file = str_replace($strUtil->sanitizeDirectorySeparator($wpRootPath), '', $strUtil->sanitizeDirectorySeparator($path)) . PHP_EOL;
80
+ if ($this->write($filesHandle, $file)) {
81
+ $filesWrittenToCache++;
82
+ }
83
  }
84
  }
85
+ } catch (Exception $e) {
86
+ throw new RuntimeException($e->getMessage());
87
  }
88
 
89
  return $filesWrittenToCache;
Framework/Traits/HydrateTrait.php CHANGED
@@ -10,7 +10,6 @@ use Exception;
10
  use ReflectionClass;
11
  use ReflectionException;
12
  use ReflectionMethod;
13
- use WPStaging\Framework\Entity\EntityException;
14
  use WPStaging\Framework\Adapter\DateTimeAdapter;
15
 
16
  trait HydrateTrait
10
  use ReflectionClass;
11
  use ReflectionException;
12
  use ReflectionMethod;
 
13
  use WPStaging\Framework\Adapter\DateTimeAdapter;
14
 
15
  trait HydrateTrait
Framework/Traits/MySQLRowsGeneratorTrait.php ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Provides methods to fetch potentially unlimited rows from a database table
5
+ * with resource-usage awareness using raw MySQL(i) queries.
6
+ *
7
+ * @package WPStaging\Framework\Traits
8
+ */
9
+
10
+ namespace WPStaging\Framework\Traits;
11
+
12
+ use Generator;
13
+ use WPStaging\Framework\Adapter\Database\InterfaceDatabaseClient;
14
+ use WPStaging\Framework\Adapter\Database\MysqliAdapter;
15
+ use WPStaging\Pro\Backup\Dto\JobDataDto;
16
+
17
+ /**
18
+ * Trait MySQLRowsGeneratorTrait
19
+ *
20
+ * @package WPStaging\Framework\Traits
21
+ */
22
+ trait MySQLRowsGeneratorTrait
23
+ {
24
+ use ResourceTrait;
25
+
26
+ /**
27
+ * Returns a generator of rows.
28
+ *
29
+ * The Generator will fetch the candidate rows to process in batches and return
30
+ * them transparently to the caller code.
31
+ * If the current thread is over 80% memory or execution time, then the Generator will yield `null` to stop
32
+ * the processing.
33
+ *
34
+ * @param string $table The prefixed name of the table to pull rows from.
35
+ * @param int $offset The number of row to start the work from.
36
+ * processed will depend on the server available memory and max request execution time.
37
+ * @param string $requestId A unique identifier for the job/task this generator is running on, as to make sure
38
+ * that if we need to retry a query, we retry for this request.
39
+ * @param InterfaceDatabaseClient|MysqliAdapter $db A reference to the database instance to fetch rows from.
40
+ *
41
+ * @return Generator A generator yielding rows one by one; refetching them if and when required.
42
+ */
43
+ protected function rowsGenerator($table, $numericPrimaryKey, $offset, $requestId, InterfaceDatabaseClient $db, JobDataDto $jobDataDto)
44
+ {
45
+ /* if (defined('WPSTG_DEBUG') && WPSTG_DEBUG) {
46
+ error_log(
47
+ sprintf(
48
+ 'MySQLRowsGeneratorTrait: max-memory-limit=%s; script-memory-limit=%s; memory-usage=%s; execution-time-limit=%s; running-time=%s; is-threshold=%s',
49
+ size_format($this->getMaxMemoryLimit()),
50
+ size_format($this->getScriptMemoryLimit()),
51
+ size_format($this->getMemoryUsage()),
52
+ $this->findExecutionTimeLimit(),
53
+ $this->getRunningTime(),
54
+ ($this->isThreshold() ? 'yes' : 'no')
55
+ )
56
+ );
57
+ }*/
58
+
59
+ $rows = [];
60
+ $lastFetch = false;
61
+
62
+ $batchSize = null;
63
+
64
+ $freeMemory = $this->getScriptMemoryLimit() - $this->getMemoryUsage();
65
+
66
+ // Fetch the average row length of the current table, if need be.
67
+ if (empty($jobDataDto->getTableAverageRowLength())) {
68
+ $averageRowLength = $db->query("SELECT AVG_ROW_LENGTH FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = '$table';")->fetch_assoc();
69
+ if (!empty($averageRowLength) && is_array($averageRowLength) && array_key_exists('AVG_ROW_LENGTH', $averageRowLength)) {
70
+ $jobDataDto->setTableAverageRowLength(max(absint($averageRowLength['AVG_ROW_LENGTH']), 1));
71
+
72
+ $batchSize = ($freeMemory / $jobDataDto->getTableAverageRowLength()) / 4;
73
+ }
74
+ } else {
75
+ $batchSize = ($freeMemory / $jobDataDto->getTableAverageRowLength()) / 4;
76
+ }
77
+
78
+ // This can happen if we can't fetch the AVG_ROW_LENGTH from the table
79
+ if ($batchSize === null) {
80
+ $batchSize = 5000;
81
+ }
82
+
83
+ // Lower the fetch limits if we couldn't store them in memory last time
84
+ if (!empty($jobDataDto->getLastQueryInfoJSON())) {
85
+ $lastQueryInfo = json_decode($jobDataDto->getLastQueryInfoJSON(), true);
86
+ if (count($lastQueryInfo) === 4) {
87
+ $previousRequestId = $lastQueryInfo[0];
88
+ if ($previousRequestId === $requestId) {
89
+ list($requestId, $table, $offset, $batchSize) = array_replace([$requestId, $table, $offset, $batchSize], $lastQueryInfo);
90
+
91
+ $batchSize = $batchSize / 2;
92
+
93
+ if ($batchSize < 1) {
94
+ throw new \RuntimeException(sprintf(
95
+ 'There is one row in the database that is bigger than the memory available to PHP, which makes it impossible to extract using PHP. More info: Maximum PHP Memory: %s | Row is in table: %s | Offset: %s',
96
+ size_format($this->getScriptMemoryLimit()),
97
+ $table,
98
+ $offset
99
+ ));
100
+ }
101
+ }
102
+ }
103
+ }
104
+
105
+ // At least 1, max 5k, integer
106
+ $batchSize = max(1, $batchSize);
107
+ $batchSize = min(5000, $batchSize);
108
+ $batchSize = ceil($batchSize);
109
+
110
+ do {
111
+ if (count($rows) === 0) {
112
+ if ($lastFetch) {
113
+ break;
114
+ }
115
+
116
+ if (!empty($numericPrimaryKey)) {
117
+ // Optimal! We have Primary Keys so it doesn't get slower on large offsets.
118
+ $query = <<<SQL
119
+ SELECT *
120
+ FROM `{$table}`
121
+ WHERE `{$numericPrimaryKey}` > {$offset}
122
+ ORDER BY `{$numericPrimaryKey}` ASC
123
+ LIMIT 0, {$batchSize}
124
+ SQL;
125
+ } else {
126
+ $query = "SELECT * FROM {$table} LIMIT {$offset}, {$batchSize}";
127
+ }
128
+ $jobDataDto->setLastQueryInfoJSON(json_encode([$requestId, $table, $offset, $batchSize]));
129
+ $result = $db->query($query);
130
+
131
+ if ($result === false) {
132
+ throw new \RuntimeException('DB error:' . $db->error() . ' Query: ' . $query . ' requestId: ' . $requestId . ' table: ' . $table . ' Offset: ' . $offset . ' Batch Size: ' . $batchSize);
133
+ }
134
+
135
+ $rows = [];
136
+ while ($row = $result->fetch_assoc()) {
137
+ $rows[] = $row;
138
+ }
139
+ $rows = array_reverse($rows);
140
+ $db->freeResult($result);
141
+ $jobDataDto->setLastQueryInfoJSON('');
142
+
143
+ if (!empty($db->error())) {
144
+ if (defined('WPSTG_DEBUG') && WPSTG_DEBUG) {
145
+ error_log($db->error());
146
+ }
147
+ }
148
+
149
+ if (empty($rows)) {
150
+ // We're done here.
151
+ break;
152
+ }
153
+
154
+ if (!is_array($rows)) {
155
+ if (defined('WPSTG_DEBUG') && WPSTG_DEBUG) {
156
+ error_log(sprintf('$rows is not an array. Actual type: %s', gettype($rows)));
157
+ }
158
+ }
159
+
160
+ // If we got less than the batch size, then this is the last fetch.
161
+ $lastFetch = count($rows) < $batchSize;
162
+ }
163
+
164
+ // Take the next row from the ready set.
165
+ $row = array_pop($rows);
166
+
167
+ if (null === $row) {
168
+ // We're done, no more rows to process.
169
+ break;
170
+ }
171
+
172
+ // Check memory usage every 10 rows
173
+ if (rand(0, 10) === 10 && $this->isThreshold()) {
174
+ $jobDataDto->setLastQueryInfoJSON(json_encode([$requestId, $table, $offset, $batchSize]));
175
+ break;
176
+ }
177
+
178
+ yield $row;
179
+
180
+ if (empty($numericPrimaryKey)) {
181
+ $offset++;
182
+ } else {
183
+ $offset = $row[$numericPrimaryKey];
184
+ }
185
+ } while (!$this->isThreshold());
186
+ }
187
+ }
Framework/Traits/ResourceTrait.php CHANGED
@@ -2,65 +2,92 @@
2
 
3
  namespace WPStaging\Framework\Traits;
4
 
 
 
5
  trait ResourceTrait
6
  {
7
- use TimerTrait;
8
-
9
  /** @var int|null */
10
  protected $timeLimit;
11
 
 
 
 
 
 
12
  public static $defaultMaxExecutionTimeInSeconds = 30;
13
- public static $executionTimeGapInSeconds = 5;
 
 
 
 
 
 
14
 
15
  /**
16
  * @return bool
17
  */
18
  public function isThreshold()
19
  {
20
- return $this->isMemoryLimit() || $this->isTimeLimit();
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  }
22
 
23
  /**
24
- * @return bool
 
 
25
  */
26
- public function isMemoryLimit()
27
  {
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
 
42
  /**
43
- * @return bool
44
  */
45
- public function isTimeLimit()
46
  {
47
- /**
48
- * Overriding this filter to return true allows someone to ignore time limits.
49
- * Useful for developers using xdebug, for instance.
50
- */
51
- $ignoreTimeLimit = (bool)apply_filters('wpstg.resources.ignoreTimeLimit', false);
52
 
53
- if ($ignoreTimeLimit) {
54
- return false;
55
- }
 
 
 
 
56
 
 
 
 
 
 
57
  $timeLimit = $this->findExecutionTimeLimit();
58
 
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.
66
 
@@ -69,6 +96,11 @@ trait ResourceTrait
69
  */
70
  public function findExecutionTimeLimit()
71
  {
 
 
 
 
 
72
  $phpMaxExecutionTime = $this->getPhpMaxExecutionTime();
73
  $cpuBoundMaxExecutionTime = $this->getCpuBoundMaxExecutionTime();
74
 
@@ -82,11 +114,19 @@ trait ResourceTrait
82
  $cpuBoundMaxExecutionTime = min($phpMaxExecutionTime, $cpuBoundMaxExecutionTime);
83
  }
84
 
85
- return $cpuBoundMaxExecutionTime - static::$executionTimeGapInSeconds;
 
 
 
 
 
 
 
86
  }
87
 
88
  /**
89
  * @param bool $realUsage
 
90
  * @return int
91
  */
92
  protected function getMemoryUsage($realUsage = true)
@@ -96,6 +136,7 @@ trait ResourceTrait
96
 
97
  /**
98
  * @param bool $realUsage
 
99
  * @return int
100
  */
101
  protected function getMemoryPeakUsage($realUsage = true)
@@ -108,6 +149,10 @@ trait ResourceTrait
108
  */
109
  public function getTimeLimit()
110
  {
 
 
 
 
111
  return $this->timeLimit;
112
  }
113
 
@@ -119,20 +164,39 @@ trait ResourceTrait
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
  /**
@@ -141,11 +205,15 @@ trait ResourceTrait
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
  /**
@@ -155,13 +223,17 @@ trait ResourceTrait
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
 
2
 
3
  namespace WPStaging\Framework\Traits;
4
 
5
+ use WPStaging\Core\WPStaging;
6
+
7
  trait ResourceTrait
8
  {
 
 
9
  /** @var int|null */
10
  protected $timeLimit;
11
 
12
+ protected $resourceTraitSettings;
13
+ protected $executionTimeLimit;
14
+ protected $memoryLimit;
15
+ protected $scriptMemoryLimit;
16
+
17
  public static $defaultMaxExecutionTimeInSeconds = 30;
18
+ public static $executionTimeGapInSeconds = 5;
19
+
20
+ /** @var bool Whether this request is taking place in the context of a unit test. */
21
+ protected $isUnitTest;
22
+
23
+ /** @var bool If it is a unit test, whether to allow resource checks. */
24
+ protected $allowResourceCheckOnUnitTests;
25
 
26
  /**
27
  * @return bool
28
  */
29
  public function isThreshold()
30
  {
31
+ if ($this->isUnitTest() && !$this->allowResourceCheckOnUnitTests) {
32
+ return false;
33
+ }
34
+
35
+ $isMemoryLimit = $this->isMemoryLimit();
36
+ $isTimeLimit = $this->isTimeLimit();
37
+
38
+ if (defined('WPSTG_DEBUG') && WPSTG_DEBUG) {
39
+ if ($isTimeLimit || $isMemoryLimit) {
40
+ error_log(wp_json_encode(['class', __CLASS__, 'isTimeLimit' => $isTimeLimit, 'isMemoryLimit' => $isMemoryLimit]));
41
+ }
42
+ }
43
+
44
+ return $isMemoryLimit || $isTimeLimit;
45
  }
46
 
47
  /**
48
+ * @see \Codeception\Module\WPLoader::_getConstants
49
+ *
50
+ * @return bool Whether this request is in the context of a unit test.
51
  */
52
+ protected function isUnitTest()
53
  {
54
+ if (isset($this->isUnitTest)) {
55
+ return $this->isUnitTest;
 
 
 
 
 
56
  }
57
 
58
+ $this->isUnitTest = defined('WPCEPT_ISOLATED_INSTALL');
59
 
60
+ return $this->isUnitTest;
61
  }
62
 
63
  /**
64
+ * @return float
65
  */
66
+ protected function getRunningTime()
67
  {
68
+ return microtime(true) - WPStaging::$startTime;
69
+ }
 
 
 
70
 
71
+ /**
72
+ * @return bool
73
+ */
74
+ public function isMemoryLimit()
75
+ {
76
+ return $this->getScriptMemoryLimit() <= $this->getMemoryUsage();
77
+ }
78
 
79
+ /**
80
+ * @return bool
81
+ */
82
+ public function isTimeLimit()
83
+ {
84
  $timeLimit = $this->findExecutionTimeLimit();
85
 
86
+ if (isset($this->timeLimit)) {
87
  $timeLimit = $this->timeLimit;
88
  }
89
 
90
+ return $this->getRunningTime() > $timeLimit;
91
  }
92
  // TODO Recursion for xDebug? Recursion is bad idea will cause more resource usage, need to avoid it.
93
 
96
  */
97
  public function findExecutionTimeLimit()
98
  {
99
+ // Early bail: Cache
100
+ if (isset($this->executionTimeLimit)) {
101
+ return $this->executionTimeLimit;
102
+ }
103
+
104
  $phpMaxExecutionTime = $this->getPhpMaxExecutionTime();
105
  $cpuBoundMaxExecutionTime = $this->getCpuBoundMaxExecutionTime();
106
 
114
  $cpuBoundMaxExecutionTime = min($phpMaxExecutionTime, $cpuBoundMaxExecutionTime);
115
  }
116
 
117
+ // Set a max of 30 seconds to avoid NGINX 504 timeouts that are beyond PHP's control, with a minimum of 5 seconds
118
+ $this->executionTimeLimit = max(min($cpuBoundMaxExecutionTime - static::$executionTimeGapInSeconds, 30), 5);
119
+
120
+ if ((bool)apply_filters('wpstg.resources.ignoreTimeLimit', false)) {
121
+ $this->executionTimeLimit = PHP_INT_MAX;
122
+ }
123
+
124
+ return $this->executionTimeLimit;
125
  }
126
 
127
  /**
128
  * @param bool $realUsage
129
+ *
130
  * @return int
131
  */
132
  protected function getMemoryUsage($realUsage = true)
136
 
137
  /**
138
  * @param bool $realUsage
139
+ *
140
  * @return int
141
  */
142
  protected function getMemoryPeakUsage($realUsage = true)
149
  */
150
  public function getTimeLimit()
151
  {
152
+ if (!isset($this->timeLimit)) {
153
+ $this->timeLimit = $this->findExecutionTimeLimit();
154
+ }
155
+
156
  return $this->timeLimit;
157
  }
158
 
164
  $this->timeLimit = $timeLimit;
165
  }
166
 
167
+ /**
168
+ * @param bool $isAllowed True to check resources on unit tests. False to not check.
169
+ */
170
+ public function resourceCheckOnUnitTests($isAllowed)
171
+ {
172
+ $this->allowResourceCheckOnUnitTests = $isAllowed;
173
+ }
174
+
175
  /**
176
  * Returns the current PHP memory limit in bytes..
177
  *
178
  * @return int The current memory limit in bytes.
179
  */
180
+ protected function getMaxMemoryLimit()
181
  {
182
+ // Early bail: Cache
183
+ if (isset($this->memoryLimit)) {
184
+ return $this->memoryLimit;
185
+ }
186
+
187
  $limit = wp_convert_hr_to_bytes(ini_get('memory_limit'));
188
 
189
  if (!is_int($limit) || $limit < 64000000) {
190
  $limit = 64000000;
191
  }
192
 
193
+ if ((bool)apply_filters('wpstg.resources.ignoreMemoryLimit', false)) {
194
+ $limit = PHP_INT_MAX;
195
+ }
196
+
197
+ $this->memoryLimit = $limit;
198
+
199
+ return $this->memoryLimit;
200
  }
201
 
202
  /**
205
  * @return int The script memory limit, by definition less then
206
  * the maximum memory limit.
207
  */
208
+ protected function getScriptMemoryLimit()
209
  {
210
+ // Early bail: Cache
211
+ if (isset($this->scriptMemoryLimit)) {
212
+ return $this->scriptMemoryLimit;
213
+ }
214
 
215
+ // 80% of max memory limit
216
+ return $this->scriptMemoryLimit = $this->getMaxMemoryLimit() * 0.8;
217
  }
218
 
219
  /**
223
  * return the max execution time for, or
224
  * `null` to read the current CPU Load
225
  * value from the Settings.
226
+ *
227
  * @return int The max execution time as bound by the CPU Load setting.
228
  */
229
  protected function getCpuBoundMaxExecutionTime($cpuLoadSetting = null)
230
  {
231
+ // Early bail: Cache
232
+ if (!isset($this->resourceTraitSettings)) {
233
+ $this->resourceTraitSettings = json_decode(json_encode(get_option('wpstg_settings', [])));
234
+ }
235
  if ($cpuLoadSetting === null) {
236
+ $cpuLoadSetting = isset($this->resourceTraitSettings->cpuLoad) ? $this->resourceTraitSettings->cpuLoad : 'medium';
237
  }
238
  $execution_gap = static::$executionTimeGapInSeconds;
239
 
Framework/Traits/TimerTrait.php DELETED
@@ -1,16 +0,0 @@
1
- <?php
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
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Framework/Utils/Cache/BufferedCache.php CHANGED
@@ -6,21 +6,24 @@
6
 
7
  namespace WPStaging\Framework\Utils\Cache;
8
 
9
- use LimitIterator;
10
  use SplFileObject;
 
11
  use WPStaging\Framework\Exceptions\IOException;
 
12
  use WPStaging\Framework\Filesystem\File;
13
- use WPStaging\Framework\Filesystem\Filesystem;
 
14
 
15
  // TODO DRY; re-use \WPStaging\Framework\Filesystem\File
16
  // Buffered cache reads the file partially
17
  class BufferedCache extends AbstractCache
18
  {
 
 
19
  const POSITION_TOP = 'top';
20
  const POSITION_BOTTOM = 'bottom';
21
 
22
  const AVERAGE_LINE_LENGTH = 4096;
23
- const MAX_LENGTH_PER_IOP = 512000; // Max Length Per Input Output Operations
24
 
25
  public function first()
26
  {
@@ -68,44 +71,124 @@ class BufferedCache extends AbstractCache
68
  if (is_array($value)) {
69
  $value = implode(PHP_EOL, $value);
70
  }
 
71
  /** @noinspection UnnecessaryCastingInspection */
72
- return (new File($this->filePath, File::MODE_APPEND))->fwriteSafe((string) $value . PHP_EOL);
73
  }
74
 
75
- public function prepend($value)
 
 
 
 
 
76
  {
77
- if (is_array($value)) {
78
- $value = implode(PHP_EOL, $value) . PHP_EOL;
79
  }
80
 
81
- $handle = fopen($this->filePath, 'wb+');
82
- $length = strlen($value);
83
 
84
- $i = 0;
85
- $data = $value;
86
- while (($buffer = fread($handle, self::AVERAGE_LINE_LENGTH)) !== false) {
87
- fseek($handle, $i * $length);
88
- fwrite($handle, $data);
89
- $data = $buffer;
90
- $i++;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
  }
92
- fclose($handle);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  }
94
 
95
  /**
96
  * @param resource $source
97
  * @param int $offset
98
- * @param callable|null $shouldStop
99
  * @return int
100
  */
101
- public function appendFile($source, $offset = 0, callable $shouldStop = null)
102
  {
103
  $target = fopen($this->filePath, 'ab');
104
 
105
- if (!$shouldStop) {
106
- return $this->appendAllFile($source, $target, $offset);
107
- }
108
- return $this->stoppableAppendFile($source, $target, $offset, $shouldStop);
109
  }
110
 
111
  public function readLines($lines = 1, $default = null, $position = self::POSITION_TOP)
@@ -234,15 +317,27 @@ class BufferedCache extends AbstractCache
234
  $file = new SplFileObject($this->filePath, 'rb');
235
  $file->seek(PHP_INT_MAX);
236
  $lastLine = $file->key();
237
- $offset = $lastLine - $lines;
238
- if ($offset < 0) {
239
- $offset = 0;
240
- }
241
 
242
  $allLines = new LimitIterator($file, $offset, $lastLine);
243
  return array_reverse(array_values(iterator_to_array($allLines)));
244
  }
245
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
246
  /**
247
  * @param int $lines
248
  * @return array|null
@@ -275,53 +370,34 @@ class BufferedCache extends AbstractCache
275
  * @param resource $target
276
  * @param int $offset
277
  * @return int
278
- * @throws IOException
279
- */
280
- private function appendAllFile($source, $target, $offset)
281
- {
282
- $bytesWritten = 0;
283
- while (!feof($source)) {
284
- $chunk = fread($source, self::MAX_LENGTH_PER_IOP);
285
- $_bytesWritten = fwrite($target, $chunk);
286
-
287
- // Failed to write
288
- if ($_bytesWritten === false) {
289
- // TODO Custom Exception
290
- throw new IOException('Failed to append stoppable file');
291
- }
292
- $bytesWritten += $_bytesWritten;
293
- }
294
- return $bytesWritten;
295
- }
296
-
297
- /**
298
- * @param resource $source
299
- * @param resource $target
300
- * @param int $offset
301
- * @param callable $shouldStop
302
- * @return int
303
- * @throws IOException
304
  */
305
- private function stoppableAppendFile($source, $target, $offset, callable $shouldStop)
306
  {
307
  $stats = fstat($source);
308
- $bytesWritten = 0;
309
- while (!$shouldStop() && !feof($source)) {
310
- $chunk = fread($source, self::MAX_LENGTH_PER_IOP);
311
- $_bytesWritten = fwrite($target, $chunk);
312
-
313
- // Failed to write
314
- if ($_bytesWritten === false) {
315
- // TODO Custom Exception
316
- throw new IOException('Failed to append stoppable file');
 
 
 
 
 
 
317
  }
318
 
319
  // Finished writing, nothing more to write!
320
- $bytesWritten += $_bytesWritten;
321
- if ($_bytesWritten === 0 || $stats['size'] <= $bytesWritten) {
322
  break;
323
  }
324
  }
325
- return $bytesWritten;
326
  }
327
  }
6
 
7
  namespace WPStaging\Framework\Utils\Cache;
8
 
 
9
  use SplFileObject;
10
+ use LimitIterator;
11
  use WPStaging\Framework\Exceptions\IOException;
12
+ use WPStaging\Framework\Traits\ResourceTrait;
13
  use WPStaging\Framework\Filesystem\File;
14
+ use WPStaging\Pro\Backup\Exceptions\DiskNotWritableException;
15
+ use WPStaging\Pro\Backup\Exceptions\ThresholdException;
16
 
17
  // TODO DRY; re-use \WPStaging\Framework\Filesystem\File
18
  // Buffered cache reads the file partially
19
  class BufferedCache extends AbstractCache
20
  {
21
+ use ResourceTrait;
22
+
23
  const POSITION_TOP = 'top';
24
  const POSITION_BOTTOM = 'bottom';
25
 
26
  const AVERAGE_LINE_LENGTH = 4096;
 
27
 
28
  public function first()
29
  {
71
  if (is_array($value)) {
72
  $value = implode(PHP_EOL, $value);
73
  }
74
+
75
  /** @noinspection UnnecessaryCastingInspection */
76
+ return (new File($this->filePath, File::MODE_APPEND))->fwriteSafe((string)$value . PHP_EOL);
77
  }
78
 
79
+ /**
80
+ * Like array_reverse(), but for files.
81
+ *
82
+ * @throws ThresholdException When threshold limit hits.
83
+ */
84
+ public function reverse()
85
  {
86
+ if (!file_exists($this->filePath . 'tmp')) {
87
+ copy($this->filePath, $this->filePath . 'tmp');
88
  }
89
 
90
+ $existingFile = new SplFileObject($this->filePath, 'rb+');
91
+ $existingFile->flock(LOCK_EX);
92
 
93
+ $tempFile = new SplFileObject($this->filePath . 'tmp', 'rb+');
94
+ $existingFile->flock(LOCK_EX);
95
+
96
+ $lastLine = null;
97
+ $currentLine = null;
98
+
99
+ try {
100
+ $i = 0;
101
+ while (true) {
102
+ $i++;
103
+ // Only check for thresholds every 25 lines
104
+ if ($i >= 25) {
105
+ $i = 0;
106
+ if ($this->isThreshold()) {
107
+ throw ThresholdException::thresholdHit('');
108
+ }
109
+ }
110
+
111
+ $existingFile->seek(PHP_INT_MAX);
112
+
113
+ if (!is_null($currentLine)) {
114
+ $currentLine--;
115
+
116
+ if ($currentLine < 0) {
117
+ throw new \OutOfBoundsException();
118
+ }
119
+
120
+ $existingFile->seek($currentLine);
121
+ }
122
+
123
+ if (is_null($lastLine)) {
124
+ $lastLine = $existingFile->key();
125
+ $currentLine = $lastLine;
126
+ $existingFile->seek($lastLine);
127
+ }
128
+
129
+ $line = $existingFile->current();
130
+ $tempFile->fwrite($line);
131
+ $existingFile->ftruncate($existingFile->ftell());
132
+ }
133
+ } catch (\OutOfBoundsException $e) {
134
+ // End of file
135
+ } catch (ThresholdException $e) {
136
+ // This exception must be handled by the caller.
137
+ throw $e;
138
  }
139
+
140
+ unlink($this->filePath);
141
+ rename($this->filePath . 'tmp', $this->filePath);
142
+ }
143
+
144
+ public function prepend($data)
145
+ {
146
+ if (is_array($data)) {
147
+ $data = implode(PHP_EOL, $data);
148
+ }
149
+
150
+ $data = trim($data) . PHP_EOL;
151
+
152
+ // Early bail: First addition
153
+ if (!file_exists($this->filePath)) {
154
+ file_put_contents($this->filePath, $data);
155
+ return;
156
+ }
157
+
158
+ /*
159
+ * To prepend to a large file, we have to re-write it from scratch,
160
+ * so let's make a copy of the file, add our data to the beginning of a new file,
161
+ * and add the data from the existing file into it.
162
+ */
163
+
164
+ copy($this->filePath, $this->filePath . 'tmp');
165
+
166
+ $existingFile = new SplFileObject($this->filePath, 'rb');
167
+ $existingFile->flock(LOCK_EX);
168
+
169
+ $tempFile = new SplFileObject($this->filePath . 'tmp', 'wb');
170
+ $existingFile->flock(LOCK_EX);
171
+ $tempFile->fwrite($data);
172
+
173
+ while (!empty($nextLine = $existingFile->fgets())) {
174
+ $tempFile->fwrite($nextLine);
175
+ }
176
+
177
+ unlink($this->filePath);
178
+ copy($this->filePath . 'tmp', $this->filePath);
179
  }
180
 
181
  /**
182
  * @param resource $source
183
  * @param int $offset
184
+ * @throws DiskNotWritableException
185
  * @return int
186
  */
187
+ public function appendFile($source, $offset = 0)
188
  {
189
  $target = fopen($this->filePath, 'ab');
190
 
191
+ return $this->stoppableAppendFile($source, $target, $offset);
 
 
 
192
  }
193
 
194
  public function readLines($lines = 1, $default = null, $position = self::POSITION_TOP)
317
  $file = new SplFileObject($this->filePath, 'rb');
318
  $file->seek(PHP_INT_MAX);
319
  $lastLine = $file->key();
320
+ $offset = max($lastLine - $lines, 0);
 
 
 
321
 
322
  $allLines = new LimitIterator($file, $offset, $lastLine);
323
  return array_reverse(array_values(iterator_to_array($allLines)));
324
  }
325
 
326
+ public function readLastLine()
327
+ {
328
+ $file = new SplFileObject($this->filePath, 'rb');
329
+ $negativeOffset = 16 * KB_IN_BYTES;
330
+
331
+ // Set the pointer to the end of the file, minus the negative offset for which to start looking for the last line.
332
+ $file->fseek(max($file->getSize() - $negativeOffset, 0), SEEK_SET);
333
+
334
+ do {
335
+ $lastLine = $file->fgets();
336
+ } while (!$file->eof());
337
+
338
+ return $lastLine;
339
+ }
340
+
341
  /**
342
  * @param int $lines
343
  * @return array|null
370
  * @param resource $target
371
  * @param int $offset
372
  * @return int
373
+ * @throws DiskNotWritableException
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
374
  */
375
+ private function stoppableAppendFile($source, $target, $offset)
376
  {
377
  $stats = fstat($source);
378
+ $bytesWrittenTotal = $offset;
379
+ fseek($source, $offset);
380
+ while (!$this->isThreshold() && !feof($source)) {
381
+ $chunk = fread($source, 512 * KB_IN_BYTES);
382
+
383
+ if (!empty($chunk)) {
384
+ $bytesWrittenInThisRequest = fwrite($target, $chunk);
385
+ unset($chunk);
386
+
387
+ // Failed to write
388
+ if ($bytesWrittenInThisRequest === false || $bytesWrittenInThisRequest <= 0) {
389
+ throw DiskNotWritableException::diskNotWritable();
390
+ }
391
+ } else {
392
+ $bytesWrittenInThisRequest = 0;
393
  }
394
 
395
  // Finished writing, nothing more to write!
396
+ $bytesWrittenTotal += $bytesWrittenInThisRequest;
397
+ if ($bytesWrittenInThisRequest === 0 || $stats['size'] <= $bytesWrittenTotal) {
398
  break;
399
  }
400
  }
401
+ return $bytesWrittenTotal;
402
  }
403
  }
Framework/Utils/Math.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WPStaging\Framework\Utils;
4
+
5
+ class Math
6
+ {
7
+ /**
8
+ * Format bytes into human readable form
9
+ * @param int $bytes
10
+ * @param int $precision
11
+ * @return string
12
+ */
13
+ public function formatSize($bytes, $precision = 2)
14
+ {
15
+ if ((int)$bytes < 1) {
16
+ return '';
17
+ }
18
+
19
+ $units = ['B', "KB", "MB", "GB", "TB"];
20
+
21
+ $bytes = (int)$bytes;
22
+ $base = log($bytes) / log(1000); // 1024 would be for MiB KiB etc
23
+ $pow = pow(1000, $base - floor($base)); // Same rule for 1000
24
+
25
+ return round($pow, $precision) . ' ' . $units[(int)floor($base)];
26
+ }
27
+ }
Framework/Utils/Urls.php CHANGED
@@ -5,7 +5,6 @@ namespace WPStaging\Framework\Utils;
5
  class Urls
6
  {
7
 
8
-
9
  /**
10
  * Retrieves the URL for a given site where the front end is accessible.
11
  *
@@ -47,7 +46,6 @@ class Urls
47
  return preg_replace('#^https?://#', '', rtrim($this->getHomeUrl(), '/'));
48
  }
49
 
50
-
51
  /**
52
  * Get raw base URL e.g. https://blog.domain.com or https://domain.com without any subfolder
53
  * @return string
@@ -58,7 +56,6 @@ class Urls
58
  return $result['scheme'] . "://" . $result['host'];
59
  }
60
 
61
-
62
  /**
63
  * Return base URL (domain) without scheme e.g. blog.domain.com or domain.com
64
  * @param string $str
@@ -68,4 +65,24 @@ class Urls
68
  {
69
  return preg_replace('#^https?://#', '', rtrim($this->getBaseUrl(), '/'));
70
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  }
5
  class Urls
6
  {
7
 
 
8
  /**
9
  * Retrieves the URL for a given site where the front end is accessible.
10
  *
46
  return preg_replace('#^https?://#', '', rtrim($this->getHomeUrl(), '/'));
47
  }
48
 
 
49
  /**
50
  * Get raw base URL e.g. https://blog.domain.com or https://domain.com without any subfolder
51
  * @return string
56
  return $result['scheme'] . "://" . $result['host'];
57
  }
58
 
 
59
  /**
60
  * Return base URL (domain) without scheme e.g. blog.domain.com or domain.com
61
  * @param string $str
65
  {
66
  return preg_replace('#^https?://#', '', rtrim($this->getBaseUrl(), '/'));
67
  }
68
+
69
+ /**
70
+ * Get hostname of production site including scheme
71
+ * @return string
72
+ */
73
+ public function getProductionHostname()
74
+ {
75
+
76
+ $connection = get_option('wpstg_connection');
77
+
78
+ // Get the stored hostname
79
+ if (!empty($connection['prodHostname'])) {
80
+ return $connection['prodHostname'];
81
+ }
82
+
83
+ // Default. Try to get the hostname from the main domain (Workaround for WP Staging Pro older < 2.9.1)
84
+ $siteurl = get_site_url();
85
+ $result = parse_url($siteurl);
86
+ return $result['scheme'] . "://" . $result['host'];
87
+ }
88
  }
Frontend/FrontendServiceProvider.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WPStaging\Frontend;
4
+
5
+ use WPStaging\Framework\DI\ServiceProvider;
6
+
7
+ class FrontendServiceProvider extends ServiceProvider
8
+ {
9
+
10
+ public function register()
11
+ {
12
+ $this->registerLoginAfterImport();
13
+ }
14
+
15
+ private function registerLoginAfterImport()
16
+ {
17
+ // Available in WordPress 4.6+
18
+ $action = 'login_header';
19
+
20
+ /** @see wp_version_check() */
21
+ if (file_exists(ABSPATH . WPINC . '/version.php')) {
22
+ require ABSPATH . WPINC . '/version.php';
23
+
24
+ if (isset($wp_version) && version_compare($wp_version, '4.6', '<')) {
25
+ // Available in WordPress >3.1
26
+ $action = 'login_footer';
27
+ }
28
+ }
29
+
30
+ #add_action($action, [$this->container->callback(LoginAfterImport::class, 'showMessage')], 10, 0);
31
+ add_action($action, [$this->container->make(LoginAfterImport::class), 'showMessage'], 10, 0);
32
+ }
33
+ }
Frontend/LoginAfterImport.php ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WPStaging\Frontend;
4
+
5
+ use WPStaging\Core\WPStaging;
6
+ use WPStaging\Framework\Security\AccessToken;
7
+
8
+ class LoginAfterImport
9
+ {
10
+ /**
11
+ * @see \WPStaging\Frontend\FrontendServiceProvider::registerLoginAfterImport
12
+ */
13
+ public function showMessage()
14
+ {
15
+ // Early bail: Not after Import
16
+ if (!isset($_GET['wpstgAfterImport']) || $_GET['wpstgAfterImport'] !== 'yes') {
17
+ return;
18
+ }
19
+
20
+ // Early bail: No access token
21
+ if (!isset($_GET['accessToken'])) {
22
+ return;
23
+ }
24
+
25
+ // Late instantiation, since this runs on the FE on every request
26
+ $auth = WPStaging::getInstance()->getContainer()->make(AccessToken::class);
27
+
28
+ // Early bail: Invalid access token
29
+ if (!$auth->isValidToken($_GET['accessToken'])) {
30
+ return;
31
+ }
32
+
33
+ // Used by loginAfterImport
34
+ $adminEmails = $this->getListOfAdminEmails();
35
+ include __DIR__ . '/views/loginAfterImport.php';
36
+ }
37
+
38
+ private function getListOfAdminEmails()
39
+ {
40
+ $adminEmails = get_users([
41
+ 'role' => 'administrator',
42
+ 'fields' => [
43
+ 'user_email',
44
+ ],
45
+ 'number' => 10,
46
+ ]);
47
+
48
+ // Early bail: Nothing to show
49
+ if (!is_array($adminEmails) || empty($adminEmails)) {
50
+ return [];
51
+ }
52
+
53
+ $adminEmails = array_map(function ($stdClass) {
54
+ if (is_object($stdClass) && property_exists($stdClass, 'user_email')) {
55
+ return $stdClass->user_email;
56
+ }
57
+
58
+ return null;
59
+ }, $adminEmails);
60
+
61
+ $adminEmails = array_filter($adminEmails, 'is_email');
62
+
63
+ // Early bail: Nothing to show
64
+ if (empty($adminEmails)) {
65
+ return [];
66
+ }
67
+
68
+ return $adminEmails;
69
+ }
70
+ }
Frontend/views/loginAfterImport.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @var array $adminEmails
4
+ */
5
+ ?>
6
+ <style>
7
+ #adminEmails {
8
+ display: none;
9
+ }
10
+ .unselectable {
11
+ -moz-user-select: none;
12
+ -webkit-user-select: none;
13
+ -ms-user-select: none;
14
+ user-select: none;
15
+ }
16
+ #loginAfterImport {
17
+ width: 320px;
18
+ padding-top: 20px;
19
+ margin: auto;
20
+ }
21
+ #loginAfterImport h1 {
22
+ margin-bottom: 20px;
23
+ }
24
+ #loginAfterImport p {
25
+ margin-bottom: 10px;
26
+ }
27
+ #showAdminEmails {
28
+ cursor: pointer;
29
+ font-weight: bold;
30
+ text-decoration: underline;
31
+ color: #2196f3;
32
+ }
33
+ div#adminEmails ul {
34
+ padding-left: 15px;
35
+ }
36
+ #login {
37
+ padding-top:40px;
38
+ }
39
+ </style>
40
+ <div id="loginAfterImport">
41
+ <h1 class="unselectable"><?php esc_html_e('Congratulations!', 'wp-staging'); ?></h1>
42
+ <p class="unselectable"><?php esc_html_e('You have just restored a WP STAGING backup.', 'wp-staging'); ?></p>
43
+ <p class="unselectable"><?php echo wp_kses_post(__(sprintf('Now you need to log-in using email and password that were in the Backup that you just restored. If you don\'t remember the credentials, click <span id="showAdminEmails">here</span> to see a list of admin e-mails you can use to restore your access by clicking "Forgot your password". This message will appear only once.'), 'wp-staging')); ?></p>
44
+ <div id="adminEmails">
45
+ <p>
46
+ <?php if (is_array($adminEmails) && !empty($adminEmails)) : ?>
47
+ <ul>
48
+ <?php
49
+ foreach ($adminEmails as $adminEmail) {
50
+ echo sprintf('<li>%s</li>', esc_html($adminEmail));
51
+ }
52
+ ?>
53
+ </ul>
54
+ <?php else : ?>
55
+ <?php esc_html_e('Sorry, there are no admin e-mails to show.', 'wp-staging'); ?>
56
+ <?php endif; ?>
57
+ </div>
58
+ </p>
59
+ </div>
60
+ <script>
61
+ document.getElementById('showAdminEmails').addEventListener('click', function() {
62
+ if (document.getElementById('adminEmails').style.display === "block") {
63
+ document.getElementById('adminEmails').style.display = "none";
64
+ } else {
65
+ document.getElementById('adminEmails').style.display = "block";
66
+ }
67
+ });
68
+ </script>
Frontend/views/loginForm.php CHANGED
@@ -1,6 +1,6 @@
1
  <main class="wp-staging-login" >
2
  <div class="wpstg-text-center">
3
- <img src="<?php echo esc_url(WPSTG_PLUGIN_URL . 'assets/img/logo_clean_small_212_25.png'); ?>" alt="WP Staging Login" />
4
  </div>
5
  <form class="wp-staging-form" name="<?php echo $args['form_id']; ?>" id="<?php echo $args['form_id']; ?>" action="" method="post">
6
  <?php if ($showNotice) { ?>
1
  <main class="wp-staging-login" >
2
  <div class="wpstg-text-center">
3
+ <img width="220" src="<?php echo esc_url(WPSTG_PLUGIN_URL . 'assets/img/logo-wp-staging-1468x230.png'); ?>" alt="WP Staging Login" />
4
  </div>
5
  <form class="wp-staging-form" name="<?php echo $args['form_id']; ?>" id="<?php echo $args['form_id']; ?>" action="" method="post">
6
  <?php if ($showNotice) { ?>
assets/css/dist/wpstg-admin.css CHANGED
@@ -7,17 +7,52 @@
7
  * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
8
  */
9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
  /* CSS for Tabs */
12
 
13
  #wpstg-tab-container ul {
14
- /*height: 200px;*/
15
  list-style: none;
16
  margin: 0;
17
  padding: 0;
18
  background: #f1f1f1;
19
  float: left;
20
- /*list-style-type: square;*/
21
  }
22
 
23
  #wpstg-tab-container ul li:first-child.selected-tab {
@@ -47,7 +82,7 @@
47
  padding: 5px;
48
  }
49
 
50
- #wpstg-tab-container>ul>li.wpstg-tabs.active {
51
  background-color: white;
52
  }
53
 
@@ -93,14 +128,17 @@
93
  #wpstg-tab-container ul {
94
  float: none;
95
  }
96
- #wpstg-tab-container .wpstg-form-table tr>th {
 
97
  width: 100%;
98
  }
 
99
  #wpstg-tab-container span.description {
100
  font-size: 14px;
101
  }
102
- #wpstg-tab-container .wpstg-form-table tr>th,
103
- #wpstg-tab-container .wpstg-form-table tr>td {
 
104
  padding: 10px;
105
  }
106
  }
@@ -134,28 +172,29 @@
134
  float: left;
135
  }
136
 
 
 
 
 
137
  .wpstg-version {
138
  display: block;
139
- padding-top: 29px
 
140
  }
141
 
142
  .wpstg_admin .nav-tab {
143
  color: #3C3C3C;
144
  }
145
 
146
- #wpstg-tab-container table tbody tr:nth-child(1)>th>div {
147
  font-size: 20px;
148
  }
149
 
150
- .wpstg_hidden {
151
- display: none;
152
- }
153
-
154
-
155
  /* Cloning workflow */
156
 
157
  #wpstg-clonepage-wrapper {
158
  margin-bottom: 20px;
 
159
  }
160
 
161
  @media screen and (min-width: 1090px) {
@@ -163,23 +202,11 @@
163
  float: left;
164
  margin-bottom: 20px;
165
  }
166
- .wpstg-sidebar {
167
- display: none;
168
- margin-left: 700px;
169
- margin-top: 138px;
170
- }
171
- }
172
-
173
- .wpstg-sidebar {
174
- display: none;
175
- padding: 10px;
176
- border: 1px solid #DFDFDF;
177
- max-width: 250px;
178
- height: 250px;
179
  }
180
 
181
  #wpstg-steps {
182
- margin-top: 30px;
 
183
  }
184
 
185
  #wpstg-steps li {
@@ -190,7 +217,7 @@
190
  }
191
 
192
  .wpstg-step-num {
193
- border: 1px solid #444;
194
  border-radius: 3px;
195
  display: inline-block;
196
  width: 20px;
@@ -204,7 +231,7 @@
204
  }
205
 
206
  .wpstg-current-step .wpstg-step-num {
207
- background: #444;
208
  color: #eee;
209
  }
210
 
@@ -217,13 +244,14 @@
217
  }
218
 
219
  .wpstg-clone {
220
- margin-bottom: 3px;
221
  padding: 16px;
222
  position: relative;
223
  transition: border-color .2s ease-in-out;
224
- background-color: #25a1f0;
225
- border-radius: .25rem;
226
- box-shadow: 0 0 1px rgba(0,0,0,.125), 0 1px 3px rgba(0,0,0,.2);
 
227
  }
228
 
229
  .wpstg-clone.active {
@@ -242,16 +270,16 @@
242
  max-width: 300px;
243
  text-decoration: none;
244
  font-weight: bold;
245
- color: white;
246
  }
247
 
248
  .wpstg-clone-title:hover {
249
- color: #f1f1f1;
250
  }
251
 
252
  .wpstg-clone-actions {
253
  display: flex;
254
- /*align-items: right;*/
255
  }
256
 
257
  .wpstg-dropdown {
@@ -260,12 +288,12 @@
260
 
261
  .wpstg-clone-actions .wpstg-dropdown-toggler {
262
  text-decoration: none;
263
- background: #fff;
264
- padding: 4px 10px;
265
  border-radius: 2px;
266
  font-size: 14px;
267
- box-shadow: 0 0 1px rgba(0,0,0,.125), 0 1px 3px rgba(0,0,0,.2);
268
- color: #002648;
269
  }
270
 
271
  .wpstg-clone-actions .wpstg-dropdown-toggler:hover {
@@ -277,12 +305,7 @@
277
  position: relative;
278
  }
279
 
280
- .wpstg-dropdown-symbol {
281
- font-size: 14px;
282
- margin-left: 4px;
283
- }
284
-
285
- .wpstg-dropdown>.wpstg-dropdown-menu {
286
  background: #fff;
287
  display: none;
288
  flex-direction: column;
@@ -292,37 +315,38 @@
292
  padding: 8px;
293
  border-radius: 2px;
294
  width: 100px;
295
- box-shadow: 0 0 1px rgba(0,0,0,.125), 0 1px 3px rgba(0,0,0,.2);
296
  z-index: 1000;
297
  }
298
 
299
- .wpstg-dropdown>.wpstg-dropdown-menu.wpstg-menu-dropup {
300
  top: auto;
301
  bottom: 100%;
302
  transform: translate3d(0px, -3px, 0px);
303
  }
304
 
305
- .wpstg-dropdown>.wpstg-dropdown-menu.shown {
306
  display: flex;
307
  }
308
 
309
  .wpstg-clone-action,
310
  .wpstg-dropdown-action {
311
- color: #002648;
312
- padding: 5px 8px;
313
  border-radius: 3px;
314
  text-decoration: none;
315
  position: relative;
316
  transition: color .2s ease-in-out;
 
317
  }
318
 
319
  .wpstg-clone-action:hover,
320
  .wpstg-dropdown-action:hover {
321
- background: rgba(0,0,0,0.05);
322
  }
323
 
324
  .wpstg-dropdown-action {
325
- color: #333;
326
  background: transparent;
327
  border: 0 solid black;
328
  outline: none;
@@ -330,7 +354,7 @@
330
  }
331
 
332
  .wpstg-remove-clone:hover {
333
- color: #ef6d6d;
334
  }
335
 
336
  .wpstg-clone-action:last-child {
@@ -370,13 +394,12 @@
370
 
371
  .wpstg-link-btn[disabled] {
372
  background: #777 !important;
 
373
  pointer-events: none;
374
  }
375
 
376
  #wpstg-cancel-cloning,
377
  #wpstg-cancel-cloning-update {
378
- background: #ff3428;
379
- border-color: #e72f24;
380
  margin-top: 5px;
381
  }
382
 
@@ -407,7 +430,7 @@
407
  }
408
 
409
  #wpstg-error-details {
410
- border-left: 5px solid #ef6d6d;
411
  padding: 10px;
412
  width: 500px;
413
  }
@@ -422,7 +445,7 @@
422
 
423
  .wpstg-loader {
424
  content: url('../../img/loading.gif');
425
- margin-top: 5px;
426
  display: none;
427
  }
428
 
@@ -437,13 +460,12 @@
437
  }
438
 
439
  #wpstg-workflow {
440
- max-width: 650px;
441
  position: relative;
442
  clear: both;
443
  padding-top: 20px;
444
  float: left;
445
  min-width: 500px;
446
- /*border-right: 1px solid #DFDFDF;*/
447
  min-height: 380px;
448
  padding-right: 20px;
449
  padding-bottom: 20px;
@@ -456,12 +478,6 @@
456
  margin-left: 10px;
457
  }
458
 
459
- @media screen and (max-width: 1150px) {
460
- #wpstg-sidebar img {
461
- margin-top: 30px;
462
- }
463
- }
464
-
465
  #wpstg-workflow.loading::after,
466
  #wpstg-removing-clone.loading::after {
467
  background: rgba(255, 255, 255, .7);
@@ -487,6 +503,10 @@
487
  position: relative;
488
  }
489
 
 
 
 
 
490
  #wpstg-removing-clone .wpstg-tab-section {
491
  display: block;
492
  }
@@ -522,10 +542,16 @@
522
 
523
  #wpstg-new-clone-id.wpstg-error-input,
524
  #wpstg-clone-path.wpstg-error-input {
525
- border: 1px solid #ff4235;
526
  box-shadow: 0 0 2px rgba(255, 66, 53, .8);
527
  }
528
 
 
 
 
 
 
 
529
  #wpstg-new-clone {
530
  background: #25a1f0;
531
  border-color: #2188c9;
@@ -542,7 +568,7 @@
542
  }
543
 
544
  .wpstg-error-msg {
545
- color: #ff4235;
546
  }
547
 
548
  #wpstg-clone-id-error {
@@ -552,7 +578,7 @@
552
  margin: 20px;
553
  }
554
 
555
- #wpstg-start-cloning+.wpstg-error-msg {
556
  display: block;
557
  margin-top: 5px;
558
  }
@@ -573,9 +599,7 @@
573
  }
574
 
575
  #wpstg-workflow #wpstg-start-cloning {
576
- display: inline-block;
577
  margin-left: 5px;
578
- font-size: 14px;
579
  vertical-align: baseline;
580
  }
581
 
@@ -593,22 +617,13 @@
593
  margin-bottom: 10px;
594
  }
595
 
596
-
597
- /* unused class should be removed or commented
598
- .wpstg-tabs-wrapper {
599
- border: 1px solid #ddd;
600
- border-right: none;
601
- border-left: none;
602
- }
603
- */
604
-
605
  .wpstg-tab-section {
606
  border-bottom: 1px solid #ddd;
607
  border-right: none;
608
  border-left: none;
609
  display: none;
610
- width: 100%;
611
- padding: 20px;
612
  }
613
 
614
  .wpstg-tab-section::after {
@@ -623,10 +638,9 @@
623
  border-left: none;
624
  color: #444;
625
  font-size: 16px;
626
- font-weight: bolder;
627
  display: block;
628
- padding: 10px;
629
- ;
630
  text-decoration: none;
631
  }
632
 
@@ -645,7 +659,6 @@
645
  #wpstg-large-files {
646
  display: none;
647
  border: 1px dashed #ccc;
648
- /*float: right;*/
649
  padding: 10px 10px 10px;
650
  margin-top: 20px;
651
  position: relative;
@@ -661,9 +674,6 @@
661
  left: 5px;
662
  }
663
 
664
-
665
- /* tmp */
666
-
667
  .wpstg-subdir {
668
  display: none;
669
  margin-left: 20px;
@@ -687,20 +697,36 @@
687
 
688
  .wpstg-notice-alert {
689
  display: block;
690
- background-color: #FFD0D0;
 
 
 
 
 
 
 
 
 
691
  padding: 20px;
692
- border-radius: 6px;
693
- border: 1px solid #FFAAAA;
694
  max-width: 600px;
695
  margin-top: 10px;
696
  }
697
 
 
 
 
 
 
 
 
 
698
  .wpstg-header {
699
  font-weight: 400;
700
  line-height: 1.6em;
701
  font-size: 19px;
702
  border-bottom: 1px solid #DFDFDF;
703
  clear: both;
 
704
  }
705
 
706
  #wpstg-clone-label {
@@ -813,40 +839,6 @@
813
  margin-left: 8px;
814
  }
815
 
816
-
817
- /* welcome screen */
818
-
819
- .wpstg-button.green {
820
- display: inline-block;
821
- padding: 10px;
822
- min-width: 170px;
823
- font-size: 16px;
824
- text-decoration: none;
825
- text-align: center;
826
- margin-top: 20px;
827
- background-color: #83c11f;
828
- color: white;
829
- }
830
-
831
- .wpstg-button.green:hover {
832
- background-color: #8ed122;
833
- }
834
-
835
- .wpstg-button.wpstg-save {
836
- background-color: #1687A7;
837
- color: white;
838
- }
839
-
840
- .wpstg-button.wpstg-save:hover {
841
- background-color: #276678;
842
- }
843
-
844
- .wpstg-button.wpstg-bordered {
845
- border-radius:3px;
846
- font-size: 14px;
847
- border: 1px solid white;
848
- }
849
-
850
  #wpstg-welcome li {
851
  font-size: 18px;
852
  line-height: 29px;
@@ -862,7 +854,6 @@
862
  }
863
 
864
  .wpstg-heading-pro {
865
- color: #0080ff;
866
  font-weight: bold;
867
  }
868
 
@@ -880,7 +871,7 @@
880
  background-size: contain;
881
  content: "";
882
  position: absolute;
883
- top: 0;
884
  left: 0;
885
  color: #77b227;
886
  }
@@ -893,7 +884,7 @@
893
  }
894
 
895
  .swal2-content h1 {
896
- color:#444;
897
  }
898
 
899
  #wpstg-welcome h2 {
@@ -908,24 +899,37 @@
908
 
909
  #wpstg-footer {
910
  clear: both;
911
- background-color: white;
912
- padding: 20px;
913
  margin-top: 20px;
914
  margin-right: 10px;
 
915
  }
916
 
917
  #wpstg-footer a {
918
  text-decoration: none;
919
  }
920
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
921
  .wpstg-staging-info {
922
  margin-top: 8px;
923
- color: white;
924
  font-size: 12px;
925
  }
926
 
927
  .wpstg-staging-info a {
928
- color: white;
929
  }
930
 
931
  .wpstg-staging-info li {
@@ -952,47 +956,21 @@
952
 
953
  #wpstg-report-issue-button {
954
  margin-left: 50px;
955
- border: 1px solid #ef5a4b;
956
- color: #ef5a4b;
957
  background-color: white;
958
  }
959
 
960
  #wpstg-report-issue-button:hover {
961
- background-color: #e74c3c;
962
  color: #fff;
963
  }
964
 
965
- .wpstg-button {
966
- display: inline-block;
967
- background-color: transparent;
968
- color: #95a5a6;
969
- border-radius: 3px;
970
- cursor: pointer;
971
- padding: 2px 10px 2px 10px;
972
- text-transform: uppercase;
973
- font-weight: 500;
974
- outline: 0;
975
- transition: background-color .1s ease-in;
976
- text-decoration: none;
977
- }
978
-
979
- .wpstg-button.wpstg-button-light {
980
- background-color: #f8f8f8;
981
- border: 1px solid #eee;
982
- color: #333;
983
- animation: background-color 0.3s;
984
- }
985
-
986
- .wpstg-button.wpstg-button-light:hover {
987
- background-color: #e0e0e0;
988
- border: 1px solid #e0e0e0;
989
- }
990
-
991
  .wpstg-blue-primary {
992
  display: inline-block;
993
  text-decoration: none;
994
  font-size: 13px;
995
- line-height: 26px;
996
  height: 28px;
997
  margin: 0;
998
  padding: 0 10px 1px;
@@ -1015,7 +993,7 @@
1015
 
1016
  .wpstg-report-issue-form {
1017
  position: absolute;
1018
- z-index: 9999;
1019
  width: 300px;
1020
  background-color: #fff;
1021
  padding: 15px 15px 10px;
@@ -1023,7 +1001,14 @@
1023
  border-radius: 3px;
1024
  box-shadow: 0 1px 0 0 #fff inset;
1025
  display: none;
1026
- margin: 67px 0 0 123px;
 
 
 
 
 
 
 
1027
  }
1028
 
1029
  .wpstg-report-show {
@@ -1065,11 +1050,11 @@
1065
  #wpstg-report-cancel {
1066
  float: right;
1067
  margin-right: 5px;
 
1068
  }
1069
 
1070
- .wpstg-buttons .spinner {
1071
- float: none;
1072
- margin: 0 0 0 5px;
1073
  }
1074
 
1075
  .wpstg-message {
@@ -1117,10 +1102,13 @@
1117
 
1118
  .wpstg-error {
1119
  display: block;
1120
- padding: 10px;
1121
- background-color: #fe6501;
1122
  color: #ffffff;
1123
- margin: 10px 10px 10px 0;
 
 
 
1124
  }
1125
 
1126
  .wpstg-error a {
@@ -1153,10 +1141,10 @@
1153
  text-align: center;
1154
  }
1155
 
1156
- .wpstg-text-field>#wpstg-db-status {
1157
  margin-top: 8px;
1158
- margin-left: 25%;
1159
- min-width: 350px;
1160
  }
1161
 
1162
  .wpstg-success {
@@ -1177,12 +1165,11 @@
1177
  }
1178
 
1179
  #wpstg-update-notify {
1180
- background-color: #fe6501;
1181
  font-size: 14px;
1182
  color: #ffffff;
1183
  line-height: normal;
1184
  padding: 10px;
1185
- margin-right: 10px;
1186
  }
1187
 
1188
  #wpstg-update-notify a {
@@ -1194,12 +1181,25 @@
1194
  cursor: pointer;
1195
  }
1196
 
 
 
 
 
 
 
 
 
 
 
 
 
1197
  .wpstg--tab--header ul {
1198
  display: flex;
1199
  }
1200
 
1201
  .wpstg--tab--header ul li {
1202
  margin-right: 1em;
 
1203
  }
1204
 
1205
  .wpstg--tab--header ul li:last-child {
@@ -1212,11 +1212,22 @@
1212
  cursor: pointer;
1213
  display: inline-block;
1214
  padding: 1em 1.25em;
 
 
 
 
1215
  border: solid 1px;
 
1216
  }
1217
 
1218
  .wpstg--tab--header a.wpstg--tab--active {
1219
- border-bottom: .5em solid #25A1F0;
 
 
 
 
 
 
1220
  color: #25A1F0;
1221
  }
1222
 
@@ -1250,29 +1261,31 @@
1250
  background-color: #ffffff;
1251
  color: #505050;
1252
  text-align: left;
1253
- padding: 20px;
1254
- border: 1px solid #e8e8e8;
1255
  border-radius: 3px;
1256
  position: absolute;
1257
  z-index: 1;
1258
- -webkit-box-shadow: -1px 1px 5px 0 rgba(0, 0, 0, 0.75);
1259
- -moz-box-shadow: -1px 1px 5px 0 rgba(0, 0, 0, 0.75);
1260
- box-shadow: -1px 1px 5px 0 rgba(0, 0, 0, 0.75);
1261
- }
1262
-
1263
- .wpstg--tooltip:hover .wpstg--tooltiptext {
1264
- visibility: visible;
1265
  }
1266
 
1267
  .wpstg--tooltiptext-backups {
1268
  width: 120px;
1269
  top: 100%;
1270
  left: -150%;
1271
- margin-left: -60px;
1272
- /* Use half of the width (120/2 = 60), to center the tooltip */
1273
- margin-top: 10px;
 
 
 
1274
  }
1275
 
 
 
 
 
1276
 
1277
  /**
1278
  Tooltip top arrow
@@ -1290,6 +1303,21 @@ Tooltip top arrow
1290
  border-color: transparent transparent white transparent;
1291
  }
1292
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1293
  .wpstg--snaphot-restore-table tr {
1294
  line-height: 12px;
1295
  }
@@ -1332,18 +1360,21 @@ Tooltip top arrow
1332
  border-color: #e72f24;
1333
  }
1334
 
1335
- .wpstg--process--content>.swal2-html-container {
1336
  padding: 4em 2em !important;
1337
  }
1338
 
1339
  .wpstg--modal--process--logs,
1340
  .wpstg--modal--error--logs {
1341
- background: black;
 
 
1342
  height: 300px;
1343
  margin-top: 1em;
1344
  display: none;
1345
- padding: 1em;
1346
- overflow-x: auto;
 
1347
  text-align: justify;
1348
  }
1349
 
@@ -1352,23 +1383,47 @@ Tooltip top arrow
1352
  max-height: 300px;
1353
  }
1354
 
1355
- .wpstg--modal--process--logs>p,
1356
- .wpstg--modal--error--logs>p {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1357
  text-align: left;
1358
  font-size: 14px;
 
1359
  }
1360
 
1361
  .wpstg--modal--process--logs p,
1362
  .wpstg--modal--error--logs p {
1363
- margin: .3em 0;
 
1364
  }
1365
 
1366
  .wpstg--modal--process--msg--error {
1367
- color: darkred;
1368
  }
1369
 
1370
  .wpstg--modal--process--msg--critical {
1371
- color: red;
1372
  }
1373
 
1374
  .wpstg--modal--process--msg--warning {
@@ -1376,43 +1431,44 @@ Tooltip top arrow
1376
  }
1377
 
1378
  .wpstg--modal--process--msg-found {
1379
- color: #f56363;
 
 
1380
  }
1381
 
1382
- body.toplevel_page_wpstg_clone .swal2-modal .swal2-cancel.wpstg--btn--cancel {
1383
- margin-bottom: 0;
 
 
1384
  }
1385
 
1386
- body.toplevel_page_wpstg_clone .swal2-modal .swal2-confirm.wpstg--btn--confirm {
1387
- font-size: 16px;
1388
- padding: .5em;
1389
- line-height: normal;
1390
- height: auto;
1391
- margin-right: 10px;
1392
  }
1393
 
1394
- body.toplevel_page_wpstg_clone .swal2-modal .wpstg-loader {
1395
  display: inline-block !important;
1396
  }
1397
 
1398
  .wpstg--modal--process--generic-problem {
1399
  display: none;
1400
- border-left: 5px solid #ef6d6d;
1401
  margin: .5em 0;
1402
  }
1403
 
1404
  .wpstg--modal--process--logs--tail {
1405
- color: #a8a8a8;
 
1406
  background: none;
1407
  border: none;
1408
  cursor: pointer;
1409
  }
1410
 
1411
  .wpstg--modal--backup--import--upload--title {
1412
- color: #505050;
1413
  }
1414
 
1415
- .wpstg--modal--backup--import--filesystem,
1416
  .wpstg--modal--backup--import--configure,
1417
  .wpstg--modal--backup--import--upload--status,
1418
  .wpstg--modal--backup--import--upload--container input[type="file"] {
@@ -1425,7 +1481,7 @@ body.toplevel_page_wpstg_clone .swal2-modal .wpstg-loader {
1425
  }
1426
 
1427
  #wpstg--backups--import--file-list-empty {
1428
- color: red;
1429
  }
1430
 
1431
  .wpstg--modal--backup--import--filesystem label {
@@ -1436,40 +1492,27 @@ body.toplevel_page_wpstg_clone .swal2-modal .wpstg-loader {
1436
  margin-bottom: 20px;
1437
  }
1438
 
1439
- .wpstg--modal--backup--import--upload,
1440
- .wpstg--modal--backup--import--filesystem {
 
 
 
 
1441
  color: #505050;
1442
  }
1443
 
1444
  .wpstg--modal--backup--import--upload--container {
1445
  position: relative;
1446
- border-radius: 1em;
1447
  margin: .5em;
1448
  padding: 1em .5em;
1449
- border: .4em dashed #dedede;
1450
- display: flex;
1451
- flex-direction: column;
1452
- }
1453
-
1454
- .wpstg--modal--backup--import--upload--container .wpstg--uploader {
1455
- display: flex;
1456
- flex-direction: column;
1457
- }
1458
-
1459
- .wpstg--modal--backup--import--upload--container.wpstg--has-dragover {
1460
- background-color: #9a9a9a;
1461
- color: white;
1462
- }
1463
-
1464
- .wpstg--modal--backup--import--upload--container span.wpstg--drop,
1465
- .wpstg--modal--backup--import--upload--container.wpstg--has-dragover span.wpstg--drag,
1466
- span.wpstg--backup--import--selected-file,
1467
- span.wpstg--drag-or-upload {
1468
- display: none;
1469
  }
1470
 
1471
  .wpstg--modal--backup--import--upload--container.wpstg--has-dragover span.wpstg--drop {
1472
- display: inline-block;
1473
  }
1474
 
1475
  .wpstg--modal--backup--import--upload--container input[type='file'] {
@@ -1486,7 +1529,7 @@ span.wpstg--drag-or-upload {
1486
  margin-top: 1em;
1487
  }
1488
 
1489
- .wpstg--backup--import--options>button {
1490
  margin-top: 1em;
1491
  padding: 1em;
1492
  align-self: center;
@@ -1495,15 +1538,6 @@ span.wpstg--drag-or-upload {
1495
  line-height: normal;
1496
  }
1497
 
1498
-
1499
- /*.wpstg--backup--import--options.wpstg--show-options > button {
1500
- background: white;
1501
- border-radius: 3px 3px 0 0;
1502
- border: .25em solid #25a1f0;
1503
- text-shadow: none;
1504
- color: #2e3436;
1505
- }*/
1506
-
1507
  .wpstg--backup--import--options {
1508
  position: relative;
1509
  display: flex;
@@ -1567,15 +1601,6 @@ span.wpstg--drag-or-upload {
1567
  margin: 0;
1568
  }
1569
 
1570
-
1571
- /* unused class should be removed or commented
1572
- .wpstg--modal--backup--import--search-replace--wrapper {
1573
- display: flex;
1574
- flex-direction: row;
1575
- padding: 0 5em;
1576
- }
1577
- */
1578
-
1579
  .wpstg--modal--backup--import--search-replace--wrapper button {
1580
  align-self: center;
1581
  }
@@ -1598,7 +1623,7 @@ span.wpstg--drag-or-upload {
1598
  background-color: #25a1f0;
1599
  width: 22px;
1600
  height: 22px;
1601
- margin-left:5px;
1602
  }
1603
 
1604
  .wpstg--modal--backup--import--search-replace--input-group:first-child button {
@@ -1631,29 +1656,28 @@ span.wpstg--drag-or-upload {
1631
 
1632
  .wpstg--modal--import--upload--process {
1633
  display: none;
1634
- position: absolute;
1635
- /*display: flex;*/
 
 
1636
  width: 100%;
1637
- height: 100%;
1638
  top: 0;
1639
  left: 0;
1640
  text-indent: 1em;
1641
  white-space: nowrap;
1642
  overflow: hidden;
1643
- color: #898989;
1644
- mix-blend-mode: difference;
1645
  justify-content: center;
1646
  align-items: center;
1647
  }
1648
 
1649
  .wpstg--modal--import--upload--progress {
1650
  position: absolute;
1651
- background: #dedede;
1652
  color: white;
1653
- width: 0;
1654
  height: 100%;
1655
- border-radius: 1em;
1656
- left: -1px;
1657
  top: 0;
1658
  }
1659
 
@@ -1667,55 +1691,61 @@ span.wpstg--drag-or-upload {
1667
  margin-top: 20px;
1668
  }
1669
 
 
 
 
 
1670
  .wpstg-fs-14 {
1671
  font-size: 14px;
1672
  }
1673
 
1674
- .wpstg-light-alert {
1675
  font-weight: bold;
1676
- background-color: #e6e6e6;
1677
  padding: 15px;
1678
- border-top: 1px solid white;
1679
- margin-top: 20px;
 
 
 
 
1680
  }
1681
 
1682
  .wpstg-form-group {
1683
- display: flex;
1684
- flex-wrap: wrap;
1685
  width: 100%;
1686
  margin-bottom: 8px;
 
1687
  }
1688
 
1689
- .wpstg-form-group>label {
1690
- display: inline-block;
1691
  font-weight: 700;
1692
- min-width: 25%;
1693
- width: 25%;
1694
  }
1695
 
1696
- .wpstg-text-field>input {
1697
- width: 350px;
1698
- display: inline-block;
 
1699
  }
1700
 
1701
  .wpstg-code-segment {
1702
  display: block;
1703
  }
1704
 
1705
- .wpstg-text-field>.wpstg-code-segment {
1706
  margin-top: 4px;
1707
- margin-left: 25%;
1708
- min-width: 350px;
1709
  }
1710
 
1711
- .wpstg-form-group>.wpstg-checkbox {
1712
  min-width: 100%;
1713
  width: 100%;
1714
  position: relative;
1715
  }
1716
 
1717
- .wpstg-form-group>.wpstg-checkbox>input[type='checkbox'] {
1718
- left: 25%;
1719
  }
1720
 
1721
  .wpstg-rounded {
@@ -1726,12 +1756,8 @@ span.wpstg--drag-or-upload {
1726
  border: 1px solid white !important;
1727
  }
1728
 
1729
- .wpstg-mt-16 {
1730
- margin-top: 16px;
1731
- }
1732
-
1733
- .wpstg-w-100pc {
1734
- width: 100%;
1735
  }
1736
 
1737
  #wpstg-confirm-backup-restore-data {
@@ -1739,22 +1765,6 @@ span.wpstg--drag-or-upload {
1739
  text-align: left;
1740
  }
1741
 
1742
- #wpstg-confirm-backup-restore-wrapper {
1743
- margin: 30px;
1744
- }
1745
-
1746
- #wpstg-confirm-backup-restore-wrapper h3 {
1747
- color: #f56363;
1748
- }
1749
-
1750
- #swal2-content h2 {
1751
- color: #a8a8a8;
1752
- }
1753
-
1754
- #wpstg_allow_emails {
1755
- margin-left: 10px;
1756
- }
1757
-
1758
  #wpstg-advanced-settings hr {
1759
  margin: 20px 0;
1760
  }
@@ -1786,86 +1796,41 @@ span.wpstg--drag-or-upload {
1786
  width: 390px;
1787
  }
1788
 
1789
- #wpstg_symlink_upload {
1790
- margin-left: 10px;
1791
- }
1792
-
1793
- .wpstg-fieldset:disabled {
1794
- opacity: 0.8;
1795
- border-top: 1px solid white;
1796
- margin-top: 20px;
1797
- }
1798
-
1799
  .wpstg-fs-14 {
1800
  font-size: 14px;
1801
  }
1802
 
1803
- .wpstg-light-alert {
1804
- font-weight: bold;
1805
- background-color: #e6e6e6;
1806
- padding: 15px;
1807
- border-top: 1px solid white;
1808
- margin-top: 20px;
1809
- }
1810
-
1811
- .wpstg-form-group {
1812
- display: flex;
1813
- flex-wrap: wrap;
1814
- width: 100%;
1815
- margin-bottom: 8px;
1816
- }
1817
-
1818
- .wpstg-form-group>label {
1819
- display: inline-block;
1820
- font-weight: 700;
1821
- min-width: 25%;
1822
- width: 25%;
1823
- }
1824
-
1825
- .wpstg-text-field>input {
1826
- width: 350px;
1827
- display: inline-block;
1828
- }
1829
-
1830
  .wpstg-code-segment {
1831
  display: block;
1832
  }
1833
 
1834
- .wpstg-text-field>.wpstg-code-segment {
1835
- margin-top: 4px;
1836
- margin-left: 25%;
1837
- min-width: 350px;
1838
- }
1839
-
1840
- .wpstg-form-group>.wpstg-checkbox {
1841
  min-width: 100%;
1842
  width: 100%;
1843
  }
1844
 
1845
- .wpstg-form-group>.wpstg-checkbox>input[type='checkbox'] {
1846
  margin-left: 10px;
1847
  }
1848
 
1849
  @media only screen and (max-width: 768px) {
1850
- .wpstg-form-group {
1851
- display: block;
1852
- }
1853
- .wpstg-form-group>label {
1854
- display: block;
1855
  min-width: auto;
1856
  width: auto;
1857
  }
1858
- .wpstg-text-field>input {
 
1859
  width: 100%;
1860
- display: block;
1861
  }
1862
- .wpstg-text-field>.wpstg-code-segment {
 
1863
  margin-left: 0;
1864
  min-width: 100%;
1865
  }
 
1866
  .wpstg-tab-section {
1867
  width: calc(100vw - 60px);
1868
- max-width: calc(100vw - 60px);
1869
  }
1870
  }
1871
 
@@ -1881,10 +1846,6 @@ span.wpstg--drag-or-upload {
1881
  margin: 0;
1882
  }
1883
 
1884
- .wpstg-mt-16 {
1885
- margin-top: 16px;
1886
- }
1887
-
1888
  .wpstg-mt-10px {
1889
  margin-top: 10px;
1890
  }
@@ -1906,23 +1867,10 @@ span.wpstg--drag-or-upload {
1906
  float: left;
1907
  }
1908
 
1909
- .wpstg-fivestar {
1910
- border-left: none;
1911
- background-color: #59a7f7;
1912
- color: white;
1913
- padding: 10px;
1914
- margin: 10px 10px 10px 0;
1915
- }
1916
-
1917
  .wpstg-bold-text {
1918
  font-weight: bold;
1919
  }
1920
 
1921
- .wpstg-rating-link {
1922
- font-weight: normal;
1923
- color: white;
1924
- }
1925
-
1926
  .wpstg-warning.notice {
1927
  border-left: 4px solid #ffba00;
1928
  }
@@ -1943,18 +1891,10 @@ span.wpstg--drag-or-upload {
1943
  margin-bottom: 10px;
1944
  }
1945
 
1946
- .wpstg-opacity-80 {
1947
- opacity: 0.8;
1948
- }
1949
-
1950
  .wpstg-clear-both {
1951
  clear: both;
1952
  }
1953
 
1954
- .wpstg-fs-10px {
1955
- font-size: 10px;
1956
- }
1957
-
1958
  .wpstg-font-italic {
1959
  font-style: italic;
1960
  }
@@ -1979,13 +1919,11 @@ span.wpstg--drag-or-upload {
1979
 
1980
  .wpstg-feedback-link {
1981
  text-decoration: none;
1982
- color: #abc116
1983
  }
1984
 
1985
  .wpstg-feedback-span {
1986
  display: block;
1987
- margin-bottom: 20px;
1988
- color: #abc116;
1989
  }
1990
 
1991
  #wpstg-confirm-backup-restore-data {
@@ -1995,19 +1933,11 @@ span.wpstg--drag-or-upload {
1995
 
1996
  #wpstg-confirm-backup-restore-wrapper {
1997
  margin: 30px;
 
1998
  }
1999
 
2000
  #wpstg-confirm-backup-restore-wrapper h3 {
2001
- color: #f56363;
2002
- }
2003
-
2004
- #wpstg-footer {
2005
- clear: both;
2006
- padding-top: 20px;
2007
- }
2008
-
2009
- #swal2-content h2 {
2010
- color: #a8a8a8;
2011
  }
2012
 
2013
  #wpstg-progress-db,
@@ -2030,7 +1960,7 @@ span.wpstg--drag-or-upload {
2030
  background-color: #378cc9;
2031
  }
2032
 
2033
- .wpstg-issue-resubmit-confirmation.swal2-container,
2034
  .wpstg-swal2-container.swal2-container {
2035
  z-index: 10500;
2036
  }
@@ -2040,8 +1970,17 @@ span.wpstg--drag-or-upload {
2040
  display: none;
2041
  }
2042
 
 
2043
  body.toplevel_page_wpstg_clone .swal2-container .swal2-content {
2044
- z-index:2;
 
 
 
 
 
 
 
 
2045
  }
2046
 
2047
  div#exportUploadsWithoutDatabaseWarning {
@@ -2073,7 +2012,7 @@ div#exportUploadsWithoutDatabaseWarning {
2073
  display: inline-block;
2074
  }
2075
 
2076
- .wpstg-import-backup-contains li .dashicons{
2077
  border-radius: 3px;
2078
  color: #979797;
2079
  background-color: #e3e3e3;
@@ -2083,11 +2022,14 @@ div#exportUploadsWithoutDatabaseWarning {
2083
  font-size: 17px;
2084
  }
2085
 
2086
- .wpstg-import-backup-contains.wpstg-listing-single-backup li .dashicons{
2087
  padding: 2px;
2088
- color: #ffffff;
2089
- background-color: #2896dd;
2090
- border: 1px solid #0c75b8;
 
 
 
2091
  }
2092
 
2093
  .wpstg-import-backup-contains .wpstg--tooltiptext {
@@ -2115,11 +2057,11 @@ ul.wpstg-import-backup-contains {
2115
  font-size: x-small;
2116
  display: inline-block;
2117
  font-style: italic;
2118
- cursor:pointer;
2119
  }
2120
 
2121
  .wpstg-backup-more-info-toggle::selection {
2122
- background:none;
2123
  }
2124
 
2125
  ul.wpstg-import-backup-more-info {
@@ -2143,6 +2085,14 @@ ul.wpstg-import-backup-more-info li {
2143
  height: 20px;
2144
  }
2145
 
 
 
 
 
 
 
 
 
2146
  .wpstg-backup-list ul ul {
2147
  margin-block-start: 1em;
2148
  margin-block-end: 1em;
@@ -2150,6 +2100,7 @@ ul.wpstg-import-backup-more-info li {
2150
 
2151
  .wpstg-push-confirmation-message {
2152
  text-align: justify;
 
2153
  }
2154
 
2155
  .wpstg-settings-row {
@@ -2178,9 +2129,9 @@ ul.wpstg-import-backup-more-info li {
2178
 
2179
  .wpstg-excluded-filters-container {
2180
  padding: 0;
2181
- margin-top: 10px;
2182
  margin-bottom: 10px;
2183
- max-width: 100%;
2184
  width: 100%;
2185
  }
2186
 
@@ -2200,53 +2151,16 @@ ul.wpstg-import-backup-more-info li {
2200
  margin: 0;
2201
  }
2202
 
2203
- /*.wpstg-excluded-filters-container tbody {
2204
- background: #fff !important;
2205
- }*/
2206
-
2207
  .wpstg-exclude-filters-foot {
2208
  display: flex;
2209
  justify-content: flex-start;
2210
  padding: 0;
2211
  }
2212
 
2213
- .wpstg-excluded-filters-container .wpstg-exclude-filter-name-column {
2214
- width: 100px;
2215
- max-width: 100px !important;
2216
- padding-left: 10px;
2217
- }
2218
-
2219
- .wpstg-excluded-filters-container .wpstg-exclude-filter-action-column {
2220
- width: 50px;
2221
- max-width: 50px;
2222
- text-align: right !important;
2223
- padding-right: 10px;
2224
- }
2225
-
2226
- .wpstg-excluded-filters-container .wpstg-exclude-filter-exclusion-column {
2227
- width: 320px;
2228
- position: relative;
2229
- }
2230
-
2231
  /**
2232
  * WP STAGING EXCLUSION RULE DROPDOWN STYLE
2233
  */
2234
 
2235
- .wpstg-exclude-filter-dropdown > button {
2236
- background: #25A0F1;
2237
- border: 1px solid #25A0F1;
2238
- color: #fff;
2239
- padding: 1px 5px;
2240
- display: inline-block;
2241
- font-weight: 400;
2242
- line-height: 1.5;
2243
- text-align: center;
2244
- border-radius: 0;
2245
- outline: none;
2246
- box-shadow: none;
2247
- cursor: pointer;
2248
- height: 24px;
2249
- }
2250
 
2251
  .wpstg-exclude-filter-dropdown > button:hover {
2252
  background: #135e96;;
@@ -2259,15 +2173,15 @@ ul.wpstg-import-backup-more-info li {
2259
 
2260
  .wpstg-remove-exclude-rule {
2261
  color: #fff !important;
2262
- background-color: #dc3545;
2263
- border: 1px solid #dc3545;
2264
  width: 20px;
2265
- height: 20px;
2266
- border-radius: 10px;
2267
- font-size: 24px;
2268
- padding: 0;
2269
- display: inline-flex;
2270
- justify-content: center;
2271
  outline: none;
2272
  box-shadow: none;
2273
  font-weight: 400;
@@ -2277,39 +2191,15 @@ ul.wpstg-import-backup-more-info li {
2277
  }
2278
 
2279
  .wpstg-remove-exclude-rule:hover {
2280
- background-color: #bb2d3b;
2281
- border-color: #bb2d3b;
2282
- }
2283
-
2284
- /**
2285
- * WP STAGING POPOVER EXCLUSION RULES INFO
2286
- */
2287
-
2288
- .wpstg-popover {
2289
- display: inline-block;
2290
- position: relative;
2291
- }
2292
-
2293
- .wpstg-popover button + p {
2294
- position: absolute;
2295
- top: 18px;
2296
- right: -150px;
2297
- display: none;
2298
- width: 320px;
2299
- z-index: 1024;
2300
- padding: 10px !important;
2301
- box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
2302
- }
2303
-
2304
- .wpstg-popover button:hover + p {
2305
- display: block;
2306
  }
2307
 
2308
  .wpstg-code-block {
2309
- margin-top: 4px;
2310
- font-size: 1.2em;
2311
- background: #f8f8f8;
2312
- border-radius: 2px;
2313
  }
2314
 
2315
  .wpstg-rule-info {
@@ -2319,11 +2209,11 @@ ul.wpstg-import-backup-more-info li {
2319
  code.wpstg-code {
2320
  display: inline-block;
2321
  font-size: 11px;
2322
- border: 1px solid #aaa;
2323
- background: #fff;
2324
- padding: 2px 4px;
2325
  margin-bottom: 1px;
2326
- color: #ff6666;
2327
  }
2328
 
2329
  .wpstg-exclusion-rule-info {
@@ -2331,12 +2221,12 @@ code.wpstg-code {
2331
  background-color: #ffc107;
2332
  border: 1px solid #ffc107;
2333
  width: 14px;
2334
- height: 14px;
2335
- border-radius: 7px;
2336
- font-size: 14px;
2337
- padding: 0;
2338
- display: inline-flex;
2339
- justify-content: center;
2340
  align-items: center;
2341
  outline: none;
2342
  box-shadow: none;
@@ -2353,7 +2243,7 @@ code.wpstg-code {
2353
  * WP STAGING INPUTS EXCLUSION RULES
2354
  */
2355
 
2356
- .wpstg-exclude-rule-input {
2357
  font-size: 12px !important;
2358
  padding: 2px 6px;
2359
  box-shadow: none;
@@ -2369,12 +2259,12 @@ code.wpstg-code {
2369
  margin-top: 4px;
2370
  margin-left: 4px;
2371
  vertical-align: baseline !important;
2372
- transition: all 0.3s cubic-bezier(.25,.8,.25,1);
2373
  width: 135px;
2374
  }
2375
 
2376
  .wpstg-excluded-filters-container tbody > tr:last-child .wpstg-exclude-rule-input {
2377
- margin-bottom: 4px;
2378
  }
2379
 
2380
  .wpstg-exclude-rule-input:hover {
@@ -2383,7 +2273,7 @@ code.wpstg-code {
2383
 
2384
  .wpstg-exclude-rule-input:focus {
2385
  border: 1px solid #25A0F1 !important;
2386
- box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24) !important;
2387
  }
2388
 
2389
  .wpstg-file-size-exclude-select,
@@ -2411,8 +2301,8 @@ code.wpstg-code {
2411
  padding-bottom: 5px;
2412
  }
2413
 
2414
- #wpstg-scanning-files.wpstg-tab-section{
2415
- padding-top:0;
2416
  }
2417
 
2418
  .wpstg-reset-excludes-container {
@@ -2429,12 +2319,12 @@ code.wpstg-code {
2429
  }
2430
 
2431
  @keyframes wpstg-loading-icon-anim {
2432
- 0% {
2433
- transform: rotate(0);
2434
- }
2435
- 100% {
2436
- transform: rotate(360deg);
2437
- }
2438
  }
2439
 
2440
  .wpstg-swal2-ajax-loader > img {
@@ -2448,6 +2338,62 @@ code.wpstg-code {
2448
  width: auto !important;
2449
  }
2450
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2451
  .wpstg-is-dir-loading {
2452
  position: absolute;
2453
  margin-top: -2px;
@@ -2463,19 +2409,17 @@ code.wpstg-code {
2463
  margin-bottom: 8px;
2464
  }
2465
 
2466
- .wpstg-button.danger {
2467
- display: inline-block;
2468
- text-decoration: none;
2469
- text-align: center;
2470
- text-transform: inherit;
2471
- background-color: #e74c3c;
2472
  color: white;
2473
- border-radius: 0px;
2474
- border-color: transparent;
2475
  }
2476
 
2477
- .wpstg-button.danger:hover {
2478
- background-color: #c0392b;
 
2479
  }
2480
 
2481
  .wpstg-swal2-container.wpstg-swal2-loading > .swal2-modal {
@@ -2519,4 +2463,641 @@ code.wpstg-code {
2519
  height: calc(100vh - 350px) !important;
2520
  }
2521
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2522
  /*# sourceMappingURL=wpstg-admin.css.map */
7
  * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
8
  */
9
 
10
+ /* Colors */
11
+
12
+ .wpstg--violet {
13
+ color: #9d37ae;
14
+ }
15
+
16
+ .wpstg-border--violet {
17
+ border: 1px solid #9d37ae;
18
+ }
19
+
20
+ .wpstg--red {
21
+ color: #E01E5A;
22
+ }
23
+
24
+ .wpstg-cta--red {
25
+ color: #fe008f;
26
+ }
27
+
28
+ .wpstg--blue {
29
+ color: #24a1f0;
30
+ }
31
+
32
+ .wpstg--darkblue {
33
+ color: #0e86d9;
34
+ }
35
+
36
+ .wpstg--green {
37
+ color: #83c11f;
38
+ }
39
+
40
+ .wpstg--grey {
41
+ color: #3e3e3e;
42
+ }
43
+
44
+ .wpstg--darkgrey {
45
+ color: #1b1b1b;
46
+ }
47
 
48
  /* CSS for Tabs */
49
 
50
  #wpstg-tab-container ul {
 
51
  list-style: none;
52
  margin: 0;
53
  padding: 0;
54
  background: #f1f1f1;
55
  float: left;
 
56
  }
57
 
58
  #wpstg-tab-container ul li:first-child.selected-tab {
82
  padding: 5px;
83
  }
84
 
85
+ #wpstg-tab-container > ul > li.wpstg-tabs.active {
86
  background-color: white;
87
  }
88
 
128
  #wpstg-tab-container ul {
129
  float: none;
130
  }
131
+
132
+ #wpstg-tab-container .wpstg-form-table tr > th {
133
  width: 100%;
134
  }
135
+
136
  #wpstg-tab-container span.description {
137
  font-size: 14px;
138
  }
139
+
140
+ #wpstg-tab-container .wpstg-form-table tr > th,
141
+ #wpstg-tab-container .wpstg-form-table tr > td {
142
  padding: 10px;
143
  }
144
  }
172
  float: left;
173
  }
174
 
175
+ .wpstg-logo img {
176
+ max-width: 212px;
177
+ }
178
+
179
  .wpstg-version {
180
  display: block;
181
+ padding-top: 34px;
182
+ color: #9b9b9b;
183
  }
184
 
185
  .wpstg_admin .nav-tab {
186
  color: #3C3C3C;
187
  }
188
 
189
+ #wpstg-tab-container table tbody tr:nth-child(1) > th > div {
190
  font-size: 20px;
191
  }
192
 
 
 
 
 
 
193
  /* Cloning workflow */
194
 
195
  #wpstg-clonepage-wrapper {
196
  margin-bottom: 20px;
197
+ width: 98%;
198
  }
199
 
200
  @media screen and (min-width: 1090px) {
202
  float: left;
203
  margin-bottom: 20px;
204
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
205
  }
206
 
207
  #wpstg-steps {
208
+ margin-top: 0px;
209
+ margin-left: 20px;
210
  }
211
 
212
  #wpstg-steps li {
217
  }
218
 
219
  .wpstg-step-num {
220
+ border: 1px solid #3e3e3e;
221
  border-radius: 3px;
222
  display: inline-block;
223
  width: 20px;
231
  }
232
 
233
  .wpstg-current-step .wpstg-step-num {
234
+ background: #3e3e3e;
235
  color: #eee;
236
  }
237
 
244
  }
245
 
246
  .wpstg-clone {
247
+ margin-bottom: 10px;
248
  padding: 16px;
249
  position: relative;
250
  transition: border-color .2s ease-in-out;
251
+ background-color: #ffffff;
252
+ color: #3e3e3e;
253
+ border-radius: 3px;
254
+ box-shadow: 0 0 1px rgba(0, 0, 0, .125), 0 1px 3px rgba(0, 0, 0, .1);
255
  }
256
 
257
  .wpstg-clone.active {
270
  max-width: 300px;
271
  text-decoration: none;
272
  font-weight: bold;
273
+ color: #3e3e3e;
274
  }
275
 
276
  .wpstg-clone-title:hover {
277
+ color: #111111;
278
  }
279
 
280
  .wpstg-clone-actions {
281
  display: flex;
282
+ margin-top: 5px;
283
  }
284
 
285
  .wpstg-dropdown {
288
 
289
  .wpstg-clone-actions .wpstg-dropdown-toggler {
290
  text-decoration: none;
291
+ background: #25a1f0;
292
+ padding: 6px 10px;
293
  border-radius: 2px;
294
  font-size: 14px;
295
+ box-shadow: 0 0 1px rgba(0, 0, 0, .125), 0 1px 3px rgba(0, 0, 0, .2);
296
+ color: #ffffff;
297
  }
298
 
299
  .wpstg-clone-actions .wpstg-dropdown-toggler:hover {
305
  position: relative;
306
  }
307
 
308
+ .wpstg-dropdown > .wpstg-dropdown-menu {
 
 
 
 
 
309
  background: #fff;
310
  display: none;
311
  flex-direction: column;
315
  padding: 8px;
316
  border-radius: 2px;
317
  width: 100px;
318
+ box-shadow: 0 0 1px rgba(0, 0, 0, .125), 0 1px 3px rgba(0, 0, 0, .2);
319
  z-index: 1000;
320
  }
321
 
322
+ .wpstg-dropdown > .wpstg-dropdown-menu.wpstg-menu-dropup {
323
  top: auto;
324
  bottom: 100%;
325
  transform: translate3d(0px, -3px, 0px);
326
  }
327
 
328
+ .wpstg-dropdown > .wpstg-dropdown-menu.shown {
329
  display: flex;
330
  }
331
 
332
  .wpstg-clone-action,
333
  .wpstg-dropdown-action {
334
+ color: #3e3e3e;
335
+ padding: 6px 8px;
336
  border-radius: 3px;
337
  text-decoration: none;
338
  position: relative;
339
  transition: color .2s ease-in-out;
340
+ border-bottom: 1px solid #f3f3f3;
341
  }
342
 
343
  .wpstg-clone-action:hover,
344
  .wpstg-dropdown-action:hover {
345
+ background: rgba(0, 0, 0, 0.05);
346
  }
347
 
348
  .wpstg-dropdown-action {
349
+ color: #3e3e3e;
350
  background: transparent;
351
  border: 0 solid black;
352
  outline: none;
354
  }
355
 
356
  .wpstg-remove-clone:hover {
357
+ color: #E01E5A;
358
  }
359
 
360
  .wpstg-clone-action:last-child {
394
 
395
  .wpstg-link-btn[disabled] {
396
  background: #777 !important;
397
+ border-color: #555 !important;
398
  pointer-events: none;
399
  }
400
 
401
  #wpstg-cancel-cloning,
402
  #wpstg-cancel-cloning-update {
 
 
403
  margin-top: 5px;
404
  }
405
 
430
  }
431
 
432
  #wpstg-error-details {
433
+ border-left: 5px solid #E01E5A;
434
  padding: 10px;
435
  width: 500px;
436
  }
445
 
446
  .wpstg-loader {
447
  content: url('../../img/loading.gif');
448
+ margin-top: 10px;
449
  display: none;
450
  }
451
 
460
  }
461
 
462
  #wpstg-workflow {
463
+ max-width: 800px;
464
  position: relative;
465
  clear: both;
466
  padding-top: 20px;
467
  float: left;
468
  min-width: 500px;
 
469
  min-height: 380px;
470
  padding-right: 20px;
471
  padding-bottom: 20px;
478
  margin-left: 10px;
479
  }
480
 
 
 
 
 
 
 
481
  #wpstg-workflow.loading::after,
482
  #wpstg-removing-clone.loading::after {
483
  background: rgba(255, 255, 255, .7);
503
  position: relative;
504
  }
505
 
506
+ #wpstg-existing-clones h3 {
507
+ color: #3e3e3e;
508
+ }
509
+
510
  #wpstg-removing-clone .wpstg-tab-section {
511
  display: block;
512
  }
542
 
543
  #wpstg-new-clone-id.wpstg-error-input,
544
  #wpstg-clone-path.wpstg-error-input {
545
+ border: 1px solid #E01E5A;
546
  box-shadow: 0 0 2px rgba(255, 66, 53, .8);
547
  }
548
 
549
+ #wpstg-new-clone-id {
550
+ width: 450px;
551
+ max-width: 100%;
552
+ margin-left: 15px;
553
+ }
554
+
555
  #wpstg-new-clone {
556
  background: #25a1f0;
557
  border-color: #2188c9;
568
  }
569
 
570
  .wpstg-error-msg {
571
+ color: #E01E5A;
572
  }
573
 
574
  #wpstg-clone-id-error {
578
  margin: 20px;
579
  }
580
 
581
+ #wpstg-start-cloning + .wpstg-error-msg {
582
  display: block;
583
  margin-top: 5px;
584
  }
599
  }
600
 
601
  #wpstg-workflow #wpstg-start-cloning {
 
602
  margin-left: 5px;
 
603
  vertical-align: baseline;
604
  }
605
 
617
  margin-bottom: 10px;
618
  }
619
 
 
 
 
 
 
 
 
 
 
620
  .wpstg-tab-section {
621
  border-bottom: 1px solid #ddd;
622
  border-right: none;
623
  border-left: none;
624
  display: none;
625
+ width: calc(100% - 72px);
626
+ padding: 0px 36px;
627
  }
628
 
629
  .wpstg-tab-section::after {
638
  border-left: none;
639
  color: #444;
640
  font-size: 16px;
641
+ font-weight: bold;
642
  display: block;
643
+ padding: 10px;;
 
644
  text-decoration: none;
645
  }
646
 
659
  #wpstg-large-files {
660
  display: none;
661
  border: 1px dashed #ccc;
 
662
  padding: 10px 10px 10px;
663
  margin-top: 20px;
664
  position: relative;
674
  left: 5px;
675
  }
676
 
 
 
 
677
  .wpstg-subdir {
678
  display: none;
679
  margin-left: 20px;
697
 
698
  .wpstg-notice-alert {
699
  display: block;
700
+ background-color: #E01E5A;
701
+ padding: 20px;
702
+ max-width: 600px;
703
+ margin-top: 10px;
704
+ color: white;
705
+ }
706
+
707
+ .wpstg-notice--white {
708
+ display: block;
709
+ background-color: #ffffff;
710
  padding: 20px;
 
 
711
  max-width: 600px;
712
  margin-top: 10px;
713
  }
714
 
715
+ .wpstg-notice-alert a {
716
+ color: white;
717
+ }
718
+
719
+ .wpstg-notice-alert h3 {
720
+ color: white;
721
+ }
722
+
723
  .wpstg-header {
724
  font-weight: 400;
725
  line-height: 1.6em;
726
  font-size: 19px;
727
  border-bottom: 1px solid #DFDFDF;
728
  clear: both;
729
+ padding-top: 10px;
730
  }
731
 
732
  #wpstg-clone-label {
839
  margin-left: 8px;
840
  }
841
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
842
  #wpstg-welcome li {
843
  font-size: 18px;
844
  line-height: 29px;
854
  }
855
 
856
  .wpstg-heading-pro {
 
857
  font-weight: bold;
858
  }
859
 
871
  background-size: contain;
872
  content: "";
873
  position: absolute;
874
+ top: -2px;
875
  left: 0;
876
  color: #77b227;
877
  }
884
  }
885
 
886
  .swal2-content h1 {
887
+ color: #444;
888
  }
889
 
890
  #wpstg-welcome h2 {
899
 
900
  #wpstg-footer {
901
  clear: both;
 
 
902
  margin-top: 20px;
903
  margin-right: 10px;
904
+ padding-top: 50px;
905
  }
906
 
907
  #wpstg-footer a {
908
  text-decoration: none;
909
  }
910
 
911
+ #wpstg-footer li {
912
+ margin-bottom: 2px;
913
+ list-style: circle;
914
+ }
915
+
916
+ #wpstg-footer ul {
917
+ margin-left: 15px;
918
+ margin-top: 0px;
919
+ }
920
+
921
+ .wpstg-footer--title {
922
+ margin-left: 15px;
923
+ }
924
+
925
  .wpstg-staging-info {
926
  margin-top: 8px;
927
+ color: #3e3e3e;
928
  font-size: 12px;
929
  }
930
 
931
  .wpstg-staging-info a {
932
+ color: #3e3e3e;
933
  }
934
 
935
  .wpstg-staging-info li {
956
 
957
  #wpstg-report-issue-button {
958
  margin-left: 50px;
959
+ border: 1px solid #E01E5A;
960
+ color: #E01E5A;
961
  background-color: white;
962
  }
963
 
964
  #wpstg-report-issue-button:hover {
965
+ background-color: #dc2b62;
966
  color: #fff;
967
  }
968
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
969
  .wpstg-blue-primary {
970
  display: inline-block;
971
  text-decoration: none;
972
  font-size: 13px;
973
+ /*line-height: 26px;*/
974
  height: 28px;
975
  margin: 0;
976
  padding: 0 10px 1px;
993
 
994
  .wpstg-report-issue-form {
995
  position: absolute;
996
+ z-index: 999;
997
  width: 300px;
998
  background-color: #fff;
999
  padding: 15px 15px 10px;
1001
  border-radius: 3px;
1002
  box-shadow: 0 1px 0 0 #fff inset;
1003
  display: none;
1004
+ right: 0;
1005
+ top: 35px;
1006
+ }
1007
+
1008
+ @media (max-width: 600px) {
1009
+ .wpstg-report-issue-form {
1010
+ position: relative;
1011
+ }
1012
  }
1013
 
1014
  .wpstg-report-show {
1050
  #wpstg-report-cancel {
1051
  float: right;
1052
  margin-right: 5px;
1053
+ font-weight: bold;
1054
  }
1055
 
1056
+ #wpstg-success-button {
1057
+ font-weight: bold;
 
1058
  }
1059
 
1060
  .wpstg-message {
1102
 
1103
  .wpstg-error {
1104
  display: block;
1105
+ padding: 10px !important;
1106
+ background-color: #E01E5A !important;
1107
  color: #ffffff;
1108
+ margin: 10px 10px 10px 0 !important;
1109
+ border-color: transparent !important;
1110
+ border-left-color: transparent !important;
1111
+ box-shadow: none !important;
1112
  }
1113
 
1114
  .wpstg-error a {
1141
  text-align: center;
1142
  }
1143
 
1144
+ .wpstg-text-field > #wpstg-db-status {
1145
  margin-top: 8px;
1146
+ margin-left: 150px;
1147
+ min-width: 300px;
1148
  }
1149
 
1150
  .wpstg-success {
1165
  }
1166
 
1167
  #wpstg-update-notify {
1168
+ background-color: #E01E5A;
1169
  font-size: 14px;
1170
  color: #ffffff;
1171
  line-height: normal;
1172
  padding: 10px;
 
1173
  }
1174
 
1175
  #wpstg-update-notify a {
1181
  cursor: pointer;
1182
  }
1183
 
1184
+ .wpstg--tab--header {
1185
+ background-color: white;
1186
+ /* margin-bottom: 10px; */
1187
+ /* padding: 16px; */
1188
+ position: relative;
1189
+ transition: border-color .2s ease-in-out;
1190
+ background-color: #ffffff;
1191
+ color: #3e3e3e;
1192
+ border-radius: 2px;
1193
+ box-shadow: 0 0 1px rgba(0, 0, 0, .125), 0 1px 3px rgba(0, 0, 0, .02);
1194
+ }
1195
+
1196
  .wpstg--tab--header ul {
1197
  display: flex;
1198
  }
1199
 
1200
  .wpstg--tab--header ul li {
1201
  margin-right: 1em;
1202
+ margin-bottom: 0px;
1203
  }
1204
 
1205
  .wpstg--tab--header ul li:last-child {
1212
  cursor: pointer;
1213
  display: inline-block;
1214
  padding: 1em 1.25em;
1215
+ padding-bottom: 9px;
1216
+ color: #c4c4c4;
1217
+ font-size: 18px;
1218
+ /*
1219
  border: solid 1px;
1220
+ */
1221
  }
1222
 
1223
  .wpstg--tab--header a.wpstg--tab--active {
1224
+ border-bottom: .4em solid #25A1F0;
1225
+ color: #25A1F0;
1226
+ }
1227
+
1228
+ .wpstg--tab--header a:hover {
1229
+ background-color: #fefefe;
1230
+ border-bottom: 0.4em solid #25A1F0;
1231
  color: #25A1F0;
1232
  }
1233
 
1261
  background-color: #ffffff;
1262
  color: #505050;
1263
  text-align: left;
1264
+ padding: 12px;
 
1265
  border-radius: 3px;
1266
  position: absolute;
1267
  z-index: 1;
1268
+ -webkit-box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);
1269
+ -moz-box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);
1270
+ box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);
 
 
 
 
1271
  }
1272
 
1273
  .wpstg--tooltiptext-backups {
1274
  width: 120px;
1275
  top: 100%;
1276
  left: -150%;
1277
+ margin-left: -56px;
1278
+ margin-top: 4px;
1279
+ }
1280
+
1281
+ .wpstg--tooltip.wpstg--exclude-rules--tooltip {
1282
+ border-bottom: 0px solid transparent;
1283
  }
1284
 
1285
+ .wpstg--tooltip.wpstg--exclude-rules--tooltip > .wpstg--tooltiptext {
1286
+ margin-top: 0px;
1287
+ margin-left: -150px;
1288
+ }
1289
 
1290
  /**
1291
  Tooltip top arrow
1303
  border-color: transparent transparent white transparent;
1304
  }
1305
 
1306
+ .wpstg--tooltip .wpstg--tooltiptext.has-top-arrow {
1307
+ margin-top: 6px;
1308
+ }
1309
+
1310
+ .wpstg--tooltip .wpstg--tooltiptext.has-top-arrow::after {
1311
+ content: " ";
1312
+ position: absolute;
1313
+ bottom: 100%;
1314
+ left: 50%;
1315
+ margin-left: -18px;
1316
+ border-width: 5px;
1317
+ border-style: solid;
1318
+ border-color: transparent transparent white transparent;
1319
+ }
1320
+
1321
  .wpstg--snaphot-restore-table tr {
1322
  line-height: 12px;
1323
  }
1360
  border-color: #e72f24;
1361
  }
1362
 
1363
+ .wpstg--process--content > .swal2-html-container {
1364
  padding: 4em 2em !important;
1365
  }
1366
 
1367
  .wpstg--modal--process--logs,
1368
  .wpstg--modal--error--logs {
1369
+ background: #ffffff;
1370
+ border: 1px solid #a8a8a8;
1371
+ border-radius: 3px;
1372
  height: 300px;
1373
  margin-top: 1em;
1374
  display: none;
1375
+ padding-top: 10px;
1376
+ padding-left: 10px;
1377
+ overflow: auto;
1378
  text-align: justify;
1379
  }
1380
 
1383
  max-height: 300px;
1384
  }
1385
 
1386
+ .wpstg--modal--process--logs p {
1387
+ font-size: 12px;
1388
+ white-space: nowrap;
1389
+ }
1390
+
1391
+ .wpstg--modal--process--logs p.wpstg--modal--process--msg--info {
1392
+ color: #222222;
1393
+ }
1394
+
1395
+ .wpstg--modal--process--logs p.wpstg--modal--process--msg--debug {
1396
+ color: #757575;
1397
+ }
1398
+
1399
+ .wpstg--modal--process--title {
1400
+ color: #565656;
1401
+ margin: .25em 0;
1402
+ }
1403
+
1404
+ .wpstg--modal--process--subtitle {
1405
+ margin: .5em 0;
1406
+ color: #565656;
1407
+ }
1408
+
1409
+ .wpstg--modal--error--logs > p {
1410
  text-align: left;
1411
  font-size: 14px;
1412
+ color: #222222;
1413
  }
1414
 
1415
  .wpstg--modal--process--logs p,
1416
  .wpstg--modal--error--logs p {
1417
+ margin: 0px;
1418
+ margin-bottom: 2px;
1419
  }
1420
 
1421
  .wpstg--modal--process--msg--error {
1422
+ color: #E01E5A;
1423
  }
1424
 
1425
  .wpstg--modal--process--msg--critical {
1426
+ color: #E01E5A;
1427
  }
1428
 
1429
  .wpstg--modal--process--msg--warning {
1431
  }
1432
 
1433
  .wpstg--modal--process--msg-found {
1434
+ font-size: 16px;
1435
+ color: #E01E5A;
1436
+ font-weight: bold;
1437
  }
1438
 
1439
+ .wpstg--modal--delete {
1440
+ text-align: left;
1441
+ margin-top: 8px;
1442
+ color: #565656;
1443
  }
1444
 
1445
+ .wpstg-swal-popup .swal2-cancel.wpstg--btn--cancel {
1446
+ margin-bottom: 0;
1447
+ text-shadow: none !important;
 
 
 
1448
  }
1449
 
1450
+ .wpstg-swal-popup .wpstg-loader {
1451
  display: inline-block !important;
1452
  }
1453
 
1454
  .wpstg--modal--process--generic-problem {
1455
  display: none;
1456
+ border-left: 5px solid #E01E5A;
1457
  margin: .5em 0;
1458
  }
1459
 
1460
  .wpstg--modal--process--logs--tail {
1461
+ font-size: 16px;
1462
+ color: #565656;
1463
  background: none;
1464
  border: none;
1465
  cursor: pointer;
1466
  }
1467
 
1468
  .wpstg--modal--backup--import--upload--title {
1469
+ color: #565656;
1470
  }
1471
 
 
1472
  .wpstg--modal--backup--import--configure,
1473
  .wpstg--modal--backup--import--upload--status,
1474
  .wpstg--modal--backup--import--upload--container input[type="file"] {
1481
  }
1482
 
1483
  #wpstg--backups--import--file-list-empty {
1484
+ color: #E01E5A;
1485
  }
1486
 
1487
  .wpstg--modal--backup--import--filesystem label {
1492
  margin-bottom: 20px;
1493
  }
1494
 
1495
+ .wpstg--modal--backup--import--upload {
1496
+ position: relative;
1497
+ min-height: 30px;
1498
+ }
1499
+
1500
+ .wpstg--modal--backup--import--upload {
1501
  color: #505050;
1502
  }
1503
 
1504
  .wpstg--modal--backup--import--upload--container {
1505
  position: relative;
1506
+ border-radius: 10px;
1507
  margin: .5em;
1508
  padding: 1em .5em;
1509
+ border: 3.5px dashed #dedede;
1510
+ transition: background-color 0.3s ease, color 0.3s ease;
1511
+ background-color: #f4fbff;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1512
  }
1513
 
1514
  .wpstg--modal--backup--import--upload--container.wpstg--has-dragover span.wpstg--drop {
1515
+ display: inline-flex;
1516
  }
1517
 
1518
  .wpstg--modal--backup--import--upload--container input[type='file'] {
1529
  margin-top: 1em;
1530
  }
1531
 
1532
+ .wpstg--backup--import--options > button {
1533
  margin-top: 1em;
1534
  padding: 1em;
1535
  align-self: center;
1538
  line-height: normal;
1539
  }
1540
 
 
 
 
 
 
 
 
 
 
1541
  .wpstg--backup--import--options {
1542
  position: relative;
1543
  display: flex;
1601
  margin: 0;
1602
  }
1603
 
 
 
 
 
 
 
 
 
 
1604
  .wpstg--modal--backup--import--search-replace--wrapper button {
1605
  align-self: center;
1606
  }
1623
  background-color: #25a1f0;
1624
  width: 22px;
1625
  height: 22px;
1626
+ margin-left: 5px;
1627
  }
1628
 
1629
  .wpstg--modal--backup--import--search-replace--input-group:first-child button {
1656
 
1657
  .wpstg--modal--import--upload--process {
1658
  display: none;
1659
+ position: relative;
1660
+ height: 30px;
1661
+ margin-top: 20px;
1662
+ margin-bottom: 20px;
1663
  width: 100%;
 
1664
  top: 0;
1665
  left: 0;
1666
  text-indent: 1em;
1667
  white-space: nowrap;
1668
  overflow: hidden;
1669
+ color: #333333;
 
1670
  justify-content: center;
1671
  align-items: center;
1672
  }
1673
 
1674
  .wpstg--modal--import--upload--progress {
1675
  position: absolute;
1676
+ background: #98d452;
1677
  color: white;
 
1678
  height: 100%;
1679
+ border-radius: 4px;
1680
+ left: 0;
1681
  top: 0;
1682
  }
1683
 
1691
  margin-top: 20px;
1692
  }
1693
 
1694
+ .wpstg-fieldset {
1695
+ padding-left: 20px;
1696
+ }
1697
+
1698
  .wpstg-fs-14 {
1699
  font-size: 14px;
1700
  }
1701
 
1702
+ .wpstg-dark-alert {
1703
  font-weight: bold;
1704
+ background-color: #0e86d9;
1705
  padding: 15px;
1706
+ margin-top: 0px;
1707
+ color: white;
1708
+ }
1709
+
1710
+ .wpstg-dark-alert .wpstg-button--cta-red {
1711
+ margin-left:10px;
1712
  }
1713
 
1714
  .wpstg-form-group {
1715
+ display: block;
 
1716
  width: 100%;
1717
  margin-bottom: 8px;
1718
+ align-items: center;
1719
  }
1720
 
1721
+ .wpstg-form-group > label {
1722
+ display: block;
1723
  font-weight: 700;
 
 
1724
  }
1725
 
1726
+ .wpstg-text-field > input {
1727
+ width: 300px;
1728
+ display: block;
1729
+ line-height: 1.5;
1730
  }
1731
 
1732
  .wpstg-code-segment {
1733
  display: block;
1734
  }
1735
 
1736
+ .wpstg-text-field > .wpstg-code-segment {
1737
  margin-top: 4px;
1738
+ min-width: 300px;
 
1739
  }
1740
 
1741
+ .wpstg-form-group > .wpstg-checkbox {
1742
  min-width: 100%;
1743
  width: 100%;
1744
  position: relative;
1745
  }
1746
 
1747
+ .wpstg-form-group > .wpstg-checkbox > input[type='checkbox'] {
1748
+ left: 150px;
1749
  }
1750
 
1751
  .wpstg-rounded {
1756
  border: 1px solid white !important;
1757
  }
1758
 
1759
+ .wpstg-ml-4 {
1760
+ margin-left: 4px;
 
 
 
 
1761
  }
1762
 
1763
  #wpstg-confirm-backup-restore-data {
1765
  text-align: left;
1766
  }
1767
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1768
  #wpstg-advanced-settings hr {
1769
  margin: 20px 0;
1770
  }
1796
  width: 390px;
1797
  }
1798
 
 
 
 
 
 
 
 
 
 
 
1799
  .wpstg-fs-14 {
1800
  font-size: 14px;
1801
  }
1802
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1803
  .wpstg-code-segment {
1804
  display: block;
1805
  }
1806
 
1807
+ .wpstg-form-group > .wpstg-checkbox {
 
 
 
 
 
 
1808
  min-width: 100%;
1809
  width: 100%;
1810
  }
1811
 
1812
+ .wpstg-form-group > .wpstg-checkbox > input[type='checkbox'] {
1813
  margin-left: 10px;
1814
  }
1815
 
1816
  @media only screen and (max-width: 768px) {
1817
+ .wpstg-form-group > label {
 
 
 
 
1818
  min-width: auto;
1819
  width: auto;
1820
  }
1821
+
1822
+ .wpstg-text-field > input {
1823
  width: 100%;
 
1824
  }
1825
+
1826
+ .wpstg-text-field > .wpstg-code-segment {
1827
  margin-left: 0;
1828
  min-width: 100%;
1829
  }
1830
+
1831
  .wpstg-tab-section {
1832
  width: calc(100vw - 60px);
1833
+ max-width: 450px;
1834
  }
1835
  }
1836
 
1846
  margin: 0;
1847
  }
1848
 
 
 
 
 
1849
  .wpstg-mt-10px {
1850
  margin-top: 10px;
1851
  }
1867
  float: left;
1868
  }
1869
 
 
 
 
 
 
 
 
 
1870
  .wpstg-bold-text {
1871
  font-weight: bold;
1872
  }
1873
 
 
 
 
 
 
1874
  .wpstg-warning.notice {
1875
  border-left: 4px solid #ffba00;
1876
  }
1891
  margin-bottom: 10px;
1892
  }
1893
 
 
 
 
 
1894
  .wpstg-clear-both {
1895
  clear: both;
1896
  }
1897
 
 
 
 
 
1898
  .wpstg-font-italic {
1899
  font-style: italic;
1900
  }
1919
 
1920
  .wpstg-feedback-link {
1921
  text-decoration: none;
 
1922
  }
1923
 
1924
  .wpstg-feedback-span {
1925
  display: block;
1926
+ margin-bottom: 3px;
 
1927
  }
1928
 
1929
  #wpstg-confirm-backup-restore-data {
1933
 
1934
  #wpstg-confirm-backup-restore-wrapper {
1935
  margin: 30px;
1936
+ margin-top: 0;
1937
  }
1938
 
1939
  #wpstg-confirm-backup-restore-wrapper h3 {
1940
+ color: #E01E5A;
 
 
 
 
 
 
 
 
 
1941
  }
1942
 
1943
  #wpstg-progress-db,
1960
  background-color: #378cc9;
1961
  }
1962
 
1963
+ .wpstg-issue-resubmit-confirmation.swal2-container,
1964
  .wpstg-swal2-container.swal2-container {
1965
  z-index: 10500;
1966
  }
1970
  display: none;
1971
  }
1972
 
1973
+ body.toplevel_page_wpstg_backup .swal2-container .swal2-content,
1974
  body.toplevel_page_wpstg_clone .swal2-container .swal2-content {
1975
+ z-index: 2;
1976
+ }
1977
+
1978
+ .toplevel_page_wpstg_clone #swal2-content h2 {
1979
+ color: #565656;
1980
+ }
1981
+
1982
+ .toplevel_page_wpstg_clone #swal2-content {
1983
+ line-height: 1.5em;
1984
  }
1985
 
1986
  div#exportUploadsWithoutDatabaseWarning {
2012
  display: inline-block;
2013
  }
2014
 
2015
+ .wpstg-import-backup-contains li .wpstg-backups-contains {
2016
  border-radius: 3px;
2017
  color: #979797;
2018
  background-color: #e3e3e3;
2022
  font-size: 17px;
2023
  }
2024
 
2025
+ .wpstg-import-backup-contains.wpstg-listing-single-backup li .wpstg-backups-contains {
2026
  padding: 2px;
2027
+ background-color: white;
2028
+ border: 1px solid #c2c2c2;
2029
+ }
2030
+
2031
+ .wpstg-import-backup-contains.wpstg-listing-single-backup li .wpstg-backups-contains > .wpstg--dashicons {
2032
+ filter: invert(50%);
2033
  }
2034
 
2035
  .wpstg-import-backup-contains .wpstg--tooltiptext {
2057
  font-size: x-small;
2058
  display: inline-block;
2059
  font-style: italic;
2060
+ cursor: pointer;
2061
  }
2062
 
2063
  .wpstg-backup-more-info-toggle::selection {
2064
+ background: none;
2065
  }
2066
 
2067
  ul.wpstg-import-backup-more-info {
2085
  height: 20px;
2086
  }
2087
 
2088
+ .wpstg-backup-list {
2089
+ max-width: 800px;
2090
+ }
2091
+
2092
+ .wpstg-backup-list h3 {
2093
+ color:#3e3e3e;
2094
+ }
2095
+
2096
  .wpstg-backup-list ul ul {
2097
  margin-block-start: 1em;
2098
  margin-block-end: 1em;
2100
 
2101
  .wpstg-push-confirmation-message {
2102
  text-align: justify;
2103
+ font-size: 15px;
2104
  }
2105
 
2106
  .wpstg-settings-row {
2129
 
2130
  .wpstg-excluded-filters-container {
2131
  padding: 0;
2132
+ margin-top: 10px;
2133
  margin-bottom: 10px;
2134
+ max-width: 100%;
2135
  width: 100%;
2136
  }
2137
 
2151
  margin: 0;
2152
  }
2153
 
 
 
 
 
2154
  .wpstg-exclude-filters-foot {
2155
  display: flex;
2156
  justify-content: flex-start;
2157
  padding: 0;
2158
  }
2159
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2160
  /**
2161
  * WP STAGING EXCLUSION RULE DROPDOWN STYLE
2162
  */
2163
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2164
 
2165
  .wpstg-exclude-filter-dropdown > button:hover {
2166
  background: #135e96;;
2173
 
2174
  .wpstg-remove-exclude-rule {
2175
  color: #fff !important;
2176
+ background-color: #e01e5a;
2177
+ border: 1px solid #e01e5a;
2178
  width: 20px;
2179
+ height: 20px;
2180
+ border-radius: 10px;
2181
+ font-size: 24px;
2182
+ padding: 0;
2183
+ display: inline-flex;
2184
+ justify-content: center;
2185
  outline: none;
2186
  box-shadow: none;
2187
  font-weight: 400;
2191
  }
2192
 
2193
  .wpstg-remove-exclude-rule:hover {
2194
+ background-color: #E01E5A;
2195
+ border-color: #E01E5A;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2196
  }
2197
 
2198
  .wpstg-code-block {
2199
+ margin-top: 4px;
2200
+ font-size: 1.2em;
2201
+ background: #f8f8f8;
2202
+ border-radius: 2px;
2203
  }
2204
 
2205
  .wpstg-rule-info {
2209
  code.wpstg-code {
2210
  display: inline-block;
2211
  font-size: 11px;
2212
+ border: 1px solid #aaa;
2213
+ background: #fff;
2214
+ padding: 2px 4px;
2215
  margin-bottom: 1px;
2216
+ color: #E01E5A;
2217
  }
2218
 
2219
  .wpstg-exclusion-rule-info {
2221
  background-color: #ffc107;
2222
  border: 1px solid #ffc107;
2223
  width: 14px;
2224
+ height: 14px;
2225
+ border-radius: 7px;
2226
+ font-size: 14px;
2227
+ padding: 0;
2228
+ display: inline-flex;
2229
+ justify-content: center;
2230
  align-items: center;
2231
  outline: none;
2232
  box-shadow: none;
2243
  * WP STAGING INPUTS EXCLUSION RULES
2244
  */
2245
 
2246
+ .wpstg-exclude-rule-input {
2247
  font-size: 12px !important;
2248
  padding: 2px 6px;
2249
  box-shadow: none;
2259
  margin-top: 4px;
2260
  margin-left: 4px;
2261
  vertical-align: baseline !important;
2262
+ transition: all 0.3s cubic-bezier(.25, .8, .25, 1);
2263
  width: 135px;
2264
  }
2265
 
2266
  .wpstg-excluded-filters-container tbody > tr:last-child .wpstg-exclude-rule-input {
2267
+ margin-bottom: 4px;
2268
  }
2269
 
2270
  .wpstg-exclude-rule-input:hover {
2273
 
2274
  .wpstg-exclude-rule-input:focus {
2275
  border: 1px solid #25A0F1 !important;
2276
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24) !important;
2277
  }
2278
 
2279
  .wpstg-file-size-exclude-select,
2301
  padding-bottom: 5px;
2302
  }
2303
 
2304
+ #wpstg-scanning-files.wpstg-tab-section, #wpstg-scanning-db.wpstg-tab-section {
2305
+ padding-top: 10px;
2306
  }
2307
 
2308
  .wpstg-reset-excludes-container {
2319
  }
2320
 
2321
  @keyframes wpstg-loading-icon-anim {
2322
+ 0% {
2323
+ transform: rotate(0);
2324
+ }
2325
+ 100% {
2326
+ transform: rotate(360deg);
2327
+ }
2328
  }
2329
 
2330
  .wpstg-swal2-ajax-loader > img {
2338
  width: auto !important;
2339
  }
2340
 
2341
+ #wpstg-no-staging-site-results {
2342
+ margin-top: 10px;
2343
+ max-width: 375px;
2344
+ }
2345
+
2346
+ li#wpstg-backup-no-results {
2347
+ max-width: 500px;
2348
+ }
2349
+
2350
+ li#wpstg-backup-no-results div, #wpstg-no-staging-site-results div {
2351
+ display: inline-block;
2352
+ text-align: center;
2353
+ }
2354
+
2355
+ li#wpstg-backup-no-results .wpstg--dashicons, #wpstg-no-staging-site-results .wpstg--dashicons {
2356
+ filter: invert(50%);
2357
+ position: absolute;
2358
+ margin-top: 1px;
2359
+ }
2360
+
2361
+ li#wpstg-backup-no-results .no-backups-found-text, #wpstg-no-staging-site-results .no-staging-site-found-text {
2362
+ color: #5d5d5d;
2363
+ margin-left: 20px;
2364
+ }
2365
+
2366
+ @media only screen and (max-width: 680px) {
2367
+ li#wpstg-backup-no-results div, #wpstg-no-staging-site-results div {
2368
+ width: 100%;
2369
+ }
2370
+ }
2371
+
2372
+ #wpstg--modal--backup--download-inner p.wpstg-download-modal-text {
2373
+ font-size: 16px;
2374
+ color: #565656;
2375
+ }
2376
+
2377
+ #wpstg--modal--backup--download-inner h2 {
2378
+ color: #565656;
2379
+ }
2380
+
2381
+ .wpstg-backup-restore-contains-database,
2382
+ .wpstg-backup-restore-contains-files {
2383
+ display: none;
2384
+ }
2385
+
2386
+ .wpstg-green-button {
2387
+ background: #8bc34a;
2388
+ border: 1px solid #78a93f;
2389
+ color: white;
2390
+ text-shadow: 0 -1px 1px #78a93f, 1px 0 1px #78a93f, 0 1px 1px #40c921, -1px 0 1px #78a93f;
2391
+ }
2392
+
2393
+ .wpstg-green-button:hover {
2394
+ background: #78a93f;
2395
+ }
2396
+
2397
  .wpstg-is-dir-loading {
2398
  position: absolute;
2399
  margin-top: -2px;
2409
  margin-bottom: 8px;
2410
  }
2411
 
2412
+
2413
+ .wpstg-btn-danger {
2414
+ background-color: #E01E5A;
2415
+ border: 1px solid #E01E5A;
 
 
2416
  color: white;
2417
+ text-shadow: none;
 
2418
  }
2419
 
2420
+ .wpstg-btn-danger:hover {
2421
+ background: #c0194d;
2422
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
2423
  }
2424
 
2425
  .wpstg-swal2-container.wpstg-swal2-loading > .swal2-modal {
2463
  height: calc(100vh - 350px) !important;
2464
  }
2465
 
2466
+ .swal2-actions.wpstg--modal--actions > button {
2467
+ margin-left: 4px;
2468
+ margin-right: 4px;
2469
+ text-transform: uppercase;
2470
+ text-shadow: initial;
2471
+ font-weight: 500;
2472
+ min-width: 80px;
2473
+ }
2474
+
2475
+ .wpstg-swal-popup {
2476
+ max-width: 1200px !important;
2477
+ }
2478
+
2479
+ .wpstg-swal-popup.wpstg-push-finished .swal2-title {
2480
+ color: #a8a8a8;
2481
+ }
2482
+
2483
+ .wpstg-swal-popup.wpstg-push-finished .swal2-content {
2484
+ margin-top: 8px;
2485
+ color: #a8a8a8;
2486
+ }
2487
+
2488
+ .wpstg-swal-popup .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step,
2489
+ .wpstg-swal-popup .swal2-progress-steps .swal2-progress-step,
2490
+ .wpstg-swal-popup .swal2-progress-steps .swal2-progress-step-line {
2491
+ background: #25a1f0;
2492
+ }
2493
+
2494
+ .wpstg-swal-popup .swal2-progress-steps .swal2-progress-step-line {
2495
+ width: 2.75em;
2496
+ }
2497
+
2498
+ .wpstg--dashicons {
2499
+ width: 16px;
2500
+ height: 16px;
2501
+ }
2502
+
2503
+ .wpstg--dashicons.wpstg-dashicons-grey {
2504
+ filter: invert(20%);
2505
+ }
2506
+
2507
+ .wpstg--dashicons.wpstg-dashicons-19 {
2508
+ width: 19px;
2509
+ height: 19px;
2510
+ }
2511
+
2512
+ .wpstg--dashicons.wpstg-dashicons-21 {
2513
+ width: 21px;
2514
+ height: 21px;
2515
+ }
2516
+
2517
+ #wpstg--tab--backup #wpstg-step-1 {
2518
+ display: flex;
2519
+ align-items: center;
2520
+ }
2521
+
2522
+ .wpstg-advanced-options .wpstg--tooltip,
2523
+ #wpstg--tab--backup #wpstg-step-1 .wpstg--tooltip {
2524
+ border-bottom: 0 solid transparent;
2525
+ display: inline-flex;
2526
+ align-items: center;
2527
+ }
2528
+
2529
+ #wpstg--tab--backup #wpstg-step-1 .wpstg--tooltip {
2530
+ border-bottom: 0 solid transparent;
2531
+ display: flex;
2532
+ align-items: center;
2533
+ }
2534
+
2535
+ .wpstg--tooltip .wpstg--tooltiptext-backups::after {
2536
+ left: calc(20% + 2px);
2537
+ }
2538
+
2539
+ .wpstg-listing-single-backup .wpstg--dashicons {
2540
+ width: 17px;
2541
+ height: 17px;
2542
+ }
2543
+
2544
+ .wpstg-100-width {
2545
+ width: 100px;
2546
+ }
2547
+
2548
+ .wpstg-caret {
2549
+ display: inline-block;
2550
+ width: 0;
2551
+ height: 0;
2552
+ margin-left: 2px;
2553
+ vertical-align: middle;
2554
+ border-top: 4px solid;
2555
+ border-right: 4px solid transparent;
2556
+ border-left: 4px solid transparent;
2557
+ transition: transform 0.2s;
2558
+ cursor: pointer;
2559
+ }
2560
+
2561
+ .wpstg-caret.wpstg-caret-up {
2562
+ transform: rotate(-180deg);
2563
+ }
2564
+
2565
+ .wpstg-advanced-options-site label {
2566
+ font-size: 16px;
2567
+ display: block;
2568
+ margin: .5em 0;
2569
+ }
2570
+
2571
+ #wpstg-confirm-backup-restore-data {
2572
+ font-size: 18px;
2573
+ margin: 0;
2574
+ margin-top: 30px;
2575
+ }
2576
+
2577
+ /* Sweetalert WP STAGING Theme */
2578
+
2579
+ body.toplevel_page_wpstg_backup .swal2-container.swal2-backdrop-show,
2580
+ body.toplevel_page_wpstg_clone .swal2-container.swal2-backdrop-show {
2581
+ background: rgba(0, 0, 0, .6);
2582
+ z-index: 9995;
2583
+ }
2584
+
2585
+ .wpstg-swal-popup.swal2-popup {
2586
+ border-radius: 8px;
2587
+ z-index: 9999;
2588
+ padding: 24px;
2589
+ color: #565656;
2590
+ font-family: Verdana, Geneva, Tahoma, sans-serif;
2591
+ }
2592
+
2593
+ .wpstg-swal-popup .swal2-title {
2594
+ font-size: 22px;
2595
+ color: #565656;
2596
+ }
2597
+
2598
+ .wpstg-swal-popup.swal2-popup:not(.centered-modal) .swal2-title {
2599
+ align-self: flex-start; /* For an actual Swal title */
2600
+ text-align: left; /* Manually adding this class to a non flex display */
2601
+ margin-bottom: 0;
2602
+ }
2603
+
2604
+ .wpstg-swal-popup .swal2-close {
2605
+ top: 8px;
2606
+ right: 8px;
2607
+ z-index: 5;
2608
+ }
2609
+
2610
+ .wpstg-swal-popup .swal2-close:focus {
2611
+ outline: none;
2612
+ }
2613
+
2614
+ .wpstg-swal-popup.swal2-popup:not(.centered-modal) .swal2-actions {
2615
+ justify-content: flex-end;
2616
+ }
2617
+
2618
+ .wpstg-swal-popup .swal2-actions > button {
2619
+ border-radius: 4px;
2620
+ font-weight: 900;
2621
+ border: 0;
2622
+ font-size: 15px;
2623
+ padding: 10px 12px;
2624
+ text-transform: capitalize;
2625
+ line-height: normal;
2626
+ height: 40px;
2627
+ min-width: 100px;
2628
+ text-shadow: none;
2629
+ }
2630
+
2631
+ .wpstg-swal-popup.swal2-popup:not(.centered-modal) .swal2-actions > button {
2632
+ margin-left: 8px;
2633
+ }
2634
+
2635
+ .wpstg-swal-popup .swal2-actions > button.swal2-cancel {
2636
+ border: 1px solid rgba(29, 28, 29, 0.3);
2637
+ background: #fff;
2638
+ color: rgb(29, 28, 29);
2639
+ font-weight: 500;
2640
+ width: 100px;
2641
+ text-shadow: none;
2642
+ }
2643
+
2644
+ .wpstg-swal-popup .swal2-actions > button:hover {
2645
+ box-shadow: 0 1px 3px 0 rgba(0 0 0 .1);
2646
+ }
2647
+
2648
+ .wpstg-swal-popup .swal2-actions > button.swal2-cancel:hover {
2649
+ background: rgba(28, 29, 28, .04);
2650
+ }
2651
+
2652
+ #wpstg-backup-name-input {
2653
+ height: 44px;
2654
+ font-size: 18px;
2655
+ }
2656
+
2657
+ .wpstg-restore-finished-container .swal2-title {
2658
+ color: #565656 !important;
2659
+ }
2660
+
2661
+ /*#wpstg-restore-success {
2662
+ color: #565656;
2663
+ }*/
2664
+
2665
+ .wpstg-restore-finished-container .swal2-content {
2666
+ margin-top: 20px;
2667
+ color: #a8a8a8;
2668
+ }
2669
+
2670
+ /* WP Staging Implementation of Windows Style Linear Loader */
2671
+
2672
+ .wpstg-linear-loader > span[class*="wpstg-linear-loader-item"] {
2673
+ height: 6px;
2674
+ width: 6px;
2675
+ background: #333;
2676
+ display: inline-block;
2677
+ margin: 12px 2px;
2678
+ border-radius: 100%;
2679
+ animation: wpstg_linear_loader 3s infinite;
2680
+ animation-timing-function: cubic-bezier(0.030, 0.615, 0.995, 0.415);
2681
+ animation-fill-mode: both;
2682
+ }
2683
+
2684
+ .wpstg-linear-loader > span.wpstg-linear-loader-item:nth-child(1) {
2685
+ animation-delay: 1s;
2686
+ }
2687
+
2688
+ .wpstg-linear-loader > span.wpstg-linear-loader-item:nth-child(2) {
2689
+ animation-delay: 0.8s;
2690
+ }
2691
+
2692
+ .wpstg-linear-loader > span.wpstg-linear-loader-item:nth-child(3) {
2693
+ animation-delay: 0.6s;
2694
+ }
2695
+
2696
+ .wpstg-linear-loader > span.wpstg-linear-loader-item:nth-child(4) {
2697
+ animation-delay: 0.4s;
2698
+ }
2699
+
2700
+ .wpstg-linear-loader > span.wpstg-linear-loader-item:nth-child(5) {
2701
+ animation-delay: 0.2s;
2702
+ }
2703
+
2704
+ .wpstg-linear-loader > span.wpstg-linear-loader-item:nth-child(6) {
2705
+ animation-delay: 0s;
2706
+ }
2707
+
2708
+ @keyframes wpstg_linear_loader {
2709
+ 0% {
2710
+ transform: translateX(-30px);
2711
+ opacity: 0;
2712
+ }
2713
+ 25% {
2714
+ opacity: 1;
2715
+ }
2716
+ 50% {
2717
+ transform: translateX(30px);
2718
+ opacity: 0;
2719
+ }
2720
+ 100% {
2721
+ opacity: 0;
2722
+ }
2723
+ }
2724
+
2725
+ /* END - Windows Style Linear Loader */
2726
+
2727
+ .wpstg--modal--backup--import--upload--content {
2728
+ padding: .75em;
2729
+ margin: 1em auto;
2730
+ }
2731
+
2732
+ .wpstg--modal--backup--import--upload--content .wpstg-linear-loader {
2733
+ display: none;
2734
+ }
2735
+
2736
+ #wpstg-multisite-disabled .wpstg-clone {
2737
+ width: 355px;
2738
+ }
2739
+
2740
+ #wpstg-free-version-backups .wpstg-clone {
2741
+ text-align: center;
2742
+ }
2743
+
2744
+ #wpstg-free-version-backups .wpstg-clone p {
2745
+ font-size: 16px;
2746
+ }
2747
+
2748
+ .wpstg-staging-info li .backup-notes {
2749
+ word-break: break-word;
2750
+ }
2751
+
2752
+ .wpstg--modal--import--upload--progress--title small {
2753
+ font-weight: normal;
2754
+ }
2755
+
2756
+ #wpstg-report-issue-wrapper {
2757
+ position: relative;
2758
+ }
2759
+
2760
+ #wpstg-report-issue-wrapper .arrow-up {
2761
+ width: 0;
2762
+ height: 0;
2763
+ border-left: 8px solid transparent;
2764
+ border-right: 8px solid transparent;
2765
+ border-bottom: 8px solid white;
2766
+ position: absolute;
2767
+ top: -8px;
2768
+ right: 40px;
2769
+ }
2770
+
2771
+ .notice {
2772
+ margin: 10px 20px 0 2px;
2773
+ }
2774
+
2775
+ .wpstg--notice {
2776
+ box-shadow: 0 1px 1px rgba(0, 0, 0, .04);
2777
+ margin: 20px 20px 20px 0px;
2778
+ padding: 1px 12px;
2779
+ }
2780
+
2781
+ .wpstg--error a:hover {
2782
+ color: #eeeeee;
2783
+ }
2784
+
2785
+ .wpstg--error, .wpstg--error a {
2786
+ background: #E01E5A;
2787
+ color: white;
2788
+ }
2789
+
2790
+ /**
2791
+ * Buttons
2792
+ */
2793
+
2794
+ .wpstg-button {
2795
+ display: inline-block;
2796
+ border-radius: 2px;
2797
+ cursor: pointer;
2798
+ padding: 2px 10px 2px 10px;
2799
+ text-transform: uppercase;
2800
+ font-weight: 500;
2801
+ outline: 0;
2802
+ transition: background-color .1s ease-in;
2803
+ text-decoration: none;
2804
+ }
2805
+
2806
+ .wpstg-button.wpstg-save {
2807
+ background-color: #1687A7;
2808
+ color: white;
2809
+ }
2810
+
2811
+ .wpstg-button.wpstg-save:hover {
2812
+ background-color: #276678;
2813
+ }
2814
+
2815
+
2816
+ .wpstg-button.wpstg-button-light {
2817
+ background-color: #f8f8f8;
2818
+ border: 1px solid #eee;
2819
+ color: #333;
2820
+ animation: background-color 0.3s;
2821
+ }
2822
+
2823
+ .wpstg-button.wpstg-button-light:hover {
2824
+ background-color: #e0e0e0;
2825
+ border: 1px solid #e0e0e0;
2826
+ }
2827
+
2828
+ .wpstg-buttons .spinner {
2829
+ float: none;
2830
+ margin: 0 0 0 5px;
2831
+ }
2832
+
2833
+ .wpstg-button.danger {
2834
+ display: inline-block;
2835
+ text-decoration: none;
2836
+ text-align: center;
2837
+ text-transform: inherit;
2838
+ background-color: #E01E5A;
2839
+ color: white;
2840
+ border-radius: 2px;
2841
+ border-color: transparent;
2842
+ }
2843
+
2844
+ .wpstg-button.danger:hover {
2845
+ background-color: #c0194d;
2846
+ }
2847
+
2848
+ .wpstg-button--big {
2849
+ display: inline-block;
2850
+ padding: 10px;
2851
+ min-width: 170px;
2852
+ font-size: 16px;
2853
+ text-decoration: none;
2854
+ text-align: center;
2855
+ margin-top: 20px;
2856
+ color: white;
2857
+ border-radius: 3px;
2858
+ }
2859
+
2860
+ .wpstg-button--primary {
2861
+ display: inline-block;
2862
+ text-decoration: none;
2863
+ font-size: 13px;
2864
+ line-height: 2.15384615;
2865
+ min-height: 30px;
2866
+ margin: 0;
2867
+ padding: 0 10px;
2868
+ cursor: pointer;
2869
+ border: 1px solid rgba(29, 28, 29, 0.3);
2870
+ -webkit-appearance: none;
2871
+ border-radius: 2px;
2872
+ white-space: nowrap;
2873
+ box-sizing: border-box;
2874
+ color: #171717;
2875
+ }
2876
+
2877
+ .wpstg-button--primary:hover {
2878
+ background: rgba(28, 29, 28, .04);
2879
+ color: black;
2880
+ }
2881
+
2882
+ .wpstg-button--secondary {
2883
+ display: inline-block;
2884
+ background-color: transparent;
2885
+ color: #95a5a6;
2886
+ border-radius: 2px;
2887
+ border: 1px solid rgba(29, 28, 29, 0.3);
2888
+ cursor: pointer;
2889
+ padding: 4px 10px 2px 10px;
2890
+ font-weight: 500;
2891
+ outline: 0;
2892
+ transition: background-color .1s ease-in;
2893
+ text-decoration: none;
2894
+ }
2895
+
2896
+ .wpstg-button--red {
2897
+ background-color: #E01E5A;
2898
+ border-color: #E01E5A;
2899
+ color: white;
2900
+ }
2901
+
2902
+ .wpstg-button--red:hover {
2903
+ background-color: #d02358;
2904
+ border-color: #e0255f;
2905
+ color: white;
2906
+ }
2907
+
2908
+ .wpstg-button--cta-red {
2909
+ background-color: #fe008f;
2910
+ border-color: #E01E5A;
2911
+ color: white;
2912
+ }
2913
+
2914
+ .wpstg-button--cta-red:hover {
2915
+ background-color: #f31391;
2916
+ border-color: #e0255f;
2917
+ color: white;
2918
+ }
2919
+
2920
+ .wpstg-button--blue {
2921
+ background-color: #25A0F1;
2922
+ border-color: #25A0F1;
2923
+ color: white;
2924
+ }
2925
+
2926
+ .wpstg-button--blue:hover {
2927
+ background-color: #259be6;
2928
+ border-color: #259be6;
2929
+ color: white;
2930
+ }
2931
+
2932
+ #wpstg-button-backup-upgrade {
2933
+ font-size: 16px;
2934
+ }
2935
+
2936
+ .wpstg-staging-status {
2937
+ color: #E01E5A;
2938
+ }
2939
+
2940
+ #wpstg-push-changes,
2941
+ #wpstg-start-updating,
2942
+ #wpstg-save-clone-data {
2943
+ margin-left: 5px;
2944
+ }
2945
+
2946
+ input.wpstg-textbox {
2947
+ border: 1px solid #aaa;
2948
+ border-radius: .25rem;
2949
+ padding: 0.25rem 0.5rem;
2950
+ font-size: 14px;
2951
+ }
2952
+
2953
+ input.wpstg-textbox:focus {
2954
+ outline: 0;
2955
+ border-color: #259be6;
2956
+ -webkit-box-shadow: 0 0 0 0.1rem rgba(221, 221, 221, .35);
2957
+ box-shadow: 0 0 0 0.1rem rgba(221, 221, 221, .35);
2958
+ }
2959
+
2960
+ input.wpstg-textbox::placeholder {
2961
+ color: #888;
2962
+ }
2963
+
2964
+ .wpstg--advance-settings--checkbox {
2965
+ display: flex;
2966
+ align-items: center;
2967
+ }
2968
+
2969
+ .wpstg--advance-settings--checkbox > label {
2970
+ font-size: 14px;
2971
+ font-weight: bolder;
2972
+ width: 165px;
2973
+ display: inline-block;
2974
+ }
2975
+
2976
+ .wpstg--advance-settings--checkbox > .wpstg--tooltip {
2977
+ margin-top: 5px;
2978
+ margin-left: 5px;
2979
+ position: relative;
2980
+ display: inline-block;
2981
+ border-bottom: 0px solid transparent;
2982
+ }
2983
+
2984
+ .wpstg--advance-settings--checkbox > .wpstg--tooltip > .wpstg--tooltiptext {
2985
+ top: 18px;
2986
+ left: -150px;
2987
+ }
2988
+
2989
+
2990
+ div#wpstg-restore-wait {
2991
+ display: none;
2992
+ flex-direction: column;
2993
+ justify-content: center;
2994
+ align-items: center;
2995
+ text-align: center;
2996
+ height: 100vh;
2997
+ width: 100vw;
2998
+ position: fixed;
2999
+ top: 0;
3000
+ left: 0;
3001
+ background: white;
3002
+ z-index: 99999;
3003
+ }
3004
+
3005
+ div#wpstg-restore-wait .wpstg-title {
3006
+ font-weight: bold;
3007
+ }
3008
+
3009
+ div#wpstg-restore-wait div {
3010
+ font-size: 16px;
3011
+ margin-top: 12px;
3012
+ }
3013
+
3014
+ .resumable-browse {
3015
+ cursor: pointer;
3016
+ }
3017
+
3018
+ .resumable-browse a {
3019
+ text-decoration: underline;
3020
+ }
3021
+
3022
+ .wpstg--modal--backup--import--upload--container.dragover {
3023
+ transition: background-color 0.7s;
3024
+ background-color: #94dc96;
3025
+ color: #FFF;
3026
+ }
3027
+
3028
+ .wpstg--modal--backup--import--upload--container.dragover * {
3029
+ pointer-events: none; /* Avoids flickering when dragging to drop a file */
3030
+ }
3031
+
3032
+ .wpstg--modal--backup--import--upload--container.dragover .upload-text {
3033
+ display: none;
3034
+ }
3035
+
3036
+ .wpstg--modal--backup--import--upload--container.dragover .dragover-text {
3037
+ display: block;
3038
+ }
3039
+
3040
+ .wpstg--modal--backup--import--upload--container .dragover-text {
3041
+ display: none;
3042
+ }
3043
+
3044
+ #wpstg-invalid-license-message, #wpstg-invalid-license-message a {
3045
+ font-weight: 500;
3046
+ color: #E01E5A;
3047
+ margin-left: 6px;
3048
+ }
3049
+
3050
+ #wpstg-sidebar--banner {
3051
+ max-width: 200px;
3052
+ }
3053
+
3054
+ @media screen and (max-width: 1234px) {
3055
+ .wpstg-h2 {
3056
+ font-size: 24px;
3057
+ }
3058
+
3059
+ #wpstg-welcome li {
3060
+ font-size: 14px;
3061
+ }
3062
+ }
3063
+
3064
+ .wpstg-exclamation {
3065
+ color: #ffffff;
3066
+ border-radius: 100%;
3067
+ background-color: #E01E5A;
3068
+ width: 20px;
3069
+ height: 20px;
3070
+ text-align: center;
3071
+ font-weight: bold;
3072
+ display: inline-block;
3073
+ margin: 6px;
3074
+ }
3075
+
3076
+ .wpstg--tab--contents {
3077
+ padding-top: 1px;
3078
+ }
3079
+
3080
+ .wpstg-swal-show.swal2-show {
3081
+ -webkit-animation: wpstg-swal-show 0.2s !important;
3082
+ animation: wpstg-swal-show 0.2s !important;
3083
+ }
3084
+
3085
+ @-webkit-keyframes wpstg-swal-show {
3086
+ 0% {
3087
+ transform: scale(0.3);
3088
+ }
3089
+ 100% {
3090
+ transform: scale(1);
3091
+ }
3092
+ }
3093
+
3094
+ @keyframes wpstg-swal-show {
3095
+ 0% {
3096
+ transform: scale(0.3);
3097
+ }
3098
+ 100% {
3099
+ transform: scale(1);
3100
+ }
3101
+ }
3102
+
3103
  /*# sourceMappingURL=wpstg-admin.css.map */
assets/css/dist/wpstg-admin.css.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["wpstg-admin.css"],"names":[],"mappings":"AAAA;;;;;;;CAOC;;;AAGD,iBAAiB;;AAEjB;IACI,iBAAiB;IACjB,gBAAgB;IAChB,SAAS;IACT,UAAU;IACV,mBAAmB;IACnB,WAAW;IACX,2BAA2B;AAC/B;;AAEA;IACI,gBAAgB;AACpB;;AAEA;IACI,iBAAiB;IACjB,qBAAqB;AACzB;;AAEA;IACI,iBAAiB;IACjB,oBAAoB;AACxB;;AAEA;IACI,UAAU;AACd;;AAEA;;IAEI,iBAAiB;AACrB;;AAEA;IACI,YAAY;AAChB;;AAEA;IACI,uBAAuB;AAC3B;;AAEA;;IAEI,aAAa;AACjB;;AAEA;IACI,yBAAyB;IACzB,cAAc;AAClB;;AAEA;IACI,mBAAmB;IACnB,gBAAgB;IAChB,yBAAyB;IACzB,gBAAgB;IAChB,iBAAiB;IACjB,eAAe;IACf,cAAc;IACd,UAAU;AACd;;AAEA;IACI,gCAAgC;AACpC;;AAEA;IACI,cAAc;IACd,gBAAgB;IAChB,kBAAkB;IAClB,eAAe;IACf,eAAe;IACf,cAAc;AAClB;;AAEA;IACI,cAAc;AAClB;;AAEA;IACI;QACI,WAAW;IACf;IACA;QACI,WAAW;IACf;IACA;QACI,eAAe;IACnB;IACA;;QAEI,aAAa;IACjB;AACJ;;AAEA;IACI,gBAAgB;AACpB;;AAEA;IACI,cAAc;IACd,2BAA2B;IAC3B,mBAAmB;IACnB,mBAAmB;IACnB,uBAAuB;IACvB,4BAA4B;IAC5B,qBAAqB;IACrB,cAAc;IACd,iBAAiB;AACrB;;AAEA;IACI,yBAAyB;IACzB,cAAc;AAClB;;AAEA;IACI,cAAc;IACd,eAAe;IACf,iBAAiB;IACjB,YAAY;IACZ,WAAW;AACf;;AAEA;IACI,cAAc;IACd;AACJ;;AAEA;IACI,cAAc;AAClB;;AAEA;IACI,eAAe;AACnB;;AAEA;IACI,aAAa;AACjB;;;AAGA,qBAAqB;;AAErB;IACI,mBAAmB;AACvB;;AAEA;IACI;QACI,WAAW;QACX,mBAAmB;IACvB;IACA;QACI,aAAa;QACb,kBAAkB;QAClB,iBAAiB;IACrB;AACJ;;AAEA;IACI,aAAa;IACb,aAAa;IACb,yBAAyB;IACzB,gBAAgB;IAChB,aAAa;AACjB;;AAEA;IACI,gBAAgB;AACpB;;AAEA;IACI,WAAW;IACX,iBAAiB;IACjB,mBAAmB;IACnB,WAAW;AACf;;AAEA;IACI,sBAAsB;IACtB,kBAAkB;IAClB,qBAAqB;IACrB,WAAW;IACX,YAAY;IACZ,kBAAkB;IAClB,iBAAiB;AACrB;;AAEA;IACI,iBAAiB;AACrB;;AAEA;IACI,gBAAgB;IAChB,WAAW;AACf;;AAEA;IACI,cAAc;IACd,aAAa;IACb,kBAAkB;IAClB,gBAAgB;IAChB,wCAAwC;AAC5C;;AAEA;IACI,kBAAkB;IAClB,aAAa;IACb,kBAAkB;IAClB,wCAAwC;IACxC,yBAAyB;IACzB,qBAAqB;IACrB,8DAA8D;AAClE;;AAEA;IACI,qBAAqB;AACzB;;AAEA;IACI,aAAa;IACb,8BAA8B;IAC9B,mBAAmB;AACvB;;AAEA;IACI,qBAAqB;IACrB,eAAe;IACf,gBAAgB;IAChB,qBAAqB;IACrB,iBAAiB;IACjB,YAAY;AAChB;;AAEA;IACI,cAAc;AAClB;;AAEA;IACI,aAAa;IACb,sBAAsB;AAC1B;;AAEA;IACI,kBAAkB;AACtB;;AAEA;IACI,qBAAqB;IACrB,gBAAgB;IAChB,iBAAiB;IACjB,kBAAkB;IAClB,eAAe;IACf,8DAA8D;IAC9D,cAAc;AAClB;;AAEA;IACI,mBAAmB;IACnB,YAAY;AAChB;;AAEA;IACI,kBAAkB;AACtB;;AAEA;IACI,eAAe;IACf,gBAAgB;AACpB;;AAEA;IACI,gBAAgB;IAChB,aAAa;IACb,sBAAsB;IACtB,kBAAkB;IAClB,QAAQ;IACR,qBAAqB;IACrB,YAAY;IACZ,kBAAkB;IAClB,YAAY;IACZ,8DAA8D;IAC9D,aAAa;AACjB;;AAEA;IACI,SAAS;IACT,YAAY;IACZ,sCAAsC;AAC1C;;AAEA;IACI,aAAa;AACjB;;AAEA;;IAEI,cAAc;IACd,gBAAgB;IAChB,kBAAkB;IAClB,qBAAqB;IACrB,kBAAkB;IAClB,iCAAiC;AACrC;;AAEA;;IAEI,4BAA4B;AAChC;;AAEA;IACI,WAAW;IACX,uBAAuB;IACvB,qBAAqB;IACrB,aAAa;IACb,gBAAgB;AACpB;;AAEA;IACI,cAAc;AAClB;;AAEA;IACI,YAAY;AAChB;;AAEA;IACI,qBAAqB;AACzB;;AAEA;;IAEI,aAAa;IACb,gBAAgB;AACpB;;AAEA;IACI,mBAAmB;IACnB,WAAW;IACX,qBAAqB;IACrB,iBAAiB;IACjB,qBAAqB;IACrB,wBAAwB;IACxB,+BAA+B;AACnC;;AAEA;;IAEI,WAAW;IACX,aAAa;IACb,gBAAgB;AACpB;;AAEA;IACI,wBAAwB;AAC5B;;AAEA;IACI,2BAA2B;IAC3B,oBAAoB;AACxB;;AAEA;;IAEI,mBAAmB;IACnB,qBAAqB;IACrB,eAAe;AACnB;;AAEA;;IAEI,mBAAmB;IACnB,qBAAqB;AACzB;;AAEA;;IAEI,aAAa;IACb,iBAAiB;IACjB,eAAe;IACf,WAAW;AACf;;AAEA;IACI,qBAAqB;IACrB,gBAAgB;IAChB,WAAW;IACX,qBAAqB;IACrB,iCAAiC;AACrC;;AAEA;IACI,cAAc;AAClB;;AAEA;IACI,8BAA8B;IAC9B,aAAa;IACb,YAAY;AAChB;;AAEA;IACI,aAAa;AACjB;;AAEA;IACI,YAAY;AAChB;;AAEA;IACI,qCAAqC;IACrC,eAAe;IACf,aAAa;AACjB;;AAEA;IACI,cAAc;IACd,mBAAmB;IACnB,yBAAyB;IACzB,YAAY;IACZ,iBAAiB;IACjB,aAAa;IACb,kBAAkB;AACtB;;AAEA;IACI,gBAAgB;IAChB,kBAAkB;IAClB,WAAW;IACX,iBAAiB;IACjB,WAAW;IACX,gBAAgB;IAChB,mCAAmC;IACnC,iBAAiB;IACjB,mBAAmB;IACnB,oBAAoB;AACxB;;AAEA;IACI,WAAW;IACX,gBAAgB;IAChB,cAAc;IACd,iBAAiB;AACrB;;AAEA;IACI;QACI,gBAAgB;IACpB;AACJ;;AAEA;;IAEI,mCAAmC;IACnC,wDAAwD;IACxD,cAAc;IACd,WAAW;IACX,YAAY;IACZ,eAAe;IACf,kBAAkB;IAClB,kBAAkB;IAClB,kBAAkB;IAClB,MAAM;IACN,OAAO;IACP,WAAW;AACf;;AAEA;IACI,8BAA8B;AAClC;;AAEA;;IAEI,kBAAkB;AACtB;;AAEA;IACI,cAAc;AAClB;;AAEA;IACI,gBAAgB;IAChB,YAAY;IACZ,UAAU;IACV,yBAAyB;AAC7B;;AAEA;IACI,WAAW;IACX,mBAAmB;IACnB,QAAQ;IACR,YAAY;IACZ,0BAA0B;IAC1B,YAAY;IACZ,iBAAiB;IACjB,kBAAkB;IAClB,gBAAgB;AACpB;;AAEA;IACI,mBAAmB;IACnB,QAAQ;IACR,YAAY;IACZ,0BAA0B;IAC1B,YAAY;IACZ,iBAAiB;IACjB,kBAAkB;AACtB;;AAEA;;IAEI,yBAAyB;IACzB,yCAAyC;AAC7C;;AAEA;IACI,mBAAmB;IACnB,qBAAqB;AACzB;;AAEA;IACI,mBAAmB;IACnB,qBAAqB;AACzB;;AAEA;IACI,iBAAiB;IACjB,YAAY;AAChB;;AAEA;IACI,cAAc;AAClB;;AAEA;IACI,cAAc;IACd,yBAAyB;IACzB,aAAa;IACb,YAAY;AAChB;;AAEA;IACI,cAAc;IACd,eAAe;AACnB;;AAEA;IACI,WAAW;IACX,mBAAmB;IACnB,kBAAkB;IAClB,SAAS;AACb;;AAEA;IACI,QAAQ;AACZ;;AAEA;IACI,yBAAyB;AAC7B;;AAEA;IACI,qBAAqB;IACrB,gBAAgB;IAChB,eAAe;IACf,wBAAwB;AAC5B;;;AAGA,SAAS;;AAET;IACI,gBAAgB;IAChB,cAAc;AAClB;;AAEA;IACI,8BAA8B;IAC9B,oBAAoB;IACpB,mBAAmB;AACvB;;;AAGA;;;;;;CAMC;;AAED;IACI,6BAA6B;IAC7B,kBAAkB;IAClB,iBAAiB;IACjB,aAAa;IACb,WAAW;IACX,aAAa;AACjB;;AAEA;IACI,cAAc;IACd,WAAW;IACX,WAAW;AACf;;AAEA;IACI,6BAA6B;IAC7B,kBAAkB;IAClB,iBAAiB;IACjB,WAAW;IACX,eAAe;IACf,mBAAmB;IACnB,cAAc;IACd,aAAa;;IAEb,qBAAqB;AACzB;;AAEA;IACI,qBAAqB;IACrB,kBAAkB;IAClB,yBAAyB;AAC7B;;AAEA;IACI,WAAW;IACX,aAAa;IACb,gBAAgB;AACpB;;AAEA;IACI,aAAa;IACb,uBAAuB;IACvB,gBAAgB;IAChB,uBAAuB;IACvB,gBAAgB;IAChB,kBAAkB;IAClB,eAAe;AACnB;;AAEA;IACI,gBAAgB;IAChB,SAAS;IACT,cAAc;IACd,kBAAkB;IAClB,UAAU;IACV,SAAS;AACb;;;AAGA,QAAQ;;AAER;IACI,aAAa;IACb,iBAAiB;AACrB;;AAEA;IACI,cAAc;IACd,iBAAiB;AACrB;;AAEA;IACI,WAAW;IACX,eAAe;IACf,qBAAqB;AACzB;;AAEA;IACI,qBAAqB;IACrB,iBAAiB;AACrB;;AAEA;IACI,cAAc;IACd,yBAAyB;IACzB,aAAa;IACb,kBAAkB;IAClB,yBAAyB;IACzB,gBAAgB;IAChB,gBAAgB;AACpB;;AAEA;IACI,gBAAgB;IAChB,kBAAkB;IAClB,eAAe;IACf,gCAAgC;IAChC,WAAW;AACf;;AAEA;IACI,eAAe;IACf,iBAAiB;AACrB;;AAEA;IACI,aAAa;IACb,gBAAgB;IAChB,gBAAgB;IAChB,sBAAsB;IACtB,eAAe;IACf,iBAAiB;IACjB,sBAAsB;IACtB,uBAAuB;IACvB,cAAc;IACd,YAAY;IACZ,mBAAmB;IACnB,gBAAgB;AACpB;;AAEA;IACI,aAAa;AACjB;;AAEA;IACI,mBAAmB;IACnB,qBAAqB;IACrB,eAAe;AACnB;;AAEA;IACI,aAAa;IACb,uBAAuB;IACvB,gBAAgB;IAChB,sBAAsB;IACtB,gBAAgB;AACpB;;AAEA;IACI,mBAAmB;AACvB;;AAEA;IACI,YAAY;IACZ,aAAa;AACjB;;AAEA;IACI,gBAAgB;AACpB;;AAEA;IACI,UAAU;AACd;;AAEA;IACI,aAAa;AACjB;;AAEA;IACI,kBAAkB;AACtB;;AAEA;IACI,qBAAqB;AACzB;;AAEA;IACI,qBAAqB;AACzB;;AAEA;IACI,uBAAuB;IACvB,iBAAiB;IACjB,qBAAqB;IACrB,kBAAkB;AACtB;;AAEA;IACI,0BAA0B;IAC1B,uBAAuB;IACvB,kBAAkB;IAClB,WAAW;IACX,eAAe;IACf,eAAe;IACf,gBAAgB;AACpB;;AAEA;IACI,yBAAyB;AAC7B;;AAEA;IACI,yBAAyB;AAC7B;;AAEA;IACI,yBAAyB;AAC7B;;AAEA;;;IAGI,yBAAyB;AAC7B;;AAEA;IACI,gBAAgB;AACpB;;;AAGA,mBAAmB;;AAEnB;IACI,qBAAqB;IACrB,aAAa;IACb,gBAAgB;IAChB,eAAe;IACf,qBAAqB;IACrB,kBAAkB;IAClB,gBAAgB;IAChB,yBAAyB;IACzB,YAAY;AAChB;;AAEA;IACI,yBAAyB;AAC7B;;AAEA;IACI,yBAAyB;IACzB,YAAY;AAChB;;AAEA;IACI,yBAAyB;AAC7B;;AAEA;IACI,iBAAiB;IACjB,eAAe;IACf,uBAAuB;AAC3B;;AAEA;IACI,eAAe;IACf,iBAAiB;IACjB,kBAAkB;IAClB,kBAAkB;IAClB,2BAA2B;AAC/B;;AAEA;IACI,gBAAgB;IAChB,kBAAkB;IAClB,uBAAuB;AAC3B;;AAEA;IACI,cAAc;IACd,iBAAiB;AACrB;;AAEA;IACI,aAAa;IACb,qBAAqB;IACrB,eAAe;IACf,mBAAmB;AACvB;;AAEA;IACI,UAAU;IACV,YAAY;IACZ,mhBAAmhB;IACnhB,wBAAwB;IACxB,WAAW;IACX,kBAAkB;IAClB,MAAM;IACN,OAAO;IACP,cAAc;AAClB;;AAEA;IACI,sBAAsB;IACtB,gBAAgB;IAChB,oBAAoB;IACpB,sBAAsB;AAC1B;;AAEA;IACI,UAAU;AACd;;AAEA;IACI,gBAAgB;AACpB;;AAEA;IACI,WAAW;IACX,gBAAgB;IAChB,kBAAkB;AACtB;;AAEA;IACI,WAAW;IACX,uBAAuB;IACvB,aAAa;IACb,gBAAgB;IAChB,kBAAkB;AACtB;;AAEA;IACI,qBAAqB;AACzB;;AAEA;IACI,eAAe;IACf,YAAY;IACZ,eAAe;AACnB;;AAEA;IACI,YAAY;AAChB;;AAEA;IACI,kBAAkB;AACtB;;AAEA;IACI,gBAAgB;AACpB;;AAEA;IACI,eAAe;IACf,eAAe;IACf,gBAAgB;IAChB,WAAW;AACf;;AAEA;IACI,eAAe;IACf,eAAe;IACf,gBAAgB;IAChB,YAAY;AAChB;;AAEA;IACI,iBAAiB;IACjB,yBAAyB;IACzB,cAAc;IACd,uBAAuB;AAC3B;;AAEA;IACI,yBAAyB;IACzB,WAAW;AACf;;AAEA;IACI,qBAAqB;IACrB,6BAA6B;IAC7B,cAAc;IACd,kBAAkB;IAClB,eAAe;IACf,0BAA0B;IAC1B,yBAAyB;IACzB,gBAAgB;IAChB,UAAU;IACV,wCAAwC;IACxC,qBAAqB;AACzB;;AAEA;IACI,yBAAyB;IACzB,sBAAsB;IACtB,WAAW;IACX,gCAAgC;AACpC;;AAEA;IACI,yBAAyB;IACzB,yBAAyB;AAC7B;;AAEA;IACI,qBAAqB;IACrB,qBAAqB;IACrB,eAAe;IACf,iBAAiB;IACjB,YAAY;IACZ,SAAS;IACT,mBAAmB;IACnB,eAAe;IACf,iBAAiB;IACjB,mBAAmB;IACnB,wBAAwB;IACxB,kBAAkB;IAClB,mBAAmB;IACnB,sBAAsB;IACtB,mBAAmB;IACnB,qBAAqB;IACrB,WAAW;IACX,yFAAyF;AAC7F;;AAEA;IACI,yBAAyB;AAC7B;;AAEA;IACI,kBAAkB;IAClB,aAAa;IACb,YAAY;IACZ,sBAAsB;IACtB,uBAAuB;IACvB,yBAAyB;IACzB,kBAAkB;IAClB,gCAAgC;IAChC,aAAa;IACb,sBAAsB;AAC1B;;AAEA;IACI,cAAc;AAClB;;AAEA;;IAEI,WAAW;IACX,gBAAgB;IAChB,gBAAgB;IAChB,kBAAkB;AACtB;;AAEA;;IAEI,WAAW;IACX,gBAAgB;IAChB,gBAAgB;IAChB,cAAc;IACd,mBAAmB;IACnB,kBAAkB;IAClB,kBAAkB;IAClB,eAAe;AACnB;;AAEA;IACI,kBAAkB;IAClB,gBAAgB;IAChB,iBAAiB;IACjB,YAAY;AAChB;;AAEA;IACI,eAAe;IACf,mBAAmB;AACvB;;AAEA;IACI,YAAY;IACZ,iBAAiB;AACrB;;AAEA;IACI,WAAW;IACX,iBAAiB;AACrB;;AAEA;IACI,sBAAsB;IACtB,2BAA2B;IAC3B,yBAAyB;IACzB,kBAAkB;IAClB,wBAAwB;IACxB,YAAY;IACZ,cAAc;IACd,gBAAgB;IAChB,iBAAiB;IACjB,kBAAkB;AACtB;;AAEA;IACI,yBAAyB;IACzB,cAAc;IACd,eAAe;AACnB;;AAEA;IACI,yBAAyB;IACzB,cAAc;AAClB;;AAEA;IACI,aAAa;IACb,eAAe;AACnB;;AAEA;IACI,cAAc;IACd,aAAa;IACb,yBAAyB;IACzB,cAAc;IACd,wBAAwB;AAC5B;;AAEA;IACI,cAAc;IACd,iBAAiB;IACjB,0BAA0B;AAC9B;;AAEA;IACI,cAAc;IACd,aAAa;IACb,yBAAyB;IACzB,cAAc;IACd,wBAAwB;AAC5B;;AAEA;IACI,cAAc;IACd,iBAAiB;IACjB,0BAA0B;AAC9B;;AAEA;IACI,aAAa;AACjB;;AAEA;IACI,gBAAgB;IAChB,YAAY;AAChB;;AAEA;IACI,mBAAmB;AACvB;;AAEA;IACI,cAAc;IACd,eAAe;IACf,YAAY;IACZ,mBAAmB;IACnB,6BAA6B;IAC7B,kBAAkB;IAClB,qBAAqB;IACrB,kBAAkB;AACtB;;AAEA;IACI,eAAe;IACf,gBAAgB;IAChB,gBAAgB;AACpB;;AAEA;IACI,cAAc;IACd,yBAAyB;IACzB,qBAAqB;AACzB;;AAEA;IACI,cAAc;IACd,yBAAyB;IACzB,qBAAqB;AACzB;;AAEA;IACI,aAAa;IACb,eAAe;AACnB;;AAEA;IACI,yBAAyB;IACzB,eAAe;IACf,cAAc;IACd,mBAAmB;IACnB,aAAa;IACb,kBAAkB;AACtB;;AAEA;IACI,cAAc;IACd,iBAAiB;AACrB;;AAEA;IACI,eAAe;AACnB;;AAEA;IACI,aAAa;AACjB;;AAEA;IACI,iBAAiB;AACrB;;AAEA;IACI,eAAe;AACnB;;AAEA;IACI,gBAAgB;IAChB,kBAAkB;IAClB,eAAe;IACf,qBAAqB;IACrB,mBAAmB;IACnB,iBAAiB;AACrB;;AAEA;IACI,iCAAiC;IACjC,cAAc;AAClB;;AAEA;IACI,aAAa;AACjB;;AAEA;IACI,cAAc;AAClB;;AAEA;;IAEI,4BAA4B;AAChC;;AAEA;IACI,cAAc;AAClB;;AAEA;IACI,kBAAkB;IAClB,qBAAqB;IACrB,+BAA+B;IAC/B,iBAAiB;AACrB;;AAEA;IACI,kBAAkB;IAClB,YAAY;IACZ,yBAAyB;IACzB,cAAc;IACd,gBAAgB;IAChB,aAAa;IACb,yBAAyB;IACzB,kBAAkB;IAClB,kBAAkB;IAClB,UAAU;IACV,sDAAsD;IACtD,mDAAmD;IACnD,8CAA8C;AAClD;;AAEA;IACI,mBAAmB;AACvB;;AAEA;IACI,YAAY;IACZ,SAAS;IACT,WAAW;IACX,kBAAkB;IAClB,8DAA8D;IAC9D,gBAAgB;AACpB;;;AAGA;;EAEE;;AAEF;IACI,YAAY;IACZ,kBAAkB;IAClB,YAAY;IACZ,8BAA8B;IAC9B,SAAS;IACT,iBAAiB;IACjB,iBAAiB;IACjB,mBAAmB;IACnB,uDAAuD;AAC3D;;AAEA;IACI,iBAAiB;AACrB;;AAEA;IACI,WAAW;AACf;;AAEA;IACI,yBAAyB;IACzB,kBAAkB;IAClB,YAAY;IACZ,mBAAmB;AACvB;;AAEA;IACI,kBAAkB;IAClB,gBAAgB;AACpB;;AAEA;IACI,oGAAoG;IACpG,mCAAmC;IACnC,iEAAiE;AACrE;;AAEA;IACI,mBAAmB;IACnB,qBAAqB;IACrB,WAAW;IACX,YAAY;IACZ,mBAAmB;IACnB,eAAe;IACf,aAAa;IACb,oBAAoB;AACxB;;AAEA;IACI,mBAAmB;IACnB,qBAAqB;AACzB;;AAEA;IACI,2BAA2B;AAC/B;;AAEA;;IAEI,iBAAiB;IACjB,aAAa;IACb,eAAe;IACf,aAAa;IACb,YAAY;IACZ,gBAAgB;IAChB,mBAAmB;AACvB;;AAEA;IACI,YAAY;IACZ,iBAAiB;AACrB;;AAEA;;IAEI,gBAAgB;IAChB,eAAe;AACnB;;AAEA;;IAEI,cAAc;AAClB;;AAEA;IACI,cAAc;AAClB;;AAEA;IACI,UAAU;AACd;;AAEA;IACI,iBAAiB;AACrB;;AAEA;IACI,cAAc;AAClB;;AAEA;IACI,gBAAgB;AACpB;;AAEA;IACI,eAAe;IACf,aAAa;IACb,mBAAmB;IACnB,YAAY;IACZ,kBAAkB;AACtB;;AAEA;IACI,gCAAgC;AACpC;;AAEA;IACI,aAAa;IACb,8BAA8B;IAC9B,cAAc;AAClB;;AAEA;IACI,cAAc;IACd,gBAAgB;IAChB,YAAY;IACZ,eAAe;AACnB;;AAEA;IACI,cAAc;AAClB;;AAEA;;;;IAII,aAAa;AACjB;;AAEA;IACI,eAAe;IACf,iBAAiB;AACrB;;AAEA;IACI,UAAU;AACd;;AAEA;IACI,eAAe;AACnB;;AAEA;IACI,mBAAmB;AACvB;;AAEA;;IAEI,cAAc;AAClB;;AAEA;IACI,kBAAkB;IAClB,kBAAkB;IAClB,YAAY;IACZ,iBAAiB;IACjB,2BAA2B;IAC3B,aAAa;IACb,sBAAsB;AAC1B;;AAEA;IACI,aAAa;IACb,sBAAsB;AAC1B;;AAEA;IACI,yBAAyB;IACzB,YAAY;AAChB;;AAEA;;;;IAII,aAAa;AACjB;;AAEA;IACI,qBAAqB;AACzB;;AAEA;IACI,aAAa;AACjB;;AAEA;IACI,UAAU;IACV,kBAAkB;IAClB,YAAY;AAChB;;AAEA;IACI,eAAe;AACnB;;AAEA;IACI,eAAe;IACf,YAAY;IACZ,kBAAkB;IAClB,YAAY;IACZ,YAAY;IACZ,mBAAmB;AACvB;;;AAGA;;;;;;EAME;;AAEF;IACI,kBAAkB;IAClB,aAAa;IACb,uBAAuB;AAC3B;;AAEA;IACI,aAAa;AACjB;;AAEA;IACI,UAAU;IACV,kBAAkB;IAClB,cAAc;IACd,kBAAkB;IAClB,YAAY;IACZ,mBAAmB;IACnB,sBAAsB;IACtB,0BAA0B;IAC1B,iBAAiB;IACjB,qBAAqB;IACrB,yFAAyF;AAC7F;;AAEA;IACI,iCAAiC;IACjC,SAAS;AACb;;AAEA;IACI,yBAAyB;AAC7B;;AAEA;IACI,mBAAmB;AACvB;;AAEA;IACI,eAAe;IACf,gBAAgB;IAChB,YAAY;IACZ,SAAS;IACT,WAAW;IACX,YAAY;IACZ,YAAY;IACZ,iBAAiB;AACrB;;AAEA;IACI,yBAAyB;AAC7B;;AAEA;IACI,aAAa;IACb,aAAa;IACb,mBAAmB;AACvB;;AAEA;IACI,gBAAgB;IAChB,SAAS;AACb;;;AAGA;;;;;;CAMC;;AAED;IACI,kBAAkB;AACtB;;AAEA;IACI,SAAS;IACT,kBAAkB;IAClB,eAAe;IACf,yFAAyF;IACzF,eAAe;AACnB;;AAEA;IACI,YAAY;IACZ,yBAAyB;AAC7B;;AAEA;IACI,YAAY;IACZ,yBAAyB;IACzB,WAAW;IACX,YAAY;IACZ,eAAe;AACnB;;AAEA;IACI,aAAa;AACjB;;AAEA;IACI,OAAO;IACP,aAAa;IACb,sBAAsB;AAC1B;;AAEA;IACI,WAAW;IACX,gCAAgC;IAChC,mBAAmB;AACvB;;AAEA;IACI,gBAAgB;IAChB,mCAAmC,EAAE,kGAAkG;IACvI,qBAAqB;IACrB,iBAAiB;IACjB,yBAAyB;IACzB,kBAAkB;IAClB,WAAW;IACX,YAAY;IACZ,mBAAmB;AACvB;;AAEA;IACI,aAAa;IACb,kBAAkB;IAClB,iBAAiB;IACjB,WAAW;IACX,YAAY;IACZ,MAAM;IACN,OAAO;IACP,gBAAgB;IAChB,mBAAmB;IACnB,gBAAgB;IAChB,cAAc;IACd,0BAA0B;IAC1B,uBAAuB;IACvB,mBAAmB;AACvB;;AAEA;IACI,kBAAkB;IAClB,mBAAmB;IACnB,YAAY;IACZ,QAAQ;IACR,YAAY;IACZ,kBAAkB;IAClB,UAAU;IACV,MAAM;AACV;;AAEA;IACI,UAAU;AACd;;AAEA;IACI,YAAY;IACZ,2BAA2B;IAC3B,gBAAgB;AACpB;;AAEA;IACI,eAAe;AACnB;;AAEA;IACI,iBAAiB;IACjB,yBAAyB;IACzB,aAAa;IACb,2BAA2B;IAC3B,gBAAgB;AACpB;;AAEA;IACI,aAAa;IACb,eAAe;IACf,WAAW;IACX,kBAAkB;AACtB;;AAEA;IACI,qBAAqB;IACrB,gBAAgB;IAChB,cAAc;IACd,UAAU;AACd;;AAEA;IACI,YAAY;IACZ,qBAAqB;AACzB;;AAEA;IACI,cAAc;AAClB;;AAEA;IACI,eAAe;IACf,gBAAgB;IAChB,gBAAgB;AACpB;;AAEA;IACI,eAAe;IACf,WAAW;IACX,kBAAkB;AACtB;;AAEA;IACI,SAAS;AACb;;AAEA;IACI,kBAAkB;AACtB;;AAEA;IACI,kCAAkC;AACtC;;AAEA;IACI,gBAAgB;AACpB;;AAEA;IACI,WAAW;AACf;;AAEA;IACI,YAAY;IACZ,gBAAgB;AACpB;;AAEA;IACI,YAAY;AAChB;;AAEA;IACI,cAAc;AAClB;;AAEA;IACI,cAAc;AAClB;;AAEA;IACI,iBAAiB;AACrB;;AAEA;IACI,cAAc;AAClB;;AAEA;IACI,cAAc;AAClB;;AAEA;;IAEI,mBAAmB;IACnB,iBAAiB;IACjB,kBAAkB;IAClB,eAAe;IACf,kBAAkB;AACtB;;AAEA;IACI,YAAY;AAChB;;AAEA;IACI,iBAAiB;IACjB,UAAU;IACV,mBAAmB;AACvB;;AAEA;IACI,YAAY;AAChB;;AAEA;IACI,iBAAiB;AACrB;;AAEA;IACI,YAAY;IACZ,2BAA2B;IAC3B,gBAAgB;AACpB;;AAEA;IACI,eAAe;AACnB;;AAEA;IACI,iBAAiB;IACjB,yBAAyB;IACzB,aAAa;IACb,2BAA2B;IAC3B,gBAAgB;AACpB;;AAEA;IACI,aAAa;IACb,eAAe;IACf,WAAW;IACX,kBAAkB;AACtB;;AAEA;IACI,qBAAqB;IACrB,gBAAgB;IAChB,cAAc;IACd,UAAU;AACd;;AAEA;IACI,YAAY;IACZ,qBAAqB;AACzB;;AAEA;IACI,cAAc;AAClB;;AAEA;IACI,eAAe;IACf,gBAAgB;IAChB,gBAAgB;AACpB;;AAEA;IACI,eAAe;IACf,WAAW;AACf;;AAEA;IACI,iBAAiB;AACrB;;AAEA;IACI;QACI,cAAc;IAClB;IACA;QACI,cAAc;QACd,eAAe;QACf,WAAW;IACf;IACA;QACI,WAAW;QACX,cAAc;IAClB;IACA;QACI,cAAc;QACd,eAAe;IACnB;IACA;QACI,yBAAyB;QACzB,6BAA6B;IACjC;AACJ;;AAEA;IACI,kBAAkB;AACtB;;AAEA;IACI,kCAAkC;AACtC;;AAEA;IACI,SAAS;AACb;;AAEA;IACI,gBAAgB;AACpB;;AAEA;IACI,gBAAgB;AACpB;;AAEA;IACI,gBAAgB;IAChB,mBAAmB;AACvB;;AAEA;IACI,WAAW;AACf;;AAEA;IACI,yCAAyC;AAC7C;;AAEA;IACI,WAAW;AACf;;AAEA;IACI,iBAAiB;IACjB,yBAAyB;IACzB,YAAY;IACZ,aAAa;IACb,wBAAwB;AAC5B;;AAEA;IACI,iBAAiB;AACrB;;AAEA;IACI,mBAAmB;IACnB,YAAY;AAChB;;AAEA;IACI,8BAA8B;AAClC;;AAEA;IACI,yBAAyB;IACzB,WAAW;IACX,YAAY;IACZ,kBAAkB;AACtB;;AAEA;IACI,kBAAkB;IAClB,eAAe;AACnB;;AAEA;IACI,mBAAmB;AACvB;;AAEA;IACI,YAAY;AAChB;;AAEA;IACI,WAAW;AACf;;AAEA;IACI,eAAe;AACnB;;AAEA;IACI,kBAAkB;AACtB;;AAEA;IACI,gBAAgB;AACpB;;AAEA;IACI,uBAAuB;IACvB,aAAa;IACb,mBAAmB;AACvB;;AAEA;IACI,iBAAiB;AACrB;;AAEA;IACI,kBAAkB;AACtB;;AAEA;IACI,qBAAqB;IACrB;AACJ;;AAEA;IACI,cAAc;IACd,mBAAmB;IACnB,cAAc;AAClB;;AAEA;IACI,YAAY;IACZ,gBAAgB;AACpB;;AAEA;IACI,YAAY;AAChB;;AAEA;IACI,cAAc;AAClB;;AAEA;IACI,WAAW;IACX,iBAAiB;AACrB;;AAEA;IACI,cAAc;AAClB;;AAEA;;IAEI,yBAAyB;AAC7B;;AAEA;;IAEI,yBAAyB;AAC7B;;AAEA;;IAEI,yBAAyB;AAC7B;;AAEA;;IAEI,yBAAyB;AAC7B;;AAEA;;IAEI,cAAc;AAClB;;AAEA;;IAEI,aAAa;AACjB;;AAEA;IACI,SAAS;AACb;;AAEA;IACI,kBAAkB;IAClB,iBAAiB;IACjB,YAAY;IACZ,aAAa;IACb,yBAAyB;IACzB,kBAAkB;IAClB,kBAAkB;IAClB,yBAAyB;AAC7B;;AAEA;IACI,aAAa,EAAE,uDAAuD;IACtE,gBAAgB;AACpB;;AAEA;IACI,gBAAgB;IAChB,gBAAgB;AACpB;;AAEA;IACI,kBAAkB;AACtB;;AAEA;IACI,qBAAqB;AACzB;;AAEA;IACI,kBAAkB;IAClB,cAAc;IACd,yBAAyB;IACzB,yBAAyB;IACzB,WAAW;IACX,YAAY;IACZ,eAAe;AACnB;;AAEA;IACI,YAAY;IACZ,cAAc;IACd,yBAAyB;IACzB,yBAAyB;AAC7B;;AAEA;IACI,WAAW;IACX,kBAAkB;IAClB,YAAY;IACZ,WAAW;IACX,kBAAkB;AACtB;;AAEA;IACI,qBAAqB;AACzB;;AAEA;IACI,qBAAqB;AACzB;;AAEA;IACI,qBAAqB;IACrB,iBAAiB;AACrB;;AAEA;IACI,kBAAkB;IAClB,qBAAqB;IACrB,kBAAkB;IAClB,cAAc;AAClB;;AAEA;IACI,eAAe;AACnB;;AAEA;IACI,eAAe;IACf,gBAAgB;IAChB,mBAAmB;IACnB,gBAAgB;IAChB,yBAAyB;IACzB,yBAAyB;IACzB,kBAAkB;IAClB,YAAY;IACZ,eAAe;AACnB;;AAEA;IACI,yBAAyB;IACzB,yBAAyB;AAC7B;;AAEA;IACI,YAAY;AAChB;;AAEA;IACI,uBAAuB;IACvB,qBAAqB;AACzB;;AAEA;IACI,mBAAmB;AACvB;;AAEA;IACI,iBAAiB;IACjB,oBAAoB;AACxB;;AAEA;IACI,gBAAgB;AACpB;;AAEA;IACI,aAAa;IACb,mBAAmB;AACvB;;AAEA;IACI,UAAU;IACV,UAAU;IACV,eAAe;AACnB;;AAEA;;EAEE;;AAEF;IACI,UAAU;CACb,gBAAgB;IACb,mBAAmB;CACtB,eAAe;IACZ,WAAW;AACf;;AAEA;IACI,WAAW;IACX,yBAAyB;IACzB,yBAAyB;AAC7B;;AAEA;IACI,gBAAgB;IAChB,mBAAmB;IACnB,YAAY;AAChB;;AAEA;IACI,SAAS;AACb;;AAEA;;EAEE;;AAEF;IACI,aAAa;IACb,2BAA2B;IAC3B,UAAU;AACd;;AAEA;IACI,YAAY;IACZ,2BAA2B;IAC3B,kBAAkB;AACtB;;AAEA;IACI,WAAW;IACX,eAAe;CAClB,4BAA4B;IACzB,mBAAmB;AACvB;;AAEA;IACI,YAAY;IACZ,kBAAkB;AACtB;;AAEA;;EAEE;;AAEF;IACI,mBAAmB;IACnB,yBAAyB;IACzB,WAAW;IACX,gBAAgB;IAChB,qBAAqB;IACrB,gBAAgB;IAChB,gBAAgB;IAChB,kBAAkB;IAClB,gBAAgB;IAChB,aAAa;IACb,gBAAgB;IAChB,eAAe;IACf,YAAY;AAChB;;AAEA;IACI,mBAAmB;IACnB,yBAAyB;AAC7B;;AAEA;IACI,YAAY;AAChB;;AAEA;IACI,sBAAsB;IACtB,yBAAyB;IACzB,yBAAyB;IACzB,WAAW;CACd,YAAY;CACZ,mBAAmB;CACnB,eAAe;CACf,UAAU;CACV,oBAAoB;CACpB,uBAAuB;IACpB,aAAa;IACb,gBAAgB;IAChB,gBAAgB;IAChB,gBAAgB;IAChB,eAAe;IACf,eAAe;AACnB;;AAEA;IACI,yBAAyB;IACzB,qBAAqB;AACzB;;AAEA;;EAEE;;CAED;CACA,qBAAqB;CACrB,kBAAkB;AACnB;;AAEA;CACC,kBAAkB;CAClB,SAAS;CACT,aAAa;CACb,aAAa;CACb,YAAY;CACZ,aAAa;CACb,wBAAwB;CACxB,kEAAkE;AACnE;;AAEA;CACC,cAAc;AACf;;AAEA;CACC,eAAe;CACf,gBAAgB;CAChB,mBAAmB;CACnB,kBAAkB;AACnB;;AAEA;IACI,8BAA8B;AAClC;;AAEA;IACI,qBAAqB;IACrB,eAAe;CAClB,sBAAsB;CACtB,gBAAgB;CAChB,gBAAgB;IACb,kBAAkB;IAClB,cAAc;AAClB;;AAEA;IACI,sBAAsB;IACtB,yBAAyB;IACzB,yBAAyB;IACzB,WAAW;CACd,YAAY;CACZ,kBAAkB;CAClB,eAAe;CACf,UAAU;CACV,oBAAoB;CACpB,uBAAuB;IACpB,mBAAmB;IACnB,aAAa;IACb,gBAAgB;IAChB,gBAAgB;IAChB,sBAAsB;AAC1B;;AAEA;IACI,yBAAyB;IACzB,yBAAyB;AAC7B;;AAEA;;EAEE;;CAED;IACG,0BAA0B;IAC1B,gBAAgB;IAChB,gBAAgB;IAChB,wBAAwB;IACxB,qBAAqB;IACrB,gBAAgB;IAChB,gBAAgB;IAChB,WAAW;IACX,2BAA2B;IAC3B,sBAAsB;IACtB,sBAAsB;IACtB,2BAA2B;IAC3B,eAAe;IACf,gBAAgB;IAChB,mCAAmC;IACnC,+CAA+C;IAC/C,YAAY;AAChB;;AAEA;CACC,kBAAkB;AACnB;;AAEA;IACI,sBAAsB;AAC1B;;AAEA;IACI,oCAAoC;IACpC,6EAA6E;AACjF;;AAEA;;IAEI,YAAY;AAChB;;AAEA;IACI,WAAW;AACf;;AAEA;IACI,WAAW;AACf;;AAEA;IACI,gBAAgB;AACpB;;AAEA;IACI,aAAa;AACjB;;AAEA;IACI,mBAAmB;AACvB;;AAEA;IACI,aAAa;AACjB;;AAEA;IACI,cAAc;AAClB;;AAEA;IACI,WAAW;IACX,aAAa;IACb,gBAAgB;IAChB,aAAa;IACb,uBAAuB;IACvB,mBAAmB;AACvB;;AAEA;CACC;EACC,oBAAoB;CACrB;CACA;EACC,yBAAyB;CAC1B;AACD;;AAEA;IACI,WAAW;IACX,YAAY;IACZ,qDAAqD;IACrD,6DAA6D;AACjE;;AAEA;IACI,sBAAsB;AAC1B;;AAEA;IACI,kBAAkB;IAClB,gBAAgB;IAChB,gBAAgB;IAChB,aAAa;AACjB;;AAEA;IACI,gBAAgB;AACpB;;AAEA;IACI,kBAAkB;AACtB;;AAEA;IACI,qBAAqB;IACrB,qBAAqB;IACrB,kBAAkB;IAClB,uBAAuB;IACvB,yBAAyB;IACzB,YAAY;IACZ,kBAAkB;IAClB,yBAAyB;AAC7B;;AAEA;IACI,yBAAyB;AAC7B;;AAEA;IACI,aAAa;AACjB;;AAEA;IACI,gBAAgB;AACpB;;AAEA;IACI,aAAa;AACjB;;AAEA;IACI,YAAY;AAChB;;AAEA;IACI,gBAAgB;IAChB,uBAAuB;AAC3B;;AAEA;IACI,eAAe;AACnB;;AAEA;IACI,kBAAkB;AACtB;;AAEA;IACI,eAAe;AACnB;;AAEA;IACI,0BAA0B;AAC9B;;AAEA;IACI,sCAAsC;AAC1C","file":"wpstg-admin.css","sourcesContent":["/**\n * WPSTG Admin CSS\n *\n * @package WPSTG\n * @subpackage Admin CSS\n * @copyright Copyright (c) 2021, René Hermenau\n * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License\n*/\n\n\n/* CSS for Tabs */\n\n#wpstg-tab-container ul {\n /*height: 200px;*/\n list-style: none;\n margin: 0;\n padding: 0;\n background: #f1f1f1;\n float: left;\n /*list-style-type: square;*/\n}\n\n#wpstg-tab-container ul li:first-child.selected-tab {\n border-top: none;\n}\n\n#wpstg-tab-container ul li a.selected-tab {\n font-weight: bold;\n text-decoration: none;\n}\n\n#wpstg-tab-container .row {\n padding-top: 10px;\n padding-bottom: 12px;\n}\n\n.wpstg-tabs-container .nav-tab-wrapper {\n padding: 0;\n}\n\n#wpstg-tab-container .row label strong,\n#wpstg-tab-container .row strong {\n font-weight: bold;\n}\n\n.wpstg-tabs a {\n padding: 5px;\n}\n\n#wpstg-tab-container>ul>li.wpstg-tabs.active {\n background-color: white;\n}\n\n#wpstg_settingsgeneral_header .row:nth-child(3),\n#wpstg_settingsgeneral_header .row:nth-child(4) {\n display: none;\n}\n\n#wpstg-tab-container .wpstg-settings-panel {\n padding: 0 20px 20px 20px;\n overflow: auto;\n}\n\n#wpstg-tab-container .wpstg-form-table th {\n vertical-align: top;\n text-align: left;\n padding: 20px 10px 20px 0;\n line-height: 1.3;\n font-weight: bold;\n font-size: 14px;\n color: #484848;\n width: 30%;\n}\n\n#wpstg-tab-container .wpstg-form-table tr {\n border-bottom: 1px solid #E7E7E7;\n}\n\n#wpstg-tab-container span.description {\n display: block;\n font-weight: 400;\n font-style: normal;\n font-size: 13px;\n margin-top: 7px;\n color: #484848;\n}\n\n#wpstg-tab-container .col-title {\n color: #484848;\n}\n\n@media only screen and (max-width: 680px) {\n #wpstg-tab-container ul {\n float: none;\n }\n #wpstg-tab-container .wpstg-form-table tr>th {\n width: 100%;\n }\n #wpstg-tab-container span.description {\n font-size: 14px;\n }\n #wpstg-tab-container .wpstg-form-table tr>th,\n #wpstg-tab-container .wpstg-form-table tr>td {\n padding: 10px;\n }\n}\n\n#wpstg-tab-container ul li {\n margin-bottom: 0;\n}\n\n#wpstg-tab-container ul li a {\n display: block;\n padding: 10px 4px 10px 14px;\n border-width: 1px 0;\n border-style: solid;\n border-top-color: white;\n border-bottom-color: #e7e7e7;\n text-decoration: none;\n color: #0097DF;\n font-weight: bold;\n}\n\n#wpstg-tab-container ul li a:hover {\n background-color: #e5e5e5;\n color: #777777;\n}\n\n.wpstg-logo {\n display: block;\n font-size: 16px;\n padding-top: 20px;\n width: 220px;\n float: left;\n}\n\n.wpstg-version {\n display: block;\n padding-top: 29px\n}\n\n.wpstg_admin .nav-tab {\n color: #3C3C3C;\n}\n\n#wpstg-tab-container table tbody tr:nth-child(1)>th>div {\n font-size: 20px;\n}\n\n.wpstg_hidden {\n display: none;\n}\n\n\n/* Cloning workflow */\n\n#wpstg-clonepage-wrapper {\n margin-bottom: 20px;\n}\n\n@media screen and (min-width: 1090px) {\n #wpstg-clonepage-wrapper {\n float: left;\n margin-bottom: 20px;\n }\n .wpstg-sidebar {\n display: none;\n margin-left: 700px;\n margin-top: 138px;\n }\n}\n\n.wpstg-sidebar {\n display: none;\n padding: 10px;\n border: 1px solid #DFDFDF;\n max-width: 250px;\n height: 250px;\n}\n\n#wpstg-steps {\n margin-top: 30px;\n}\n\n#wpstg-steps li {\n color: #444;\n line-height: 20px;\n padding-right: 10px;\n float: left;\n}\n\n.wpstg-step-num {\n border: 1px solid #444;\n border-radius: 3px;\n display: inline-block;\n width: 20px;\n height: 20px;\n text-align: center;\n margin-right: 5px;\n}\n\n.wpstg-current-step {\n font-weight: bold;\n}\n\n.wpstg-current-step .wpstg-step-num {\n background: #444;\n color: #eee;\n}\n\n.wpstg-box {\n margin: 10px 0;\n padding: 10px;\n position: relative;\n overflow: hidden;\n transition: border-color .2s ease-in-out;\n}\n\n.wpstg-clone {\n margin-bottom: 3px;\n padding: 16px;\n position: relative;\n transition: border-color .2s ease-in-out;\n background-color: #25a1f0;\n border-radius: .25rem;\n box-shadow: 0 0 1px rgba(0,0,0,.125), 0 1px 3px rgba(0,0,0,.2);\n}\n\n.wpstg-clone.active {\n border-color: #1d94cf;\n}\n\n.wpstg-clone-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.wpstg-clone-title {\n display: inline-block;\n font-size: 15px;\n max-width: 300px;\n text-decoration: none;\n font-weight: bold;\n color: white;\n}\n\n.wpstg-clone-title:hover {\n color: #f1f1f1;\n}\n\n.wpstg-clone-actions {\n display: flex;\n /*align-items: right;*/\n}\n\n.wpstg-dropdown {\n position: relative;\n}\n\n.wpstg-clone-actions .wpstg-dropdown-toggler {\n text-decoration: none;\n background: #fff;\n padding: 4px 10px;\n border-radius: 2px;\n font-size: 14px;\n box-shadow: 0 0 1px rgba(0,0,0,.125), 0 1px 3px rgba(0,0,0,.2);\n color: #002648;\n}\n\n.wpstg-clone-actions .wpstg-dropdown-toggler:hover {\n background: #002648;\n color: white;\n}\n\n.wpstg-dropdown {\n position: relative;\n}\n\n.wpstg-dropdown-symbol {\n font-size: 14px;\n margin-left: 4px;\n}\n\n.wpstg-dropdown>.wpstg-dropdown-menu {\n background: #fff;\n display: none;\n flex-direction: column;\n position: absolute;\n right: 0;\n top: calc(100% + 4px);\n padding: 8px;\n border-radius: 2px;\n width: 100px;\n box-shadow: 0 0 1px rgba(0,0,0,.125), 0 1px 3px rgba(0,0,0,.2);\n z-index: 1000;\n}\n\n.wpstg-dropdown>.wpstg-dropdown-menu.wpstg-menu-dropup {\n top: auto;\n bottom: 100%;\n transform: translate3d(0px, -3px, 0px);\n}\n\n.wpstg-dropdown>.wpstg-dropdown-menu.shown {\n display: flex;\n}\n\n.wpstg-clone-action,\n.wpstg-dropdown-action {\n color: #002648;\n padding: 5px 8px;\n border-radius: 3px;\n text-decoration: none;\n position: relative;\n transition: color .2s ease-in-out;\n}\n\n.wpstg-clone-action:hover,\n.wpstg-dropdown-action:hover {\n background: rgba(0,0,0,0.05);\n}\n\n.wpstg-dropdown-action {\n color: #333;\n background: transparent;\n border: 0 solid black;\n outline: none;\n box-shadow: none;\n}\n\n.wpstg-remove-clone:hover {\n color: #ef6d6d;\n}\n\n.wpstg-clone-action:last-child {\n border: none;\n}\n\n.wpstg-clone:hover .wpstg-clone-action {\n display: inline-block;\n}\n\n#wpstg-show-error-details:focus,\n#wpstg-workflow .wpstg-clone-action {\n outline: none;\n box-shadow: none;\n}\n\n.wpstg-link-btn {\n background: #45a1c9;\n color: #fff;\n display: inline-block;\n padding: 5px 10px;\n text-decoration: none;\n vertical-align: baseline;\n transition: all .2s ease-in-out;\n}\n\n.wpstg-link-btn:hover,\n.wpstg-link-btn:focus {\n color: #fff;\n outline: none;\n box-shadow: none;\n}\n\n#wpstg-workflow .wpstg-link-btn:active {\n vertical-align: baseline;\n}\n\n.wpstg-link-btn[disabled] {\n background: #777 !important;\n pointer-events: none;\n}\n\n#wpstg-cancel-cloning,\n#wpstg-cancel-cloning-update {\n background: #ff3428;\n border-color: #e72f24;\n margin-top: 5px;\n}\n\n#wpstg-cancel-cloning.success,\n#wpstg-cancel-cloning.success {\n background: #64dd58;\n border-color: #54bd4a;\n}\n\n#wpstg-error-wrapper,\n#wpstg-error-details {\n display: none;\n padding-top: 10px;\n font-size: 13px;\n clear: both;\n}\n\n#wpstg-show-error-details {\n display: inline-block;\n margin-left: 5px;\n color: #555;\n text-decoration: none;\n transition: color .2s ease-in-out;\n}\n\n#wpstg-show-error-details:hover {\n color: #1d94cf;\n}\n\n#wpstg-error-details {\n border-left: 5px solid #ef6d6d;\n padding: 10px;\n width: 500px;\n}\n\n#wpstg-try-again {\n display: none;\n}\n\n#wpstg-home-link {\n float: right;\n}\n\n.wpstg-loader {\n content: url('../../img/loading.gif');\n margin-top: 5px;\n display: none;\n}\n\n.wpstg-loader.wpstg-finished {\n display: block;\n content: \"Finished\";\n background-color: #00c89a;\n color: white;\n padding: 2px 10px;\n margin-top: 0;\n border-radius: 3px;\n}\n\n#wpstg-workflow {\n max-width: 650px;\n position: relative;\n clear: both;\n padding-top: 20px;\n float: left;\n min-width: 500px;\n /*border-right: 1px solid #DFDFDF;*/\n min-height: 380px;\n padding-right: 20px;\n padding-bottom: 20px;\n}\n\n#wpstg-sidebar {\n float: left;\n max-width: 400px;\n display: block;\n margin-left: 10px;\n}\n\n@media screen and (max-width: 1150px) {\n #wpstg-sidebar img {\n margin-top: 30px;\n }\n}\n\n#wpstg-workflow.loading::after,\n#wpstg-removing-clone.loading::after {\n background: rgba(255, 255, 255, .7);\n content: 'Loading... may take a while for huge websites';\n display: block;\n width: 100%;\n height: 100%;\n font-size: 20px;\n padding-top: 100px;\n text-align: center;\n position: absolute;\n top: 0;\n left: 0;\n z-index: 99;\n}\n\n#wpstg-removing-clone.loading::after {\n content: 'REMOVING' !important;\n}\n\n#wpstg-existing-clones,\n#wpstg-removing-clone {\n position: relative;\n}\n\n#wpstg-removing-clone .wpstg-tab-section {\n display: block;\n}\n\n.wpstg-progress-bar {\n max-width: 900px;\n height: 27px;\n padding: 0;\n background-color: #d6d8d7;\n}\n\n.wpstg-progress {\n float: left;\n background: #3fa5ee;\n width: 0;\n height: 100%;\n transition: width .6s ease;\n color: white;\n line-height: 25px;\n text-align: center;\n overflow: hidden;\n}\n\n.wpstg-progress-files {\n background: #16b4f0;\n width: 0;\n height: 100%;\n transition: width .6s ease;\n color: white;\n line-height: 25px;\n text-align: center;\n}\n\n#wpstg-new-clone-id.wpstg-error-input,\n#wpstg-clone-path.wpstg-error-input {\n border: 1px solid #ff4235;\n box-shadow: 0 0 2px rgba(255, 66, 53, .8);\n}\n\n#wpstg-new-clone {\n background: #25a1f0;\n border-color: #2188c9;\n}\n\n#wpstg-new-clone:hover {\n background: #259be6;\n border-color: #2188c9;\n}\n\n#wpstg-clone-path {\n margin-left: 10px;\n width: 350px;\n}\n\n.wpstg-error-msg {\n color: #ff4235;\n}\n\n#wpstg-clone-id-error {\n display: block;\n background-color: #f0f8ff;\n padding: 10px;\n margin: 20px;\n}\n\n#wpstg-start-cloning+.wpstg-error-msg {\n display: block;\n margin-top: 5px;\n}\n\n.wpstg-size-info {\n color: #999;\n font-weight: normal;\n position: relative;\n left: 2px;\n}\n\n.wpstg-db-table .wpstg-size-info {\n top: 2px;\n}\n\n.wpstg-db-table:hover {\n background-color: #f0f8ff;\n}\n\n#wpstg-workflow #wpstg-start-cloning {\n display: inline-block;\n margin-left: 5px;\n font-size: 14px;\n vertical-align: baseline;\n}\n\n\n/* Tabs */\n\n.wpstg-tabs-wrapper {\n max-width: 640px;\n margin: 10px 0;\n}\n\n#wpstg-path-wrapper {\n border-bottom: 2px dashed #ccc;\n padding-bottom: 10px;\n margin-bottom: 10px;\n}\n\n\n/* unused class should be removed or commented\n.wpstg-tabs-wrapper {\n border: 1px solid #ddd;\n border-right: none;\n border-left: none;\n}\n*/\n\n.wpstg-tab-section {\n border-bottom: 1px solid #ddd;\n border-right: none;\n border-left: none;\n display: none;\n width: 100%;\n padding: 20px;\n}\n\n.wpstg-tab-section::after {\n display: block;\n content: '';\n clear: both;\n}\n\n.wpstg-tab-header {\n border-bottom: 1px solid #ddd;\n border-right: none;\n border-left: none;\n color: #444;\n font-size: 16px;\n font-weight: bolder;\n display: block;\n padding: 10px;\n ;\n text-decoration: none;\n}\n\n.wpstg-tab-triangle {\n display: inline-block;\n margin-right: 10px;\n animation: transform 0.5s;\n}\n\n.wpstg-tab-header:focus {\n color: #444;\n outline: none;\n box-shadow: none;\n}\n\n#wpstg-large-files {\n display: none;\n border: 1px dashed #ccc;\n /*float: right;*/\n padding: 10px 10px 10px;\n margin-top: 20px;\n position: relative;\n font-size: 12px;\n}\n\n#wpstg-large-files h3 {\n background: #fff;\n margin: 0;\n padding: 0 5px;\n position: absolute;\n top: -10px;\n left: 5px;\n}\n\n\n/* tmp */\n\n.wpstg-subdir {\n display: none;\n margin-left: 20px;\n}\n\n.wpstg-subdir.wpstg-push {\n display: block;\n margin-left: 20px;\n}\n\n.wpstg-dir a.disabled {\n color: #888;\n cursor: default;\n text-decoration: none;\n}\n\n.wpstg-check-subdirs {\n display: inline-block;\n margin-left: 10px;\n}\n\n.wpstg-notice-alert {\n display: block;\n background-color: #FFD0D0;\n padding: 20px;\n border-radius: 6px;\n border: 1px solid #FFAAAA;\n max-width: 600px;\n margin-top: 10px;\n}\n\n.wpstg-header {\n font-weight: 400;\n line-height: 1.6em;\n font-size: 19px;\n border-bottom: 1px solid #DFDFDF;\n clear: both;\n}\n\n#wpstg-clone-label {\n font-size: 14px;\n font-weight: bold;\n}\n\n.wpstg-log-details {\n height: 300px;\n overflow: scroll;\n max-width: 650px;\n font-family: monospace;\n font-size: 12px;\n line-height: 15px;\n border: 1px solid #FFF;\n background-color: black;\n color: #c0c0c0;\n padding: 3px;\n white-space: nowrap;\n margin-top: 15px;\n}\n\n#wpstg-finished-result {\n display: none;\n}\n\n#wpstg-remove-cloning {\n background: #ff3428;\n border-color: #e72f24;\n margin-top: 5px;\n}\n\n#wpstg-success-notice {\n padding: 10px;\n background-color: white;\n max-width: 900px;\n border: 1px solid #ccc;\n margin-top: 20px;\n}\n\n.wpstg_beta_notice {\n margin-bottom: 20px;\n}\n\n.wpstg-sysinfo {\n width: 700px;\n height: 700px;\n}\n\n.wpstg-form-table .col-title label {\n font-weight: 600;\n}\n\n.wpstg-form-table td:first-child {\n width: 30%;\n}\n\n.wpstg-share-button-container {\n margin: 5px 0;\n}\n\n.wpstg-share-button-container p {\n margin: 0 0 10px 0;\n}\n\n.wpstg-share-button {\n display: inline-block;\n}\n\n.wpstg-share-button a {\n text-decoration: none;\n}\n\n.wpstg-share-button .wpstg-share {\n font-family: sans-serif;\n font-weight: bold;\n text-decoration: none;\n text-align: center;\n}\n\n.wpstg-share-button .wpstg-share {\n -webkit-border-radius: 2px;\n -moz-border-radius: 2px;\n border-radius: 2px;\n color: #FFF;\n display: inline;\n font-size: 12px;\n padding: 4px 8px;\n}\n\n.wpstg-share-button-twitter .wpstg-share {\n background-color: #00ABF0;\n}\n\n.wpstg-share-button-facebook .wpstg-share {\n background-color: #3b5998;\n}\n\n.wpstg-share-button-googleplus .wpstg-share {\n background-color: #F53424;\n}\n\n.wpstg-share-button-twitter .share:active,\n.wpstg-share-button-facebook .share:active,\n.wpstg-share-button-googleplus .share:active {\n background-color: #353535;\n}\n\n#wpstg-check-space {\n margin-left: 8px;\n}\n\n\n/* welcome screen */\n\n.wpstg-button.green {\n display: inline-block;\n padding: 10px;\n min-width: 170px;\n font-size: 16px;\n text-decoration: none;\n text-align: center;\n margin-top: 20px;\n background-color: #83c11f;\n color: white;\n}\n\n.wpstg-button.green:hover {\n background-color: #8ed122;\n}\n\n.wpstg-button.wpstg-save {\n background-color: #1687A7;\n color: white;\n}\n\n.wpstg-button.wpstg-save:hover {\n background-color: #276678;\n}\n\n.wpstg-button.wpstg-bordered {\n border-radius:3px;\n font-size: 14px;\n border: 1px solid white;\n}\n\n#wpstg-welcome li {\n font-size: 18px;\n line-height: 29px;\n position: relative;\n padding-left: 23px;\n list-style: none !important;\n}\n\n#wpstg-welcome {\n margin-top: 20px;\n margin-right: 20px;\n background-color: white;\n}\n\n.wpstg-heading-pro {\n color: #0080ff;\n font-weight: bold;\n}\n\n.wpstg-h2 {\n margin-top: 0;\n margin-bottom: 1.2rem;\n font-size: 30px;\n line-height: 2.5rem;\n}\n\n#wpstg-welcome li:before {\n width: 1em;\n height: 100%;\n background: url(data:image/svg+xml;charset=utf8,%3Csvg%20width%3D%221792%22%20height%3D%221792%22%20viewBox%3D%220%200%201792%201792%22%20xmlns%3D%22http%3A%2F%2Fwww%2Ew3%2Eorg%2F2000%2Fsvg%22%3E%3Cpath%20fill%3D%22%2377B227%22%20d%3D%22M1671%20566q0%2040%2D28%2068l%2D724%20724%2D136%20136q%2D28%2028%2D68%2028t%2D68%2D28l%2D136%2D136%2D362%2D362q%2D28%2D28%2D28%2D68t28%2D68l136%2D136q28%2D28%2068%2D28t68%2028l294%20295%20656%2D657q28%2D28%2068%2D28t68%2028l136%20136q28%2028%2028%2068z%22%2F%3E%3C%2Fsvg%3E) left .4em no-repeat;\n background-size: contain;\n content: \"\";\n position: absolute;\n top: 0;\n left: 0;\n color: #77b227;\n}\n\n.wpstg-h1 {\n margin-bottom: 1.35rem;\n font-size: 2.5em;\n line-height: 3.68rem;\n letter-spacing: normal;\n}\n\n.swal2-content h1 {\n color:#444;\n}\n\n#wpstg-welcome h2 {\n margin: 0 0 15px;\n}\n\n#wpstg-welcome .wpstg-footer {\n clear: both;\n margin-top: 20px;\n font-style: italic;\n}\n\n#wpstg-footer {\n clear: both;\n background-color: white;\n padding: 20px;\n margin-top: 20px;\n margin-right: 10px;\n}\n\n#wpstg-footer a {\n text-decoration: none;\n}\n\n.wpstg-staging-info {\n margin-top: 8px;\n color: white;\n font-size: 12px;\n}\n\n.wpstg-staging-info a {\n color: white;\n}\n\n.wpstg-staging-info li {\n margin-bottom: 2px;\n}\n\n.wpstg-bold {\n font-weight: 600;\n}\n\n#wpstg-processing-status {\n margin-top: 5px;\n font-size: 13px;\n font-weight: 400;\n float: left;\n}\n\n#wpstg-processing-timer {\n margin-top: 5px;\n font-size: 13px;\n font-weight: 400;\n float: right;\n}\n\n#wpstg-report-issue-button {\n margin-left: 50px;\n border: 1px solid #ef5a4b;\n color: #ef5a4b;\n background-color: white;\n}\n\n#wpstg-report-issue-button:hover {\n background-color: #e74c3c;\n color: #fff;\n}\n\n.wpstg-button {\n display: inline-block;\n background-color: transparent;\n color: #95a5a6;\n border-radius: 3px;\n cursor: pointer;\n padding: 2px 10px 2px 10px;\n text-transform: uppercase;\n font-weight: 500;\n outline: 0;\n transition: background-color .1s ease-in;\n text-decoration: none;\n}\n\n.wpstg-button.wpstg-button-light {\n background-color: #f8f8f8;\n border: 1px solid #eee;\n color: #333;\n animation: background-color 0.3s;\n}\n\n.wpstg-button.wpstg-button-light:hover {\n background-color: #e0e0e0;\n border: 1px solid #e0e0e0;\n}\n\n.wpstg-blue-primary {\n display: inline-block;\n text-decoration: none;\n font-size: 13px;\n line-height: 26px;\n height: 28px;\n margin: 0;\n padding: 0 10px 1px;\n cursor: pointer;\n border-width: 1px;\n border-style: solid;\n -webkit-appearance: none;\n border-radius: 3px;\n white-space: nowrap;\n box-sizing: border-box;\n background: #25a1f0;\n border-color: #2188c9;\n color: #fff;\n text-shadow: 0 -1px 1px #006799, 1px 0 1px #006799, 0 1px 1px #006799, -1px 0 1px #006799;\n}\n\n.wpstg-blue-primary:hover {\n background-color: #259be6;\n}\n\n.wpstg-report-issue-form {\n position: absolute;\n z-index: 9999;\n width: 300px;\n background-color: #fff;\n padding: 15px 15px 10px;\n border: 1px solid #e8e8e8;\n border-radius: 3px;\n box-shadow: 0 1px 0 0 #fff inset;\n display: none;\n margin: 67px 0 0 123px;\n}\n\n.wpstg-report-show {\n display: block;\n}\n\n.wpstg-field input[type=text],\n.wpstg-field textarea {\n width: 100%;\n font-weight: 400;\n line-height: 1.4;\n margin-bottom: 4px;\n}\n\n.wpstg-report-email,\n.wpstg-report-hosting-provider {\n width: 100%;\n font-weight: 400;\n font-size: .8rem;\n height: 2.3rem;\n line-height: 2.3rem;\n border-radius: 3px;\n margin-bottom: 4px;\n padding: 0 10px;\n}\n\n.wpstg-report-description {\n border-radius: 3px;\n font-size: .8rem;\n padding: 6px 10px;\n resize: none;\n}\n\n.wpstg-report-privacy-policy {\n font-size: 12px;\n margin-bottom: 15px;\n}\n\n#wpstg-report-cancel {\n float: right;\n margin-right: 5px;\n}\n\n.wpstg-buttons .spinner {\n float: none;\n margin: 0 0 0 5px;\n}\n\n.wpstg-message {\n box-sizing: border-box;\n -moz-box-sizing: border-box;\n background-color: #f5e0de;\n border-radius: 3px;\n color: rgba(0, 0, 0, .6);\n height: auto;\n margin: 10px 0;\n min-height: 18px;\n padding: 6px 10px;\n position: relative;\n}\n\n.wpstg-message.wpstg-error-message {\n background-color: #f5e0de;\n color: #b65147;\n font-size: 12px;\n}\n\n.wpstg-message.wpstg-success-message {\n background-color: #d7f8e0;\n color: #515151;\n}\n\n.wpstg-message p {\n margin: 3px 0;\n font-size: 13px;\n}\n\n.wpstg-warning {\n display: block;\n padding: 10px;\n background-color: #ffb804;\n color: #ffffff;\n margin: 10px 10px 10px 0;\n}\n\n.wpstg-warning a {\n color: #ffffff;\n font-weight: bold;\n text-decoration: underline;\n}\n\n.wpstg-error {\n display: block;\n padding: 10px;\n background-color: #fe6501;\n color: #ffffff;\n margin: 10px 10px 10px 0;\n}\n\n.wpstg-error a {\n color: #ffffff;\n font-weight: bold;\n text-decoration: underline;\n}\n\n#wpstg-resume-cloning {\n display: none;\n}\n\n#wpstg-external-db th {\n text-align: left;\n width: 120px;\n}\n\n#wpstg-db-connect {\n font-weight: normal;\n}\n\n#wpstg-db-status {\n display: block;\n margin-top: 5px;\n padding: 5px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n border-radius: 4px;\n text-decoration: none;\n text-align: center;\n}\n\n.wpstg-text-field>#wpstg-db-status {\n margin-top: 8px;\n margin-left: 25%;\n min-width: 350px;\n}\n\n.wpstg-success {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #d6e9c6;\n}\n\n.wpstg-failed {\n color: #a94442;\n background-color: #f2dede;\n border-color: #ebccd1;\n}\n\n#wpstg_select_tables_cloning {\n height: 600px;\n font-size: 13px;\n}\n\n#wpstg-update-notify {\n background-color: #fe6501;\n font-size: 14px;\n color: #ffffff;\n line-height: normal;\n padding: 10px;\n margin-right: 10px;\n}\n\n#wpstg-update-notify a {\n color: #ffffff;\n font-weight: bold;\n}\n\n.wpstg-pointer {\n cursor: pointer;\n}\n\n.wpstg--tab--header ul {\n display: flex;\n}\n\n.wpstg--tab--header ul li {\n margin-right: 1em;\n}\n\n.wpstg--tab--header ul li:last-child {\n margin-right: 0;\n}\n\n.wpstg--tab--header a {\n min-width: 150px;\n text-align: center;\n cursor: pointer;\n display: inline-block;\n padding: 1em 1.25em;\n border: solid 1px;\n}\n\n.wpstg--tab--header a.wpstg--tab--active {\n border-bottom: .5em solid #25A1F0;\n color: #25A1F0;\n}\n\n.wpstg--tab--content {\n display: none;\n}\n\n.wpstg--tab--active {\n display: block;\n}\n\n.wpstg--text--strong,\n.wpstg--text--strong * {\n font-weight: bold !important;\n}\n\n.wpstg--text--danger {\n color: #a94442;\n}\n\n.wpstg--tooltip {\n position: relative;\n display: inline-block;\n border-bottom: 1px dotted black;\n margin-left: 10px;\n}\n\n.wpstg--tooltip .wpstg--tooltiptext {\n visibility: hidden;\n width: 300px;\n background-color: #ffffff;\n color: #505050;\n text-align: left;\n padding: 20px;\n border: 1px solid #e8e8e8;\n border-radius: 3px;\n position: absolute;\n z-index: 1;\n -webkit-box-shadow: -1px 1px 5px 0 rgba(0, 0, 0, 0.75);\n -moz-box-shadow: -1px 1px 5px 0 rgba(0, 0, 0, 0.75);\n box-shadow: -1px 1px 5px 0 rgba(0, 0, 0, 0.75);\n}\n\n.wpstg--tooltip:hover .wpstg--tooltiptext {\n visibility: visible;\n}\n\n.wpstg--tooltiptext-backups {\n width: 120px;\n top: 100%;\n left: -150%;\n margin-left: -60px;\n /* Use half of the width (120/2 = 60), to center the tooltip */\n margin-top: 10px;\n}\n\n\n/**\nTooltip top arrow\n */\n\n.wpstg--tooltip .wpstg--tooltiptext-backups::after {\n content: \" \";\n position: absolute;\n bottom: 100%;\n /* At the top of the tooltip */\n left: 50%;\n margin-left: 25px;\n border-width: 5px;\n border-style: solid;\n border-color: transparent transparent white transparent;\n}\n\n.wpstg--snaphot-restore-table tr {\n line-height: 12px;\n}\n\n.wpstg-float-left {\n float: left;\n}\n\n.wpstg-beta-notice {\n background-color: #b0e8b0;\n border-radius: 3px;\n padding: 7px;\n margin-bottom: 20px;\n}\n\n#wpstg-backup-name {\n font-size: 1.875em;\n font-weight: 600;\n}\n\n#wpstg_select_tables_cloning option:checked {\n /* Cannot use background color here because Chrome and Firefox ignore it even if set to !important */\n -webkit-appearance: menulist-button;\n background-image: linear-gradient(0deg, #1e90ff 0%, #1e90ff 100%);\n}\n\n.wpstg--btn--cancel {\n background: #ff3428;\n border-color: #e72f24;\n color: #fff;\n height: auto;\n line-height: normal;\n font-size: 16px;\n padding: .5em;\n margin-bottom: 1.5em;\n}\n\n.wpstg--btn--cancel:hover {\n background: #ff3428;\n border-color: #e72f24;\n}\n\n.wpstg--process--content>.swal2-html-container {\n padding: 4em 2em !important;\n}\n\n.wpstg--modal--process--logs,\n.wpstg--modal--error--logs {\n background: black;\n height: 300px;\n margin-top: 1em;\n display: none;\n padding: 1em;\n overflow-x: auto;\n text-align: justify;\n}\n\n.wpstg--modal--error--logs {\n height: auto;\n max-height: 300px;\n}\n\n.wpstg--modal--process--logs>p,\n.wpstg--modal--error--logs>p {\n text-align: left;\n font-size: 14px;\n}\n\n.wpstg--modal--process--logs p,\n.wpstg--modal--error--logs p {\n margin: .3em 0;\n}\n\n.wpstg--modal--process--msg--error {\n color: darkred;\n}\n\n.wpstg--modal--process--msg--critical {\n color: red;\n}\n\n.wpstg--modal--process--msg--warning {\n color: darkorange;\n}\n\n.wpstg--modal--process--msg-found {\n color: #f56363;\n}\n\nbody.toplevel_page_wpstg_clone .swal2-modal .swal2-cancel.wpstg--btn--cancel {\n margin-bottom: 0;\n}\n\nbody.toplevel_page_wpstg_clone .swal2-modal .swal2-confirm.wpstg--btn--confirm {\n font-size: 16px;\n padding: .5em;\n line-height: normal;\n height: auto;\n margin-right: 10px;\n}\n\nbody.toplevel_page_wpstg_clone .swal2-modal .wpstg-loader {\n display: inline-block !important;\n}\n\n.wpstg--modal--process--generic-problem {\n display: none;\n border-left: 5px solid #ef6d6d;\n margin: .5em 0;\n}\n\n.wpstg--modal--process--logs--tail {\n color: #a8a8a8;\n background: none;\n border: none;\n cursor: pointer;\n}\n\n.wpstg--modal--backup--import--upload--title {\n color: #505050;\n}\n\n.wpstg--modal--backup--import--filesystem,\n.wpstg--modal--backup--import--configure,\n.wpstg--modal--backup--import--upload--status,\n.wpstg--modal--backup--import--upload--container input[type=\"file\"] {\n display: none;\n}\n\n#wpstg--backups--import--file-list {\n font-size: 14px;\n font-weight: bold;\n}\n\n#wpstg--backups--import--file-list-empty {\n color: red;\n}\n\n.wpstg--modal--backup--import--filesystem label {\n font-size: 14px;\n}\n\n.wpstg--modal--backup--import--filesystem button {\n margin-bottom: 20px;\n}\n\n.wpstg--modal--backup--import--upload,\n.wpstg--modal--backup--import--filesystem {\n color: #505050;\n}\n\n.wpstg--modal--backup--import--upload--container {\n position: relative;\n border-radius: 1em;\n margin: .5em;\n padding: 1em .5em;\n border: .4em dashed #dedede;\n display: flex;\n flex-direction: column;\n}\n\n.wpstg--modal--backup--import--upload--container .wpstg--uploader {\n display: flex;\n flex-direction: column;\n}\n\n.wpstg--modal--backup--import--upload--container.wpstg--has-dragover {\n background-color: #9a9a9a;\n color: white;\n}\n\n.wpstg--modal--backup--import--upload--container span.wpstg--drop,\n.wpstg--modal--backup--import--upload--container.wpstg--has-dragover span.wpstg--drag,\nspan.wpstg--backup--import--selected-file,\nspan.wpstg--drag-or-upload {\n display: none;\n}\n\n.wpstg--modal--backup--import--upload--container.wpstg--has-dragover span.wpstg--drop {\n display: inline-block;\n}\n\n.wpstg--modal--backup--import--upload--container input[type='file'] {\n display: none;\n}\n\n.wpstg--modal--backup--import--upload--container img {\n width: 4em;\n align-self: center;\n border: none;\n}\n\n.wpstg--modal--backup--import--upload--container span {\n margin-top: 1em;\n}\n\n.wpstg--backup--import--options>button {\n margin-top: 1em;\n padding: 1em;\n align-self: center;\n width: 185px;\n height: auto;\n line-height: normal;\n}\n\n\n/*.wpstg--backup--import--options.wpstg--show-options > button {\n background: white;\n border-radius: 3px 3px 0 0;\n border: .25em solid #25a1f0;\n text-shadow: none;\n color: #2e3436;\n}*/\n\n.wpstg--backup--import--options {\n position: relative;\n display: flex;\n justify-content: center;\n}\n\n.wpstg--backup--import--options ul {\n display: none;\n}\n\n.wpstg--backup--import--options.wpstg--show-options ul {\n padding: 0;\n margin: 54px 0 0 0;\n display: block;\n position: absolute;\n width: 185px;\n background: #25a1f0;\n box-sizing: border-box;\n border-radius: 0 0 3px 3px;\n border-width: 1px;\n border-color: #2188c9;\n text-shadow: 0 -1px 1px #006799, 1px 0 1px #006799, 0 1px 1px #006799, -1px 0 1px #006799;\n}\n\n.wpstg--backup--import--options.wpstg--show-options ul li {\n border-bottom: .1em solid #25a1f0;\n margin: 0;\n}\n\n.wpstg--backup--import--options.wpstg--show-options ul li:hover {\n background-color: #25a1f0;\n}\n\n.wpstg--backup--import--options.wpstg--show-options ul li:last-child {\n border-bottom: none;\n}\n\n.wpstg--backup--import--options ul li button {\n cursor: pointer;\n background: none;\n border: none;\n margin: 0;\n width: 100%;\n color: white;\n height: 40px;\n line-height: 40px;\n}\n\n.wpstg--backup--import--options ul li button:hover {\n background-color: #259be6;\n}\n\n.wpstg--modal--backup--import--search-replace--info {\n margin: 1em 0;\n display: flex;\n flex-direction: row;\n}\n\n.wpstg--modal--backup--import--info p {\n text-align: left;\n margin: 0;\n}\n\n\n/* unused class should be removed or commented\n.wpstg--modal--backup--import--search-replace--wrapper {\n display: flex;\n flex-direction: row;\n padding: 0 5em;\n}\n*/\n\n.wpstg--modal--backup--import--search-replace--wrapper button {\n align-self: center;\n}\n\n.wpstg--import--advanced-options--button {\n border: 0;\n border-radius: 3px;\n font-size: 18px;\n text-shadow: 0 -1px 1px #006799, 1px 0 1px #006799, 0 1px 1px #006799, -1px 0 1px #006799;\n cursor: pointer;\n}\n\n.wpstg--modal--backup--import--search-replace--new {\n color: white;\n background-color: #25a1f0;\n}\n\n.wpstg--modal--backup--import--search-replace--remove {\n color: white;\n background-color: #25a1f0;\n width: 22px;\n height: 22px;\n margin-left:5px;\n}\n\n.wpstg--modal--backup--import--search-replace--input-group:first-child button {\n display: none;\n}\n\n.wpstg--modal--backup--import--search-replace--input--container {\n flex: 1;\n display: flex;\n flex-direction: column;\n}\n\n.wpstg--modal--backup--import--search-replace--input-group {\n width: 100%;\n border-bottom: 6px solid #f1f1f1;\n margin-bottom: 10px;\n}\n\n.wpstg--modal--backup--import--search-replace--input-group input {\n min-width: 250px;\n width: calc(50% - 4px - 11px - 5px); /* -4px is half of the padding; -11px is half of the button; -5 is the margin left of the button */\n display: inline-block;\n line-height: 10px;\n border: 1px solid #dedede;\n border-radius: 3px;\n color: #666;\n padding: 8px;\n margin-bottom: 12px;\n}\n\n.wpstg--modal--import--upload--process {\n display: none;\n position: absolute;\n /*display: flex;*/\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n text-indent: 1em;\n white-space: nowrap;\n overflow: hidden;\n color: #898989;\n mix-blend-mode: difference;\n justify-content: center;\n align-items: center;\n}\n\n.wpstg--modal--import--upload--progress {\n position: absolute;\n background: #dedede;\n color: white;\n width: 0;\n height: 100%;\n border-radius: 1em;\n left: -1px;\n top: 0;\n}\n\n.wpstg--modal--import--upload--progress--title {\n z-index: 9;\n}\n\n.wpstg-fieldset:disabled {\n opacity: 0.8;\n border-top: 1px solid white;\n margin-top: 20px;\n}\n\n.wpstg-fs-14 {\n font-size: 14px;\n}\n\n.wpstg-light-alert {\n font-weight: bold;\n background-color: #e6e6e6;\n padding: 15px;\n border-top: 1px solid white;\n margin-top: 20px;\n}\n\n.wpstg-form-group {\n display: flex;\n flex-wrap: wrap;\n width: 100%;\n margin-bottom: 8px;\n}\n\n.wpstg-form-group>label {\n display: inline-block;\n font-weight: 700;\n min-width: 25%;\n width: 25%;\n}\n\n.wpstg-text-field>input {\n width: 350px;\n display: inline-block;\n}\n\n.wpstg-code-segment {\n display: block;\n}\n\n.wpstg-text-field>.wpstg-code-segment {\n margin-top: 4px;\n margin-left: 25%;\n min-width: 350px;\n}\n\n.wpstg-form-group>.wpstg-checkbox {\n min-width: 100%;\n width: 100%;\n position: relative;\n}\n\n.wpstg-form-group>.wpstg-checkbox>input[type='checkbox'] {\n left: 25%;\n}\n\n.wpstg-rounded {\n border-radius: 3px;\n}\n\n.wpstg-white-border {\n border: 1px solid white !important;\n}\n\n.wpstg-mt-16 {\n margin-top: 16px;\n}\n\n.wpstg-w-100pc {\n width: 100%;\n}\n\n#wpstg-confirm-backup-restore-data {\n margin: 40px;\n text-align: left;\n}\n\n#wpstg-confirm-backup-restore-wrapper {\n margin: 30px;\n}\n\n#wpstg-confirm-backup-restore-wrapper h3 {\n color: #f56363;\n}\n\n#swal2-content h2 {\n color: #a8a8a8;\n}\n\n#wpstg_allow_emails {\n margin-left: 10px;\n}\n\n#wpstg-advanced-settings hr {\n margin: 20px 0;\n}\n\n.wpstg-form-row {\n display: block;\n}\n\n.wpstg-form-row label,\n.wpstg-form-row input {\n display: table-cell;\n padding-left: 5px;\n padding-right: 5px;\n margin-top: 3px;\n margin-bottom: 3px;\n}\n\n.wpstg-form-row input {\n width: 400px;\n}\n\n.wpstg-form-row label {\n font-weight: bold;\n width: 1px;\n white-space: nowrap;\n}\n\n#wpstg-db-connect-output #wpstg-db-status {\n width: 390px;\n}\n\n#wpstg_symlink_upload {\n margin-left: 10px;\n}\n\n.wpstg-fieldset:disabled {\n opacity: 0.8;\n border-top: 1px solid white;\n margin-top: 20px;\n}\n\n.wpstg-fs-14 {\n font-size: 14px;\n}\n\n.wpstg-light-alert {\n font-weight: bold;\n background-color: #e6e6e6;\n padding: 15px;\n border-top: 1px solid white;\n margin-top: 20px;\n}\n\n.wpstg-form-group {\n display: flex;\n flex-wrap: wrap;\n width: 100%;\n margin-bottom: 8px;\n}\n\n.wpstg-form-group>label {\n display: inline-block;\n font-weight: 700;\n min-width: 25%;\n width: 25%;\n}\n\n.wpstg-text-field>input {\n width: 350px;\n display: inline-block;\n}\n\n.wpstg-code-segment {\n display: block;\n}\n\n.wpstg-text-field>.wpstg-code-segment {\n margin-top: 4px;\n margin-left: 25%;\n min-width: 350px;\n}\n\n.wpstg-form-group>.wpstg-checkbox {\n min-width: 100%;\n width: 100%;\n}\n\n.wpstg-form-group>.wpstg-checkbox>input[type='checkbox'] {\n margin-left: 10px;\n}\n\n@media only screen and (max-width: 768px) {\n .wpstg-form-group {\n display: block;\n }\n .wpstg-form-group>label {\n display: block;\n min-width: auto;\n width: auto;\n }\n .wpstg-text-field>input {\n width: 100%;\n display: block;\n }\n .wpstg-text-field>.wpstg-code-segment {\n margin-left: 0;\n min-width: 100%;\n }\n .wpstg-tab-section {\n width: calc(100vw - 60px);\n max-width: calc(100vw - 60px);\n }\n}\n\n.wpstg-rounded {\n border-radius: 3px;\n}\n\n.wpstg-white-border {\n border: 1px solid white !important;\n}\n\n.wpstg-m-0 {\n margin: 0;\n}\n\n.wpstg-mt-16 {\n margin-top: 16px;\n}\n\n.wpstg-mt-10px {\n margin-top: 10px;\n}\n\n.wpstg-my-10px {\n margin-top: 10px;\n margin-bottom: 10px;\n}\n\n.wpstg-w-100 {\n width: 100%;\n}\n\n.wpstg-box-shadow {\n box-shadow: 0 1px 1px 0 rgba(0, 0, 0, .1);\n}\n\n.wpstg-float-left {\n float: left;\n}\n\n.wpstg-fivestar {\n border-left: none;\n background-color: #59a7f7;\n color: white;\n padding: 10px;\n margin: 10px 10px 10px 0;\n}\n\n.wpstg-bold-text {\n font-weight: bold;\n}\n\n.wpstg-rating-link {\n font-weight: normal;\n color: white;\n}\n\n.wpstg-warning.notice {\n border-left: 4px solid #ffba00;\n}\n\n.wpstg-confirmation-label {\n background-color: #5b9dd9;\n color: #fff;\n padding: 2px;\n border-radius: 3px;\n}\n\n.wpstg-my-6px {\n margin-bottom: 6px;\n margin-top: 6px;\n}\n\n.wpstg-mb-10px {\n margin-bottom: 10px;\n}\n\n.wpstg-opacity-80 {\n opacity: 0.8;\n}\n\n.wpstg-clear-both {\n clear: both;\n}\n\n.wpstg-fs-10px {\n font-size: 10px;\n}\n\n.wpstg-font-italic {\n font-style: italic;\n}\n\n.wpstg-mt-20px {\n margin-top: 20px;\n}\n\n.wpstg-welcome-container {\n border: 2px solid white;\n padding: 20px;\n margin-bottom: 20px;\n}\n\n.wpstg-ml-30px {\n margin-left: 30px;\n}\n\n.wpstg-text-center {\n text-align: center;\n}\n\n.wpstg-feedback-link {\n text-decoration: none;\n color: #abc116\n}\n\n.wpstg-feedback-span {\n display: block;\n margin-bottom: 20px;\n color: #abc116;\n}\n\n#wpstg-confirm-backup-restore-data {\n margin: 40px;\n text-align: left;\n}\n\n#wpstg-confirm-backup-restore-wrapper {\n margin: 30px;\n}\n\n#wpstg-confirm-backup-restore-wrapper h3 {\n color: #f56363;\n}\n\n#wpstg-footer {\n clear: both;\n padding-top: 20px;\n}\n\n#swal2-content h2 {\n color: #a8a8a8;\n}\n\n#wpstg-progress-db,\n#wpstg-progress-backup {\n background-color: #3fa5ee;\n}\n\n#wpstg-progress-sr,\n#wpstg-progress-files.wpstg-pro {\n background-color: #3c9ee4;\n}\n\n#wpstg-progress-dirs,\n#wpstg-progress-data {\n background-color: #3a96d7;\n}\n\n#wpstg-progress-files:not(.wpstg-pro),\n#wpstg-progress-finishing {\n background-color: #378cc9;\n}\n\n.wpstg-issue-resubmit-confirmation.swal2-container, \n.wpstg-swal2-container.swal2-container {\n z-index: 10500;\n}\n\n.wpstg-swal2-container.wpstg-swal2-loading .swal2-actions,\n.wpstg-swal2-container.wpstg-swal2-loading .swal2-header {\n display: none;\n}\n\nbody.toplevel_page_wpstg_clone .swal2-container .swal2-content {\n z-index:2;\n}\n\ndiv#exportUploadsWithoutDatabaseWarning {\n font-style: italic;\n font-size: 0.9rem;\n margin: 10px;\n padding: 10px;\n border: 1px solid #e3e3e3;\n border-radius: 5px;\n text-align: center;\n background-color: #fafafa;\n}\n\n.wpstg-advanced-options-dropdown-wrapper {\n display: none; /* ENABLE WHEN WE HAVE ADVANCED OPTIONS FOR EXPORTING */\n margin-top: 20px;\n}\n\n.wpstg--modal--backup--import--search-replace--wrapper {\n text-align: left;\n margin-top: 20px;\n}\n\n.wpstg--modal--backup--import--search-replace--new--wrapper {\n text-align: center;\n}\n\n.wpstg-import-backup-contains li {\n display: inline-block;\n}\n\n.wpstg-import-backup-contains li .dashicons{\n border-radius: 3px;\n color: #979797;\n background-color: #e3e3e3;\n border: 1px solid #c2c2c2;\n width: 17px;\n height: 17px;\n font-size: 17px;\n}\n\n.wpstg-import-backup-contains.wpstg-listing-single-backup li .dashicons{\n padding: 2px;\n color: #ffffff;\n background-color: #2896dd;\n border: 1px solid #0c75b8;\n}\n\n.wpstg-import-backup-contains .wpstg--tooltiptext {\n width: 50px;\n font-size: x-small;\n padding: 5px;\n left: -25px;\n text-align: center;\n}\n\n.wpstg-import-backup-contains-title {\n display: inline-block;\n}\n\nul.wpstg-import-backup-contains {\n display: inline-block;\n}\n\n.wpstg-import-backup-name {\n display: inline-block;\n font-weight: bold;\n}\n\n.wpstg-backup-more-info-toggle {\n font-size: x-small;\n display: inline-block;\n font-style: italic;\n cursor:pointer;\n}\n\n.wpstg-backup-more-info-toggle::selection {\n background:none;\n}\n\nul.wpstg-import-backup-more-info {\n font-size: 14px;\n text-align: left;\n margin-bottom: 30px;\n margin-top: 10px;\n background-color: #f6f6f6;\n border: 1px solid #878787;\n border-radius: 3px;\n padding: 7px;\n cursor: pointer;\n}\n\nul.wpstg-import-backup-more-info:hover {\n background-color: #def2ff;\n border: 1px solid #25a1f0;\n}\n\nul.wpstg-import-backup-more-info li {\n height: 20px;\n}\n\n.wpstg-backup-list ul ul {\n margin-block-start: 1em;\n margin-block-end: 1em;\n}\n\n.wpstg-push-confirmation-message {\n text-align: justify;\n}\n\n.wpstg-settings-row {\n padding-top: 10px;\n padding-bottom: 10px;\n}\n\n.wpstg-settings-title {\n font-weight: 600;\n}\n\n.wpstg-settings-form-group {\n display: flex;\n align-items: center;\n}\n\n.wpstg-settings-form-group > .wpstg-settings-message {\n width: 30%;\n padding: 0;\n margin: 7px 0 0;\n}\n\n/**\n * WP STAGING EXCLUSION RULES TABLE LAYOUT\n */\n\n.wpstg-excluded-filters-container {\n padding: 0;\n\tmargin-top: 10px;\n margin-bottom: 10px;\n\tmax-width: 100%;\n width: 100%;\n}\n\n.wpstg-excluded-filters-container > table {\n width: 100%;\n border-collapse: collapse;\n border-color: transparent;\n}\n\n.wpstg-excluded-filters-container td {\n padding-top: 4px;\n padding-bottom: 4px;\n height: 20px;\n}\n\n.wpstg-excluded-filters-container h4 {\n margin: 0;\n}\n\n/*.wpstg-excluded-filters-container tbody {\n\tbackground: #fff !important;\n}*/\n\n.wpstg-exclude-filters-foot {\n display: flex;\n justify-content: flex-start;\n padding: 0;\n}\n\n.wpstg-excluded-filters-container .wpstg-exclude-filter-name-column {\n width: 100px;\n max-width: 100px !important;\n padding-left: 10px;\n}\n\n.wpstg-excluded-filters-container .wpstg-exclude-filter-action-column {\n width: 50px;\n max-width: 50px;\n\ttext-align: right !important;\n padding-right: 10px;\n}\n\n.wpstg-excluded-filters-container .wpstg-exclude-filter-exclusion-column {\n width: 320px;\n position: relative;\n}\n\n/**\n * WP STAGING EXCLUSION RULE DROPDOWN STYLE\n */\n\n.wpstg-exclude-filter-dropdown > button {\n background: #25A0F1;\n border: 1px solid #25A0F1;\n color: #fff;\n padding: 1px 5px;\n display: inline-block;\n font-weight: 400;\n line-height: 1.5;\n text-align: center;\n border-radius: 0;\n outline: none;\n box-shadow: none;\n cursor: pointer;\n height: 24px;\n}\n\n.wpstg-exclude-filter-dropdown > button:hover {\n background: #135e96;;\n border: 1px solid #135e96;;\n}\n\n.wpstg-exclude-filter-dropdown > .wpstg-dropdown-menu {\n width: 128px;\n}\n\n.wpstg-remove-exclude-rule {\n color: #fff !important;\n background-color: #dc3545;\n border: 1px solid #dc3545;\n width: 20px;\n\theight: 20px;\n\tborder-radius: 10px;\n\tfont-size: 24px;\n\tpadding: 0;\n\tdisplay: inline-flex;\n\tjustify-content: center;\n outline: none;\n box-shadow: none;\n font-weight: 400;\n line-height: 0.7;\n margin-top: 5px;\n cursor: pointer;\n}\n\n.wpstg-remove-exclude-rule:hover {\n background-color: #bb2d3b;\n border-color: #bb2d3b;\n}\n\n/**\n * WP STAGING POPOVER EXCLUSION RULES INFO\n */\n\n .wpstg-popover {\n\tdisplay: inline-block;\n\tposition: relative;\n}\n\n.wpstg-popover button + p {\n\tposition: absolute;\n\ttop: 18px;\n\tright: -150px;\n\tdisplay: none;\n\twidth: 320px;\n\tz-index: 1024;\n\tpadding: 10px !important;\n\tbox-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);\n}\n\n.wpstg-popover button:hover + p {\n\tdisplay: block;\n}\n\n.wpstg-code-block {\n\tmargin-top: 4px;\n\tfont-size: 1.2em;\n\tbackground: #f8f8f8;\n\tborder-radius: 2px;\n}\n\n.wpstg-rule-info {\n background: #f8f8f8 !important;\n}\n\ncode.wpstg-code {\n display: inline-block;\n font-size: 11px;\n\tborder: 1px solid #aaa;\n\tbackground: #fff;\n\tpadding: 2px 4px;\n margin-bottom: 1px;\n color: #ff6666;\n}\n\n.wpstg-exclusion-rule-info {\n color: #fff !important;\n background-color: #ffc107;\n border: 1px solid #ffc107;\n width: 14px;\n\theight: 14px;\n\tborder-radius: 7px;\n\tfont-size: 14px;\n\tpadding: 0;\n\tdisplay: inline-flex;\n\tjustify-content: center;\n align-items: center;\n outline: none;\n box-shadow: none;\n font-weight: 400;\n vertical-align: middle;\n}\n\n.wpstg-exclusion-rule-info:hover {\n background-color: #ffba0c;\n border: 1px solid #ffba0c;\n}\n\n/**\n * WP STAGING INPUTS EXCLUSION RULES\n */\n\n .wpstg-exclude-rule-input {\n font-size: 12px !important;\n padding: 2px 6px;\n box-shadow: none;\n outline: none !important;\n display: inline-block;\n font-weight: 400;\n line-height: 1.5;\n color: #222;\n border-radius: 0 !important;\n background-color: #fff;\n border: 1px solid #bbb;\n min-height: 24px !important;\n margin-top: 4px;\n margin-left: 4px;\n vertical-align: baseline !important;\n transition: all 0.3s cubic-bezier(.25,.8,.25,1);\n width: 135px;\n}\n\n.wpstg-excluded-filters-container tbody > tr:last-child .wpstg-exclude-rule-input {\n\tmargin-bottom: 4px;\n}\n\n.wpstg-exclude-rule-input:hover {\n border: 1px solid #999;\n}\n\n.wpstg-exclude-rule-input:focus {\n border: 1px solid #25A0F1 !important;\n box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24) !important;\n}\n\n.wpstg-file-size-exclude-select,\n.wpstg-path-exclude-select {\n width: 135px;\n}\n\n.wpstg-file-size-exclude-select-small {\n width: 52px;\n}\n\n.wpstg-file-size-exclude-input {\n width: 75px;\n}\n\n.wpstg-staging-option-title {\n margin: 15px 0 0;\n}\n\n.wpstg-swal-push-container.swal2-container {\n z-index: 9995;\n}\n\n#wpstg-scanning-files {\n padding-bottom: 5px;\n}\n\n#wpstg-scanning-files.wpstg-tab-section{\n padding-top:0;\n}\n\n.wpstg-reset-excludes-container {\n margin: 10px 0;\n}\n\n.wpstg-swal2-ajax-loader {\n width: 100%;\n height: 150px;\n overflow: hidden;\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n@keyframes wpstg-loading-icon-anim {\n\t0% {\n\t\ttransform: rotate(0);\n\t}\n\t100% {\n\t\ttransform: rotate(360deg);\n\t}\n}\n\n.wpstg-swal2-ajax-loader > img {\n width: 64px;\n height: 64px;\n animation: wpstg-loading-icon-anim 1s infinite linear;\n -webkit-animation: wpstg-loading-icon-anim 1s infinite linear;\n}\n\n.wpstg-swal2-container .wpstg-tab-section {\n width: auto !important;\n}\n\n.wpstg-is-dir-loading {\n position: absolute;\n margin-top: -2px;\n margin-left: 8px;\n display: none;\n}\n\n.wpstg-ml-8px {\n margin-left: 8px;\n}\n\n.wpstg-mb-8px {\n margin-bottom: 8px;\n}\n\n.wpstg-button.danger {\n display: inline-block;\n text-decoration: none;\n text-align: center;\n text-transform: inherit;\n background-color: #e74c3c;\n color: white;\n border-radius: 0px;\n border-color: transparent;\n}\n\n.wpstg-button.danger:hover {\n background-color: #c0392b;\n}\n\n.wpstg-swal2-container.wpstg-swal2-loading > .swal2-modal {\n height: 200px;\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container:not(.wpstg-swal2-loading) > .swal2-modal {\n max-width: 480px;\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container .swal2-header {\n display: none;\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container .swal2-content {\n height: auto;\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container > .swal2-modal > .swal2-content .wpstg-tabs-wrapper {\n overflow-y: auto;\n height: auto !important;\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container > .swal2-modal > .swal2-content {\n font-size: 13px;\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container > .swal2-modal > .swal2-content .wpstg-dir {\n margin-bottom: 4px;\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container > .swal2-modal > .swal2-content .wpstg-subdir {\n margin-top: 4px;\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container.has-collapsible-open .swal2-modal {\n height: calc(100vh - 70px);\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container.has-collapsible-open > .swal2-modal > .swal2-content .wpstg-tabs-wrapper {\n height: calc(100vh - 350px) !important;\n}\n"]}
1
+ {"version":3,"sources":["wpstg-admin.css"],"names":[],"mappings":"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","file":"wpstg-admin.css","sourcesContent":["/**\n * WPSTG Admin CSS\n *\n * @package WPSTG\n * @subpackage Admin CSS\n * @copyright Copyright (c) 2021, René Hermenau\n * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License\n*/\n\n/* Colors */\n\n.wpstg--violet {\n color: #9d37ae;\n}\n\n.wpstg-border--violet {\n border: 1px solid #9d37ae;\n}\n\n.wpstg--red {\n color: #E01E5A;\n}\n\n.wpstg-cta--red {\n color: #fe008f;\n}\n\n.wpstg--blue {\n color: #24a1f0;\n}\n\n.wpstg--darkblue {\n color: #0e86d9;\n}\n\n.wpstg--green {\n color: #83c11f;\n}\n\n.wpstg--grey {\n color: #3e3e3e;\n}\n\n.wpstg--darkgrey {\n color: #1b1b1b;\n}\n\n/* CSS for Tabs */\n\n#wpstg-tab-container ul {\n list-style: none;\n margin: 0;\n padding: 0;\n background: #f1f1f1;\n float: left;\n}\n\n#wpstg-tab-container ul li:first-child.selected-tab {\n border-top: none;\n}\n\n#wpstg-tab-container ul li a.selected-tab {\n font-weight: bold;\n text-decoration: none;\n}\n\n#wpstg-tab-container .row {\n padding-top: 10px;\n padding-bottom: 12px;\n}\n\n.wpstg-tabs-container .nav-tab-wrapper {\n padding: 0;\n}\n\n#wpstg-tab-container .row label strong,\n#wpstg-tab-container .row strong {\n font-weight: bold;\n}\n\n.wpstg-tabs a {\n padding: 5px;\n}\n\n#wpstg-tab-container > ul > li.wpstg-tabs.active {\n background-color: white;\n}\n\n#wpstg_settingsgeneral_header .row:nth-child(3),\n#wpstg_settingsgeneral_header .row:nth-child(4) {\n display: none;\n}\n\n#wpstg-tab-container .wpstg-settings-panel {\n padding: 0 20px 20px 20px;\n overflow: auto;\n}\n\n#wpstg-tab-container .wpstg-form-table th {\n vertical-align: top;\n text-align: left;\n padding: 20px 10px 20px 0;\n line-height: 1.3;\n font-weight: bold;\n font-size: 14px;\n color: #484848;\n width: 30%;\n}\n\n#wpstg-tab-container .wpstg-form-table tr {\n border-bottom: 1px solid #E7E7E7;\n}\n\n#wpstg-tab-container span.description {\n display: block;\n font-weight: 400;\n font-style: normal;\n font-size: 13px;\n margin-top: 7px;\n color: #484848;\n}\n\n#wpstg-tab-container .col-title {\n color: #484848;\n}\n\n@media only screen and (max-width: 680px) {\n #wpstg-tab-container ul {\n float: none;\n }\n\n #wpstg-tab-container .wpstg-form-table tr > th {\n width: 100%;\n }\n\n #wpstg-tab-container span.description {\n font-size: 14px;\n }\n\n #wpstg-tab-container .wpstg-form-table tr > th,\n #wpstg-tab-container .wpstg-form-table tr > td {\n padding: 10px;\n }\n}\n\n#wpstg-tab-container ul li {\n margin-bottom: 0;\n}\n\n#wpstg-tab-container ul li a {\n display: block;\n padding: 10px 4px 10px 14px;\n border-width: 1px 0;\n border-style: solid;\n border-top-color: white;\n border-bottom-color: #e7e7e7;\n text-decoration: none;\n color: #0097DF;\n font-weight: bold;\n}\n\n#wpstg-tab-container ul li a:hover {\n background-color: #e5e5e5;\n color: #777777;\n}\n\n.wpstg-logo {\n display: block;\n font-size: 16px;\n padding-top: 20px;\n width: 220px;\n float: left;\n}\n\n.wpstg-logo img {\n max-width: 212px;\n}\n\n.wpstg-version {\n display: block;\n padding-top: 34px;\n color: #9b9b9b;\n}\n\n.wpstg_admin .nav-tab {\n color: #3C3C3C;\n}\n\n#wpstg-tab-container table tbody tr:nth-child(1) > th > div {\n font-size: 20px;\n}\n\n/* Cloning workflow */\n\n#wpstg-clonepage-wrapper {\n margin-bottom: 20px;\n width: 98%;\n}\n\n@media screen and (min-width: 1090px) {\n #wpstg-clonepage-wrapper {\n float: left;\n margin-bottom: 20px;\n }\n}\n\n#wpstg-steps {\n margin-top: 0px;\n margin-left: 20px;\n}\n\n#wpstg-steps li {\n color: #444;\n line-height: 20px;\n padding-right: 10px;\n float: left;\n}\n\n.wpstg-step-num {\n border: 1px solid #3e3e3e;\n border-radius: 3px;\n display: inline-block;\n width: 20px;\n height: 20px;\n text-align: center;\n margin-right: 5px;\n}\n\n.wpstg-current-step {\n font-weight: bold;\n}\n\n.wpstg-current-step .wpstg-step-num {\n background: #3e3e3e;\n color: #eee;\n}\n\n.wpstg-box {\n margin: 10px 0;\n padding: 10px;\n position: relative;\n overflow: hidden;\n transition: border-color .2s ease-in-out;\n}\n\n.wpstg-clone {\n margin-bottom: 10px;\n padding: 16px;\n position: relative;\n transition: border-color .2s ease-in-out;\n background-color: #ffffff;\n color: #3e3e3e;\n border-radius: 3px;\n box-shadow: 0 0 1px rgba(0, 0, 0, .125), 0 1px 3px rgba(0, 0, 0, .1);\n}\n\n.wpstg-clone.active {\n border-color: #1d94cf;\n}\n\n.wpstg-clone-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.wpstg-clone-title {\n display: inline-block;\n font-size: 15px;\n max-width: 300px;\n text-decoration: none;\n font-weight: bold;\n color: #3e3e3e;\n}\n\n.wpstg-clone-title:hover {\n color: #111111;\n}\n\n.wpstg-clone-actions {\n display: flex;\n margin-top: 5px;\n}\n\n.wpstg-dropdown {\n position: relative;\n}\n\n.wpstg-clone-actions .wpstg-dropdown-toggler {\n text-decoration: none;\n background: #25a1f0;\n padding: 6px 10px;\n border-radius: 2px;\n font-size: 14px;\n box-shadow: 0 0 1px rgba(0, 0, 0, .125), 0 1px 3px rgba(0, 0, 0, .2);\n color: #ffffff;\n}\n\n.wpstg-clone-actions .wpstg-dropdown-toggler:hover {\n background: #002648;\n color: white;\n}\n\n.wpstg-dropdown {\n position: relative;\n}\n\n.wpstg-dropdown > .wpstg-dropdown-menu {\n background: #fff;\n display: none;\n flex-direction: column;\n position: absolute;\n right: 0;\n top: calc(100% + 4px);\n padding: 8px;\n border-radius: 2px;\n width: 100px;\n box-shadow: 0 0 1px rgba(0, 0, 0, .125), 0 1px 3px rgba(0, 0, 0, .2);\n z-index: 1000;\n}\n\n.wpstg-dropdown > .wpstg-dropdown-menu.wpstg-menu-dropup {\n top: auto;\n bottom: 100%;\n transform: translate3d(0px, -3px, 0px);\n}\n\n.wpstg-dropdown > .wpstg-dropdown-menu.shown {\n display: flex;\n}\n\n.wpstg-clone-action,\n.wpstg-dropdown-action {\n color: #3e3e3e;\n padding: 6px 8px;\n border-radius: 3px;\n text-decoration: none;\n position: relative;\n transition: color .2s ease-in-out;\n border-bottom: 1px solid #f3f3f3;\n}\n\n.wpstg-clone-action:hover,\n.wpstg-dropdown-action:hover {\n background: rgba(0, 0, 0, 0.05);\n}\n\n.wpstg-dropdown-action {\n color: #3e3e3e;\n background: transparent;\n border: 0 solid black;\n outline: none;\n box-shadow: none;\n}\n\n.wpstg-remove-clone:hover {\n color: #E01E5A;\n}\n\n.wpstg-clone-action:last-child {\n border: none;\n}\n\n.wpstg-clone:hover .wpstg-clone-action {\n display: inline-block;\n}\n\n#wpstg-show-error-details:focus,\n#wpstg-workflow .wpstg-clone-action {\n outline: none;\n box-shadow: none;\n}\n\n.wpstg-link-btn {\n background: #45a1c9;\n color: #fff;\n display: inline-block;\n padding: 5px 10px;\n text-decoration: none;\n vertical-align: baseline;\n transition: all .2s ease-in-out;\n}\n\n.wpstg-link-btn:hover,\n.wpstg-link-btn:focus {\n color: #fff;\n outline: none;\n box-shadow: none;\n}\n\n#wpstg-workflow .wpstg-link-btn:active {\n vertical-align: baseline;\n}\n\n.wpstg-link-btn[disabled] {\n background: #777 !important;\n border-color: #555 !important;\n pointer-events: none;\n}\n\n#wpstg-cancel-cloning,\n#wpstg-cancel-cloning-update {\n margin-top: 5px;\n}\n\n#wpstg-cancel-cloning.success,\n#wpstg-cancel-cloning.success {\n background: #64dd58;\n border-color: #54bd4a;\n}\n\n#wpstg-error-wrapper,\n#wpstg-error-details {\n display: none;\n padding-top: 10px;\n font-size: 13px;\n clear: both;\n}\n\n#wpstg-show-error-details {\n display: inline-block;\n margin-left: 5px;\n color: #555;\n text-decoration: none;\n transition: color .2s ease-in-out;\n}\n\n#wpstg-show-error-details:hover {\n color: #1d94cf;\n}\n\n#wpstg-error-details {\n border-left: 5px solid #E01E5A;\n padding: 10px;\n width: 500px;\n}\n\n#wpstg-try-again {\n display: none;\n}\n\n#wpstg-home-link {\n float: right;\n}\n\n.wpstg-loader {\n content: url('../../img/loading.gif');\n margin-top: 10px;\n display: none;\n}\n\n.wpstg-loader.wpstg-finished {\n display: block;\n content: \"Finished\";\n background-color: #00c89a;\n color: white;\n padding: 2px 10px;\n margin-top: 0;\n border-radius: 3px;\n}\n\n#wpstg-workflow {\n max-width: 800px;\n position: relative;\n clear: both;\n padding-top: 20px;\n float: left;\n min-width: 500px;\n min-height: 380px;\n padding-right: 20px;\n padding-bottom: 20px;\n}\n\n#wpstg-sidebar {\n float: left;\n max-width: 400px;\n display: block;\n margin-left: 10px;\n}\n\n#wpstg-workflow.loading::after,\n#wpstg-removing-clone.loading::after {\n background: rgba(255, 255, 255, .7);\n content: 'Loading... may take a while for huge websites';\n display: block;\n width: 100%;\n height: 100%;\n font-size: 20px;\n padding-top: 100px;\n text-align: center;\n position: absolute;\n top: 0;\n left: 0;\n z-index: 99;\n}\n\n#wpstg-removing-clone.loading::after {\n content: 'REMOVING' !important;\n}\n\n#wpstg-existing-clones,\n#wpstg-removing-clone {\n position: relative;\n}\n\n#wpstg-existing-clones h3 {\n color: #3e3e3e;\n}\n\n#wpstg-removing-clone .wpstg-tab-section {\n display: block;\n}\n\n.wpstg-progress-bar {\n max-width: 900px;\n height: 27px;\n padding: 0;\n background-color: #d6d8d7;\n}\n\n.wpstg-progress {\n float: left;\n background: #3fa5ee;\n width: 0;\n height: 100%;\n transition: width .6s ease;\n color: white;\n line-height: 25px;\n text-align: center;\n overflow: hidden;\n}\n\n.wpstg-progress-files {\n background: #16b4f0;\n width: 0;\n height: 100%;\n transition: width .6s ease;\n color: white;\n line-height: 25px;\n text-align: center;\n}\n\n#wpstg-new-clone-id.wpstg-error-input,\n#wpstg-clone-path.wpstg-error-input {\n border: 1px solid #E01E5A;\n box-shadow: 0 0 2px rgba(255, 66, 53, .8);\n}\n\n#wpstg-new-clone-id {\n width: 450px;\n max-width: 100%;\n margin-left: 15px;\n}\n\n#wpstg-new-clone {\n background: #25a1f0;\n border-color: #2188c9;\n}\n\n#wpstg-new-clone:hover {\n background: #259be6;\n border-color: #2188c9;\n}\n\n#wpstg-clone-path {\n margin-left: 10px;\n width: 350px;\n}\n\n.wpstg-error-msg {\n color: #E01E5A;\n}\n\n#wpstg-clone-id-error {\n display: block;\n background-color: #f0f8ff;\n padding: 10px;\n margin: 20px;\n}\n\n#wpstg-start-cloning + .wpstg-error-msg {\n display: block;\n margin-top: 5px;\n}\n\n.wpstg-size-info {\n color: #999;\n font-weight: normal;\n position: relative;\n left: 2px;\n}\n\n.wpstg-db-table .wpstg-size-info {\n top: 2px;\n}\n\n.wpstg-db-table:hover {\n background-color: #f0f8ff;\n}\n\n#wpstg-workflow #wpstg-start-cloning {\n margin-left: 5px;\n vertical-align: baseline;\n}\n\n\n/* Tabs */\n\n.wpstg-tabs-wrapper {\n max-width: 640px;\n margin: 10px 0;\n}\n\n#wpstg-path-wrapper {\n border-bottom: 2px dashed #ccc;\n padding-bottom: 10px;\n margin-bottom: 10px;\n}\n\n.wpstg-tab-section {\n border-bottom: 1px solid #ddd;\n border-right: none;\n border-left: none;\n display: none;\n width: calc(100% - 72px);\n padding: 0px 36px;\n}\n\n.wpstg-tab-section::after {\n display: block;\n content: '';\n clear: both;\n}\n\n.wpstg-tab-header {\n border-bottom: 1px solid #ddd;\n border-right: none;\n border-left: none;\n color: #444;\n font-size: 16px;\n font-weight: bold;\n display: block;\n padding: 10px;;\n text-decoration: none;\n}\n\n.wpstg-tab-triangle {\n display: inline-block;\n margin-right: 10px;\n animation: transform 0.5s;\n}\n\n.wpstg-tab-header:focus {\n color: #444;\n outline: none;\n box-shadow: none;\n}\n\n#wpstg-large-files {\n display: none;\n border: 1px dashed #ccc;\n padding: 10px 10px 10px;\n margin-top: 20px;\n position: relative;\n font-size: 12px;\n}\n\n#wpstg-large-files h3 {\n background: #fff;\n margin: 0;\n padding: 0 5px;\n position: absolute;\n top: -10px;\n left: 5px;\n}\n\n.wpstg-subdir {\n display: none;\n margin-left: 20px;\n}\n\n.wpstg-subdir.wpstg-push {\n display: block;\n margin-left: 20px;\n}\n\n.wpstg-dir a.disabled {\n color: #888;\n cursor: default;\n text-decoration: none;\n}\n\n.wpstg-check-subdirs {\n display: inline-block;\n margin-left: 10px;\n}\n\n.wpstg-notice-alert {\n display: block;\n background-color: #E01E5A;\n padding: 20px;\n max-width: 600px;\n margin-top: 10px;\n color: white;\n}\n\n.wpstg-notice--white {\n display: block;\n background-color: #ffffff;\n padding: 20px;\n max-width: 600px;\n margin-top: 10px;\n}\n\n.wpstg-notice-alert a {\n color: white;\n}\n\n.wpstg-notice-alert h3 {\n color: white;\n}\n\n.wpstg-header {\n font-weight: 400;\n line-height: 1.6em;\n font-size: 19px;\n border-bottom: 1px solid #DFDFDF;\n clear: both;\n padding-top: 10px;\n}\n\n#wpstg-clone-label {\n font-size: 14px;\n font-weight: bold;\n}\n\n.wpstg-log-details {\n height: 300px;\n overflow: scroll;\n max-width: 650px;\n font-family: monospace;\n font-size: 12px;\n line-height: 15px;\n border: 1px solid #FFF;\n background-color: black;\n color: #c0c0c0;\n padding: 3px;\n white-space: nowrap;\n margin-top: 15px;\n}\n\n#wpstg-finished-result {\n display: none;\n}\n\n#wpstg-remove-cloning {\n background: #ff3428;\n border-color: #e72f24;\n margin-top: 5px;\n}\n\n#wpstg-success-notice {\n padding: 10px;\n background-color: white;\n max-width: 900px;\n border: 1px solid #ccc;\n margin-top: 20px;\n}\n\n.wpstg_beta_notice {\n margin-bottom: 20px;\n}\n\n.wpstg-sysinfo {\n width: 700px;\n height: 700px;\n}\n\n.wpstg-form-table .col-title label {\n font-weight: 600;\n}\n\n.wpstg-form-table td:first-child {\n width: 30%;\n}\n\n.wpstg-share-button-container {\n margin: 5px 0;\n}\n\n.wpstg-share-button-container p {\n margin: 0 0 10px 0;\n}\n\n.wpstg-share-button {\n display: inline-block;\n}\n\n.wpstg-share-button a {\n text-decoration: none;\n}\n\n.wpstg-share-button .wpstg-share {\n font-family: sans-serif;\n font-weight: bold;\n text-decoration: none;\n text-align: center;\n}\n\n.wpstg-share-button .wpstg-share {\n -webkit-border-radius: 2px;\n -moz-border-radius: 2px;\n border-radius: 2px;\n color: #FFF;\n display: inline;\n font-size: 12px;\n padding: 4px 8px;\n}\n\n.wpstg-share-button-twitter .wpstg-share {\n background-color: #00ABF0;\n}\n\n.wpstg-share-button-facebook .wpstg-share {\n background-color: #3b5998;\n}\n\n.wpstg-share-button-googleplus .wpstg-share {\n background-color: #F53424;\n}\n\n.wpstg-share-button-twitter .share:active,\n.wpstg-share-button-facebook .share:active,\n.wpstg-share-button-googleplus .share:active {\n background-color: #353535;\n}\n\n#wpstg-check-space {\n margin-left: 8px;\n}\n\n#wpstg-welcome li {\n font-size: 18px;\n line-height: 29px;\n position: relative;\n padding-left: 23px;\n list-style: none !important;\n}\n\n#wpstg-welcome {\n margin-top: 20px;\n margin-right: 20px;\n background-color: white;\n}\n\n.wpstg-heading-pro {\n font-weight: bold;\n}\n\n.wpstg-h2 {\n margin-top: 0;\n margin-bottom: 1.2rem;\n font-size: 30px;\n line-height: 2.5rem;\n}\n\n#wpstg-welcome li:before {\n width: 1em;\n height: 100%;\n background: url(data:image/svg+xml;charset=utf8,%3Csvg%20width%3D%221792%22%20height%3D%221792%22%20viewBox%3D%220%200%201792%201792%22%20xmlns%3D%22http%3A%2F%2Fwww%2Ew3%2Eorg%2F2000%2Fsvg%22%3E%3Cpath%20fill%3D%22%2377B227%22%20d%3D%22M1671%20566q0%2040%2D28%2068l%2D724%20724%2D136%20136q%2D28%2028%2D68%2028t%2D68%2D28l%2D136%2D136%2D362%2D362q%2D28%2D28%2D28%2D68t28%2D68l136%2D136q28%2D28%2068%2D28t68%2028l294%20295%20656%2D657q28%2D28%2068%2D28t68%2028l136%20136q28%2028%2028%2068z%22%2F%3E%3C%2Fsvg%3E) left .4em no-repeat;\n background-size: contain;\n content: \"\";\n position: absolute;\n top: -2px;\n left: 0;\n color: #77b227;\n}\n\n.wpstg-h1 {\n margin-bottom: 1.35rem;\n font-size: 2.5em;\n line-height: 3.68rem;\n letter-spacing: normal;\n}\n\n.swal2-content h1 {\n color: #444;\n}\n\n#wpstg-welcome h2 {\n margin: 0 0 15px;\n}\n\n#wpstg-welcome .wpstg-footer {\n clear: both;\n margin-top: 20px;\n font-style: italic;\n}\n\n#wpstg-footer {\n clear: both;\n margin-top: 20px;\n margin-right: 10px;\n padding-top: 50px;\n}\n\n#wpstg-footer a {\n text-decoration: none;\n}\n\n#wpstg-footer li {\n margin-bottom: 2px;\n list-style: circle;\n}\n\n#wpstg-footer ul {\n margin-left: 15px;\n margin-top: 0px;\n}\n\n.wpstg-footer--title {\n margin-left: 15px;\n}\n\n.wpstg-staging-info {\n margin-top: 8px;\n color: #3e3e3e;\n font-size: 12px;\n}\n\n.wpstg-staging-info a {\n color: #3e3e3e;\n}\n\n.wpstg-staging-info li {\n margin-bottom: 2px;\n}\n\n.wpstg-bold {\n font-weight: 600;\n}\n\n#wpstg-processing-status {\n margin-top: 5px;\n font-size: 13px;\n font-weight: 400;\n float: left;\n}\n\n#wpstg-processing-timer {\n margin-top: 5px;\n font-size: 13px;\n font-weight: 400;\n float: right;\n}\n\n#wpstg-report-issue-button {\n margin-left: 50px;\n border: 1px solid #E01E5A;\n color: #E01E5A;\n background-color: white;\n}\n\n#wpstg-report-issue-button:hover {\n background-color: #dc2b62;\n color: #fff;\n}\n\n.wpstg-blue-primary {\n display: inline-block;\n text-decoration: none;\n font-size: 13px;\n /*line-height: 26px;*/\n height: 28px;\n margin: 0;\n padding: 0 10px 1px;\n cursor: pointer;\n border-width: 1px;\n border-style: solid;\n -webkit-appearance: none;\n border-radius: 3px;\n white-space: nowrap;\n box-sizing: border-box;\n background: #25a1f0;\n border-color: #2188c9;\n color: #fff;\n text-shadow: 0 -1px 1px #006799, 1px 0 1px #006799, 0 1px 1px #006799, -1px 0 1px #006799;\n}\n\n.wpstg-blue-primary:hover {\n background-color: #259be6;\n}\n\n.wpstg-report-issue-form {\n position: absolute;\n z-index: 999;\n width: 300px;\n background-color: #fff;\n padding: 15px 15px 10px;\n border: 1px solid #e8e8e8;\n border-radius: 3px;\n box-shadow: 0 1px 0 0 #fff inset;\n display: none;\n right: 0;\n top: 35px;\n}\n\n@media (max-width: 600px) {\n .wpstg-report-issue-form {\n position: relative;\n }\n}\n\n.wpstg-report-show {\n display: block;\n}\n\n.wpstg-field input[type=text],\n.wpstg-field textarea {\n width: 100%;\n font-weight: 400;\n line-height: 1.4;\n margin-bottom: 4px;\n}\n\n.wpstg-report-email,\n.wpstg-report-hosting-provider {\n width: 100%;\n font-weight: 400;\n font-size: .8rem;\n height: 2.3rem;\n line-height: 2.3rem;\n border-radius: 3px;\n margin-bottom: 4px;\n padding: 0 10px;\n}\n\n.wpstg-report-description {\n border-radius: 3px;\n font-size: .8rem;\n padding: 6px 10px;\n resize: none;\n}\n\n.wpstg-report-privacy-policy {\n font-size: 12px;\n margin-bottom: 15px;\n}\n\n#wpstg-report-cancel {\n float: right;\n margin-right: 5px;\n font-weight: bold;\n}\n\n#wpstg-success-button {\n font-weight: bold;\n}\n\n.wpstg-message {\n box-sizing: border-box;\n -moz-box-sizing: border-box;\n background-color: #f5e0de;\n border-radius: 3px;\n color: rgba(0, 0, 0, .6);\n height: auto;\n margin: 10px 0;\n min-height: 18px;\n padding: 6px 10px;\n position: relative;\n}\n\n.wpstg-message.wpstg-error-message {\n background-color: #f5e0de;\n color: #b65147;\n font-size: 12px;\n}\n\n.wpstg-message.wpstg-success-message {\n background-color: #d7f8e0;\n color: #515151;\n}\n\n.wpstg-message p {\n margin: 3px 0;\n font-size: 13px;\n}\n\n.wpstg-warning {\n display: block;\n padding: 10px;\n background-color: #ffb804;\n color: #ffffff;\n margin: 10px 10px 10px 0;\n}\n\n.wpstg-warning a {\n color: #ffffff;\n font-weight: bold;\n text-decoration: underline;\n}\n\n.wpstg-error {\n display: block;\n padding: 10px !important;\n background-color: #E01E5A !important;\n color: #ffffff;\n margin: 10px 10px 10px 0 !important;\n border-color: transparent !important;\n border-left-color: transparent !important;\n box-shadow: none !important;\n}\n\n.wpstg-error a {\n color: #ffffff;\n font-weight: bold;\n text-decoration: underline;\n}\n\n#wpstg-resume-cloning {\n display: none;\n}\n\n#wpstg-external-db th {\n text-align: left;\n width: 120px;\n}\n\n#wpstg-db-connect {\n font-weight: normal;\n}\n\n#wpstg-db-status {\n display: block;\n margin-top: 5px;\n padding: 5px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n border-radius: 4px;\n text-decoration: none;\n text-align: center;\n}\n\n.wpstg-text-field > #wpstg-db-status {\n margin-top: 8px;\n margin-left: 150px;\n min-width: 300px;\n}\n\n.wpstg-success {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #d6e9c6;\n}\n\n.wpstg-failed {\n color: #a94442;\n background-color: #f2dede;\n border-color: #ebccd1;\n}\n\n#wpstg_select_tables_cloning {\n height: 600px;\n font-size: 13px;\n}\n\n#wpstg-update-notify {\n background-color: #E01E5A;\n font-size: 14px;\n color: #ffffff;\n line-height: normal;\n padding: 10px;\n}\n\n#wpstg-update-notify a {\n color: #ffffff;\n font-weight: bold;\n}\n\n.wpstg-pointer {\n cursor: pointer;\n}\n\n.wpstg--tab--header {\n background-color: white;\n /* margin-bottom: 10px; */\n /* padding: 16px; */\n position: relative;\n transition: border-color .2s ease-in-out;\n background-color: #ffffff;\n color: #3e3e3e;\n border-radius: 2px;\n box-shadow: 0 0 1px rgba(0, 0, 0, .125), 0 1px 3px rgba(0, 0, 0, .02);\n}\n\n.wpstg--tab--header ul {\n display: flex;\n}\n\n.wpstg--tab--header ul li {\n margin-right: 1em;\n margin-bottom: 0px;\n}\n\n.wpstg--tab--header ul li:last-child {\n margin-right: 0;\n}\n\n.wpstg--tab--header a {\n min-width: 150px;\n text-align: center;\n cursor: pointer;\n display: inline-block;\n padding: 1em 1.25em;\n padding-bottom: 9px;\n color: #c4c4c4;\n font-size: 18px;\n /*\n border: solid 1px;\n */\n}\n\n.wpstg--tab--header a.wpstg--tab--active {\n border-bottom: .4em solid #25A1F0;\n color: #25A1F0;\n}\n\n.wpstg--tab--header a:hover {\n background-color: #fefefe;\n border-bottom: 0.4em solid #25A1F0;\n color: #25A1F0;\n}\n\n.wpstg--tab--content {\n display: none;\n}\n\n.wpstg--tab--active {\n display: block;\n}\n\n.wpstg--text--strong,\n.wpstg--text--strong * {\n font-weight: bold !important;\n}\n\n.wpstg--text--danger {\n color: #a94442;\n}\n\n.wpstg--tooltip {\n position: relative;\n display: inline-block;\n border-bottom: 1px dotted black;\n margin-left: 10px;\n}\n\n.wpstg--tooltip .wpstg--tooltiptext {\n visibility: hidden;\n width: 300px;\n background-color: #ffffff;\n color: #505050;\n text-align: left;\n padding: 12px;\n border-radius: 3px;\n position: absolute;\n z-index: 1;\n -webkit-box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\n -moz-box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\n box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\n}\n\n.wpstg--tooltiptext-backups {\n width: 120px;\n top: 100%;\n left: -150%;\n margin-left: -56px;\n margin-top: 4px;\n}\n\n.wpstg--tooltip.wpstg--exclude-rules--tooltip {\n border-bottom: 0px solid transparent;\n}\n\n.wpstg--tooltip.wpstg--exclude-rules--tooltip > .wpstg--tooltiptext {\n margin-top: 0px;\n margin-left: -150px;\n}\n\n/**\nTooltip top arrow\n */\n\n.wpstg--tooltip .wpstg--tooltiptext-backups::after {\n content: \" \";\n position: absolute;\n bottom: 100%;\n /* At the top of the tooltip */\n left: 50%;\n margin-left: 25px;\n border-width: 5px;\n border-style: solid;\n border-color: transparent transparent white transparent;\n}\n\n.wpstg--tooltip .wpstg--tooltiptext.has-top-arrow {\n margin-top: 6px;\n}\n\n.wpstg--tooltip .wpstg--tooltiptext.has-top-arrow::after {\n content: \" \";\n position: absolute;\n bottom: 100%;\n left: 50%;\n margin-left: -18px;\n border-width: 5px;\n border-style: solid;\n border-color: transparent transparent white transparent;\n}\n\n.wpstg--snaphot-restore-table tr {\n line-height: 12px;\n}\n\n.wpstg-float-left {\n float: left;\n}\n\n.wpstg-beta-notice {\n background-color: #b0e8b0;\n border-radius: 3px;\n padding: 7px;\n margin-bottom: 20px;\n}\n\n#wpstg-backup-name {\n font-size: 1.875em;\n font-weight: 600;\n}\n\n#wpstg_select_tables_cloning option:checked {\n /* Cannot use background color here because Chrome and Firefox ignore it even if set to !important */\n -webkit-appearance: menulist-button;\n background-image: linear-gradient(0deg, #1e90ff 0%, #1e90ff 100%);\n}\n\n.wpstg--btn--cancel {\n background: #ff3428;\n border-color: #e72f24;\n color: #fff;\n height: auto;\n line-height: normal;\n font-size: 16px;\n padding: .5em;\n margin-bottom: 1.5em;\n}\n\n.wpstg--btn--cancel:hover {\n background: #ff3428;\n border-color: #e72f24;\n}\n\n.wpstg--process--content > .swal2-html-container {\n padding: 4em 2em !important;\n}\n\n.wpstg--modal--process--logs,\n.wpstg--modal--error--logs {\n background: #ffffff;\n border: 1px solid #a8a8a8;\n border-radius: 3px;\n height: 300px;\n margin-top: 1em;\n display: none;\n padding-top: 10px;\n padding-left: 10px;\n overflow: auto;\n text-align: justify;\n}\n\n.wpstg--modal--error--logs {\n height: auto;\n max-height: 300px;\n}\n\n.wpstg--modal--process--logs p {\n font-size: 12px;\n white-space: nowrap;\n}\n\n.wpstg--modal--process--logs p.wpstg--modal--process--msg--info {\n color: #222222;\n}\n\n.wpstg--modal--process--logs p.wpstg--modal--process--msg--debug {\n color: #757575;\n}\n\n.wpstg--modal--process--title {\n color: #565656;\n margin: .25em 0;\n}\n\n.wpstg--modal--process--subtitle {\n margin: .5em 0;\n color: #565656;\n}\n\n.wpstg--modal--error--logs > p {\n text-align: left;\n font-size: 14px;\n color: #222222;\n}\n\n.wpstg--modal--process--logs p,\n.wpstg--modal--error--logs p {\n margin: 0px;\n margin-bottom: 2px;\n}\n\n.wpstg--modal--process--msg--error {\n color: #E01E5A;\n}\n\n.wpstg--modal--process--msg--critical {\n color: #E01E5A;\n}\n\n.wpstg--modal--process--msg--warning {\n color: darkorange;\n}\n\n.wpstg--modal--process--msg-found {\n font-size: 16px;\n color: #E01E5A;\n font-weight: bold;\n}\n\n.wpstg--modal--delete {\n text-align: left;\n margin-top: 8px;\n color: #565656;\n}\n\n.wpstg-swal-popup .swal2-cancel.wpstg--btn--cancel {\n margin-bottom: 0;\n text-shadow: none !important;\n}\n\n.wpstg-swal-popup .wpstg-loader {\n display: inline-block !important;\n}\n\n.wpstg--modal--process--generic-problem {\n display: none;\n border-left: 5px solid #E01E5A;\n margin: .5em 0;\n}\n\n.wpstg--modal--process--logs--tail {\n font-size: 16px;\n color: #565656;\n background: none;\n border: none;\n cursor: pointer;\n}\n\n.wpstg--modal--backup--import--upload--title {\n color: #565656;\n}\n\n.wpstg--modal--backup--import--configure,\n.wpstg--modal--backup--import--upload--status,\n.wpstg--modal--backup--import--upload--container input[type=\"file\"] {\n display: none;\n}\n\n#wpstg--backups--import--file-list {\n font-size: 14px;\n font-weight: bold;\n}\n\n#wpstg--backups--import--file-list-empty {\n color: #E01E5A;\n}\n\n.wpstg--modal--backup--import--filesystem label {\n font-size: 14px;\n}\n\n.wpstg--modal--backup--import--filesystem button {\n margin-bottom: 20px;\n}\n\n.wpstg--modal--backup--import--upload {\n position: relative;\n min-height: 30px;\n}\n\n.wpstg--modal--backup--import--upload {\n color: #505050;\n}\n\n.wpstg--modal--backup--import--upload--container {\n position: relative;\n border-radius: 10px;\n margin: .5em;\n padding: 1em .5em;\n border: 3.5px dashed #dedede;\n transition: background-color 0.3s ease, color 0.3s ease;\n background-color: #f4fbff;\n}\n\n.wpstg--modal--backup--import--upload--container.wpstg--has-dragover span.wpstg--drop {\n display: inline-flex;\n}\n\n.wpstg--modal--backup--import--upload--container input[type='file'] {\n display: none;\n}\n\n.wpstg--modal--backup--import--upload--container img {\n width: 4em;\n align-self: center;\n border: none;\n}\n\n.wpstg--modal--backup--import--upload--container span {\n margin-top: 1em;\n}\n\n.wpstg--backup--import--options > button {\n margin-top: 1em;\n padding: 1em;\n align-self: center;\n width: 185px;\n height: auto;\n line-height: normal;\n}\n\n.wpstg--backup--import--options {\n position: relative;\n display: flex;\n justify-content: center;\n}\n\n.wpstg--backup--import--options ul {\n display: none;\n}\n\n.wpstg--backup--import--options.wpstg--show-options ul {\n padding: 0;\n margin: 54px 0 0 0;\n display: block;\n position: absolute;\n width: 185px;\n background: #25a1f0;\n box-sizing: border-box;\n border-radius: 0 0 3px 3px;\n border-width: 1px;\n border-color: #2188c9;\n text-shadow: 0 -1px 1px #006799, 1px 0 1px #006799, 0 1px 1px #006799, -1px 0 1px #006799;\n}\n\n.wpstg--backup--import--options.wpstg--show-options ul li {\n border-bottom: .1em solid #25a1f0;\n margin: 0;\n}\n\n.wpstg--backup--import--options.wpstg--show-options ul li:hover {\n background-color: #25a1f0;\n}\n\n.wpstg--backup--import--options.wpstg--show-options ul li:last-child {\n border-bottom: none;\n}\n\n.wpstg--backup--import--options ul li button {\n cursor: pointer;\n background: none;\n border: none;\n margin: 0;\n width: 100%;\n color: white;\n height: 40px;\n line-height: 40px;\n}\n\n.wpstg--backup--import--options ul li button:hover {\n background-color: #259be6;\n}\n\n.wpstg--modal--backup--import--search-replace--info {\n margin: 1em 0;\n display: flex;\n flex-direction: row;\n}\n\n.wpstg--modal--backup--import--info p {\n text-align: left;\n margin: 0;\n}\n\n.wpstg--modal--backup--import--search-replace--wrapper button {\n align-self: center;\n}\n\n.wpstg--import--advanced-options--button {\n border: 0;\n border-radius: 3px;\n font-size: 18px;\n text-shadow: 0 -1px 1px #006799, 1px 0 1px #006799, 0 1px 1px #006799, -1px 0 1px #006799;\n cursor: pointer;\n}\n\n.wpstg--modal--backup--import--search-replace--new {\n color: white;\n background-color: #25a1f0;\n}\n\n.wpstg--modal--backup--import--search-replace--remove {\n color: white;\n background-color: #25a1f0;\n width: 22px;\n height: 22px;\n margin-left: 5px;\n}\n\n.wpstg--modal--backup--import--search-replace--input-group:first-child button {\n display: none;\n}\n\n.wpstg--modal--backup--import--search-replace--input--container {\n flex: 1;\n display: flex;\n flex-direction: column;\n}\n\n.wpstg--modal--backup--import--search-replace--input-group {\n width: 100%;\n border-bottom: 6px solid #f1f1f1;\n margin-bottom: 10px;\n}\n\n.wpstg--modal--backup--import--search-replace--input-group input {\n min-width: 250px;\n width: calc(50% - 4px - 11px - 5px); /* -4px is half of the padding; -11px is half of the button; -5 is the margin left of the button */\n display: inline-block;\n line-height: 10px;\n border: 1px solid #dedede;\n border-radius: 3px;\n color: #666;\n padding: 8px;\n margin-bottom: 12px;\n}\n\n.wpstg--modal--import--upload--process {\n display: none;\n position: relative;\n height: 30px;\n margin-top: 20px;\n margin-bottom: 20px;\n width: 100%;\n top: 0;\n left: 0;\n text-indent: 1em;\n white-space: nowrap;\n overflow: hidden;\n color: #333333;\n justify-content: center;\n align-items: center;\n}\n\n.wpstg--modal--import--upload--progress {\n position: absolute;\n background: #98d452;\n color: white;\n height: 100%;\n border-radius: 4px;\n left: 0;\n top: 0;\n}\n\n.wpstg--modal--import--upload--progress--title {\n z-index: 9;\n}\n\n.wpstg-fieldset:disabled {\n opacity: 0.8;\n border-top: 1px solid white;\n margin-top: 20px;\n}\n\n.wpstg-fieldset {\n padding-left: 20px;\n}\n\n.wpstg-fs-14 {\n font-size: 14px;\n}\n\n.wpstg-dark-alert {\n font-weight: bold;\n background-color: #0e86d9;\n padding: 15px;\n margin-top: 0px;\n color: white;\n}\n\n.wpstg-dark-alert .wpstg-button--cta-red {\n margin-left:10px;\n}\n\n.wpstg-form-group {\n display: block;\n width: 100%;\n margin-bottom: 8px;\n align-items: center;\n}\n\n.wpstg-form-group > label {\n display: block;\n font-weight: 700;\n}\n\n.wpstg-text-field > input {\n width: 300px;\n display: block;\n line-height: 1.5;\n}\n\n.wpstg-code-segment {\n display: block;\n}\n\n.wpstg-text-field > .wpstg-code-segment {\n margin-top: 4px;\n min-width: 300px;\n}\n\n.wpstg-form-group > .wpstg-checkbox {\n min-width: 100%;\n width: 100%;\n position: relative;\n}\n\n.wpstg-form-group > .wpstg-checkbox > input[type='checkbox'] {\n left: 150px;\n}\n\n.wpstg-rounded {\n border-radius: 3px;\n}\n\n.wpstg-white-border {\n border: 1px solid white !important;\n}\n\n.wpstg-ml-4 {\n margin-left: 4px;\n}\n\n#wpstg-confirm-backup-restore-data {\n margin: 40px;\n text-align: left;\n}\n\n#wpstg-advanced-settings hr {\n margin: 20px 0;\n}\n\n.wpstg-form-row {\n display: block;\n}\n\n.wpstg-form-row label,\n.wpstg-form-row input {\n display: table-cell;\n padding-left: 5px;\n padding-right: 5px;\n margin-top: 3px;\n margin-bottom: 3px;\n}\n\n.wpstg-form-row input {\n width: 400px;\n}\n\n.wpstg-form-row label {\n font-weight: bold;\n width: 1px;\n white-space: nowrap;\n}\n\n#wpstg-db-connect-output #wpstg-db-status {\n width: 390px;\n}\n\n.wpstg-fs-14 {\n font-size: 14px;\n}\n\n.wpstg-code-segment {\n display: block;\n}\n\n.wpstg-form-group > .wpstg-checkbox {\n min-width: 100%;\n width: 100%;\n}\n\n.wpstg-form-group > .wpstg-checkbox > input[type='checkbox'] {\n margin-left: 10px;\n}\n\n@media only screen and (max-width: 768px) {\n .wpstg-form-group > label {\n min-width: auto;\n width: auto;\n }\n\n .wpstg-text-field > input {\n width: 100%;\n }\n\n .wpstg-text-field > .wpstg-code-segment {\n margin-left: 0;\n min-width: 100%;\n }\n\n .wpstg-tab-section {\n width: calc(100vw - 60px);\n max-width: 450px;\n }\n}\n\n.wpstg-rounded {\n border-radius: 3px;\n}\n\n.wpstg-white-border {\n border: 1px solid white !important;\n}\n\n.wpstg-m-0 {\n margin: 0;\n}\n\n.wpstg-mt-10px {\n margin-top: 10px;\n}\n\n.wpstg-my-10px {\n margin-top: 10px;\n margin-bottom: 10px;\n}\n\n.wpstg-w-100 {\n width: 100%;\n}\n\n.wpstg-box-shadow {\n box-shadow: 0 1px 1px 0 rgba(0, 0, 0, .1);\n}\n\n.wpstg-float-left {\n float: left;\n}\n\n.wpstg-bold-text {\n font-weight: bold;\n}\n\n.wpstg-warning.notice {\n border-left: 4px solid #ffba00;\n}\n\n.wpstg-confirmation-label {\n background-color: #5b9dd9;\n color: #fff;\n padding: 2px;\n border-radius: 3px;\n}\n\n.wpstg-my-6px {\n margin-bottom: 6px;\n margin-top: 6px;\n}\n\n.wpstg-mb-10px {\n margin-bottom: 10px;\n}\n\n.wpstg-clear-both {\n clear: both;\n}\n\n.wpstg-font-italic {\n font-style: italic;\n}\n\n.wpstg-mt-20px {\n margin-top: 20px;\n}\n\n.wpstg-welcome-container {\n border: 2px solid white;\n padding: 20px;\n margin-bottom: 20px;\n}\n\n.wpstg-ml-30px {\n margin-left: 30px;\n}\n\n.wpstg-text-center {\n text-align: center;\n}\n\n.wpstg-feedback-link {\n text-decoration: none;\n}\n\n.wpstg-feedback-span {\n display: block;\n margin-bottom: 3px;\n}\n\n#wpstg-confirm-backup-restore-data {\n margin: 40px;\n text-align: left;\n}\n\n#wpstg-confirm-backup-restore-wrapper {\n margin: 30px;\n margin-top: 0;\n}\n\n#wpstg-confirm-backup-restore-wrapper h3 {\n color: #E01E5A;\n}\n\n#wpstg-progress-db,\n#wpstg-progress-backup {\n background-color: #3fa5ee;\n}\n\n#wpstg-progress-sr,\n#wpstg-progress-files.wpstg-pro {\n background-color: #3c9ee4;\n}\n\n#wpstg-progress-dirs,\n#wpstg-progress-data {\n background-color: #3a96d7;\n}\n\n#wpstg-progress-files:not(.wpstg-pro),\n#wpstg-progress-finishing {\n background-color: #378cc9;\n}\n\n.wpstg-issue-resubmit-confirmation.swal2-container,\n.wpstg-swal2-container.swal2-container {\n z-index: 10500;\n}\n\n.wpstg-swal2-container.wpstg-swal2-loading .swal2-actions,\n.wpstg-swal2-container.wpstg-swal2-loading .swal2-header {\n display: none;\n}\n\nbody.toplevel_page_wpstg_backup .swal2-container .swal2-content,\nbody.toplevel_page_wpstg_clone .swal2-container .swal2-content {\n z-index: 2;\n}\n\n.toplevel_page_wpstg_clone #swal2-content h2 {\n color: #565656;\n}\n\n.toplevel_page_wpstg_clone #swal2-content {\n line-height: 1.5em;\n}\n\ndiv#exportUploadsWithoutDatabaseWarning {\n font-style: italic;\n font-size: 0.9rem;\n margin: 10px;\n padding: 10px;\n border: 1px solid #e3e3e3;\n border-radius: 5px;\n text-align: center;\n background-color: #fafafa;\n}\n\n.wpstg-advanced-options-dropdown-wrapper {\n display: none; /* ENABLE WHEN WE HAVE ADVANCED OPTIONS FOR EXPORTING */\n margin-top: 20px;\n}\n\n.wpstg--modal--backup--import--search-replace--wrapper {\n text-align: left;\n margin-top: 20px;\n}\n\n.wpstg--modal--backup--import--search-replace--new--wrapper {\n text-align: center;\n}\n\n.wpstg-import-backup-contains li {\n display: inline-block;\n}\n\n.wpstg-import-backup-contains li .wpstg-backups-contains {\n border-radius: 3px;\n color: #979797;\n background-color: #e3e3e3;\n border: 1px solid #c2c2c2;\n width: 17px;\n height: 17px;\n font-size: 17px;\n}\n\n.wpstg-import-backup-contains.wpstg-listing-single-backup li .wpstg-backups-contains {\n padding: 2px;\n background-color: white;\n border: 1px solid #c2c2c2;\n}\n\n.wpstg-import-backup-contains.wpstg-listing-single-backup li .wpstg-backups-contains > .wpstg--dashicons {\n filter: invert(50%);\n}\n\n.wpstg-import-backup-contains .wpstg--tooltiptext {\n width: 50px;\n font-size: x-small;\n padding: 5px;\n left: -25px;\n text-align: center;\n}\n\n.wpstg-import-backup-contains-title {\n display: inline-block;\n}\n\nul.wpstg-import-backup-contains {\n display: inline-block;\n}\n\n.wpstg-import-backup-name {\n display: inline-block;\n font-weight: bold;\n}\n\n.wpstg-backup-more-info-toggle {\n font-size: x-small;\n display: inline-block;\n font-style: italic;\n cursor: pointer;\n}\n\n.wpstg-backup-more-info-toggle::selection {\n background: none;\n}\n\nul.wpstg-import-backup-more-info {\n font-size: 14px;\n text-align: left;\n margin-bottom: 30px;\n margin-top: 10px;\n background-color: #f6f6f6;\n border: 1px solid #878787;\n border-radius: 3px;\n padding: 7px;\n cursor: pointer;\n}\n\nul.wpstg-import-backup-more-info:hover {\n background-color: #def2ff;\n border: 1px solid #25a1f0;\n}\n\nul.wpstg-import-backup-more-info li {\n height: 20px;\n}\n\n.wpstg-backup-list {\n max-width: 800px;\n}\n\n.wpstg-backup-list h3 {\n color:#3e3e3e;\n}\n\n.wpstg-backup-list ul ul {\n margin-block-start: 1em;\n margin-block-end: 1em;\n}\n\n.wpstg-push-confirmation-message {\n text-align: justify;\n font-size: 15px;\n}\n\n.wpstg-settings-row {\n padding-top: 10px;\n padding-bottom: 10px;\n}\n\n.wpstg-settings-title {\n font-weight: 600;\n}\n\n.wpstg-settings-form-group {\n display: flex;\n align-items: center;\n}\n\n.wpstg-settings-form-group > .wpstg-settings-message {\n width: 30%;\n padding: 0;\n margin: 7px 0 0;\n}\n\n/**\n * WP STAGING EXCLUSION RULES TABLE LAYOUT\n */\n\n.wpstg-excluded-filters-container {\n padding: 0;\n margin-top: 10px;\n margin-bottom: 10px;\n max-width: 100%;\n width: 100%;\n}\n\n.wpstg-excluded-filters-container > table {\n width: 100%;\n border-collapse: collapse;\n border-color: transparent;\n}\n\n.wpstg-excluded-filters-container td {\n padding-top: 4px;\n padding-bottom: 4px;\n height: 20px;\n}\n\n.wpstg-excluded-filters-container h4 {\n margin: 0;\n}\n\n.wpstg-exclude-filters-foot {\n display: flex;\n justify-content: flex-start;\n padding: 0;\n}\n\n/**\n * WP STAGING EXCLUSION RULE DROPDOWN STYLE\n */\n\n\n.wpstg-exclude-filter-dropdown > button:hover {\n background: #135e96;;\n border: 1px solid #135e96;;\n}\n\n.wpstg-exclude-filter-dropdown > .wpstg-dropdown-menu {\n width: 128px;\n}\n\n.wpstg-remove-exclude-rule {\n color: #fff !important;\n background-color: #e01e5a;\n border: 1px solid #e01e5a;\n width: 20px;\n height: 20px;\n border-radius: 10px;\n font-size: 24px;\n padding: 0;\n display: inline-flex;\n justify-content: center;\n outline: none;\n box-shadow: none;\n font-weight: 400;\n line-height: 0.7;\n margin-top: 5px;\n cursor: pointer;\n}\n\n.wpstg-remove-exclude-rule:hover {\n background-color: #E01E5A;\n border-color: #E01E5A;\n}\n\n.wpstg-code-block {\n margin-top: 4px;\n font-size: 1.2em;\n background: #f8f8f8;\n border-radius: 2px;\n}\n\n.wpstg-rule-info {\n background: #f8f8f8 !important;\n}\n\ncode.wpstg-code {\n display: inline-block;\n font-size: 11px;\n border: 1px solid #aaa;\n background: #fff;\n padding: 2px 4px;\n margin-bottom: 1px;\n color: #E01E5A;\n}\n\n.wpstg-exclusion-rule-info {\n color: #fff !important;\n background-color: #ffc107;\n border: 1px solid #ffc107;\n width: 14px;\n height: 14px;\n border-radius: 7px;\n font-size: 14px;\n padding: 0;\n display: inline-flex;\n justify-content: center;\n align-items: center;\n outline: none;\n box-shadow: none;\n font-weight: 400;\n vertical-align: middle;\n}\n\n.wpstg-exclusion-rule-info:hover {\n background-color: #ffba0c;\n border: 1px solid #ffba0c;\n}\n\n/**\n * WP STAGING INPUTS EXCLUSION RULES\n */\n\n.wpstg-exclude-rule-input {\n font-size: 12px !important;\n padding: 2px 6px;\n box-shadow: none;\n outline: none !important;\n display: inline-block;\n font-weight: 400;\n line-height: 1.5;\n color: #222;\n border-radius: 0 !important;\n background-color: #fff;\n border: 1px solid #bbb;\n min-height: 24px !important;\n margin-top: 4px;\n margin-left: 4px;\n vertical-align: baseline !important;\n transition: all 0.3s cubic-bezier(.25, .8, .25, 1);\n width: 135px;\n}\n\n.wpstg-excluded-filters-container tbody > tr:last-child .wpstg-exclude-rule-input {\n margin-bottom: 4px;\n}\n\n.wpstg-exclude-rule-input:hover {\n border: 1px solid #999;\n}\n\n.wpstg-exclude-rule-input:focus {\n border: 1px solid #25A0F1 !important;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24) !important;\n}\n\n.wpstg-file-size-exclude-select,\n.wpstg-path-exclude-select {\n width: 135px;\n}\n\n.wpstg-file-size-exclude-select-small {\n width: 52px;\n}\n\n.wpstg-file-size-exclude-input {\n width: 75px;\n}\n\n.wpstg-staging-option-title {\n margin: 15px 0 0;\n}\n\n.wpstg-swal-push-container.swal2-container {\n z-index: 9995;\n}\n\n#wpstg-scanning-files {\n padding-bottom: 5px;\n}\n\n#wpstg-scanning-files.wpstg-tab-section, #wpstg-scanning-db.wpstg-tab-section {\n padding-top: 10px;\n}\n\n.wpstg-reset-excludes-container {\n margin: 10px 0;\n}\n\n.wpstg-swal2-ajax-loader {\n width: 100%;\n height: 150px;\n overflow: hidden;\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n@keyframes wpstg-loading-icon-anim {\n 0% {\n transform: rotate(0);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n\n.wpstg-swal2-ajax-loader > img {\n width: 64px;\n height: 64px;\n animation: wpstg-loading-icon-anim 1s infinite linear;\n -webkit-animation: wpstg-loading-icon-anim 1s infinite linear;\n}\n\n.wpstg-swal2-container .wpstg-tab-section {\n width: auto !important;\n}\n\n#wpstg-no-staging-site-results {\n margin-top: 10px;\n max-width: 375px;\n}\n\nli#wpstg-backup-no-results {\n max-width: 500px;\n}\n\nli#wpstg-backup-no-results div, #wpstg-no-staging-site-results div {\n display: inline-block;\n text-align: center;\n}\n\nli#wpstg-backup-no-results .wpstg--dashicons, #wpstg-no-staging-site-results .wpstg--dashicons {\n filter: invert(50%);\n position: absolute;\n margin-top: 1px;\n}\n\nli#wpstg-backup-no-results .no-backups-found-text, #wpstg-no-staging-site-results .no-staging-site-found-text {\n color: #5d5d5d;\n margin-left: 20px;\n}\n\n@media only screen and (max-width: 680px) {\n li#wpstg-backup-no-results div, #wpstg-no-staging-site-results div {\n width: 100%;\n }\n}\n\n#wpstg--modal--backup--download-inner p.wpstg-download-modal-text {\n font-size: 16px;\n color: #565656;\n}\n\n#wpstg--modal--backup--download-inner h2 {\n color: #565656;\n}\n\n.wpstg-backup-restore-contains-database,\n.wpstg-backup-restore-contains-files {\n display: none;\n}\n\n.wpstg-green-button {\n background: #8bc34a;\n border: 1px solid #78a93f;\n color: white;\n text-shadow: 0 -1px 1px #78a93f, 1px 0 1px #78a93f, 0 1px 1px #40c921, -1px 0 1px #78a93f;\n}\n\n.wpstg-green-button:hover {\n background: #78a93f;\n}\n\n.wpstg-is-dir-loading {\n position: absolute;\n margin-top: -2px;\n margin-left: 8px;\n display: none;\n}\n\n.wpstg-ml-8px {\n margin-left: 8px;\n}\n\n.wpstg-mb-8px {\n margin-bottom: 8px;\n}\n\n\n.wpstg-btn-danger {\n background-color: #E01E5A;\n border: 1px solid #E01E5A;\n color: white;\n text-shadow: none;\n}\n\n.wpstg-btn-danger:hover {\n background: #c0194d;\n box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);\n}\n\n.wpstg-swal2-container.wpstg-swal2-loading > .swal2-modal {\n height: 200px;\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container:not(.wpstg-swal2-loading) > .swal2-modal {\n max-width: 480px;\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container .swal2-header {\n display: none;\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container .swal2-content {\n height: auto;\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container > .swal2-modal > .swal2-content .wpstg-tabs-wrapper {\n overflow-y: auto;\n height: auto !important;\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container > .swal2-modal > .swal2-content {\n font-size: 13px;\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container > .swal2-modal > .swal2-content .wpstg-dir {\n margin-bottom: 4px;\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container > .swal2-modal > .swal2-content .wpstg-subdir {\n margin-top: 4px;\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container.has-collapsible-open .swal2-modal {\n height: calc(100vh - 70px);\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container.has-collapsible-open > .swal2-modal > .swal2-content .wpstg-tabs-wrapper {\n height: calc(100vh - 350px) !important;\n}\n\n.swal2-actions.wpstg--modal--actions > button {\n margin-left: 4px;\n margin-right: 4px;\n text-transform: uppercase;\n text-shadow: initial;\n font-weight: 500;\n min-width: 80px;\n}\n\n.wpstg-swal-popup {\n max-width: 1200px !important;\n}\n\n.wpstg-swal-popup.wpstg-push-finished .swal2-title {\n color: #a8a8a8;\n}\n\n.wpstg-swal-popup.wpstg-push-finished .swal2-content {\n margin-top: 8px;\n color: #a8a8a8;\n}\n\n.wpstg-swal-popup .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step,\n.wpstg-swal-popup .swal2-progress-steps .swal2-progress-step,\n.wpstg-swal-popup .swal2-progress-steps .swal2-progress-step-line {\n background: #25a1f0;\n}\n\n.wpstg-swal-popup .swal2-progress-steps .swal2-progress-step-line {\n width: 2.75em;\n}\n\n.wpstg--dashicons {\n width: 16px;\n height: 16px;\n}\n\n.wpstg--dashicons.wpstg-dashicons-grey {\n filter: invert(20%);\n}\n\n.wpstg--dashicons.wpstg-dashicons-19 {\n width: 19px;\n height: 19px;\n}\n\n.wpstg--dashicons.wpstg-dashicons-21 {\n width: 21px;\n height: 21px;\n}\n\n#wpstg--tab--backup #wpstg-step-1 {\n display: flex;\n align-items: center;\n}\n\n.wpstg-advanced-options .wpstg--tooltip,\n#wpstg--tab--backup #wpstg-step-1 .wpstg--tooltip {\n border-bottom: 0 solid transparent;\n display: inline-flex;\n align-items: center;\n}\n\n#wpstg--tab--backup #wpstg-step-1 .wpstg--tooltip {\n border-bottom: 0 solid transparent;\n display: flex;\n align-items: center;\n}\n\n.wpstg--tooltip .wpstg--tooltiptext-backups::after {\n left: calc(20% + 2px);\n}\n\n.wpstg-listing-single-backup .wpstg--dashicons {\n width: 17px;\n height: 17px;\n}\n\n.wpstg-100-width {\n width: 100px;\n}\n\n.wpstg-caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: 4px solid;\n border-right: 4px solid transparent;\n border-left: 4px solid transparent;\n transition: transform 0.2s;\n cursor: pointer;\n}\n\n.wpstg-caret.wpstg-caret-up {\n transform: rotate(-180deg);\n}\n\n.wpstg-advanced-options-site label {\n font-size: 16px;\n display: block;\n margin: .5em 0;\n}\n\n#wpstg-confirm-backup-restore-data {\n font-size: 18px;\n margin: 0;\n margin-top: 30px;\n}\n\n/* Sweetalert WP STAGING Theme */\n\nbody.toplevel_page_wpstg_backup .swal2-container.swal2-backdrop-show,\nbody.toplevel_page_wpstg_clone .swal2-container.swal2-backdrop-show {\n background: rgba(0, 0, 0, .6);\n z-index: 9995;\n}\n\n.wpstg-swal-popup.swal2-popup {\n border-radius: 8px;\n z-index: 9999;\n padding: 24px;\n color: #565656;\n font-family: Verdana, Geneva, Tahoma, sans-serif;\n}\n\n.wpstg-swal-popup .swal2-title {\n font-size: 22px;\n color: #565656;\n}\n\n.wpstg-swal-popup.swal2-popup:not(.centered-modal) .swal2-title {\n align-self: flex-start; /* For an actual Swal title */\n text-align: left; /* Manually adding this class to a non flex display */\n margin-bottom: 0;\n}\n\n.wpstg-swal-popup .swal2-close {\n top: 8px;\n right: 8px;\n z-index: 5;\n}\n\n.wpstg-swal-popup .swal2-close:focus {\n outline: none;\n}\n\n.wpstg-swal-popup.swal2-popup:not(.centered-modal) .swal2-actions {\n justify-content: flex-end;\n}\n\n.wpstg-swal-popup .swal2-actions > button {\n border-radius: 4px;\n font-weight: 900;\n border: 0;\n font-size: 15px;\n padding: 10px 12px;\n text-transform: capitalize;\n line-height: normal;\n height: 40px;\n min-width: 100px;\n text-shadow: none;\n}\n\n.wpstg-swal-popup.swal2-popup:not(.centered-modal) .swal2-actions > button {\n margin-left: 8px;\n}\n\n.wpstg-swal-popup .swal2-actions > button.swal2-cancel {\n border: 1px solid rgba(29, 28, 29, 0.3);\n background: #fff;\n color: rgb(29, 28, 29);\n font-weight: 500;\n width: 100px;\n text-shadow: none;\n}\n\n.wpstg-swal-popup .swal2-actions > button:hover {\n box-shadow: 0 1px 3px 0 rgba(0 0 0 .1);\n}\n\n.wpstg-swal-popup .swal2-actions > button.swal2-cancel:hover {\n background: rgba(28, 29, 28, .04);\n}\n\n#wpstg-backup-name-input {\n height: 44px;\n font-size: 18px;\n}\n\n.wpstg-restore-finished-container .swal2-title {\n color: #565656 !important;\n}\n\n/*#wpstg-restore-success {\n color: #565656;\n}*/\n\n.wpstg-restore-finished-container .swal2-content {\n margin-top: 20px;\n color: #a8a8a8;\n}\n\n/* WP Staging Implementation of Windows Style Linear Loader */\n\n.wpstg-linear-loader > span[class*=\"wpstg-linear-loader-item\"] {\n height: 6px;\n width: 6px;\n background: #333;\n display: inline-block;\n margin: 12px 2px;\n border-radius: 100%;\n animation: wpstg_linear_loader 3s infinite;\n animation-timing-function: cubic-bezier(0.030, 0.615, 0.995, 0.415);\n animation-fill-mode: both;\n}\n\n.wpstg-linear-loader > span.wpstg-linear-loader-item:nth-child(1) {\n animation-delay: 1s;\n}\n\n.wpstg-linear-loader > span.wpstg-linear-loader-item:nth-child(2) {\n animation-delay: 0.8s;\n}\n\n.wpstg-linear-loader > span.wpstg-linear-loader-item:nth-child(3) {\n animation-delay: 0.6s;\n}\n\n.wpstg-linear-loader > span.wpstg-linear-loader-item:nth-child(4) {\n animation-delay: 0.4s;\n}\n\n.wpstg-linear-loader > span.wpstg-linear-loader-item:nth-child(5) {\n animation-delay: 0.2s;\n}\n\n.wpstg-linear-loader > span.wpstg-linear-loader-item:nth-child(6) {\n animation-delay: 0s;\n}\n\n@keyframes wpstg_linear_loader {\n 0% {\n transform: translateX(-30px);\n opacity: 0;\n }\n 25% {\n opacity: 1;\n }\n 50% {\n transform: translateX(30px);\n opacity: 0;\n }\n 100% {\n opacity: 0;\n }\n}\n\n/* END - Windows Style Linear Loader */\n\n.wpstg--modal--backup--import--upload--content {\n padding: .75em;\n margin: 1em auto;\n}\n\n.wpstg--modal--backup--import--upload--content .wpstg-linear-loader {\n display: none;\n}\n\n#wpstg-multisite-disabled .wpstg-clone {\n width: 355px;\n}\n\n#wpstg-free-version-backups .wpstg-clone {\n text-align: center;\n}\n\n#wpstg-free-version-backups .wpstg-clone p {\n font-size: 16px;\n}\n\n.wpstg-staging-info li .backup-notes {\n word-break: break-word;\n}\n\n.wpstg--modal--import--upload--progress--title small {\n font-weight: normal;\n}\n\n#wpstg-report-issue-wrapper {\n position: relative;\n}\n\n#wpstg-report-issue-wrapper .arrow-up {\n width: 0;\n height: 0;\n border-left: 8px solid transparent;\n border-right: 8px solid transparent;\n border-bottom: 8px solid white;\n position: absolute;\n top: -8px;\n right: 40px;\n}\n\n.notice {\n margin: 10px 20px 0 2px;\n}\n\n.wpstg--notice {\n box-shadow: 0 1px 1px rgba(0, 0, 0, .04);\n margin: 20px 20px 20px 0px;\n padding: 1px 12px;\n}\n\n.wpstg--error a:hover {\n color: #eeeeee;\n}\n\n.wpstg--error, .wpstg--error a {\n background: #E01E5A;\n color: white;\n}\n\n/**\n * Buttons\n */\n\n.wpstg-button {\n display: inline-block;\n border-radius: 2px;\n cursor: pointer;\n padding: 2px 10px 2px 10px;\n text-transform: uppercase;\n font-weight: 500;\n outline: 0;\n transition: background-color .1s ease-in;\n text-decoration: none;\n}\n\n.wpstg-button.wpstg-save {\n background-color: #1687A7;\n color: white;\n}\n\n.wpstg-button.wpstg-save:hover {\n background-color: #276678;\n}\n\n\n.wpstg-button.wpstg-button-light {\n background-color: #f8f8f8;\n border: 1px solid #eee;\n color: #333;\n animation: background-color 0.3s;\n}\n\n.wpstg-button.wpstg-button-light:hover {\n background-color: #e0e0e0;\n border: 1px solid #e0e0e0;\n}\n\n.wpstg-buttons .spinner {\n float: none;\n margin: 0 0 0 5px;\n}\n\n.wpstg-button.danger {\n display: inline-block;\n text-decoration: none;\n text-align: center;\n text-transform: inherit;\n background-color: #E01E5A;\n color: white;\n border-radius: 2px;\n border-color: transparent;\n}\n\n.wpstg-button.danger:hover {\n background-color: #c0194d;\n}\n\n.wpstg-button--big {\n display: inline-block;\n padding: 10px;\n min-width: 170px;\n font-size: 16px;\n text-decoration: none;\n text-align: center;\n margin-top: 20px;\n color: white;\n border-radius: 3px;\n}\n\n.wpstg-button--primary {\n display: inline-block;\n text-decoration: none;\n font-size: 13px;\n line-height: 2.15384615;\n min-height: 30px;\n margin: 0;\n padding: 0 10px;\n cursor: pointer;\n border: 1px solid rgba(29, 28, 29, 0.3);\n -webkit-appearance: none;\n border-radius: 2px;\n white-space: nowrap;\n box-sizing: border-box;\n color: #171717;\n}\n\n.wpstg-button--primary:hover {\n background: rgba(28, 29, 28, .04);\n color: black;\n}\n\n.wpstg-button--secondary {\n display: inline-block;\n background-color: transparent;\n color: #95a5a6;\n border-radius: 2px;\n border: 1px solid rgba(29, 28, 29, 0.3);\n cursor: pointer;\n padding: 4px 10px 2px 10px;\n font-weight: 500;\n outline: 0;\n transition: background-color .1s ease-in;\n text-decoration: none;\n}\n\n.wpstg-button--red {\n background-color: #E01E5A;\n border-color: #E01E5A;\n color: white;\n}\n\n.wpstg-button--red:hover {\n background-color: #d02358;\n border-color: #e0255f;\n color: white;\n}\n\n.wpstg-button--cta-red {\n background-color: #fe008f;\n border-color: #E01E5A;\n color: white;\n}\n\n.wpstg-button--cta-red:hover {\n background-color: #f31391;\n border-color: #e0255f;\n color: white;\n}\n\n.wpstg-button--blue {\n background-color: #25A0F1;\n border-color: #25A0F1;\n color: white;\n}\n\n.wpstg-button--blue:hover {\n background-color: #259be6;\n border-color: #259be6;\n color: white;\n}\n\n#wpstg-button-backup-upgrade {\n font-size: 16px;\n}\n\n.wpstg-staging-status {\n color: #E01E5A;\n}\n\n#wpstg-push-changes,\n#wpstg-start-updating,\n#wpstg-save-clone-data {\n margin-left: 5px;\n}\n\ninput.wpstg-textbox {\n border: 1px solid #aaa;\n border-radius: .25rem;\n padding: 0.25rem 0.5rem;\n font-size: 14px;\n}\n\ninput.wpstg-textbox:focus {\n outline: 0;\n border-color: #259be6;\n -webkit-box-shadow: 0 0 0 0.1rem rgba(221, 221, 221, .35);\n box-shadow: 0 0 0 0.1rem rgba(221, 221, 221, .35);\n}\n\ninput.wpstg-textbox::placeholder {\n color: #888;\n}\n\n.wpstg--advance-settings--checkbox {\n display: flex;\n align-items: center;\n}\n\n.wpstg--advance-settings--checkbox > label {\n font-size: 14px;\n font-weight: bolder;\n width: 165px;\n display: inline-block;\n}\n\n.wpstg--advance-settings--checkbox > .wpstg--tooltip {\n margin-top: 5px;\n margin-left: 5px;\n position: relative;\n display: inline-block;\n border-bottom: 0px solid transparent;\n}\n\n.wpstg--advance-settings--checkbox > .wpstg--tooltip > .wpstg--tooltiptext {\n top: 18px;\n left: -150px;\n}\n\n\ndiv#wpstg-restore-wait {\n display: none;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n text-align: center;\n height: 100vh;\n width: 100vw;\n position: fixed;\n top: 0;\n left: 0;\n background: white;\n z-index: 99999;\n}\n\ndiv#wpstg-restore-wait .wpstg-title {\n font-weight: bold;\n}\n\ndiv#wpstg-restore-wait div {\n font-size: 16px;\n margin-top: 12px;\n}\n\n.resumable-browse {\n cursor: pointer;\n}\n\n.resumable-browse a {\n text-decoration: underline;\n}\n\n.wpstg--modal--backup--import--upload--container.dragover {\n transition: background-color 0.7s;\n background-color: #94dc96;\n color: #FFF;\n}\n\n.wpstg--modal--backup--import--upload--container.dragover * {\n pointer-events: none; /* Avoids flickering when dragging to drop a file */\n}\n\n.wpstg--modal--backup--import--upload--container.dragover .upload-text {\n display: none;\n}\n\n.wpstg--modal--backup--import--upload--container.dragover .dragover-text {\n display: block;\n}\n\n.wpstg--modal--backup--import--upload--container .dragover-text {\n display: none;\n}\n\n#wpstg-invalid-license-message, #wpstg-invalid-license-message a {\n font-weight: 500;\n color: #E01E5A;\n margin-left: 6px;\n}\n\n#wpstg-sidebar--banner {\n max-width: 200px;\n}\n\n@media screen and (max-width: 1234px) {\n .wpstg-h2 {\n font-size: 24px;\n }\n\n #wpstg-welcome li {\n font-size: 14px;\n }\n}\n\n.wpstg-exclamation {\n color: #ffffff;\n border-radius: 100%;\n background-color: #E01E5A;\n width: 20px;\n height: 20px;\n text-align: center;\n font-weight: bold;\n display: inline-block;\n margin: 6px;\n}\n\n.wpstg--tab--contents {\n padding-top: 1px;\n}\n\n.wpstg-swal-show.swal2-show {\n -webkit-animation: wpstg-swal-show 0.2s !important;\n animation: wpstg-swal-show 0.2s !important;\n}\n\n@-webkit-keyframes wpstg-swal-show {\n 0% {\n transform: scale(0.3);\n }\n 100% {\n transform: scale(1);\n }\n}\n\n@keyframes wpstg-swal-show {\n 0% {\n transform: scale(0.3);\n }\n 100% {\n transform: scale(1);\n }\n}\n"]}
assets/css/dist/wpstg-admin.min.css CHANGED
@@ -1,2 +1,2 @@
1
- #wpstg-tab-container ul{background:#f1f1f1;float:left;list-style:none;margin:0;padding:0}#wpstg-tab-container ul li:first-child.selected-tab{border-top:none}#wpstg-tab-container ul li a.selected-tab{font-weight:700;text-decoration:none}#wpstg-tab-container .row{padding-bottom:12px;padding-top:10px}.wpstg-tabs-container .nav-tab-wrapper{padding:0}#wpstg-tab-container .row label strong,#wpstg-tab-container .row strong{font-weight:700}.wpstg-tabs a{padding:5px}#wpstg-tab-container>ul>li.wpstg-tabs.active{background-color:#fff}#wpstg_settingsgeneral_header .row:nth-child(3),#wpstg_settingsgeneral_header .row:nth-child(4){display:none}#wpstg-tab-container .wpstg-settings-panel{overflow:auto;padding:0 20px 20px}#wpstg-tab-container .wpstg-form-table th{color:#484848;font-size:14px;font-weight:700;line-height:1.3;padding:20px 10px 20px 0;text-align:left;vertical-align:top;width:30%}#wpstg-tab-container .wpstg-form-table tr{border-bottom:1px solid #e7e7e7}#wpstg-tab-container span.description{color:#484848;display:block;font-size:13px;font-style:normal;font-weight:400;margin-top:7px}#wpstg-tab-container .col-title{color:#484848}@media only screen and (max-width:680px){#wpstg-tab-container ul{float:none}#wpstg-tab-container .wpstg-form-table tr>th{width:100%}#wpstg-tab-container span.description{font-size:14px}#wpstg-tab-container .wpstg-form-table tr>td,#wpstg-tab-container .wpstg-form-table tr>th{padding:10px}}#wpstg-tab-container ul li{margin-bottom:0}#wpstg-tab-container ul li a{border-bottom:1px solid #e7e7e7;border-left-style:solid;border-left-width:0;border-right-style:solid;border-right-width:0;border-top:1px solid #fff;color:#0097df;display:block;font-weight:700;padding:10px 4px 10px 14px;text-decoration:none}#wpstg-tab-container ul li a:hover{background-color:#e5e5e5;color:#777}.wpstg-logo{display:block;float:left;font-size:16px;padding-top:20px;width:220px}.wpstg-version{display:block;padding-top:29px}.wpstg_admin .nav-tab{color:#3c3c3c}#wpstg-tab-container table tbody tr:first-child>th>div{font-size:20px}.wpstg_hidden{display:none}#wpstg-clonepage-wrapper{margin-bottom:20px}@media screen and (min-width:1090px){#wpstg-clonepage-wrapper{float:left;margin-bottom:20px}.wpstg-sidebar{display:none;margin-left:700px;margin-top:138px}}.wpstg-sidebar{border:1px solid #dfdfdf;display:none;height:250px;max-width:250px;padding:10px}#wpstg-steps{margin-top:30px}#wpstg-steps li{color:#444;float:left;line-height:20px;padding-right:10px}.wpstg-step-num{border:1px solid #444;border-radius:3px;display:inline-block;height:20px;margin-right:5px;text-align:center;width:20px}.wpstg-current-step{font-weight:700}.wpstg-current-step .wpstg-step-num{background:#444;color:#eee}.wpstg-box{margin:10px 0;overflow:hidden;padding:10px}.wpstg-box,.wpstg-clone{position:relative;transition:border-color .2s ease-in-out}.wpstg-clone{background-color:#25a1f0;border-radius:.25rem;box-shadow:0 0 1px rgba(0,0,0,.125),0 1px 3px rgba(0,0,0,.2);margin-bottom:3px;padding:16px}.wpstg-clone.active{border-color:#1d94cf}.wpstg-clone-header{align-items:center;display:flex;justify-content:space-between}.wpstg-clone-title{color:#fff;display:inline-block;font-size:15px;font-weight:700;max-width:300px;text-decoration:none}.wpstg-clone-title:hover{color:#f1f1f1}.wpstg-clone-actions{display:flex}.wpstg-clone-actions .wpstg-dropdown-toggler{background:#fff;border-radius:2px;box-shadow:0 0 1px rgba(0,0,0,.125),0 1px 3px rgba(0,0,0,.2);color:#002648;font-size:14px;padding:4px 10px;text-decoration:none}.wpstg-clone-actions .wpstg-dropdown-toggler:hover{background:#002648;color:#fff}.wpstg-dropdown{position:relative}.wpstg-dropdown-symbol{font-size:14px;margin-left:4px}.wpstg-dropdown>.wpstg-dropdown-menu{background:#fff;border-radius:2px;box-shadow:0 0 1px rgba(0,0,0,.125),0 1px 3px rgba(0,0,0,.2);display:none;flex-direction:column;padding:8px;position:absolute;right:0;top:calc(100% + 4px);width:100px;z-index:1000}.wpstg-dropdown>.wpstg-dropdown-menu.wpstg-menu-dropup{bottom:100%;top:auto;transform:translate3d(0,-3px,0)}.wpstg-dropdown>.wpstg-dropdown-menu.shown{display:flex}.wpstg-clone-action,.wpstg-dropdown-action{border-radius:3px;color:#002648;padding:5px 8px;position:relative;text-decoration:none;transition:color .2s ease-in-out}.wpstg-clone-action:hover,.wpstg-dropdown-action:hover{background:rgba(0,0,0,.05)}.wpstg-dropdown-action{background:transparent;border:0 solid #000;box-shadow:none;color:#333;outline:none}.wpstg-remove-clone:hover{color:#ef6d6d}.wpstg-clone-action:last-child{border:none}.wpstg-clone:hover .wpstg-clone-action{display:inline-block}#wpstg-show-error-details:focus,#wpstg-workflow .wpstg-clone-action{box-shadow:none;outline:none}.wpstg-link-btn{background:#45a1c9;color:#fff;display:inline-block;padding:5px 10px;text-decoration:none;transition:all .2s ease-in-out;vertical-align:baseline}.wpstg-link-btn:focus,.wpstg-link-btn:hover{box-shadow:none;color:#fff;outline:none}#wpstg-workflow .wpstg-link-btn:active{vertical-align:baseline}.wpstg-link-btn[disabled]{background:#777!important;pointer-events:none}#wpstg-cancel-cloning,#wpstg-cancel-cloning-update{background:#ff3428;border-color:#e72f24;margin-top:5px}#wpstg-cancel-cloning.success{background:#64dd58;border-color:#54bd4a}#wpstg-error-details,#wpstg-error-wrapper{clear:both;display:none;font-size:13px;padding-top:10px}#wpstg-show-error-details{color:#555;display:inline-block;margin-left:5px;text-decoration:none;transition:color .2s ease-in-out}#wpstg-show-error-details:hover{color:#1d94cf}#wpstg-error-details{border-left:5px solid #ef6d6d;padding:10px;width:500px}#wpstg-try-again{display:none}#wpstg-home-link{float:right}.wpstg-loader{content:url(../../img/loading.gif);display:none;margin-top:5px}.wpstg-loader.wpstg-finished{background-color:#00c89a;border-radius:3px;color:#fff;content:"Finished";display:block;margin-top:0;padding:2px 10px}#wpstg-workflow{clear:both;float:left;max-width:650px;min-height:380px;min-width:500px;padding-bottom:20px;padding-right:20px;padding-top:20px;position:relative}#wpstg-sidebar{display:block;float:left;margin-left:10px;max-width:400px}@media screen and (max-width:1150px){#wpstg-sidebar img{margin-top:30px}}#wpstg-removing-clone.loading:after,#wpstg-workflow.loading:after{background:hsla(0,0%,100%,.7);content:"Loading... may take a while for huge websites";display:block;font-size:20px;height:100%;left:0;padding-top:100px;position:absolute;text-align:center;top:0;width:100%;z-index:99}#wpstg-removing-clone.loading:after{content:"REMOVING"!important}#wpstg-existing-clones,#wpstg-removing-clone{position:relative}#wpstg-removing-clone .wpstg-tab-section{display:block}.wpstg-progress-bar{background-color:#d6d8d7;height:27px;max-width:900px;padding:0}.wpstg-progress{background:#3fa5ee;float:left;overflow:hidden}.wpstg-progress,.wpstg-progress-files{color:#fff;height:100%;line-height:25px;text-align:center;transition:width .6s ease;width:0}.wpstg-progress-files{background:#16b4f0}#wpstg-clone-path.wpstg-error-input,#wpstg-new-clone-id.wpstg-error-input{border:1px solid #ff4235;box-shadow:0 0 2px rgba(255,66,53,.8)}#wpstg-new-clone{background:#25a1f0;border-color:#2188c9}#wpstg-new-clone:hover{background:#259be6;border-color:#2188c9}#wpstg-clone-path{margin-left:10px;width:350px}.wpstg-error-msg{color:#ff4235}#wpstg-clone-id-error{background-color:#f0f8ff;display:block;margin:20px;padding:10px}#wpstg-start-cloning+.wpstg-error-msg{display:block;margin-top:5px}.wpstg-size-info{color:#999;font-weight:400;left:2px;position:relative}.wpstg-db-table .wpstg-size-info{top:2px}.wpstg-db-table:hover{background-color:#f0f8ff}#wpstg-workflow #wpstg-start-cloning{display:inline-block;font-size:14px;margin-left:5px;vertical-align:baseline}.wpstg-tabs-wrapper{margin:10px 0;max-width:640px}#wpstg-path-wrapper{border-bottom:2px dashed #ccc;margin-bottom:10px;padding-bottom:10px}.wpstg-tab-section{border-bottom:1px solid #ddd;border-left:none;border-right:none;display:none;padding:20px;width:100%}.wpstg-tab-section:after{clear:both;content:"";display:block}.wpstg-tab-header{border-bottom:1px solid #ddd;border-left:none;border-right:none;color:#444;display:block;font-size:16px;font-weight:bolder;padding:10px;text-decoration:none}.wpstg-tab-triangle{animation:transform .5s;display:inline-block;margin-right:10px}.wpstg-tab-header:focus{box-shadow:none;color:#444;outline:none}#wpstg-large-files{border:1px dashed #ccc;display:none;font-size:12px;margin-top:20px;padding:10px;position:relative}#wpstg-large-files h3{background:#fff;left:5px;margin:0;padding:0 5px;position:absolute;top:-10px}.wpstg-subdir{display:none;margin-left:20px}.wpstg-subdir.wpstg-push{display:block;margin-left:20px}.wpstg-dir a.disabled{color:#888;cursor:default;text-decoration:none}.wpstg-check-subdirs{display:inline-block;margin-left:10px}.wpstg-notice-alert{background-color:#ffd0d0;border:1px solid #faa;border-radius:6px;display:block;margin-top:10px;max-width:600px;padding:20px}.wpstg-header{border-bottom:1px solid #dfdfdf;clear:both;font-size:19px;font-weight:400;line-height:1.6em}#wpstg-clone-label{font-size:14px;font-weight:700}.wpstg-log-details{background-color:#000;border:1px solid #fff;color:silver;font-family:monospace;font-size:12px;height:300px;line-height:15px;margin-top:15px;max-width:650px;overflow:scroll;padding:3px;white-space:nowrap}#wpstg-finished-result{display:none}#wpstg-remove-cloning{background:#ff3428;border-color:#e72f24;margin-top:5px}#wpstg-success-notice{background-color:#fff;border:1px solid #ccc;margin-top:20px;max-width:900px;padding:10px}.wpstg_beta_notice{margin-bottom:20px}.wpstg-sysinfo{height:700px;width:700px}.wpstg-form-table .col-title label{font-weight:600}.wpstg-form-table td:first-child{width:30%}.wpstg-share-button-container{margin:5px 0}.wpstg-share-button-container p{margin:0 0 10px}.wpstg-share-button{display:inline-block}.wpstg-share-button a{text-decoration:none}.wpstg-share-button .wpstg-share{-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px;color:#fff;display:inline;font-family:sans-serif;font-size:12px;font-weight:700;padding:4px 8px;text-align:center;text-decoration:none}.wpstg-share-button-twitter .wpstg-share{background-color:#00abf0}.wpstg-share-button-facebook .wpstg-share{background-color:#3b5998}.wpstg-share-button-googleplus .wpstg-share{background-color:#f53424}.wpstg-share-button-facebook .share:active,.wpstg-share-button-googleplus .share:active,.wpstg-share-button-twitter .share:active{background-color:#353535}#wpstg-check-space{margin-left:8px}.wpstg-button.green{background-color:#83c11f;color:#fff;display:inline-block;font-size:16px;margin-top:20px;min-width:170px;padding:10px;text-align:center;text-decoration:none}.wpstg-button.green:hover{background-color:#8ed122}.wpstg-button.wpstg-save{background-color:#1687a7;color:#fff}.wpstg-button.wpstg-save:hover{background-color:#276678}.wpstg-button.wpstg-bordered{border:1px solid #fff;border-radius:3px;font-size:14px}#wpstg-welcome li{font-size:18px;line-height:29px;list-style:none!important;padding-left:23px;position:relative}#wpstg-welcome{background-color:#fff;margin-right:20px;margin-top:20px}.wpstg-heading-pro{color:#0080ff;font-weight:700}.wpstg-h2{font-size:30px;line-height:2.5rem;margin-bottom:1.2rem;margin-top:0}#wpstg-welcome li:before{background:url(data:image/svg+xml;charset=utf8,%3Csvg%20width%3D%221792%22%20height%3D%221792%22%20viewBox%3D%220%200%201792%201792%22%20xmlns%3D%22http%3A%2F%2Fwww%2Ew3%2Eorg%2F2000%2Fsvg%22%3E%3Cpath%20fill%3D%22%2377B227%22%20d%3D%22M1671%20566q0%2040%2D28%2068l%2D724%20724%2D136%20136q%2D28%2028%2D68%2028t%2D68%2D28l%2D136%2D136%2D362%2D362q%2D28%2D28%2D28%2D68t28%2D68l136%2D136q28%2D28%2068%2D28t68%2028l294%20295%20656%2D657q28%2D28%2068%2D28t68%2028l136%20136q28%2028%2028%2068z%22%2F%3E%3C%2Fsvg%3E) left .4em no-repeat;background-size:contain;color:#77b227;content:"";height:100%;left:0;position:absolute;top:0;width:1em}.wpstg-h1{font-size:2.5em;letter-spacing:normal;line-height:3.68rem;margin-bottom:1.35rem}.swal2-content h1{color:#444}#wpstg-welcome h2{margin:0 0 15px}#wpstg-welcome .wpstg-footer{clear:both;font-style:italic;margin-top:20px}#wpstg-footer{background-color:#fff;margin-right:10px;margin-top:20px;padding:20px}#wpstg-footer a{text-decoration:none}.wpstg-staging-info{color:#fff;font-size:12px;margin-top:8px}.wpstg-staging-info a{color:#fff}.wpstg-staging-info li{margin-bottom:2px}.wpstg-bold{font-weight:600}#wpstg-processing-status{float:left;font-size:13px;font-weight:400;margin-top:5px}#wpstg-processing-timer{float:right;font-size:13px;font-weight:400;margin-top:5px}#wpstg-report-issue-button{background-color:#fff;border:1px solid #ef5a4b;color:#ef5a4b;margin-left:50px}#wpstg-report-issue-button:hover{background-color:#e74c3c;color:#fff}.wpstg-button{background-color:transparent;border-radius:3px;color:#95a5a6;cursor:pointer;display:inline-block;font-weight:500;outline:0;padding:2px 10px;text-decoration:none;text-transform:uppercase;transition:background-color .1s ease-in}.wpstg-button.wpstg-button-light{animation:background-color .3s;background-color:#f8f8f8;border:1px solid #eee;color:#333}.wpstg-button.wpstg-button-light:hover{background-color:#e0e0e0;border:1px solid #e0e0e0}.wpstg-blue-primary{-webkit-appearance:none;background:#25a1f0;border:1px solid #2188c9;border-radius:3px;box-sizing:border-box;color:#fff;cursor:pointer;display:inline-block;font-size:13px;height:28px;line-height:26px;margin:0;padding:0 10px 1px;text-decoration:none;text-shadow:0 -1px 1px #006799,1px 0 1px #006799,0 1px 1px #006799,-1px 0 1px #006799;white-space:nowrap}.wpstg-blue-primary:hover{background-color:#259be6}.wpstg-report-issue-form{background-color:#fff;border:1px solid #e8e8e8;border-radius:3px;box-shadow:inset 0 1px 0 0 #fff;display:none;margin:67px 0 0 123px;padding:15px 15px 10px;position:absolute;width:300px;z-index:9999}.wpstg-report-show{display:block}.wpstg-field input[type=text],.wpstg-field textarea{font-weight:400;line-height:1.4;margin-bottom:4px;width:100%}.wpstg-report-email,.wpstg-report-hosting-provider{border-radius:3px;font-size:.8rem;font-weight:400;height:2.3rem;line-height:2.3rem;margin-bottom:4px;padding:0 10px;width:100%}.wpstg-report-description{border-radius:3px;font-size:.8rem;padding:6px 10px;resize:none}.wpstg-report-privacy-policy{font-size:12px;margin-bottom:15px}#wpstg-report-cancel{float:right;margin-right:5px}.wpstg-buttons .spinner{float:none;margin:0 0 0 5px}.wpstg-message{background-color:#f5e0de;border-radius:3px;box-sizing:border-box;-moz-box-sizing:border-box;color:rgba(0,0,0,.6);height:auto;margin:10px 0;min-height:18px;padding:6px 10px;position:relative}.wpstg-message.wpstg-error-message{background-color:#f5e0de;color:#b65147;font-size:12px}.wpstg-message.wpstg-success-message{background-color:#d7f8e0;color:#515151}.wpstg-message p{font-size:13px;margin:3px 0}.wpstg-warning{background-color:#ffb804;color:#fff;display:block;margin:10px 10px 10px 0;padding:10px}.wpstg-warning a{color:#fff;font-weight:700;text-decoration:underline}.wpstg-error{background-color:#fe6501;color:#fff;display:block;margin:10px 10px 10px 0;padding:10px}.wpstg-error a{color:#fff;font-weight:700;text-decoration:underline}#wpstg-resume-cloning{display:none}#wpstg-external-db th{text-align:left;width:120px}#wpstg-db-connect{font-weight:400}#wpstg-db-status{border:1px solid transparent;border-radius:4px;display:block;margin-bottom:20px;margin-top:5px;padding:5px;text-align:center;text-decoration:none}.wpstg-text-field>#wpstg-db-status{margin-left:25%;margin-top:8px;min-width:350px}.wpstg-success{background-color:#dff0d8;border-color:#d6e9c6;color:#3c763d}.wpstg-failed{background-color:#f2dede;border-color:#ebccd1;color:#a94442}#wpstg_select_tables_cloning{font-size:13px;height:600px}#wpstg-update-notify{background-color:#fe6501;color:#fff;font-size:14px;line-height:normal;margin-right:10px;padding:10px}#wpstg-update-notify a{color:#fff;font-weight:700}.wpstg-pointer{cursor:pointer}.wpstg--tab--header ul{display:flex}.wpstg--tab--header ul li{margin-right:1em}.wpstg--tab--header ul li:last-child{margin-right:0}.wpstg--tab--header a{border:1px solid;cursor:pointer;display:inline-block;min-width:150px;padding:1em 1.25em;text-align:center}.wpstg--tab--header a.wpstg--tab--active{border-bottom:.5em solid #25a1f0;color:#25a1f0}.wpstg--tab--content{display:none}.wpstg--tab--active{display:block}.wpstg--text--strong,.wpstg--text--strong *{font-weight:700!important}.wpstg--text--danger{color:#a94442}.wpstg--tooltip{border-bottom:1px dotted #000;display:inline-block;margin-left:10px;position:relative}.wpstg--tooltip .wpstg--tooltiptext{background-color:#fff;border:1px solid #e8e8e8;border-radius:3px;-webkit-box-shadow:-1px 1px 5px 0 rgba(0,0,0,.75);-moz-box-shadow:-1px 1px 5px 0 rgba(0,0,0,.75);box-shadow:-1px 1px 5px 0 rgba(0,0,0,.75);color:#505050;padding:20px;position:absolute;text-align:left;visibility:hidden;width:300px;z-index:1}.wpstg--tooltip:hover .wpstg--tooltiptext{visibility:visible}.wpstg--tooltiptext-backups{left:-150%;margin-left:-60px;margin-top:10px;top:100%;width:120px}.wpstg--tooltip .wpstg--tooltiptext-backups:after{border:5px solid transparent;border-bottom-color:#fff;bottom:100%;content:" ";left:50%;margin-left:25px;position:absolute}.wpstg--snaphot-restore-table tr{line-height:12px}.wpstg-beta-notice{background-color:#b0e8b0;border-radius:3px;margin-bottom:20px;padding:7px}#wpstg-backup-name{font-size:1.875em;font-weight:600}#wpstg_select_tables_cloning option:checked{-webkit-appearance:menulist-button;background-image:linear-gradient(0deg,#1e90ff,#1e90ff)}.wpstg--btn--cancel{color:#fff;font-size:16px;height:auto;line-height:normal;margin-bottom:1.5em;padding:.5em}.wpstg--btn--cancel,.wpstg--btn--cancel:hover{background:#ff3428;border-color:#e72f24}.wpstg--process--content>.swal2-html-container{padding:4em 2em!important}.wpstg--modal--error--logs,.wpstg--modal--process--logs{background:#000;display:none;height:300px;margin-top:1em;overflow-x:auto;padding:1em;text-align:justify}.wpstg--modal--error--logs{height:auto;max-height:300px}.wpstg--modal--error--logs>p,.wpstg--modal--process--logs>p{font-size:14px;text-align:left}.wpstg--modal--error--logs p,.wpstg--modal--process--logs p{margin:.3em 0}.wpstg--modal--process--msg--error{color:#8b0000}.wpstg--modal--process--msg--critical{color:red}.wpstg--modal--process--msg--warning{color:#ff8c00}.wpstg--modal--process--msg-found{color:#f56363}body.toplevel_page_wpstg_clone .swal2-modal .swal2-cancel.wpstg--btn--cancel{margin-bottom:0}body.toplevel_page_wpstg_clone .swal2-modal .swal2-confirm.wpstg--btn--confirm{font-size:16px;height:auto;line-height:normal;margin-right:10px;padding:.5em}body.toplevel_page_wpstg_clone .swal2-modal .wpstg-loader{display:inline-block!important}.wpstg--modal--process--generic-problem{border-left:5px solid #ef6d6d;display:none;margin:.5em 0}.wpstg--modal--process--logs--tail{background:none;border:none;color:#a8a8a8;cursor:pointer}.wpstg--modal--backup--import--upload--title{color:#505050}.wpstg--modal--backup--import--configure,.wpstg--modal--backup--import--filesystem,.wpstg--modal--backup--import--upload--container input[type=file],.wpstg--modal--backup--import--upload--status{display:none}#wpstg--backups--import--file-list{font-size:14px;font-weight:700}#wpstg--backups--import--file-list-empty{color:red}.wpstg--modal--backup--import--filesystem label{font-size:14px}.wpstg--modal--backup--import--filesystem button{margin-bottom:20px}.wpstg--modal--backup--import--filesystem,.wpstg--modal--backup--import--upload{color:#505050}.wpstg--modal--backup--import--upload--container{border:.4em dashed #dedede;border-radius:1em;display:flex;flex-direction:column;margin:.5em;padding:1em .5em;position:relative}.wpstg--modal--backup--import--upload--container .wpstg--uploader{display:flex;flex-direction:column}.wpstg--modal--backup--import--upload--container.wpstg--has-dragover{background-color:#9a9a9a;color:#fff}.wpstg--modal--backup--import--upload--container.wpstg--has-dragover span.wpstg--drag,.wpstg--modal--backup--import--upload--container span.wpstg--drop,span.wpstg--backup--import--selected-file,span.wpstg--drag-or-upload{display:none}.wpstg--modal--backup--import--upload--container.wpstg--has-dragover span.wpstg--drop{display:inline-block}.wpstg--modal--backup--import--upload--container input[type=file]{display:none}.wpstg--modal--backup--import--upload--container img{align-self:center;border:none;width:4em}.wpstg--modal--backup--import--upload--container span{margin-top:1em}.wpstg--backup--import--options>button{align-self:center;height:auto;line-height:normal;margin-top:1em;padding:1em;width:185px}.wpstg--backup--import--options{display:flex;justify-content:center;position:relative}.wpstg--backup--import--options ul{display:none}.wpstg--backup--import--options.wpstg--show-options ul{background:#25a1f0;border-color:#2188c9;border-radius:0 0 3px 3px;border-width:1px;box-sizing:border-box;display:block;margin:54px 0 0;padding:0;position:absolute;text-shadow:0 -1px 1px #006799,1px 0 1px #006799,0 1px 1px #006799,-1px 0 1px #006799;width:185px}.wpstg--backup--import--options.wpstg--show-options ul li{border-bottom:.1em solid #25a1f0;margin:0}.wpstg--backup--import--options.wpstg--show-options ul li:hover{background-color:#25a1f0}.wpstg--backup--import--options.wpstg--show-options ul li:last-child{border-bottom:none}.wpstg--backup--import--options ul li button{background:none;border:none;color:#fff;cursor:pointer;height:40px;line-height:40px;margin:0;width:100%}.wpstg--backup--import--options ul li button:hover{background-color:#259be6}.wpstg--modal--backup--import--search-replace--info{display:flex;flex-direction:row;margin:1em 0}.wpstg--modal--backup--import--info p{margin:0;text-align:left}.wpstg--modal--backup--import--search-replace--wrapper button{align-self:center}.wpstg--import--advanced-options--button{border:0;border-radius:3px;cursor:pointer;font-size:18px;text-shadow:0 -1px 1px #006799,1px 0 1px #006799,0 1px 1px #006799,-1px 0 1px #006799}.wpstg--modal--backup--import--search-replace--new{background-color:#25a1f0;color:#fff}.wpstg--modal--backup--import--search-replace--remove{background-color:#25a1f0;color:#fff;height:22px;margin-left:5px;width:22px}.wpstg--modal--backup--import--search-replace--input-group:first-child button{display:none}.wpstg--modal--backup--import--search-replace--input--container{display:flex;flex:1;flex-direction:column}.wpstg--modal--backup--import--search-replace--input-group{border-bottom:6px solid #f1f1f1;margin-bottom:10px;width:100%}.wpstg--modal--backup--import--search-replace--input-group input{border:1px solid #dedede;border-radius:3px;color:#666;display:inline-block;line-height:10px;margin-bottom:12px;min-width:250px;padding:8px;width:calc(50% - 20px)}.wpstg--modal--import--upload--process{align-items:center;color:#898989;display:none;height:100%;justify-content:center;left:0;mix-blend-mode:difference;overflow:hidden;position:absolute;text-indent:1em;top:0;white-space:nowrap;width:100%}.wpstg--modal--import--upload--progress{background:#dedede;border-radius:1em;color:#fff;height:100%;left:-1px;position:absolute;top:0;width:0}.wpstg--modal--import--upload--progress--title{z-index:9}.wpstg-form-group>.wpstg-checkbox{position:relative}.wpstg-form-group>.wpstg-checkbox>input[type=checkbox]{left:25%}.wpstg-w-100pc{width:100%}#wpstg_allow_emails{margin-left:10px}#wpstg-advanced-settings hr{margin:20px 0}.wpstg-form-row{display:block}.wpstg-form-row input,.wpstg-form-row label{display:table-cell;margin-bottom:3px;margin-top:3px;padding-left:5px;padding-right:5px}.wpstg-form-row input{width:400px}.wpstg-form-row label{font-weight:700;white-space:nowrap;width:1px}#wpstg-db-connect-output #wpstg-db-status{width:390px}#wpstg_symlink_upload{margin-left:10px}.wpstg-fieldset:disabled{border-top:1px solid #fff;margin-top:20px;opacity:.8}.wpstg-fs-14{font-size:14px}.wpstg-light-alert{background-color:#e6e6e6;border-top:1px solid #fff;font-weight:700;margin-top:20px;padding:15px}.wpstg-form-group{display:flex;flex-wrap:wrap;margin-bottom:8px;width:100%}.wpstg-form-group>label{display:inline-block;font-weight:700;min-width:25%;width:25%}.wpstg-text-field>input{display:inline-block;width:350px}.wpstg-code-segment{display:block}.wpstg-text-field>.wpstg-code-segment{margin-left:25%;margin-top:4px;min-width:350px}.wpstg-form-group>.wpstg-checkbox{min-width:100%;width:100%}.wpstg-form-group>.wpstg-checkbox>input[type=checkbox]{margin-left:10px}@media only screen and (max-width:768px){.wpstg-form-group{display:block}.wpstg-form-group>label{display:block;min-width:auto;width:auto}.wpstg-text-field>input{display:block;width:100%}.wpstg-text-field>.wpstg-code-segment{margin-left:0;min-width:100%}.wpstg-tab-section{max-width:calc(100vw - 60px);width:calc(100vw - 60px)}}.wpstg-rounded{border-radius:3px}.wpstg-white-border{border:1px solid #fff!important}.wpstg-m-0{margin:0}.wpstg-mt-16{margin-top:16px}.wpstg-mt-10px,.wpstg-my-10px{margin-top:10px}.wpstg-my-10px{margin-bottom:10px}.wpstg-w-100{width:100%}.wpstg-box-shadow{box-shadow:0 1px 1px 0 rgba(0,0,0,.1)}.wpstg-float-left{float:left}.wpstg-fivestar{background-color:#59a7f7;border-left:none;color:#fff;margin:10px 10px 10px 0;padding:10px}.wpstg-bold-text{font-weight:700}.wpstg-rating-link{color:#fff;font-weight:400}.wpstg-warning.notice{border-left:4px solid #ffba00}.wpstg-confirmation-label{background-color:#5b9dd9;border-radius:3px;color:#fff;padding:2px}.wpstg-my-6px{margin-bottom:6px;margin-top:6px}.wpstg-mb-10px{margin-bottom:10px}.wpstg-opacity-80{opacity:.8}.wpstg-clear-both{clear:both}.wpstg-fs-10px{font-size:10px}.wpstg-font-italic{font-style:italic}.wpstg-mt-20px{margin-top:20px}.wpstg-welcome-container{border:2px solid #fff;margin-bottom:20px;padding:20px}.wpstg-ml-30px{margin-left:30px}.wpstg-text-center{text-align:center}.wpstg-feedback-link{color:#abc116;text-decoration:none}.wpstg-feedback-span{color:#abc116;display:block;margin-bottom:20px}#wpstg-confirm-backup-restore-data{margin:40px;text-align:left}#wpstg-confirm-backup-restore-wrapper{margin:30px}#wpstg-confirm-backup-restore-wrapper h3{color:#f56363}#wpstg-footer{clear:both;padding-top:20px}#swal2-content h2{color:#a8a8a8}#wpstg-progress-backup,#wpstg-progress-db{background-color:#3fa5ee}#wpstg-progress-files.wpstg-pro,#wpstg-progress-sr{background-color:#3c9ee4}#wpstg-progress-data,#wpstg-progress-dirs{background-color:#3a96d7}#wpstg-progress-files:not(.wpstg-pro),#wpstg-progress-finishing{background-color:#378cc9}.wpstg-issue-resubmit-confirmation.swal2-container,.wpstg-swal2-container.swal2-container{z-index:10500}.wpstg-swal2-container.wpstg-swal2-loading .swal2-actions,.wpstg-swal2-container.wpstg-swal2-loading .swal2-header{display:none}body.toplevel_page_wpstg_clone .swal2-container .swal2-content{z-index:2}div#exportUploadsWithoutDatabaseWarning{background-color:#fafafa;border:1px solid #e3e3e3;border-radius:5px;font-size:.9rem;font-style:italic;margin:10px;padding:10px;text-align:center}.wpstg-advanced-options-dropdown-wrapper{display:none;margin-top:20px}.wpstg--modal--backup--import--search-replace--wrapper{margin-top:20px;text-align:left}.wpstg--modal--backup--import--search-replace--new--wrapper{text-align:center}.wpstg-import-backup-contains li{display:inline-block}.wpstg-import-backup-contains li .dashicons{background-color:#e3e3e3;border:1px solid #c2c2c2;border-radius:3px;color:#979797;font-size:17px;height:17px;width:17px}.wpstg-import-backup-contains.wpstg-listing-single-backup li .dashicons{background-color:#2896dd;border:1px solid #0c75b8;color:#fff;padding:2px}.wpstg-import-backup-contains .wpstg--tooltiptext{font-size:x-small;left:-25px;padding:5px;text-align:center;width:50px}.wpstg-import-backup-contains-title,ul.wpstg-import-backup-contains{display:inline-block}.wpstg-import-backup-name{display:inline-block;font-weight:700}.wpstg-backup-more-info-toggle{cursor:pointer;display:inline-block;font-size:x-small;font-style:italic}.wpstg-backup-more-info-toggle::selection{background:none}ul.wpstg-import-backup-more-info{background-color:#f6f6f6;border:1px solid #878787;border-radius:3px;cursor:pointer;font-size:14px;margin-bottom:30px;margin-top:10px;padding:7px;text-align:left}ul.wpstg-import-backup-more-info:hover{background-color:#def2ff;border:1px solid #25a1f0}ul.wpstg-import-backup-more-info li{height:20px}.wpstg-backup-list ul ul{margin-block-end:1em;margin-block-start:1em}.wpstg-push-confirmation-message{text-align:justify}.wpstg-settings-row{padding-bottom:10px;padding-top:10px}.wpstg-settings-title{font-weight:600}.wpstg-settings-form-group{align-items:center;display:flex}.wpstg-settings-form-group>.wpstg-settings-message{margin:7px 0 0;padding:0;width:30%}.wpstg-excluded-filters-container{margin-bottom:10px;margin-top:10px;max-width:100%;padding:0;width:100%}.wpstg-excluded-filters-container>table{border-collapse:collapse;border-color:transparent;width:100%}.wpstg-excluded-filters-container td{height:20px;padding-bottom:4px;padding-top:4px}.wpstg-excluded-filters-container h4{margin:0}.wpstg-exclude-filters-foot{display:flex;justify-content:flex-start;padding:0}.wpstg-excluded-filters-container .wpstg-exclude-filter-name-column{max-width:100px!important;padding-left:10px;width:100px}.wpstg-excluded-filters-container .wpstg-exclude-filter-action-column{max-width:50px;padding-right:10px;text-align:right!important;width:50px}.wpstg-excluded-filters-container .wpstg-exclude-filter-exclusion-column{position:relative;width:320px}.wpstg-exclude-filter-dropdown>button{background:#25a0f1;border:1px solid #25a0f1;border-radius:0;box-shadow:none;color:#fff;cursor:pointer;display:inline-block;font-weight:400;height:24px;line-height:1.5;outline:none;padding:1px 5px;text-align:center}.wpstg-exclude-filter-dropdown>button:hover{background:#135e96;border:1px solid #135e96}.wpstg-exclude-filter-dropdown>.wpstg-dropdown-menu{width:128px}.wpstg-remove-exclude-rule{background-color:#dc3545;border:1px solid #dc3545;border-radius:10px;box-shadow:none;color:#fff!important;cursor:pointer;display:inline-flex;font-size:24px;font-weight:400;height:20px;justify-content:center;line-height:.7;margin-top:5px;outline:none;padding:0;width:20px}.wpstg-remove-exclude-rule:hover{background-color:#bb2d3b;border-color:#bb2d3b}.wpstg-popover{display:inline-block;position:relative}.wpstg-popover button+p{box-shadow:0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24);display:none;padding:10px!important;position:absolute;right:-150px;top:18px;width:320px;z-index:1024}.wpstg-popover button:hover+p{display:block}.wpstg-code-block{background:#f8f8f8;border-radius:2px;font-size:1.2em;margin-top:4px}.wpstg-rule-info{background:#f8f8f8!important}code.wpstg-code{background:#fff;border:1px solid #aaa;color:#f66;display:inline-block;font-size:11px;margin-bottom:1px;padding:2px 4px}.wpstg-exclusion-rule-info{align-items:center;background-color:#ffc107;border:1px solid #ffc107;border-radius:7px;box-shadow:none;color:#fff!important;display:inline-flex;font-size:14px;font-weight:400;height:14px;justify-content:center;outline:none;padding:0;vertical-align:middle;width:14px}.wpstg-exclusion-rule-info:hover{background-color:#ffba0c;border:1px solid #ffba0c}.wpstg-exclude-rule-input{background-color:#fff;border:1px solid #bbb;border-radius:0!important;box-shadow:none;color:#222;display:inline-block;font-size:12px!important;font-weight:400;line-height:1.5;margin-left:4px;margin-top:4px;min-height:24px!important;outline:none!important;padding:2px 6px;transition:all .3s cubic-bezier(.25,.8,.25,1);vertical-align:baseline!important;width:135px}.wpstg-excluded-filters-container tbody>tr:last-child .wpstg-exclude-rule-input{margin-bottom:4px}.wpstg-exclude-rule-input:hover{border:1px solid #999}.wpstg-exclude-rule-input:focus{border:1px solid #25a0f1!important;box-shadow:0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24)!important}.wpstg-file-size-exclude-select,.wpstg-path-exclude-select{width:135px}.wpstg-file-size-exclude-select-small{width:52px}.wpstg-file-size-exclude-input{width:75px}.wpstg-staging-option-title{margin:15px 0 0}.wpstg-swal-push-container.swal2-container{z-index:9995}#wpstg-scanning-files{padding-bottom:5px}#wpstg-scanning-files.wpstg-tab-section{padding-top:0}.wpstg-reset-excludes-container{margin:10px 0}.wpstg-swal2-ajax-loader{align-items:center;display:flex;height:150px;justify-content:center;overflow:hidden;width:100%}@keyframes wpstg-loading-icon-anim{0%{transform:rotate(0)}to{transform:rotate(1turn)}}.wpstg-swal2-ajax-loader>img{animation:wpstg-loading-icon-anim 1s linear infinite;-webkit-animation:wpstg-loading-icon-anim 1s linear infinite;height:64px;width:64px}.wpstg-swal2-container .wpstg-tab-section{width:auto!important}.wpstg-is-dir-loading{display:none;margin-left:8px;margin-top:-2px;position:absolute}.wpstg-ml-8px{margin-left:8px}.wpstg-mb-8px{margin-bottom:8px}.wpstg-button.danger{background-color:#e74c3c;border-color:transparent;border-radius:0;color:#fff;display:inline-block;text-align:center;text-decoration:none;text-transform:inherit}.wpstg-button.danger:hover{background-color:#c0392b}.wpstg-swal2-container.wpstg-swal2-loading>.swal2-modal{height:200px}.wpstg-reset-confirmation.wpstg-swal2-container:not(.wpstg-swal2-loading)>.swal2-modal{max-width:480px}.wpstg-reset-confirmation.wpstg-swal2-container .swal2-header{display:none}.wpstg-reset-confirmation.wpstg-swal2-container .swal2-content{height:auto}.wpstg-reset-confirmation.wpstg-swal2-container>.swal2-modal>.swal2-content .wpstg-tabs-wrapper{height:auto!important;overflow-y:auto}.wpstg-reset-confirmation.wpstg-swal2-container>.swal2-modal>.swal2-content{font-size:13px}.wpstg-reset-confirmation.wpstg-swal2-container>.swal2-modal>.swal2-content .wpstg-dir{margin-bottom:4px}.wpstg-reset-confirmation.wpstg-swal2-container>.swal2-modal>.swal2-content .wpstg-subdir{margin-top:4px}.wpstg-reset-confirmation.wpstg-swal2-container.has-collapsible-open .swal2-modal{height:calc(100vh - 70px)}.wpstg-reset-confirmation.wpstg-swal2-container.has-collapsible-open>.swal2-modal>.swal2-content .wpstg-tabs-wrapper{height:calc(100vh - 350px)!important}
2
  /*# sourceMappingURL=wpstg-admin.min.css.map */
1
+ .wpstg--violet{color:#9d37ae}.wpstg-border--violet{border:1px solid #9d37ae}.wpstg--red{color:#e01e5a}.wpstg-cta--red{color:#fe008f}.wpstg--blue{color:#24a1f0}.wpstg--darkblue{color:#0e86d9}.wpstg--green{color:#83c11f}.wpstg--grey{color:#3e3e3e}.wpstg--darkgrey{color:#1b1b1b}#wpstg-tab-container ul{background:#f1f1f1;float:left;list-style:none;margin:0;padding:0}#wpstg-tab-container ul li:first-child.selected-tab{border-top:none}#wpstg-tab-container ul li a.selected-tab{font-weight:700;text-decoration:none}#wpstg-tab-container .row{padding-bottom:12px;padding-top:10px}.wpstg-tabs-container .nav-tab-wrapper{padding:0}#wpstg-tab-container .row label strong,#wpstg-tab-container .row strong{font-weight:700}.wpstg-tabs a{padding:5px}#wpstg-tab-container>ul>li.wpstg-tabs.active{background-color:#fff}#wpstg_settingsgeneral_header .row:nth-child(3),#wpstg_settingsgeneral_header .row:nth-child(4){display:none}#wpstg-tab-container .wpstg-settings-panel{overflow:auto;padding:0 20px 20px}#wpstg-tab-container .wpstg-form-table th{color:#484848;font-size:14px;font-weight:700;line-height:1.3;padding:20px 10px 20px 0;text-align:left;vertical-align:top;width:30%}#wpstg-tab-container .wpstg-form-table tr{border-bottom:1px solid #e7e7e7}#wpstg-tab-container span.description{color:#484848;display:block;font-size:13px;font-style:normal;font-weight:400;margin-top:7px}#wpstg-tab-container .col-title{color:#484848}@media only screen and (max-width:680px){#wpstg-tab-container ul{float:none}#wpstg-tab-container .wpstg-form-table tr>th{width:100%}#wpstg-tab-container span.description{font-size:14px}#wpstg-tab-container .wpstg-form-table tr>td,#wpstg-tab-container .wpstg-form-table tr>th{padding:10px}}#wpstg-tab-container ul li{margin-bottom:0}#wpstg-tab-container ul li a{border-bottom:1px solid #e7e7e7;border-left-style:solid;border-left-width:0;border-right-style:solid;border-right-width:0;border-top:1px solid #fff;color:#0097df;display:block;font-weight:700;padding:10px 4px 10px 14px;text-decoration:none}#wpstg-tab-container ul li a:hover{background-color:#e5e5e5;color:#777}.wpstg-logo{display:block;float:left;font-size:16px;padding-top:20px;width:220px}.wpstg-logo img{max-width:212px}.wpstg-version{color:#9b9b9b;display:block;padding-top:34px}.wpstg_admin .nav-tab{color:#3c3c3c}#wpstg-tab-container table tbody tr:first-child>th>div{font-size:20px}#wpstg-clonepage-wrapper{margin-bottom:20px;width:98%}@media screen and (min-width:1090px){#wpstg-clonepage-wrapper{float:left;margin-bottom:20px}}#wpstg-steps{margin-left:20px;margin-top:0}#wpstg-steps li{color:#444;float:left;line-height:20px;padding-right:10px}.wpstg-step-num{border:1px solid #3e3e3e;border-radius:3px;display:inline-block;height:20px;margin-right:5px;text-align:center;width:20px}.wpstg-current-step{font-weight:700}.wpstg-current-step .wpstg-step-num{background:#3e3e3e;color:#eee}.wpstg-box{margin:10px 0;overflow:hidden;padding:10px}.wpstg-box,.wpstg-clone{position:relative;transition:border-color .2s ease-in-out}.wpstg-clone{background-color:#fff;border-radius:3px;box-shadow:0 0 1px rgba(0,0,0,.125),0 1px 3px rgba(0,0,0,.1);color:#3e3e3e;margin-bottom:10px;padding:16px}.wpstg-clone.active{border-color:#1d94cf}.wpstg-clone-header{align-items:center;display:flex;justify-content:space-between}.wpstg-clone-title{color:#3e3e3e;display:inline-block;font-size:15px;font-weight:700;max-width:300px;text-decoration:none}.wpstg-clone-title:hover{color:#111}.wpstg-clone-actions{display:flex;margin-top:5px}.wpstg-clone-actions .wpstg-dropdown-toggler{background:#25a1f0;border-radius:2px;box-shadow:0 0 1px rgba(0,0,0,.125),0 1px 3px rgba(0,0,0,.2);color:#fff;font-size:14px;padding:6px 10px;text-decoration:none}.wpstg-clone-actions .wpstg-dropdown-toggler:hover{background:#002648;color:#fff}.wpstg-dropdown{position:relative}.wpstg-dropdown>.wpstg-dropdown-menu{background:#fff;border-radius:2px;box-shadow:0 0 1px rgba(0,0,0,.125),0 1px 3px rgba(0,0,0,.2);display:none;flex-direction:column;padding:8px;position:absolute;right:0;top:calc(100% + 4px);width:100px;z-index:1000}.wpstg-dropdown>.wpstg-dropdown-menu.wpstg-menu-dropup{bottom:100%;top:auto;transform:translate3d(0,-3px,0)}.wpstg-dropdown>.wpstg-dropdown-menu.shown{display:flex}.wpstg-clone-action,.wpstg-dropdown-action{border-bottom:1px solid #f3f3f3;border-radius:3px;color:#3e3e3e;padding:6px 8px;position:relative;text-decoration:none;transition:color .2s ease-in-out}.wpstg-clone-action:hover,.wpstg-dropdown-action:hover{background:rgba(0,0,0,.05)}.wpstg-dropdown-action{background:transparent;border:0 solid #000;box-shadow:none;color:#3e3e3e;outline:none}.wpstg-remove-clone:hover{color:#e01e5a}.wpstg-clone-action:last-child{border:none}.wpstg-clone:hover .wpstg-clone-action{display:inline-block}#wpstg-show-error-details:focus,#wpstg-workflow .wpstg-clone-action{box-shadow:none;outline:none}.wpstg-link-btn{background:#45a1c9;color:#fff;display:inline-block;padding:5px 10px;text-decoration:none;transition:all .2s ease-in-out;vertical-align:baseline}.wpstg-link-btn:focus,.wpstg-link-btn:hover{box-shadow:none;color:#fff;outline:none}#wpstg-workflow .wpstg-link-btn:active{vertical-align:baseline}.wpstg-link-btn[disabled]{background:#777!important;border-color:#555!important;pointer-events:none}#wpstg-cancel-cloning,#wpstg-cancel-cloning-update{margin-top:5px}#wpstg-cancel-cloning.success{background:#64dd58;border-color:#54bd4a}#wpstg-error-details,#wpstg-error-wrapper{clear:both;display:none;font-size:13px;padding-top:10px}#wpstg-show-error-details{color:#555;display:inline-block;margin-left:5px;text-decoration:none;transition:color .2s ease-in-out}#wpstg-show-error-details:hover{color:#1d94cf}#wpstg-error-details{border-left:5px solid #e01e5a;padding:10px;width:500px}#wpstg-try-again{display:none}#wpstg-home-link{float:right}.wpstg-loader{content:url(../../img/loading.gif);display:none;margin-top:10px}.wpstg-loader.wpstg-finished{background-color:#00c89a;border-radius:3px;color:#fff;content:"Finished";display:block;margin-top:0;padding:2px 10px}#wpstg-workflow{clear:both;float:left;max-width:800px;min-height:380px;min-width:500px;padding-bottom:20px;padding-right:20px;padding-top:20px;position:relative}#wpstg-sidebar{display:block;float:left;margin-left:10px;max-width:400px}#wpstg-removing-clone.loading:after,#wpstg-workflow.loading:after{background:hsla(0,0%,100%,.7);content:"Loading... may take a while for huge websites";display:block;font-size:20px;height:100%;left:0;padding-top:100px;position:absolute;text-align:center;top:0;width:100%;z-index:99}#wpstg-removing-clone.loading:after{content:"REMOVING"!important}#wpstg-existing-clones,#wpstg-removing-clone{position:relative}#wpstg-existing-clones h3{color:#3e3e3e}#wpstg-removing-clone .wpstg-tab-section{display:block}.wpstg-progress-bar{background-color:#d6d8d7;height:27px;max-width:900px;padding:0}.wpstg-progress{background:#3fa5ee;float:left;overflow:hidden}.wpstg-progress,.wpstg-progress-files{color:#fff;height:100%;line-height:25px;text-align:center;transition:width .6s ease;width:0}.wpstg-progress-files{background:#16b4f0}#wpstg-clone-path.wpstg-error-input,#wpstg-new-clone-id.wpstg-error-input{border:1px solid #e01e5a;box-shadow:0 0 2px rgba(255,66,53,.8)}#wpstg-new-clone-id{margin-left:15px;max-width:100%;width:450px}#wpstg-new-clone{background:#25a1f0;border-color:#2188c9}#wpstg-new-clone:hover{background:#259be6;border-color:#2188c9}#wpstg-clone-path{margin-left:10px;width:350px}.wpstg-error-msg{color:#e01e5a}#wpstg-clone-id-error{background-color:#f0f8ff;display:block;margin:20px;padding:10px}#wpstg-start-cloning+.wpstg-error-msg{display:block;margin-top:5px}.wpstg-size-info{color:#999;font-weight:400;left:2px;position:relative}.wpstg-db-table .wpstg-size-info{top:2px}.wpstg-db-table:hover{background-color:#f0f8ff}#wpstg-workflow #wpstg-start-cloning{margin-left:5px;vertical-align:baseline}.wpstg-tabs-wrapper{margin:10px 0;max-width:640px}#wpstg-path-wrapper{border-bottom:2px dashed #ccc;margin-bottom:10px;padding-bottom:10px}.wpstg-tab-section{border-bottom:1px solid #ddd;border-left:none;border-right:none;display:none;padding:0 36px;width:calc(100% - 72px)}.wpstg-tab-section:after{clear:both;content:"";display:block}.wpstg-tab-header{border-bottom:1px solid #ddd;border-left:none;border-right:none;color:#444;display:block;font-size:16px;font-weight:700;padding:10px;text-decoration:none}.wpstg-tab-triangle{animation:transform .5s;display:inline-block;margin-right:10px}.wpstg-tab-header:focus{box-shadow:none;color:#444;outline:none}#wpstg-large-files{border:1px dashed #ccc;display:none;font-size:12px;margin-top:20px;padding:10px;position:relative}#wpstg-large-files h3{background:#fff;left:5px;margin:0;padding:0 5px;position:absolute;top:-10px}.wpstg-subdir{display:none;margin-left:20px}.wpstg-subdir.wpstg-push{display:block;margin-left:20px}.wpstg-dir a.disabled{color:#888;cursor:default;text-decoration:none}.wpstg-check-subdirs{display:inline-block;margin-left:10px}.wpstg-notice-alert{background-color:#e01e5a;color:#fff}.wpstg-notice--white,.wpstg-notice-alert{display:block;margin-top:10px;max-width:600px;padding:20px}.wpstg-notice--white{background-color:#fff}.wpstg-notice-alert a,.wpstg-notice-alert h3{color:#fff}.wpstg-header{border-bottom:1px solid #dfdfdf;clear:both;font-size:19px;font-weight:400;line-height:1.6em;padding-top:10px}#wpstg-clone-label{font-size:14px;font-weight:700}.wpstg-log-details{background-color:#000;border:1px solid #fff;color:silver;font-family:monospace;font-size:12px;height:300px;line-height:15px;margin-top:15px;max-width:650px;overflow:scroll;padding:3px;white-space:nowrap}#wpstg-finished-result{display:none}#wpstg-remove-cloning{background:#ff3428;border-color:#e72f24;margin-top:5px}#wpstg-success-notice{background-color:#fff;border:1px solid #ccc;margin-top:20px;max-width:900px;padding:10px}.wpstg_beta_notice{margin-bottom:20px}.wpstg-sysinfo{height:700px;width:700px}.wpstg-form-table .col-title label{font-weight:600}.wpstg-form-table td:first-child{width:30%}.wpstg-share-button-container{margin:5px 0}.wpstg-share-button-container p{margin:0 0 10px}.wpstg-share-button{display:inline-block}.wpstg-share-button a{text-decoration:none}.wpstg-share-button .wpstg-share{-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px;color:#fff;display:inline;font-family:sans-serif;font-size:12px;font-weight:700;padding:4px 8px;text-align:center;text-decoration:none}.wpstg-share-button-twitter .wpstg-share{background-color:#00abf0}.wpstg-share-button-facebook .wpstg-share{background-color:#3b5998}.wpstg-share-button-googleplus .wpstg-share{background-color:#f53424}.wpstg-share-button-facebook .share:active,.wpstg-share-button-googleplus .share:active,.wpstg-share-button-twitter .share:active{background-color:#353535}#wpstg-check-space{margin-left:8px}#wpstg-welcome li{font-size:18px;line-height:29px;list-style:none!important;padding-left:23px;position:relative}#wpstg-welcome{background-color:#fff;margin-right:20px;margin-top:20px}.wpstg-heading-pro{font-weight:700}.wpstg-h2{font-size:30px;line-height:2.5rem;margin-bottom:1.2rem;margin-top:0}#wpstg-welcome li:before{background:url(data:image/svg+xml;charset=utf8,%3Csvg%20width%3D%221792%22%20height%3D%221792%22%20viewBox%3D%220%200%201792%201792%22%20xmlns%3D%22http%3A%2F%2Fwww%2Ew3%2Eorg%2F2000%2Fsvg%22%3E%3Cpath%20fill%3D%22%2377B227%22%20d%3D%22M1671%20566q0%2040%2D28%2068l%2D724%20724%2D136%20136q%2D28%2028%2D68%2028t%2D68%2D28l%2D136%2D136%2D362%2D362q%2D28%2D28%2D28%2D68t28%2D68l136%2D136q28%2D28%2068%2D28t68%2028l294%20295%20656%2D657q28%2D28%2068%2D28t68%2028l136%20136q28%2028%2028%2068z%22%2F%3E%3C%2Fsvg%3E) left .4em no-repeat;background-size:contain;color:#77b227;content:"";height:100%;left:0;position:absolute;top:-2px;width:1em}.wpstg-h1{font-size:2.5em;letter-spacing:normal;line-height:3.68rem;margin-bottom:1.35rem}.swal2-content h1{color:#444}#wpstg-welcome h2{margin:0 0 15px}#wpstg-welcome .wpstg-footer{clear:both;font-style:italic;margin-top:20px}#wpstg-footer{clear:both;margin-right:10px;margin-top:20px;padding-top:50px}#wpstg-footer a{text-decoration:none}#wpstg-footer li{list-style:circle;margin-bottom:2px}#wpstg-footer ul{margin-left:15px;margin-top:0}.wpstg-footer--title{margin-left:15px}.wpstg-staging-info{color:#3e3e3e;font-size:12px;margin-top:8px}.wpstg-staging-info a{color:#3e3e3e}.wpstg-staging-info li{margin-bottom:2px}.wpstg-bold{font-weight:600}#wpstg-processing-status{float:left;font-size:13px;font-weight:400;margin-top:5px}#wpstg-processing-timer{float:right;font-size:13px;font-weight:400;margin-top:5px}#wpstg-report-issue-button{background-color:#fff;border:1px solid #e01e5a;color:#e01e5a;margin-left:50px}#wpstg-report-issue-button:hover{background-color:#dc2b62;color:#fff}.wpstg-blue-primary{-webkit-appearance:none;background:#25a1f0;border:1px solid #2188c9;border-radius:3px;box-sizing:border-box;color:#fff;cursor:pointer;display:inline-block;font-size:13px;height:28px;margin:0;padding:0 10px 1px;text-decoration:none;text-shadow:0 -1px 1px #006799,1px 0 1px #006799,0 1px 1px #006799,-1px 0 1px #006799;white-space:nowrap}.wpstg-blue-primary:hover{background-color:#259be6}.wpstg-report-issue-form{background-color:#fff;border:1px solid #e8e8e8;border-radius:3px;box-shadow:inset 0 1px 0 0 #fff;display:none;padding:15px 15px 10px;position:absolute;right:0;top:35px;width:300px;z-index:999}@media (max-width:600px){.wpstg-report-issue-form{position:relative}}.wpstg-report-show{display:block}.wpstg-field input[type=text],.wpstg-field textarea{font-weight:400;line-height:1.4;margin-bottom:4px;width:100%}.wpstg-report-email,.wpstg-report-hosting-provider{border-radius:3px;font-size:.8rem;font-weight:400;height:2.3rem;line-height:2.3rem;margin-bottom:4px;padding:0 10px;width:100%}.wpstg-report-description{border-radius:3px;font-size:.8rem;padding:6px 10px;resize:none}.wpstg-report-privacy-policy{font-size:12px;margin-bottom:15px}#wpstg-report-cancel{float:right;font-weight:700;margin-right:5px}#wpstg-success-button{font-weight:700}.wpstg-message{background-color:#f5e0de;border-radius:3px;box-sizing:border-box;-moz-box-sizing:border-box;color:rgba(0,0,0,.6);height:auto;margin:10px 0;min-height:18px;padding:6px 10px;position:relative}.wpstg-message.wpstg-error-message{background-color:#f5e0de;color:#b65147;font-size:12px}.wpstg-message.wpstg-success-message{background-color:#d7f8e0;color:#515151}.wpstg-message p{font-size:13px;margin:3px 0}.wpstg-warning{background-color:#ffb804;color:#fff;display:block;margin:10px 10px 10px 0;padding:10px}.wpstg-warning a{color:#fff;font-weight:700;text-decoration:underline}.wpstg-error{background-color:#e01e5a!important;border-color:transparent!important;box-shadow:none!important;color:#fff;display:block;margin:10px 10px 10px 0!important;padding:10px!important}.wpstg-error a{color:#fff;font-weight:700;text-decoration:underline}#wpstg-resume-cloning{display:none}#wpstg-external-db th{text-align:left;width:120px}#wpstg-db-connect{font-weight:400}#wpstg-db-status{border:1px solid transparent;border-radius:4px;display:block;margin-bottom:20px;margin-top:5px;padding:5px;text-align:center;text-decoration:none}.wpstg-text-field>#wpstg-db-status{margin-left:150px;margin-top:8px;min-width:300px}.wpstg-success{background-color:#dff0d8;border-color:#d6e9c6;color:#3c763d}.wpstg-failed{background-color:#f2dede;border-color:#ebccd1;color:#a94442}#wpstg_select_tables_cloning{font-size:13px;height:600px}#wpstg-update-notify{background-color:#e01e5a;color:#fff;font-size:14px;line-height:normal;padding:10px}#wpstg-update-notify a{color:#fff;font-weight:700}.wpstg-pointer{cursor:pointer}.wpstg--tab--header{background-color:#fff;border-radius:2px;box-shadow:0 0 1px rgba(0,0,0,.125),0 1px 3px rgba(0,0,0,.02);color:#3e3e3e;position:relative;transition:border-color .2s ease-in-out}.wpstg--tab--header ul{display:flex}.wpstg--tab--header ul li{margin-bottom:0;margin-right:1em}.wpstg--tab--header ul li:last-child{margin-right:0}.wpstg--tab--header a{color:#c4c4c4;cursor:pointer;display:inline-block;font-size:18px;min-width:150px;padding:1em 1.25em 9px;text-align:center}.wpstg--tab--header a.wpstg--tab--active,.wpstg--tab--header a:hover{border-bottom:.4em solid #25a1f0;color:#25a1f0}.wpstg--tab--header a:hover{background-color:#fefefe}.wpstg--tab--content{display:none}.wpstg--tab--active{display:block}.wpstg--text--strong,.wpstg--text--strong *{font-weight:700!important}.wpstg--text--danger{color:#a94442}.wpstg--tooltip{border-bottom:1px dotted #000;display:inline-block;margin-left:10px;position:relative}.wpstg--tooltip .wpstg--tooltiptext{background-color:#fff;border-radius:3px;-webkit-box-shadow:0 3px 6px rgba(0,0,0,.16),0 3px 6px rgba(0,0,0,.23);-moz-box-shadow:0 3px 6px rgba(0,0,0,.16),0 3px 6px rgba(0,0,0,.23);box-shadow:0 3px 6px rgba(0,0,0,.16),0 3px 6px rgba(0,0,0,.23);color:#505050;padding:12px;position:absolute;text-align:left;visibility:hidden;width:300px;z-index:1}.wpstg--tooltiptext-backups{left:-150%;margin-left:-56px;margin-top:4px;top:100%;width:120px}.wpstg--tooltip.wpstg--exclude-rules--tooltip{border-bottom:0 solid transparent}.wpstg--tooltip.wpstg--exclude-rules--tooltip>.wpstg--tooltiptext{margin-left:-150px;margin-top:0}.wpstg--tooltip .wpstg--tooltiptext-backups:after{border:5px solid transparent;border-bottom-color:#fff;bottom:100%;content:" ";left:50%;margin-left:25px;position:absolute}.wpstg--tooltip .wpstg--tooltiptext.has-top-arrow{margin-top:6px}.wpstg--tooltip .wpstg--tooltiptext.has-top-arrow:after{border:5px solid transparent;border-bottom-color:#fff;bottom:100%;content:" ";left:50%;margin-left:-18px;position:absolute}.wpstg--snaphot-restore-table tr{line-height:12px}.wpstg-beta-notice{background-color:#b0e8b0;border-radius:3px;margin-bottom:20px;padding:7px}#wpstg-backup-name{font-size:1.875em;font-weight:600}#wpstg_select_tables_cloning option:checked{-webkit-appearance:menulist-button;background-image:linear-gradient(0deg,#1e90ff,#1e90ff)}.wpstg--btn--cancel{color:#fff;font-size:16px;height:auto;line-height:normal;margin-bottom:1.5em;padding:.5em}.wpstg--btn--cancel,.wpstg--btn--cancel:hover{background:#ff3428;border-color:#e72f24}.wpstg--process--content>.swal2-html-container{padding:4em 2em!important}.wpstg--modal--error--logs,.wpstg--modal--process--logs{background:#fff;border:1px solid #a8a8a8;border-radius:3px;display:none;height:300px;margin-top:1em;overflow:auto;padding-left:10px;padding-top:10px;text-align:justify}.wpstg--modal--error--logs{height:auto;max-height:300px}.wpstg--modal--process--logs p{font-size:12px;white-space:nowrap}.wpstg--modal--process--logs p.wpstg--modal--process--msg--info{color:#222}.wpstg--modal--process--logs p.wpstg--modal--process--msg--debug{color:#757575}.wpstg--modal--process--title{color:#565656;margin:.25em 0}.wpstg--modal--process--subtitle{color:#565656;margin:.5em 0}.wpstg--modal--error--logs>p{color:#222;font-size:14px;text-align:left}.wpstg--modal--error--logs p,.wpstg--modal--process--logs p{margin:0 0 2px}.wpstg--modal--process--msg--critical,.wpstg--modal--process--msg--error{color:#e01e5a}.wpstg--modal--process--msg--warning{color:#ff8c00}.wpstg--modal--process--msg-found{color:#e01e5a;font-size:16px;font-weight:700}.wpstg--modal--delete{color:#565656;margin-top:8px;text-align:left}.wpstg-swal-popup .swal2-cancel.wpstg--btn--cancel{margin-bottom:0;text-shadow:none!important}.wpstg-swal-popup .wpstg-loader{display:inline-block!important}.wpstg--modal--process--generic-problem{border-left:5px solid #e01e5a;display:none;margin:.5em 0}.wpstg--modal--process--logs--tail{background:none;border:none;color:#565656;cursor:pointer;font-size:16px}.wpstg--modal--backup--import--upload--title{color:#565656}.wpstg--modal--backup--import--configure,.wpstg--modal--backup--import--upload--container input[type=file],.wpstg--modal--backup--import--upload--status{display:none}#wpstg--backups--import--file-list{font-size:14px;font-weight:700}#wpstg--backups--import--file-list-empty{color:#e01e5a}.wpstg--modal--backup--import--filesystem label{font-size:14px}.wpstg--modal--backup--import--filesystem button{margin-bottom:20px}.wpstg--modal--backup--import--upload{color:#505050;min-height:30px;position:relative}.wpstg--modal--backup--import--upload--container{background-color:#f4fbff;border:3.5px dashed #dedede;border-radius:10px;margin:.5em;padding:1em .5em;position:relative;transition:background-color .3s ease,color .3s ease}.wpstg--modal--backup--import--upload--container.wpstg--has-dragover span.wpstg--drop{display:inline-flex}.wpstg--modal--backup--import--upload--container input[type=file]{display:none}.wpstg--modal--backup--import--upload--container img{align-self:center;border:none;width:4em}.wpstg--modal--backup--import--upload--container span{margin-top:1em}.wpstg--backup--import--options>button{align-self:center;height:auto;line-height:normal;margin-top:1em;padding:1em;width:185px}.wpstg--backup--import--options{display:flex;justify-content:center;position:relative}.wpstg--backup--import--options ul{display:none}.wpstg--backup--import--options.wpstg--show-options ul{background:#25a1f0;border-color:#2188c9;border-radius:0 0 3px 3px;border-width:1px;box-sizing:border-box;display:block;margin:54px 0 0;padding:0;position:absolute;text-shadow:0 -1px 1px #006799,1px 0 1px #006799,0 1px 1px #006799,-1px 0 1px #006799;width:185px}.wpstg--backup--import--options.wpstg--show-options ul li{border-bottom:.1em solid #25a1f0;margin:0}.wpstg--backup--import--options.wpstg--show-options ul li:hover{background-color:#25a1f0}.wpstg--backup--import--options.wpstg--show-options ul li:last-child{border-bottom:none}.wpstg--backup--import--options ul li button{background:none;border:none;color:#fff;cursor:pointer;height:40px;line-height:40px;margin:0;width:100%}.wpstg--backup--import--options ul li button:hover{background-color:#259be6}.wpstg--modal--backup--import--search-replace--info{display:flex;flex-direction:row;margin:1em 0}.wpstg--modal--backup--import--info p{margin:0;text-align:left}.wpstg--modal--backup--import--search-replace--wrapper button{align-self:center}.wpstg--import--advanced-options--button{border:0;border-radius:3px;cursor:pointer;font-size:18px;text-shadow:0 -1px 1px #006799,1px 0 1px #006799,0 1px 1px #006799,-1px 0 1px #006799}.wpstg--modal--backup--import--search-replace--new{background-color:#25a1f0;color:#fff}.wpstg--modal--backup--import--search-replace--remove{background-color:#25a1f0;color:#fff;height:22px;margin-left:5px;width:22px}.wpstg--modal--backup--import--search-replace--input-group:first-child button{display:none}.wpstg--modal--backup--import--search-replace--input--container{display:flex;flex:1;flex-direction:column}.wpstg--modal--backup--import--search-replace--input-group{border-bottom:6px solid #f1f1f1;margin-bottom:10px;width:100%}.wpstg--modal--backup--import--search-replace--input-group input{border:1px solid #dedede;border-radius:3px;color:#666;display:inline-block;line-height:10px;margin-bottom:12px;min-width:250px;padding:8px;width:calc(50% - 20px)}.wpstg--modal--import--upload--process{align-items:center;color:#333;display:none;height:30px;justify-content:center;left:0;margin-bottom:20px;margin-top:20px;overflow:hidden;position:relative;text-indent:1em;top:0;white-space:nowrap;width:100%}.wpstg--modal--import--upload--progress{background:#98d452;border-radius:4px;color:#fff;height:100%;left:0;position:absolute;top:0}.wpstg--modal--import--upload--progress--title{z-index:9}.wpstg-fieldset:disabled{border-top:1px solid #fff;margin-top:20px;opacity:.8}.wpstg-fieldset{padding-left:20px}.wpstg-dark-alert{background-color:#0e86d9;color:#fff;font-weight:700;margin-top:0;padding:15px}.wpstg-dark-alert .wpstg-button--cta-red{margin-left:10px}.wpstg-form-group{align-items:center;display:block;margin-bottom:8px;width:100%}.wpstg-form-group>label{display:block;font-weight:700}.wpstg-text-field>input{display:block;line-height:1.5;width:300px}.wpstg-text-field>.wpstg-code-segment{margin-top:4px;min-width:300px}.wpstg-form-group>.wpstg-checkbox{position:relative}.wpstg-form-group>.wpstg-checkbox>input[type=checkbox]{left:150px}.wpstg-ml-4{margin-left:4px}#wpstg-advanced-settings hr{margin:20px 0}.wpstg-form-row{display:block}.wpstg-form-row input,.wpstg-form-row label{display:table-cell;margin-bottom:3px;margin-top:3px;padding-left:5px;padding-right:5px}.wpstg-form-row input{width:400px}.wpstg-form-row label{font-weight:700;white-space:nowrap;width:1px}#wpstg-db-connect-output #wpstg-db-status{width:390px}.wpstg-fs-14{font-size:14px}.wpstg-code-segment{display:block}.wpstg-form-group>.wpstg-checkbox{min-width:100%;width:100%}.wpstg-form-group>.wpstg-checkbox>input[type=checkbox]{margin-left:10px}@media only screen and (max-width:768px){.wpstg-form-group>label{min-width:auto;width:auto}.wpstg-text-field>input{width:100%}.wpstg-text-field>.wpstg-code-segment{margin-left:0;min-width:100%}.wpstg-tab-section{max-width:450px;width:calc(100vw - 60px)}}.wpstg-rounded{border-radius:3px}.wpstg-white-border{border:1px solid #fff!important}.wpstg-m-0{margin:0}.wpstg-mt-10px,.wpstg-my-10px{margin-top:10px}.wpstg-my-10px{margin-bottom:10px}.wpstg-w-100{width:100%}.wpstg-box-shadow{box-shadow:0 1px 1px 0 rgba(0,0,0,.1)}.wpstg-float-left{float:left}.wpstg-bold-text{font-weight:700}.wpstg-warning.notice{border-left:4px solid #ffba00}.wpstg-confirmation-label{background-color:#5b9dd9;border-radius:3px;color:#fff;padding:2px}.wpstg-my-6px{margin-bottom:6px;margin-top:6px}.wpstg-mb-10px{margin-bottom:10px}.wpstg-clear-both{clear:both}.wpstg-font-italic{font-style:italic}.wpstg-mt-20px{margin-top:20px}.wpstg-welcome-container{border:2px solid #fff;margin-bottom:20px;padding:20px}.wpstg-ml-30px{margin-left:30px}.wpstg-text-center{text-align:center}.wpstg-feedback-link{text-decoration:none}.wpstg-feedback-span{display:block;margin-bottom:3px}#wpstg-confirm-backup-restore-data{margin:40px;text-align:left}#wpstg-confirm-backup-restore-wrapper{margin:0 30px 30px}#wpstg-confirm-backup-restore-wrapper h3{color:#e01e5a}#wpstg-progress-backup,#wpstg-progress-db{background-color:#3fa5ee}#wpstg-progress-files.wpstg-pro,#wpstg-progress-sr{background-color:#3c9ee4}#wpstg-progress-data,#wpstg-progress-dirs{background-color:#3a96d7}#wpstg-progress-files:not(.wpstg-pro),#wpstg-progress-finishing{background-color:#378cc9}.wpstg-issue-resubmit-confirmation.swal2-container,.wpstg-swal2-container.swal2-container{z-index:10500}.wpstg-swal2-container.wpstg-swal2-loading .swal2-actions,.wpstg-swal2-container.wpstg-swal2-loading .swal2-header{display:none}body.toplevel_page_wpstg_backup .swal2-container .swal2-content,body.toplevel_page_wpstg_clone .swal2-container .swal2-content{z-index:2}.toplevel_page_wpstg_clone #swal2-content h2{color:#565656}.toplevel_page_wpstg_clone #swal2-content{line-height:1.5em}div#exportUploadsWithoutDatabaseWarning{background-color:#fafafa;border:1px solid #e3e3e3;border-radius:5px;font-size:.9rem;font-style:italic;margin:10px;padding:10px;text-align:center}.wpstg-advanced-options-dropdown-wrapper{display:none;margin-top:20px}.wpstg--modal--backup--import--search-replace--wrapper{margin-top:20px;text-align:left}.wpstg--modal--backup--import--search-replace--new--wrapper{text-align:center}.wpstg-import-backup-contains li{display:inline-block}.wpstg-import-backup-contains li .wpstg-backups-contains{background-color:#e3e3e3;border:1px solid #c2c2c2;border-radius:3px;color:#979797;font-size:17px;height:17px;width:17px}.wpstg-import-backup-contains.wpstg-listing-single-backup li .wpstg-backups-contains{background-color:#fff;border:1px solid #c2c2c2;padding:2px}.wpstg-import-backup-contains.wpstg-listing-single-backup li .wpstg-backups-contains>.wpstg--dashicons{filter:invert(50%)}.wpstg-import-backup-contains .wpstg--tooltiptext{font-size:x-small;left:-25px;padding:5px;text-align:center;width:50px}.wpstg-import-backup-contains-title,ul.wpstg-import-backup-contains{display:inline-block}.wpstg-import-backup-name{display:inline-block;font-weight:700}.wpstg-backup-more-info-toggle{cursor:pointer;display:inline-block;font-size:x-small;font-style:italic}.wpstg-backup-more-info-toggle::selection{background:none}ul.wpstg-import-backup-more-info{background-color:#f6f6f6;border:1px solid #878787;border-radius:3px;cursor:pointer;font-size:14px;margin-bottom:30px;margin-top:10px;padding:7px;text-align:left}ul.wpstg-import-backup-more-info:hover{background-color:#def2ff;border:1px solid #25a1f0}ul.wpstg-import-backup-more-info li{height:20px}.wpstg-backup-list{max-width:800px}.wpstg-backup-list h3{color:#3e3e3e}.wpstg-backup-list ul ul{margin-block-end:1em;margin-block-start:1em}.wpstg-push-confirmation-message{font-size:15px;text-align:justify}.wpstg-settings-row{padding-bottom:10px;padding-top:10px}.wpstg-settings-title{font-weight:600}.wpstg-settings-form-group{align-items:center;display:flex}.wpstg-settings-form-group>.wpstg-settings-message{margin:7px 0 0;padding:0;width:30%}.wpstg-excluded-filters-container{margin-bottom:10px;margin-top:10px;max-width:100%;padding:0;width:100%}.wpstg-excluded-filters-container>table{border-collapse:collapse;border-color:transparent;width:100%}.wpstg-excluded-filters-container td{height:20px;padding-bottom:4px;padding-top:4px}.wpstg-excluded-filters-container h4{margin:0}.wpstg-exclude-filters-foot{display:flex;justify-content:flex-start;padding:0}.wpstg-exclude-filter-dropdown>button:hover{background:#135e96;border:1px solid #135e96}.wpstg-exclude-filter-dropdown>.wpstg-dropdown-menu{width:128px}.wpstg-remove-exclude-rule{background-color:#e01e5a;border:1px solid #e01e5a;border-radius:10px;box-shadow:none;color:#fff!important;cursor:pointer;display:inline-flex;font-size:24px;font-weight:400;height:20px;justify-content:center;line-height:.7;margin-top:5px;outline:none;padding:0;width:20px}.wpstg-remove-exclude-rule:hover{background-color:#e01e5a;border-color:#e01e5a}.wpstg-code-block{background:#f8f8f8;border-radius:2px;font-size:1.2em;margin-top:4px}.wpstg-rule-info{background:#f8f8f8!important}code.wpstg-code{background:#fff;border:1px solid #aaa;color:#e01e5a;display:inline-block;font-size:11px;margin-bottom:1px;padding:2px 4px}.wpstg-exclusion-rule-info{align-items:center;background-color:#ffc107;border:1px solid #ffc107;border-radius:7px;box-shadow:none;color:#fff!important;display:inline-flex;font-size:14px;font-weight:400;height:14px;justify-content:center;outline:none;padding:0;vertical-align:middle;width:14px}.wpstg-exclusion-rule-info:hover{background-color:#ffba0c;border:1px solid #ffba0c}.wpstg-exclude-rule-input{background-color:#fff;border:1px solid #bbb;border-radius:0!important;box-shadow:none;color:#222;display:inline-block;font-size:12px!important;font-weight:400;line-height:1.5;margin-left:4px;margin-top:4px;min-height:24px!important;outline:none!important;padding:2px 6px;transition:all .3s cubic-bezier(.25,.8,.25,1);vertical-align:baseline!important;width:135px}.wpstg-excluded-filters-container tbody>tr:last-child .wpstg-exclude-rule-input{margin-bottom:4px}.wpstg-exclude-rule-input:hover{border:1px solid #999}.wpstg-exclude-rule-input:focus{border:1px solid #25a0f1!important;box-shadow:0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24)!important}.wpstg-file-size-exclude-select,.wpstg-path-exclude-select{width:135px}.wpstg-file-size-exclude-select-small{width:52px}.wpstg-file-size-exclude-input{width:75px}.wpstg-staging-option-title{margin:15px 0 0}.wpstg-swal-push-container.swal2-container{z-index:9995}#wpstg-scanning-files{padding-bottom:5px}#wpstg-scanning-db.wpstg-tab-section,#wpstg-scanning-files.wpstg-tab-section{padding-top:10px}.wpstg-reset-excludes-container{margin:10px 0}.wpstg-swal2-ajax-loader{align-items:center;display:flex;height:150px;justify-content:center;overflow:hidden;width:100%}@keyframes wpstg-loading-icon-anim{0%{transform:rotate(0)}to{transform:rotate(1turn)}}.wpstg-swal2-ajax-loader>img{animation:wpstg-loading-icon-anim 1s linear infinite;-webkit-animation:wpstg-loading-icon-anim 1s linear infinite;height:64px;width:64px}.wpstg-swal2-container .wpstg-tab-section{width:auto!important}#wpstg-no-staging-site-results{margin-top:10px;max-width:375px}li#wpstg-backup-no-results{max-width:500px}#wpstg-no-staging-site-results div,li#wpstg-backup-no-results div{display:inline-block;text-align:center}#wpstg-no-staging-site-results .wpstg--dashicons,li#wpstg-backup-no-results .wpstg--dashicons{filter:invert(50%);margin-top:1px;position:absolute}#wpstg-no-staging-site-results .no-staging-site-found-text,li#wpstg-backup-no-results .no-backups-found-text{color:#5d5d5d;margin-left:20px}@media only screen and (max-width:680px){#wpstg-no-staging-site-results div,li#wpstg-backup-no-results div{width:100%}}#wpstg--modal--backup--download-inner p.wpstg-download-modal-text{color:#565656;font-size:16px}#wpstg--modal--backup--download-inner h2{color:#565656}.wpstg-backup-restore-contains-database,.wpstg-backup-restore-contains-files{display:none}.wpstg-green-button{background:#8bc34a;border:1px solid #78a93f;color:#fff;text-shadow:0 -1px 1px #78a93f,1px 0 1px #78a93f,0 1px 1px #40c921,-1px 0 1px #78a93f}.wpstg-green-button:hover{background:#78a93f}.wpstg-is-dir-loading{display:none;margin-left:8px;margin-top:-2px;position:absolute}.wpstg-ml-8px{margin-left:8px}.wpstg-mb-8px{margin-bottom:8px}.wpstg-btn-danger{background-color:#e01e5a;border:1px solid #e01e5a;color:#fff;text-shadow:none}.wpstg-btn-danger:hover{background:#c0194d;box-shadow:0 1px 4px rgba(0,0,0,.3)}.wpstg-swal2-container.wpstg-swal2-loading>.swal2-modal{height:200px}.wpstg-reset-confirmation.wpstg-swal2-container:not(.wpstg-swal2-loading)>.swal2-modal{max-width:480px}.wpstg-reset-confirmation.wpstg-swal2-container .swal2-header{display:none}.wpstg-reset-confirmation.wpstg-swal2-container .swal2-content{height:auto}.wpstg-reset-confirmation.wpstg-swal2-container>.swal2-modal>.swal2-content .wpstg-tabs-wrapper{height:auto!important;overflow-y:auto}.wpstg-reset-confirmation.wpstg-swal2-container>.swal2-modal>.swal2-content{font-size:13px}.wpstg-reset-confirmation.wpstg-swal2-container>.swal2-modal>.swal2-content .wpstg-dir{margin-bottom:4px}.wpstg-reset-confirmation.wpstg-swal2-container>.swal2-modal>.swal2-content .wpstg-subdir{margin-top:4px}.wpstg-reset-confirmation.wpstg-swal2-container.has-collapsible-open .swal2-modal{height:calc(100vh - 70px)}.wpstg-reset-confirmation.wpstg-swal2-container.has-collapsible-open>.swal2-modal>.swal2-content .wpstg-tabs-wrapper{height:calc(100vh - 350px)!important}.swal2-actions.wpstg--modal--actions>button{font-weight:500;margin-left:4px;margin-right:4px;min-width:80px;text-shadow:none;text-transform:uppercase}.wpstg-swal-popup{max-width:1200px!important}.wpstg-swal-popup.wpstg-push-finished .swal2-title{color:#a8a8a8}.wpstg-swal-popup.wpstg-push-finished .swal2-content{color:#a8a8a8;margin-top:8px}.wpstg-swal-popup .swal2-progress-steps .swal2-progress-step,.wpstg-swal-popup .swal2-progress-steps .swal2-progress-step-line,.wpstg-swal-popup .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step{background:#25a1f0}.wpstg-swal-popup .swal2-progress-steps .swal2-progress-step-line{width:2.75em}.wpstg--dashicons{height:16px;width:16px}.wpstg--dashicons.wpstg-dashicons-grey{filter:invert(20%)}.wpstg--dashicons.wpstg-dashicons-19{height:19px;width:19px}.wpstg--dashicons.wpstg-dashicons-21{height:21px;width:21px}#wpstg--tab--backup #wpstg-step-1{align-items:center;display:flex}#wpstg--tab--backup #wpstg-step-1 .wpstg--tooltip,.wpstg-advanced-options .wpstg--tooltip{align-items:center;border-bottom:0 solid transparent;display:inline-flex}#wpstg--tab--backup #wpstg-step-1 .wpstg--tooltip{align-items:center;border-bottom:0 solid transparent;display:flex}.wpstg--tooltip .wpstg--tooltiptext-backups:after{left:calc(20% + 2px)}.wpstg-listing-single-backup .wpstg--dashicons{height:17px;width:17px}.wpstg-100-width{width:100px}.wpstg-caret{border-left:4px solid transparent;border-right:4px solid transparent;border-top:4px solid;cursor:pointer;display:inline-block;height:0;margin-left:2px;transition:transform .2s;vertical-align:middle;width:0}.wpstg-caret.wpstg-caret-up{transform:rotate(-180deg)}.wpstg-advanced-options-site label{display:block;font-size:16px;margin:.5em 0}#wpstg-confirm-backup-restore-data{font-size:18px;margin:30px 0 0}body.toplevel_page_wpstg_backup .swal2-container.swal2-backdrop-show,body.toplevel_page_wpstg_clone .swal2-container.swal2-backdrop-show{background:rgba(0,0,0,.6);z-index:9995}.wpstg-swal-popup.swal2-popup{border-radius:8px;color:#565656;font-family:Verdana,Geneva,Tahoma,sans-serif;padding:24px;z-index:9999}.wpstg-swal-popup .swal2-title{color:#565656;font-size:22px}.wpstg-swal-popup.swal2-popup:not(.centered-modal) .swal2-title{align-self:flex-start;margin-bottom:0;text-align:left}.wpstg-swal-popup .swal2-close{right:8px;top:8px;z-index:5}.wpstg-swal-popup .swal2-close:focus{outline:none}.wpstg-swal-popup.swal2-popup:not(.centered-modal) .swal2-actions{justify-content:flex-end}.wpstg-swal-popup .swal2-actions>button{border:0;border-radius:4px;font-size:15px;font-weight:900;height:40px;line-height:normal;min-width:100px;padding:10px 12px;text-shadow:none;text-transform:capitalize}.wpstg-swal-popup.swal2-popup:not(.centered-modal) .swal2-actions>button{margin-left:8px}.wpstg-swal-popup .swal2-actions>button.swal2-cancel{background:#fff;border:1px solid rgba(29,28,29,.3);color:#1d1c1d;font-weight:500;text-shadow:none;width:100px}.wpstg-swal-popup .swal2-actions>button:hover{box-shadow:0 1px 3px 0 rgba(0 0 0 .1)}.wpstg-swal-popup .swal2-actions>button.swal2-cancel:hover{background:rgba(28,29,28,.04)}#wpstg-backup-name-input{font-size:18px;height:44px}.wpstg-restore-finished-container .swal2-title{color:#565656!important}.wpstg-restore-finished-container .swal2-content{color:#a8a8a8;margin-top:20px}.wpstg-linear-loader>span[class*=wpstg-linear-loader-item]{animation:wpstg_linear_loader 3s infinite;animation-fill-mode:both;animation-timing-function:cubic-bezier(.03,.615,.995,.415);background:#333;border-radius:100%;display:inline-block;height:6px;margin:12px 2px;width:6px}.wpstg-linear-loader>span.wpstg-linear-loader-item:first-child{animation-delay:1s}.wpstg-linear-loader>span.wpstg-linear-loader-item:nth-child(2){animation-delay:.8s}.wpstg-linear-loader>span.wpstg-linear-loader-item:nth-child(3){animation-delay:.6s}.wpstg-linear-loader>span.wpstg-linear-loader-item:nth-child(4){animation-delay:.4s}.wpstg-linear-loader>span.wpstg-linear-loader-item:nth-child(5){animation-delay:.2s}.wpstg-linear-loader>span.wpstg-linear-loader-item:nth-child(6){animation-delay:0s}@keyframes wpstg_linear_loader{0%{opacity:0;transform:translateX(-30px)}25%{opacity:1}50%{opacity:0;transform:translateX(30px)}to{opacity:0}}.wpstg--modal--backup--import--upload--content{margin:1em auto;padding:.75em}.wpstg--modal--backup--import--upload--content .wpstg-linear-loader{display:none}#wpstg-multisite-disabled .wpstg-clone{width:355px}#wpstg-free-version-backups .wpstg-clone{text-align:center}#wpstg-free-version-backups .wpstg-clone p{font-size:16px}.wpstg-staging-info li .backup-notes{word-break:break-word}.wpstg--modal--import--upload--progress--title small{font-weight:400}#wpstg-report-issue-wrapper{position:relative}#wpstg-report-issue-wrapper .arrow-up{border-bottom:8px solid #fff;border-left:8px solid transparent;border-right:8px solid transparent;height:0;position:absolute;right:40px;top:-8px;width:0}.notice{margin:10px 20px 0 2px}.wpstg--notice{box-shadow:0 1px 1px rgba(0,0,0,.04);margin:20px 20px 20px 0;padding:1px 12px}.wpstg--error a:hover{color:#eee}.wpstg--error,.wpstg--error a{background:#e01e5a;color:#fff}.wpstg-button{border-radius:2px;cursor:pointer;display:inline-block;font-weight:500;outline:0;padding:2px 10px;text-decoration:none;text-transform:uppercase;transition:background-color .1s ease-in}.wpstg-button.wpstg-save{background-color:#1687a7;color:#fff}.wpstg-button.wpstg-save:hover{background-color:#276678}.wpstg-button.wpstg-button-light{animation:background-color .3s;background-color:#f8f8f8;border:1px solid #eee;color:#333}.wpstg-button.wpstg-button-light:hover{background-color:#e0e0e0;border:1px solid #e0e0e0}.wpstg-buttons .spinner{float:none;margin:0 0 0 5px}.wpstg-button.danger{background-color:#e01e5a;border-color:transparent;border-radius:2px;color:#fff;display:inline-block;text-align:center;text-decoration:none;text-transform:inherit}.wpstg-button.danger:hover{background-color:#c0194d}.wpstg-button--big{border-radius:3px;color:#fff;display:inline-block;font-size:16px;margin-top:20px;min-width:170px;padding:10px;text-align:center;text-decoration:none}.wpstg-button--primary{-webkit-appearance:none;border:1px solid rgba(29,28,29,.3);border-radius:2px;box-sizing:border-box;color:#171717;cursor:pointer;display:inline-block;font-size:13px;line-height:2.15384615;margin:0;min-height:30px;padding:0 10px;text-decoration:none;white-space:nowrap}.wpstg-button--primary:hover{background:rgba(28,29,28,.04);color:#000}.wpstg-button--secondary{background-color:transparent;border:1px solid rgba(29,28,29,.3);border-radius:2px;color:#95a5a6;cursor:pointer;display:inline-block;font-weight:500;outline:0;padding:4px 10px 2px;text-decoration:none;transition:background-color .1s ease-in}.wpstg-button--red{background-color:#e01e5a;border-color:#e01e5a;color:#fff}.wpstg-button--red:hover{background-color:#d02358;border-color:#e0255f;color:#fff}.wpstg-button--cta-red{background-color:#fe008f;border-color:#e01e5a;color:#fff}.wpstg-button--cta-red:hover{background-color:#f31391;border-color:#e0255f;color:#fff}.wpstg-button--blue{background-color:#25a0f1;border-color:#25a0f1;color:#fff}.wpstg-button--blue:hover{background-color:#259be6;border-color:#259be6;color:#fff}#wpstg-button-backup-upgrade{font-size:16px}.wpstg-staging-status{color:#e01e5a}#wpstg-push-changes,#wpstg-save-clone-data,#wpstg-start-updating{margin-left:5px}input.wpstg-textbox{border:1px solid #aaa;border-radius:.25rem;font-size:14px;padding:.25rem .5rem}input.wpstg-textbox:focus{border-color:#259be6;-webkit-box-shadow:0 0 0 .1rem hsla(0,0%,86.7%,.35);box-shadow:0 0 0 .1rem hsla(0,0%,86.7%,.35);outline:0}input.wpstg-textbox::placeholder{color:#888}.wpstg--advance-settings--checkbox{align-items:center;display:flex}.wpstg--advance-settings--checkbox>label{display:inline-block;font-size:14px;font-weight:bolder;width:165px}.wpstg--advance-settings--checkbox>.wpstg--tooltip{border-bottom:0 solid transparent;display:inline-block;margin-left:5px;margin-top:5px;position:relative}.wpstg--advance-settings--checkbox>.wpstg--tooltip>.wpstg--tooltiptext{left:-150px;top:18px}div#wpstg-restore-wait{align-items:center;background:#fff;display:none;flex-direction:column;height:100vh;justify-content:center;left:0;position:fixed;text-align:center;top:0;width:100vw;z-index:99999}div#wpstg-restore-wait .wpstg-title{font-weight:700}div#wpstg-restore-wait div{font-size:16px;margin-top:12px}.resumable-browse{cursor:pointer}.resumable-browse a{text-decoration:underline}.wpstg--modal--backup--import--upload--container.dragover{background-color:#94dc96;color:#fff;transition:background-color .7s}.wpstg--modal--backup--import--upload--container.dragover *{pointer-events:none}.wpstg--modal--backup--import--upload--container.dragover .upload-text{display:none}.wpstg--modal--backup--import--upload--container.dragover .dragover-text{display:block}.wpstg--modal--backup--import--upload--container .dragover-text{display:none}#wpstg-invalid-license-message,#wpstg-invalid-license-message a{color:#e01e5a;font-weight:500;margin-left:6px}#wpstg-sidebar--banner{max-width:200px}@media screen and (max-width:1234px){.wpstg-h2{font-size:24px}#wpstg-welcome li{font-size:14px}}.wpstg-exclamation{background-color:#e01e5a;border-radius:100%;color:#fff;display:inline-block;font-weight:700;height:20px;margin:6px;text-align:center;width:20px}.wpstg--tab--contents{padding-top:1px}.wpstg-swal-show.swal2-show{-webkit-animation:wpstg-swal-show .2s!important;animation:wpstg-swal-show .2s!important}@-webkit-keyframes wpstg-swal-show{0%{transform:scale(.3)}to{transform:scale(1)}}@keyframes wpstg-swal-show{0%{transform:scale(.3)}to{transform:scale(1)}}
2
  /*# sourceMappingURL=wpstg-admin.min.css.map */
assets/css/dist/wpstg-admin.min.css.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["wpstg-admin.css"],"names":[],"mappings":"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","file":"wpstg-admin.min.css","sourcesContent":["/**\n * WPSTG Admin CSS\n *\n * @package WPSTG\n * @subpackage Admin CSS\n * @copyright Copyright (c) 2021, René Hermenau\n * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License\n*/\n\n\n/* CSS for Tabs */\n\n#wpstg-tab-container ul {\n /*height: 200px;*/\n list-style: none;\n margin: 0;\n padding: 0;\n background: #f1f1f1;\n float: left;\n /*list-style-type: square;*/\n}\n\n#wpstg-tab-container ul li:first-child.selected-tab {\n border-top: none;\n}\n\n#wpstg-tab-container ul li a.selected-tab {\n font-weight: bold;\n text-decoration: none;\n}\n\n#wpstg-tab-container .row {\n padding-top: 10px;\n padding-bottom: 12px;\n}\n\n.wpstg-tabs-container .nav-tab-wrapper {\n padding: 0;\n}\n\n#wpstg-tab-container .row label strong,\n#wpstg-tab-container .row strong {\n font-weight: bold;\n}\n\n.wpstg-tabs a {\n padding: 5px;\n}\n\n#wpstg-tab-container>ul>li.wpstg-tabs.active {\n background-color: white;\n}\n\n#wpstg_settingsgeneral_header .row:nth-child(3),\n#wpstg_settingsgeneral_header .row:nth-child(4) {\n display: none;\n}\n\n#wpstg-tab-container .wpstg-settings-panel {\n padding: 0 20px 20px 20px;\n overflow: auto;\n}\n\n#wpstg-tab-container .wpstg-form-table th {\n vertical-align: top;\n text-align: left;\n padding: 20px 10px 20px 0;\n line-height: 1.3;\n font-weight: bold;\n font-size: 14px;\n color: #484848;\n width: 30%;\n}\n\n#wpstg-tab-container .wpstg-form-table tr {\n border-bottom: 1px solid #E7E7E7;\n}\n\n#wpstg-tab-container span.description {\n display: block;\n font-weight: 400;\n font-style: normal;\n font-size: 13px;\n margin-top: 7px;\n color: #484848;\n}\n\n#wpstg-tab-container .col-title {\n color: #484848;\n}\n\n@media only screen and (max-width: 680px) {\n #wpstg-tab-container ul {\n float: none;\n }\n #wpstg-tab-container .wpstg-form-table tr>th {\n width: 100%;\n }\n #wpstg-tab-container span.description {\n font-size: 14px;\n }\n #wpstg-tab-container .wpstg-form-table tr>th,\n #wpstg-tab-container .wpstg-form-table tr>td {\n padding: 10px;\n }\n}\n\n#wpstg-tab-container ul li {\n margin-bottom: 0;\n}\n\n#wpstg-tab-container ul li a {\n display: block;\n padding: 10px 4px 10px 14px;\n border-width: 1px 0;\n border-style: solid;\n border-top-color: white;\n border-bottom-color: #e7e7e7;\n text-decoration: none;\n color: #0097DF;\n font-weight: bold;\n}\n\n#wpstg-tab-container ul li a:hover {\n background-color: #e5e5e5;\n color: #777777;\n}\n\n.wpstg-logo {\n display: block;\n font-size: 16px;\n padding-top: 20px;\n width: 220px;\n float: left;\n}\n\n.wpstg-version {\n display: block;\n padding-top: 29px\n}\n\n.wpstg_admin .nav-tab {\n color: #3C3C3C;\n}\n\n#wpstg-tab-container table tbody tr:nth-child(1)>th>div {\n font-size: 20px;\n}\n\n.wpstg_hidden {\n display: none;\n}\n\n\n/* Cloning workflow */\n\n#wpstg-clonepage-wrapper {\n margin-bottom: 20px;\n}\n\n@media screen and (min-width: 1090px) {\n #wpstg-clonepage-wrapper {\n float: left;\n margin-bottom: 20px;\n }\n .wpstg-sidebar {\n display: none;\n margin-left: 700px;\n margin-top: 138px;\n }\n}\n\n.wpstg-sidebar {\n display: none;\n padding: 10px;\n border: 1px solid #DFDFDF;\n max-width: 250px;\n height: 250px;\n}\n\n#wpstg-steps {\n margin-top: 30px;\n}\n\n#wpstg-steps li {\n color: #444;\n line-height: 20px;\n padding-right: 10px;\n float: left;\n}\n\n.wpstg-step-num {\n border: 1px solid #444;\n border-radius: 3px;\n display: inline-block;\n width: 20px;\n height: 20px;\n text-align: center;\n margin-right: 5px;\n}\n\n.wpstg-current-step {\n font-weight: bold;\n}\n\n.wpstg-current-step .wpstg-step-num {\n background: #444;\n color: #eee;\n}\n\n.wpstg-box {\n margin: 10px 0;\n padding: 10px;\n position: relative;\n overflow: hidden;\n transition: border-color .2s ease-in-out;\n}\n\n.wpstg-clone {\n margin-bottom: 3px;\n padding: 16px;\n position: relative;\n transition: border-color .2s ease-in-out;\n background-color: #25a1f0;\n border-radius: .25rem;\n box-shadow: 0 0 1px rgba(0,0,0,.125), 0 1px 3px rgba(0,0,0,.2);\n}\n\n.wpstg-clone.active {\n border-color: #1d94cf;\n}\n\n.wpstg-clone-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.wpstg-clone-title {\n display: inline-block;\n font-size: 15px;\n max-width: 300px;\n text-decoration: none;\n font-weight: bold;\n color: white;\n}\n\n.wpstg-clone-title:hover {\n color: #f1f1f1;\n}\n\n.wpstg-clone-actions {\n display: flex;\n /*align-items: right;*/\n}\n\n.wpstg-dropdown {\n position: relative;\n}\n\n.wpstg-clone-actions .wpstg-dropdown-toggler {\n text-decoration: none;\n background: #fff;\n padding: 4px 10px;\n border-radius: 2px;\n font-size: 14px;\n box-shadow: 0 0 1px rgba(0,0,0,.125), 0 1px 3px rgba(0,0,0,.2);\n color: #002648;\n}\n\n.wpstg-clone-actions .wpstg-dropdown-toggler:hover {\n background: #002648;\n color: white;\n}\n\n.wpstg-dropdown {\n position: relative;\n}\n\n.wpstg-dropdown-symbol {\n font-size: 14px;\n margin-left: 4px;\n}\n\n.wpstg-dropdown>.wpstg-dropdown-menu {\n background: #fff;\n display: none;\n flex-direction: column;\n position: absolute;\n right: 0;\n top: calc(100% + 4px);\n padding: 8px;\n border-radius: 2px;\n width: 100px;\n box-shadow: 0 0 1px rgba(0,0,0,.125), 0 1px 3px rgba(0,0,0,.2);\n z-index: 1000;\n}\n\n.wpstg-dropdown>.wpstg-dropdown-menu.wpstg-menu-dropup {\n top: auto;\n bottom: 100%;\n transform: translate3d(0px, -3px, 0px);\n}\n\n.wpstg-dropdown>.wpstg-dropdown-menu.shown {\n display: flex;\n}\n\n.wpstg-clone-action,\n.wpstg-dropdown-action {\n color: #002648;\n padding: 5px 8px;\n border-radius: 3px;\n text-decoration: none;\n position: relative;\n transition: color .2s ease-in-out;\n}\n\n.wpstg-clone-action:hover,\n.wpstg-dropdown-action:hover {\n background: rgba(0,0,0,0.05);\n}\n\n.wpstg-dropdown-action {\n color: #333;\n background: transparent;\n border: 0 solid black;\n outline: none;\n box-shadow: none;\n}\n\n.wpstg-remove-clone:hover {\n color: #ef6d6d;\n}\n\n.wpstg-clone-action:last-child {\n border: none;\n}\n\n.wpstg-clone:hover .wpstg-clone-action {\n display: inline-block;\n}\n\n#wpstg-show-error-details:focus,\n#wpstg-workflow .wpstg-clone-action {\n outline: none;\n box-shadow: none;\n}\n\n.wpstg-link-btn {\n background: #45a1c9;\n color: #fff;\n display: inline-block;\n padding: 5px 10px;\n text-decoration: none;\n vertical-align: baseline;\n transition: all .2s ease-in-out;\n}\n\n.wpstg-link-btn:hover,\n.wpstg-link-btn:focus {\n color: #fff;\n outline: none;\n box-shadow: none;\n}\n\n#wpstg-workflow .wpstg-link-btn:active {\n vertical-align: baseline;\n}\n\n.wpstg-link-btn[disabled] {\n background: #777 !important;\n pointer-events: none;\n}\n\n#wpstg-cancel-cloning,\n#wpstg-cancel-cloning-update {\n background: #ff3428;\n border-color: #e72f24;\n margin-top: 5px;\n}\n\n#wpstg-cancel-cloning.success,\n#wpstg-cancel-cloning.success {\n background: #64dd58;\n border-color: #54bd4a;\n}\n\n#wpstg-error-wrapper,\n#wpstg-error-details {\n display: none;\n padding-top: 10px;\n font-size: 13px;\n clear: both;\n}\n\n#wpstg-show-error-details {\n display: inline-block;\n margin-left: 5px;\n color: #555;\n text-decoration: none;\n transition: color .2s ease-in-out;\n}\n\n#wpstg-show-error-details:hover {\n color: #1d94cf;\n}\n\n#wpstg-error-details {\n border-left: 5px solid #ef6d6d;\n padding: 10px;\n width: 500px;\n}\n\n#wpstg-try-again {\n display: none;\n}\n\n#wpstg-home-link {\n float: right;\n}\n\n.wpstg-loader {\n content: url('../../img/loading.gif');\n margin-top: 5px;\n display: none;\n}\n\n.wpstg-loader.wpstg-finished {\n display: block;\n content: \"Finished\";\n background-color: #00c89a;\n color: white;\n padding: 2px 10px;\n margin-top: 0;\n border-radius: 3px;\n}\n\n#wpstg-workflow {\n max-width: 650px;\n position: relative;\n clear: both;\n padding-top: 20px;\n float: left;\n min-width: 500px;\n /*border-right: 1px solid #DFDFDF;*/\n min-height: 380px;\n padding-right: 20px;\n padding-bottom: 20px;\n}\n\n#wpstg-sidebar {\n float: left;\n max-width: 400px;\n display: block;\n margin-left: 10px;\n}\n\n@media screen and (max-width: 1150px) {\n #wpstg-sidebar img {\n margin-top: 30px;\n }\n}\n\n#wpstg-workflow.loading::after,\n#wpstg-removing-clone.loading::after {\n background: rgba(255, 255, 255, .7);\n content: 'Loading... may take a while for huge websites';\n display: block;\n width: 100%;\n height: 100%;\n font-size: 20px;\n padding-top: 100px;\n text-align: center;\n position: absolute;\n top: 0;\n left: 0;\n z-index: 99;\n}\n\n#wpstg-removing-clone.loading::after {\n content: 'REMOVING' !important;\n}\n\n#wpstg-existing-clones,\n#wpstg-removing-clone {\n position: relative;\n}\n\n#wpstg-removing-clone .wpstg-tab-section {\n display: block;\n}\n\n.wpstg-progress-bar {\n max-width: 900px;\n height: 27px;\n padding: 0;\n background-color: #d6d8d7;\n}\n\n.wpstg-progress {\n float: left;\n background: #3fa5ee;\n width: 0;\n height: 100%;\n transition: width .6s ease;\n color: white;\n line-height: 25px;\n text-align: center;\n overflow: hidden;\n}\n\n.wpstg-progress-files {\n background: #16b4f0;\n width: 0;\n height: 100%;\n transition: width .6s ease;\n color: white;\n line-height: 25px;\n text-align: center;\n}\n\n#wpstg-new-clone-id.wpstg-error-input,\n#wpstg-clone-path.wpstg-error-input {\n border: 1px solid #ff4235;\n box-shadow: 0 0 2px rgba(255, 66, 53, .8);\n}\n\n#wpstg-new-clone {\n background: #25a1f0;\n border-color: #2188c9;\n}\n\n#wpstg-new-clone:hover {\n background: #259be6;\n border-color: #2188c9;\n}\n\n#wpstg-clone-path {\n margin-left: 10px;\n width: 350px;\n}\n\n.wpstg-error-msg {\n color: #ff4235;\n}\n\n#wpstg-clone-id-error {\n display: block;\n background-color: #f0f8ff;\n padding: 10px;\n margin: 20px;\n}\n\n#wpstg-start-cloning+.wpstg-error-msg {\n display: block;\n margin-top: 5px;\n}\n\n.wpstg-size-info {\n color: #999;\n font-weight: normal;\n position: relative;\n left: 2px;\n}\n\n.wpstg-db-table .wpstg-size-info {\n top: 2px;\n}\n\n.wpstg-db-table:hover {\n background-color: #f0f8ff;\n}\n\n#wpstg-workflow #wpstg-start-cloning {\n display: inline-block;\n margin-left: 5px;\n font-size: 14px;\n vertical-align: baseline;\n}\n\n\n/* Tabs */\n\n.wpstg-tabs-wrapper {\n max-width: 640px;\n margin: 10px 0;\n}\n\n#wpstg-path-wrapper {\n border-bottom: 2px dashed #ccc;\n padding-bottom: 10px;\n margin-bottom: 10px;\n}\n\n\n/* unused class should be removed or commented\n.wpstg-tabs-wrapper {\n border: 1px solid #ddd;\n border-right: none;\n border-left: none;\n}\n*/\n\n.wpstg-tab-section {\n border-bottom: 1px solid #ddd;\n border-right: none;\n border-left: none;\n display: none;\n width: 100%;\n padding: 20px;\n}\n\n.wpstg-tab-section::after {\n display: block;\n content: '';\n clear: both;\n}\n\n.wpstg-tab-header {\n border-bottom: 1px solid #ddd;\n border-right: none;\n border-left: none;\n color: #444;\n font-size: 16px;\n font-weight: bolder;\n display: block;\n padding: 10px;\n ;\n text-decoration: none;\n}\n\n.wpstg-tab-triangle {\n display: inline-block;\n margin-right: 10px;\n animation: transform 0.5s;\n}\n\n.wpstg-tab-header:focus {\n color: #444;\n outline: none;\n box-shadow: none;\n}\n\n#wpstg-large-files {\n display: none;\n border: 1px dashed #ccc;\n /*float: right;*/\n padding: 10px 10px 10px;\n margin-top: 20px;\n position: relative;\n font-size: 12px;\n}\n\n#wpstg-large-files h3 {\n background: #fff;\n margin: 0;\n padding: 0 5px;\n position: absolute;\n top: -10px;\n left: 5px;\n}\n\n\n/* tmp */\n\n.wpstg-subdir {\n display: none;\n margin-left: 20px;\n}\n\n.wpstg-subdir.wpstg-push {\n display: block;\n margin-left: 20px;\n}\n\n.wpstg-dir a.disabled {\n color: #888;\n cursor: default;\n text-decoration: none;\n}\n\n.wpstg-check-subdirs {\n display: inline-block;\n margin-left: 10px;\n}\n\n.wpstg-notice-alert {\n display: block;\n background-color: #FFD0D0;\n padding: 20px;\n border-radius: 6px;\n border: 1px solid #FFAAAA;\n max-width: 600px;\n margin-top: 10px;\n}\n\n.wpstg-header {\n font-weight: 400;\n line-height: 1.6em;\n font-size: 19px;\n border-bottom: 1px solid #DFDFDF;\n clear: both;\n}\n\n#wpstg-clone-label {\n font-size: 14px;\n font-weight: bold;\n}\n\n.wpstg-log-details {\n height: 300px;\n overflow: scroll;\n max-width: 650px;\n font-family: monospace;\n font-size: 12px;\n line-height: 15px;\n border: 1px solid #FFF;\n background-color: black;\n color: #c0c0c0;\n padding: 3px;\n white-space: nowrap;\n margin-top: 15px;\n}\n\n#wpstg-finished-result {\n display: none;\n}\n\n#wpstg-remove-cloning {\n background: #ff3428;\n border-color: #e72f24;\n margin-top: 5px;\n}\n\n#wpstg-success-notice {\n padding: 10px;\n background-color: white;\n max-width: 900px;\n border: 1px solid #ccc;\n margin-top: 20px;\n}\n\n.wpstg_beta_notice {\n margin-bottom: 20px;\n}\n\n.wpstg-sysinfo {\n width: 700px;\n height: 700px;\n}\n\n.wpstg-form-table .col-title label {\n font-weight: 600;\n}\n\n.wpstg-form-table td:first-child {\n width: 30%;\n}\n\n.wpstg-share-button-container {\n margin: 5px 0;\n}\n\n.wpstg-share-button-container p {\n margin: 0 0 10px 0;\n}\n\n.wpstg-share-button {\n display: inline-block;\n}\n\n.wpstg-share-button a {\n text-decoration: none;\n}\n\n.wpstg-share-button .wpstg-share {\n font-family: sans-serif;\n font-weight: bold;\n text-decoration: none;\n text-align: center;\n}\n\n.wpstg-share-button .wpstg-share {\n -webkit-border-radius: 2px;\n -moz-border-radius: 2px;\n border-radius: 2px;\n color: #FFF;\n display: inline;\n font-size: 12px;\n padding: 4px 8px;\n}\n\n.wpstg-share-button-twitter .wpstg-share {\n background-color: #00ABF0;\n}\n\n.wpstg-share-button-facebook .wpstg-share {\n background-color: #3b5998;\n}\n\n.wpstg-share-button-googleplus .wpstg-share {\n background-color: #F53424;\n}\n\n.wpstg-share-button-twitter .share:active,\n.wpstg-share-button-facebook .share:active,\n.wpstg-share-button-googleplus .share:active {\n background-color: #353535;\n}\n\n#wpstg-check-space {\n margin-left: 8px;\n}\n\n\n/* welcome screen */\n\n.wpstg-button.green {\n display: inline-block;\n padding: 10px;\n min-width: 170px;\n font-size: 16px;\n text-decoration: none;\n text-align: center;\n margin-top: 20px;\n background-color: #83c11f;\n color: white;\n}\n\n.wpstg-button.green:hover {\n background-color: #8ed122;\n}\n\n.wpstg-button.wpstg-save {\n background-color: #1687A7;\n color: white;\n}\n\n.wpstg-button.wpstg-save:hover {\n background-color: #276678;\n}\n\n.wpstg-button.wpstg-bordered {\n border-radius:3px;\n font-size: 14px;\n border: 1px solid white;\n}\n\n#wpstg-welcome li {\n font-size: 18px;\n line-height: 29px;\n position: relative;\n padding-left: 23px;\n list-style: none !important;\n}\n\n#wpstg-welcome {\n margin-top: 20px;\n margin-right: 20px;\n background-color: white;\n}\n\n.wpstg-heading-pro {\n color: #0080ff;\n font-weight: bold;\n}\n\n.wpstg-h2 {\n margin-top: 0;\n margin-bottom: 1.2rem;\n font-size: 30px;\n line-height: 2.5rem;\n}\n\n#wpstg-welcome li:before {\n width: 1em;\n height: 100%;\n background: url(data:image/svg+xml;charset=utf8,%3Csvg%20width%3D%221792%22%20height%3D%221792%22%20viewBox%3D%220%200%201792%201792%22%20xmlns%3D%22http%3A%2F%2Fwww%2Ew3%2Eorg%2F2000%2Fsvg%22%3E%3Cpath%20fill%3D%22%2377B227%22%20d%3D%22M1671%20566q0%2040%2D28%2068l%2D724%20724%2D136%20136q%2D28%2028%2D68%2028t%2D68%2D28l%2D136%2D136%2D362%2D362q%2D28%2D28%2D28%2D68t28%2D68l136%2D136q28%2D28%2068%2D28t68%2028l294%20295%20656%2D657q28%2D28%2068%2D28t68%2028l136%20136q28%2028%2028%2068z%22%2F%3E%3C%2Fsvg%3E) left .4em no-repeat;\n background-size: contain;\n content: \"\";\n position: absolute;\n top: 0;\n left: 0;\n color: #77b227;\n}\n\n.wpstg-h1 {\n margin-bottom: 1.35rem;\n font-size: 2.5em;\n line-height: 3.68rem;\n letter-spacing: normal;\n}\n\n.swal2-content h1 {\n color:#444;\n}\n\n#wpstg-welcome h2 {\n margin: 0 0 15px;\n}\n\n#wpstg-welcome .wpstg-footer {\n clear: both;\n margin-top: 20px;\n font-style: italic;\n}\n\n#wpstg-footer {\n clear: both;\n background-color: white;\n padding: 20px;\n margin-top: 20px;\n margin-right: 10px;\n}\n\n#wpstg-footer a {\n text-decoration: none;\n}\n\n.wpstg-staging-info {\n margin-top: 8px;\n color: white;\n font-size: 12px;\n}\n\n.wpstg-staging-info a {\n color: white;\n}\n\n.wpstg-staging-info li {\n margin-bottom: 2px;\n}\n\n.wpstg-bold {\n font-weight: 600;\n}\n\n#wpstg-processing-status {\n margin-top: 5px;\n font-size: 13px;\n font-weight: 400;\n float: left;\n}\n\n#wpstg-processing-timer {\n margin-top: 5px;\n font-size: 13px;\n font-weight: 400;\n float: right;\n}\n\n#wpstg-report-issue-button {\n margin-left: 50px;\n border: 1px solid #ef5a4b;\n color: #ef5a4b;\n background-color: white;\n}\n\n#wpstg-report-issue-button:hover {\n background-color: #e74c3c;\n color: #fff;\n}\n\n.wpstg-button {\n display: inline-block;\n background-color: transparent;\n color: #95a5a6;\n border-radius: 3px;\n cursor: pointer;\n padding: 2px 10px 2px 10px;\n text-transform: uppercase;\n font-weight: 500;\n outline: 0;\n transition: background-color .1s ease-in;\n text-decoration: none;\n}\n\n.wpstg-button.wpstg-button-light {\n background-color: #f8f8f8;\n border: 1px solid #eee;\n color: #333;\n animation: background-color 0.3s;\n}\n\n.wpstg-button.wpstg-button-light:hover {\n background-color: #e0e0e0;\n border: 1px solid #e0e0e0;\n}\n\n.wpstg-blue-primary {\n display: inline-block;\n text-decoration: none;\n font-size: 13px;\n line-height: 26px;\n height: 28px;\n margin: 0;\n padding: 0 10px 1px;\n cursor: pointer;\n border-width: 1px;\n border-style: solid;\n -webkit-appearance: none;\n border-radius: 3px;\n white-space: nowrap;\n box-sizing: border-box;\n background: #25a1f0;\n border-color: #2188c9;\n color: #fff;\n text-shadow: 0 -1px 1px #006799, 1px 0 1px #006799, 0 1px 1px #006799, -1px 0 1px #006799;\n}\n\n.wpstg-blue-primary:hover {\n background-color: #259be6;\n}\n\n.wpstg-report-issue-form {\n position: absolute;\n z-index: 9999;\n width: 300px;\n background-color: #fff;\n padding: 15px 15px 10px;\n border: 1px solid #e8e8e8;\n border-radius: 3px;\n box-shadow: 0 1px 0 0 #fff inset;\n display: none;\n margin: 67px 0 0 123px;\n}\n\n.wpstg-report-show {\n display: block;\n}\n\n.wpstg-field input[type=text],\n.wpstg-field textarea {\n width: 100%;\n font-weight: 400;\n line-height: 1.4;\n margin-bottom: 4px;\n}\n\n.wpstg-report-email,\n.wpstg-report-hosting-provider {\n width: 100%;\n font-weight: 400;\n font-size: .8rem;\n height: 2.3rem;\n line-height: 2.3rem;\n border-radius: 3px;\n margin-bottom: 4px;\n padding: 0 10px;\n}\n\n.wpstg-report-description {\n border-radius: 3px;\n font-size: .8rem;\n padding: 6px 10px;\n resize: none;\n}\n\n.wpstg-report-privacy-policy {\n font-size: 12px;\n margin-bottom: 15px;\n}\n\n#wpstg-report-cancel {\n float: right;\n margin-right: 5px;\n}\n\n.wpstg-buttons .spinner {\n float: none;\n margin: 0 0 0 5px;\n}\n\n.wpstg-message {\n box-sizing: border-box;\n -moz-box-sizing: border-box;\n background-color: #f5e0de;\n border-radius: 3px;\n color: rgba(0, 0, 0, .6);\n height: auto;\n margin: 10px 0;\n min-height: 18px;\n padding: 6px 10px;\n position: relative;\n}\n\n.wpstg-message.wpstg-error-message {\n background-color: #f5e0de;\n color: #b65147;\n font-size: 12px;\n}\n\n.wpstg-message.wpstg-success-message {\n background-color: #d7f8e0;\n color: #515151;\n}\n\n.wpstg-message p {\n margin: 3px 0;\n font-size: 13px;\n}\n\n.wpstg-warning {\n display: block;\n padding: 10px;\n background-color: #ffb804;\n color: #ffffff;\n margin: 10px 10px 10px 0;\n}\n\n.wpstg-warning a {\n color: #ffffff;\n font-weight: bold;\n text-decoration: underline;\n}\n\n.wpstg-error {\n display: block;\n padding: 10px;\n background-color: #fe6501;\n color: #ffffff;\n margin: 10px 10px 10px 0;\n}\n\n.wpstg-error a {\n color: #ffffff;\n font-weight: bold;\n text-decoration: underline;\n}\n\n#wpstg-resume-cloning {\n display: none;\n}\n\n#wpstg-external-db th {\n text-align: left;\n width: 120px;\n}\n\n#wpstg-db-connect {\n font-weight: normal;\n}\n\n#wpstg-db-status {\n display: block;\n margin-top: 5px;\n padding: 5px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n border-radius: 4px;\n text-decoration: none;\n text-align: center;\n}\n\n.wpstg-text-field>#wpstg-db-status {\n margin-top: 8px;\n margin-left: 25%;\n min-width: 350px;\n}\n\n.wpstg-success {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #d6e9c6;\n}\n\n.wpstg-failed {\n color: #a94442;\n background-color: #f2dede;\n border-color: #ebccd1;\n}\n\n#wpstg_select_tables_cloning {\n height: 600px;\n font-size: 13px;\n}\n\n#wpstg-update-notify {\n background-color: #fe6501;\n font-size: 14px;\n color: #ffffff;\n line-height: normal;\n padding: 10px;\n margin-right: 10px;\n}\n\n#wpstg-update-notify a {\n color: #ffffff;\n font-weight: bold;\n}\n\n.wpstg-pointer {\n cursor: pointer;\n}\n\n.wpstg--tab--header ul {\n display: flex;\n}\n\n.wpstg--tab--header ul li {\n margin-right: 1em;\n}\n\n.wpstg--tab--header ul li:last-child {\n margin-right: 0;\n}\n\n.wpstg--tab--header a {\n min-width: 150px;\n text-align: center;\n cursor: pointer;\n display: inline-block;\n padding: 1em 1.25em;\n border: solid 1px;\n}\n\n.wpstg--tab--header a.wpstg--tab--active {\n border-bottom: .5em solid #25A1F0;\n color: #25A1F0;\n}\n\n.wpstg--tab--content {\n display: none;\n}\n\n.wpstg--tab--active {\n display: block;\n}\n\n.wpstg--text--strong,\n.wpstg--text--strong * {\n font-weight: bold !important;\n}\n\n.wpstg--text--danger {\n color: #a94442;\n}\n\n.wpstg--tooltip {\n position: relative;\n display: inline-block;\n border-bottom: 1px dotted black;\n margin-left: 10px;\n}\n\n.wpstg--tooltip .wpstg--tooltiptext {\n visibility: hidden;\n width: 300px;\n background-color: #ffffff;\n color: #505050;\n text-align: left;\n padding: 20px;\n border: 1px solid #e8e8e8;\n border-radius: 3px;\n position: absolute;\n z-index: 1;\n -webkit-box-shadow: -1px 1px 5px 0 rgba(0, 0, 0, 0.75);\n -moz-box-shadow: -1px 1px 5px 0 rgba(0, 0, 0, 0.75);\n box-shadow: -1px 1px 5px 0 rgba(0, 0, 0, 0.75);\n}\n\n.wpstg--tooltip:hover .wpstg--tooltiptext {\n visibility: visible;\n}\n\n.wpstg--tooltiptext-backups {\n width: 120px;\n top: 100%;\n left: -150%;\n margin-left: -60px;\n /* Use half of the width (120/2 = 60), to center the tooltip */\n margin-top: 10px;\n}\n\n\n/**\nTooltip top arrow\n */\n\n.wpstg--tooltip .wpstg--tooltiptext-backups::after {\n content: \" \";\n position: absolute;\n bottom: 100%;\n /* At the top of the tooltip */\n left: 50%;\n margin-left: 25px;\n border-width: 5px;\n border-style: solid;\n border-color: transparent transparent white transparent;\n}\n\n.wpstg--snaphot-restore-table tr {\n line-height: 12px;\n}\n\n.wpstg-float-left {\n float: left;\n}\n\n.wpstg-beta-notice {\n background-color: #b0e8b0;\n border-radius: 3px;\n padding: 7px;\n margin-bottom: 20px;\n}\n\n#wpstg-backup-name {\n font-size: 1.875em;\n font-weight: 600;\n}\n\n#wpstg_select_tables_cloning option:checked {\n /* Cannot use background color here because Chrome and Firefox ignore it even if set to !important */\n -webkit-appearance: menulist-button;\n background-image: linear-gradient(0deg, #1e90ff 0%, #1e90ff 100%);\n}\n\n.wpstg--btn--cancel {\n background: #ff3428;\n border-color: #e72f24;\n color: #fff;\n height: auto;\n line-height: normal;\n font-size: 16px;\n padding: .5em;\n margin-bottom: 1.5em;\n}\n\n.wpstg--btn--cancel:hover {\n background: #ff3428;\n border-color: #e72f24;\n}\n\n.wpstg--process--content>.swal2-html-container {\n padding: 4em 2em !important;\n}\n\n.wpstg--modal--process--logs,\n.wpstg--modal--error--logs {\n background: black;\n height: 300px;\n margin-top: 1em;\n display: none;\n padding: 1em;\n overflow-x: auto;\n text-align: justify;\n}\n\n.wpstg--modal--error--logs {\n height: auto;\n max-height: 300px;\n}\n\n.wpstg--modal--process--logs>p,\n.wpstg--modal--error--logs>p {\n text-align: left;\n font-size: 14px;\n}\n\n.wpstg--modal--process--logs p,\n.wpstg--modal--error--logs p {\n margin: .3em 0;\n}\n\n.wpstg--modal--process--msg--error {\n color: darkred;\n}\n\n.wpstg--modal--process--msg--critical {\n color: red;\n}\n\n.wpstg--modal--process--msg--warning {\n color: darkorange;\n}\n\n.wpstg--modal--process--msg-found {\n color: #f56363;\n}\n\nbody.toplevel_page_wpstg_clone .swal2-modal .swal2-cancel.wpstg--btn--cancel {\n margin-bottom: 0;\n}\n\nbody.toplevel_page_wpstg_clone .swal2-modal .swal2-confirm.wpstg--btn--confirm {\n font-size: 16px;\n padding: .5em;\n line-height: normal;\n height: auto;\n margin-right: 10px;\n}\n\nbody.toplevel_page_wpstg_clone .swal2-modal .wpstg-loader {\n display: inline-block !important;\n}\n\n.wpstg--modal--process--generic-problem {\n display: none;\n border-left: 5px solid #ef6d6d;\n margin: .5em 0;\n}\n\n.wpstg--modal--process--logs--tail {\n color: #a8a8a8;\n background: none;\n border: none;\n cursor: pointer;\n}\n\n.wpstg--modal--backup--import--upload--title {\n color: #505050;\n}\n\n.wpstg--modal--backup--import--filesystem,\n.wpstg--modal--backup--import--configure,\n.wpstg--modal--backup--import--upload--status,\n.wpstg--modal--backup--import--upload--container input[type=\"file\"] {\n display: none;\n}\n\n#wpstg--backups--import--file-list {\n font-size: 14px;\n font-weight: bold;\n}\n\n#wpstg--backups--import--file-list-empty {\n color: red;\n}\n\n.wpstg--modal--backup--import--filesystem label {\n font-size: 14px;\n}\n\n.wpstg--modal--backup--import--filesystem button {\n margin-bottom: 20px;\n}\n\n.wpstg--modal--backup--import--upload,\n.wpstg--modal--backup--import--filesystem {\n color: #505050;\n}\n\n.wpstg--modal--backup--import--upload--container {\n position: relative;\n border-radius: 1em;\n margin: .5em;\n padding: 1em .5em;\n border: .4em dashed #dedede;\n display: flex;\n flex-direction: column;\n}\n\n.wpstg--modal--backup--import--upload--container .wpstg--uploader {\n display: flex;\n flex-direction: column;\n}\n\n.wpstg--modal--backup--import--upload--container.wpstg--has-dragover {\n background-color: #9a9a9a;\n color: white;\n}\n\n.wpstg--modal--backup--import--upload--container span.wpstg--drop,\n.wpstg--modal--backup--import--upload--container.wpstg--has-dragover span.wpstg--drag,\nspan.wpstg--backup--import--selected-file,\nspan.wpstg--drag-or-upload {\n display: none;\n}\n\n.wpstg--modal--backup--import--upload--container.wpstg--has-dragover span.wpstg--drop {\n display: inline-block;\n}\n\n.wpstg--modal--backup--import--upload--container input[type='file'] {\n display: none;\n}\n\n.wpstg--modal--backup--import--upload--container img {\n width: 4em;\n align-self: center;\n border: none;\n}\n\n.wpstg--modal--backup--import--upload--container span {\n margin-top: 1em;\n}\n\n.wpstg--backup--import--options>button {\n margin-top: 1em;\n padding: 1em;\n align-self: center;\n width: 185px;\n height: auto;\n line-height: normal;\n}\n\n\n/*.wpstg--backup--import--options.wpstg--show-options > button {\n background: white;\n border-radius: 3px 3px 0 0;\n border: .25em solid #25a1f0;\n text-shadow: none;\n color: #2e3436;\n}*/\n\n.wpstg--backup--import--options {\n position: relative;\n display: flex;\n justify-content: center;\n}\n\n.wpstg--backup--import--options ul {\n display: none;\n}\n\n.wpstg--backup--import--options.wpstg--show-options ul {\n padding: 0;\n margin: 54px 0 0 0;\n display: block;\n position: absolute;\n width: 185px;\n background: #25a1f0;\n box-sizing: border-box;\n border-radius: 0 0 3px 3px;\n border-width: 1px;\n border-color: #2188c9;\n text-shadow: 0 -1px 1px #006799, 1px 0 1px #006799, 0 1px 1px #006799, -1px 0 1px #006799;\n}\n\n.wpstg--backup--import--options.wpstg--show-options ul li {\n border-bottom: .1em solid #25a1f0;\n margin: 0;\n}\n\n.wpstg--backup--import--options.wpstg--show-options ul li:hover {\n background-color: #25a1f0;\n}\n\n.wpstg--backup--import--options.wpstg--show-options ul li:last-child {\n border-bottom: none;\n}\n\n.wpstg--backup--import--options ul li button {\n cursor: pointer;\n background: none;\n border: none;\n margin: 0;\n width: 100%;\n color: white;\n height: 40px;\n line-height: 40px;\n}\n\n.wpstg--backup--import--options ul li button:hover {\n background-color: #259be6;\n}\n\n.wpstg--modal--backup--import--search-replace--info {\n margin: 1em 0;\n display: flex;\n flex-direction: row;\n}\n\n.wpstg--modal--backup--import--info p {\n text-align: left;\n margin: 0;\n}\n\n\n/* unused class should be removed or commented\n.wpstg--modal--backup--import--search-replace--wrapper {\n display: flex;\n flex-direction: row;\n padding: 0 5em;\n}\n*/\n\n.wpstg--modal--backup--import--search-replace--wrapper button {\n align-self: center;\n}\n\n.wpstg--import--advanced-options--button {\n border: 0;\n border-radius: 3px;\n font-size: 18px;\n text-shadow: 0 -1px 1px #006799, 1px 0 1px #006799, 0 1px 1px #006799, -1px 0 1px #006799;\n cursor: pointer;\n}\n\n.wpstg--modal--backup--import--search-replace--new {\n color: white;\n background-color: #25a1f0;\n}\n\n.wpstg--modal--backup--import--search-replace--remove {\n color: white;\n background-color: #25a1f0;\n width: 22px;\n height: 22px;\n margin-left:5px;\n}\n\n.wpstg--modal--backup--import--search-replace--input-group:first-child button {\n display: none;\n}\n\n.wpstg--modal--backup--import--search-replace--input--container {\n flex: 1;\n display: flex;\n flex-direction: column;\n}\n\n.wpstg--modal--backup--import--search-replace--input-group {\n width: 100%;\n border-bottom: 6px solid #f1f1f1;\n margin-bottom: 10px;\n}\n\n.wpstg--modal--backup--import--search-replace--input-group input {\n min-width: 250px;\n width: calc(50% - 4px - 11px - 5px); /* -4px is half of the padding; -11px is half of the button; -5 is the margin left of the button */\n display: inline-block;\n line-height: 10px;\n border: 1px solid #dedede;\n border-radius: 3px;\n color: #666;\n padding: 8px;\n margin-bottom: 12px;\n}\n\n.wpstg--modal--import--upload--process {\n display: none;\n position: absolute;\n /*display: flex;*/\n width: 100%;\n height: 100%;\n top: 0;\n left: 0;\n text-indent: 1em;\n white-space: nowrap;\n overflow: hidden;\n color: #898989;\n mix-blend-mode: difference;\n justify-content: center;\n align-items: center;\n}\n\n.wpstg--modal--import--upload--progress {\n position: absolute;\n background: #dedede;\n color: white;\n width: 0;\n height: 100%;\n border-radius: 1em;\n left: -1px;\n top: 0;\n}\n\n.wpstg--modal--import--upload--progress--title {\n z-index: 9;\n}\n\n.wpstg-fieldset:disabled {\n opacity: 0.8;\n border-top: 1px solid white;\n margin-top: 20px;\n}\n\n.wpstg-fs-14 {\n font-size: 14px;\n}\n\n.wpstg-light-alert {\n font-weight: bold;\n background-color: #e6e6e6;\n padding: 15px;\n border-top: 1px solid white;\n margin-top: 20px;\n}\n\n.wpstg-form-group {\n display: flex;\n flex-wrap: wrap;\n width: 100%;\n margin-bottom: 8px;\n}\n\n.wpstg-form-group>label {\n display: inline-block;\n font-weight: 700;\n min-width: 25%;\n width: 25%;\n}\n\n.wpstg-text-field>input {\n width: 350px;\n display: inline-block;\n}\n\n.wpstg-code-segment {\n display: block;\n}\n\n.wpstg-text-field>.wpstg-code-segment {\n margin-top: 4px;\n margin-left: 25%;\n min-width: 350px;\n}\n\n.wpstg-form-group>.wpstg-checkbox {\n min-width: 100%;\n width: 100%;\n position: relative;\n}\n\n.wpstg-form-group>.wpstg-checkbox>input[type='checkbox'] {\n left: 25%;\n}\n\n.wpstg-rounded {\n border-radius: 3px;\n}\n\n.wpstg-white-border {\n border: 1px solid white !important;\n}\n\n.wpstg-mt-16 {\n margin-top: 16px;\n}\n\n.wpstg-w-100pc {\n width: 100%;\n}\n\n#wpstg-confirm-backup-restore-data {\n margin: 40px;\n text-align: left;\n}\n\n#wpstg-confirm-backup-restore-wrapper {\n margin: 30px;\n}\n\n#wpstg-confirm-backup-restore-wrapper h3 {\n color: #f56363;\n}\n\n#swal2-content h2 {\n color: #a8a8a8;\n}\n\n#wpstg_allow_emails {\n margin-left: 10px;\n}\n\n#wpstg-advanced-settings hr {\n margin: 20px 0;\n}\n\n.wpstg-form-row {\n display: block;\n}\n\n.wpstg-form-row label,\n.wpstg-form-row input {\n display: table-cell;\n padding-left: 5px;\n padding-right: 5px;\n margin-top: 3px;\n margin-bottom: 3px;\n}\n\n.wpstg-form-row input {\n width: 400px;\n}\n\n.wpstg-form-row label {\n font-weight: bold;\n width: 1px;\n white-space: nowrap;\n}\n\n#wpstg-db-connect-output #wpstg-db-status {\n width: 390px;\n}\n\n#wpstg_symlink_upload {\n margin-left: 10px;\n}\n\n.wpstg-fieldset:disabled {\n opacity: 0.8;\n border-top: 1px solid white;\n margin-top: 20px;\n}\n\n.wpstg-fs-14 {\n font-size: 14px;\n}\n\n.wpstg-light-alert {\n font-weight: bold;\n background-color: #e6e6e6;\n padding: 15px;\n border-top: 1px solid white;\n margin-top: 20px;\n}\n\n.wpstg-form-group {\n display: flex;\n flex-wrap: wrap;\n width: 100%;\n margin-bottom: 8px;\n}\n\n.wpstg-form-group>label {\n display: inline-block;\n font-weight: 700;\n min-width: 25%;\n width: 25%;\n}\n\n.wpstg-text-field>input {\n width: 350px;\n display: inline-block;\n}\n\n.wpstg-code-segment {\n display: block;\n}\n\n.wpstg-text-field>.wpstg-code-segment {\n margin-top: 4px;\n margin-left: 25%;\n min-width: 350px;\n}\n\n.wpstg-form-group>.wpstg-checkbox {\n min-width: 100%;\n width: 100%;\n}\n\n.wpstg-form-group>.wpstg-checkbox>input[type='checkbox'] {\n margin-left: 10px;\n}\n\n@media only screen and (max-width: 768px) {\n .wpstg-form-group {\n display: block;\n }\n .wpstg-form-group>label {\n display: block;\n min-width: auto;\n width: auto;\n }\n .wpstg-text-field>input {\n width: 100%;\n display: block;\n }\n .wpstg-text-field>.wpstg-code-segment {\n margin-left: 0;\n min-width: 100%;\n }\n .wpstg-tab-section {\n width: calc(100vw - 60px);\n max-width: calc(100vw - 60px);\n }\n}\n\n.wpstg-rounded {\n border-radius: 3px;\n}\n\n.wpstg-white-border {\n border: 1px solid white !important;\n}\n\n.wpstg-m-0 {\n margin: 0;\n}\n\n.wpstg-mt-16 {\n margin-top: 16px;\n}\n\n.wpstg-mt-10px {\n margin-top: 10px;\n}\n\n.wpstg-my-10px {\n margin-top: 10px;\n margin-bottom: 10px;\n}\n\n.wpstg-w-100 {\n width: 100%;\n}\n\n.wpstg-box-shadow {\n box-shadow: 0 1px 1px 0 rgba(0, 0, 0, .1);\n}\n\n.wpstg-float-left {\n float: left;\n}\n\n.wpstg-fivestar {\n border-left: none;\n background-color: #59a7f7;\n color: white;\n padding: 10px;\n margin: 10px 10px 10px 0;\n}\n\n.wpstg-bold-text {\n font-weight: bold;\n}\n\n.wpstg-rating-link {\n font-weight: normal;\n color: white;\n}\n\n.wpstg-warning.notice {\n border-left: 4px solid #ffba00;\n}\n\n.wpstg-confirmation-label {\n background-color: #5b9dd9;\n color: #fff;\n padding: 2px;\n border-radius: 3px;\n}\n\n.wpstg-my-6px {\n margin-bottom: 6px;\n margin-top: 6px;\n}\n\n.wpstg-mb-10px {\n margin-bottom: 10px;\n}\n\n.wpstg-opacity-80 {\n opacity: 0.8;\n}\n\n.wpstg-clear-both {\n clear: both;\n}\n\n.wpstg-fs-10px {\n font-size: 10px;\n}\n\n.wpstg-font-italic {\n font-style: italic;\n}\n\n.wpstg-mt-20px {\n margin-top: 20px;\n}\n\n.wpstg-welcome-container {\n border: 2px solid white;\n padding: 20px;\n margin-bottom: 20px;\n}\n\n.wpstg-ml-30px {\n margin-left: 30px;\n}\n\n.wpstg-text-center {\n text-align: center;\n}\n\n.wpstg-feedback-link {\n text-decoration: none;\n color: #abc116\n}\n\n.wpstg-feedback-span {\n display: block;\n margin-bottom: 20px;\n color: #abc116;\n}\n\n#wpstg-confirm-backup-restore-data {\n margin: 40px;\n text-align: left;\n}\n\n#wpstg-confirm-backup-restore-wrapper {\n margin: 30px;\n}\n\n#wpstg-confirm-backup-restore-wrapper h3 {\n color: #f56363;\n}\n\n#wpstg-footer {\n clear: both;\n padding-top: 20px;\n}\n\n#swal2-content h2 {\n color: #a8a8a8;\n}\n\n#wpstg-progress-db,\n#wpstg-progress-backup {\n background-color: #3fa5ee;\n}\n\n#wpstg-progress-sr,\n#wpstg-progress-files.wpstg-pro {\n background-color: #3c9ee4;\n}\n\n#wpstg-progress-dirs,\n#wpstg-progress-data {\n background-color: #3a96d7;\n}\n\n#wpstg-progress-files:not(.wpstg-pro),\n#wpstg-progress-finishing {\n background-color: #378cc9;\n}\n\n.wpstg-issue-resubmit-confirmation.swal2-container, \n.wpstg-swal2-container.swal2-container {\n z-index: 10500;\n}\n\n.wpstg-swal2-container.wpstg-swal2-loading .swal2-actions,\n.wpstg-swal2-container.wpstg-swal2-loading .swal2-header {\n display: none;\n}\n\nbody.toplevel_page_wpstg_clone .swal2-container .swal2-content {\n z-index:2;\n}\n\ndiv#exportUploadsWithoutDatabaseWarning {\n font-style: italic;\n font-size: 0.9rem;\n margin: 10px;\n padding: 10px;\n border: 1px solid #e3e3e3;\n border-radius: 5px;\n text-align: center;\n background-color: #fafafa;\n}\n\n.wpstg-advanced-options-dropdown-wrapper {\n display: none; /* ENABLE WHEN WE HAVE ADVANCED OPTIONS FOR EXPORTING */\n margin-top: 20px;\n}\n\n.wpstg--modal--backup--import--search-replace--wrapper {\n text-align: left;\n margin-top: 20px;\n}\n\n.wpstg--modal--backup--import--search-replace--new--wrapper {\n text-align: center;\n}\n\n.wpstg-import-backup-contains li {\n display: inline-block;\n}\n\n.wpstg-import-backup-contains li .dashicons{\n border-radius: 3px;\n color: #979797;\n background-color: #e3e3e3;\n border: 1px solid #c2c2c2;\n width: 17px;\n height: 17px;\n font-size: 17px;\n}\n\n.wpstg-import-backup-contains.wpstg-listing-single-backup li .dashicons{\n padding: 2px;\n color: #ffffff;\n background-color: #2896dd;\n border: 1px solid #0c75b8;\n}\n\n.wpstg-import-backup-contains .wpstg--tooltiptext {\n width: 50px;\n font-size: x-small;\n padding: 5px;\n left: -25px;\n text-align: center;\n}\n\n.wpstg-import-backup-contains-title {\n display: inline-block;\n}\n\nul.wpstg-import-backup-contains {\n display: inline-block;\n}\n\n.wpstg-import-backup-name {\n display: inline-block;\n font-weight: bold;\n}\n\n.wpstg-backup-more-info-toggle {\n font-size: x-small;\n display: inline-block;\n font-style: italic;\n cursor:pointer;\n}\n\n.wpstg-backup-more-info-toggle::selection {\n background:none;\n}\n\nul.wpstg-import-backup-more-info {\n font-size: 14px;\n text-align: left;\n margin-bottom: 30px;\n margin-top: 10px;\n background-color: #f6f6f6;\n border: 1px solid #878787;\n border-radius: 3px;\n padding: 7px;\n cursor: pointer;\n}\n\nul.wpstg-import-backup-more-info:hover {\n background-color: #def2ff;\n border: 1px solid #25a1f0;\n}\n\nul.wpstg-import-backup-more-info li {\n height: 20px;\n}\n\n.wpstg-backup-list ul ul {\n margin-block-start: 1em;\n margin-block-end: 1em;\n}\n\n.wpstg-push-confirmation-message {\n text-align: justify;\n}\n\n.wpstg-settings-row {\n padding-top: 10px;\n padding-bottom: 10px;\n}\n\n.wpstg-settings-title {\n font-weight: 600;\n}\n\n.wpstg-settings-form-group {\n display: flex;\n align-items: center;\n}\n\n.wpstg-settings-form-group > .wpstg-settings-message {\n width: 30%;\n padding: 0;\n margin: 7px 0 0;\n}\n\n/**\n * WP STAGING EXCLUSION RULES TABLE LAYOUT\n */\n\n.wpstg-excluded-filters-container {\n padding: 0;\n\tmargin-top: 10px;\n margin-bottom: 10px;\n\tmax-width: 100%;\n width: 100%;\n}\n\n.wpstg-excluded-filters-container > table {\n width: 100%;\n border-collapse: collapse;\n border-color: transparent;\n}\n\n.wpstg-excluded-filters-container td {\n padding-top: 4px;\n padding-bottom: 4px;\n height: 20px;\n}\n\n.wpstg-excluded-filters-container h4 {\n margin: 0;\n}\n\n/*.wpstg-excluded-filters-container tbody {\n\tbackground: #fff !important;\n}*/\n\n.wpstg-exclude-filters-foot {\n display: flex;\n justify-content: flex-start;\n padding: 0;\n}\n\n.wpstg-excluded-filters-container .wpstg-exclude-filter-name-column {\n width: 100px;\n max-width: 100px !important;\n padding-left: 10px;\n}\n\n.wpstg-excluded-filters-container .wpstg-exclude-filter-action-column {\n width: 50px;\n max-width: 50px;\n\ttext-align: right !important;\n padding-right: 10px;\n}\n\n.wpstg-excluded-filters-container .wpstg-exclude-filter-exclusion-column {\n width: 320px;\n position: relative;\n}\n\n/**\n * WP STAGING EXCLUSION RULE DROPDOWN STYLE\n */\n\n.wpstg-exclude-filter-dropdown > button {\n background: #25A0F1;\n border: 1px solid #25A0F1;\n color: #fff;\n padding: 1px 5px;\n display: inline-block;\n font-weight: 400;\n line-height: 1.5;\n text-align: center;\n border-radius: 0;\n outline: none;\n box-shadow: none;\n cursor: pointer;\n height: 24px;\n}\n\n.wpstg-exclude-filter-dropdown > button:hover {\n background: #135e96;;\n border: 1px solid #135e96;;\n}\n\n.wpstg-exclude-filter-dropdown > .wpstg-dropdown-menu {\n width: 128px;\n}\n\n.wpstg-remove-exclude-rule {\n color: #fff !important;\n background-color: #dc3545;\n border: 1px solid #dc3545;\n width: 20px;\n\theight: 20px;\n\tborder-radius: 10px;\n\tfont-size: 24px;\n\tpadding: 0;\n\tdisplay: inline-flex;\n\tjustify-content: center;\n outline: none;\n box-shadow: none;\n font-weight: 400;\n line-height: 0.7;\n margin-top: 5px;\n cursor: pointer;\n}\n\n.wpstg-remove-exclude-rule:hover {\n background-color: #bb2d3b;\n border-color: #bb2d3b;\n}\n\n/**\n * WP STAGING POPOVER EXCLUSION RULES INFO\n */\n\n .wpstg-popover {\n\tdisplay: inline-block;\n\tposition: relative;\n}\n\n.wpstg-popover button + p {\n\tposition: absolute;\n\ttop: 18px;\n\tright: -150px;\n\tdisplay: none;\n\twidth: 320px;\n\tz-index: 1024;\n\tpadding: 10px !important;\n\tbox-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);\n}\n\n.wpstg-popover button:hover + p {\n\tdisplay: block;\n}\n\n.wpstg-code-block {\n\tmargin-top: 4px;\n\tfont-size: 1.2em;\n\tbackground: #f8f8f8;\n\tborder-radius: 2px;\n}\n\n.wpstg-rule-info {\n background: #f8f8f8 !important;\n}\n\ncode.wpstg-code {\n display: inline-block;\n font-size: 11px;\n\tborder: 1px solid #aaa;\n\tbackground: #fff;\n\tpadding: 2px 4px;\n margin-bottom: 1px;\n color: #ff6666;\n}\n\n.wpstg-exclusion-rule-info {\n color: #fff !important;\n background-color: #ffc107;\n border: 1px solid #ffc107;\n width: 14px;\n\theight: 14px;\n\tborder-radius: 7px;\n\tfont-size: 14px;\n\tpadding: 0;\n\tdisplay: inline-flex;\n\tjustify-content: center;\n align-items: center;\n outline: none;\n box-shadow: none;\n font-weight: 400;\n vertical-align: middle;\n}\n\n.wpstg-exclusion-rule-info:hover {\n background-color: #ffba0c;\n border: 1px solid #ffba0c;\n}\n\n/**\n * WP STAGING INPUTS EXCLUSION RULES\n */\n\n .wpstg-exclude-rule-input {\n font-size: 12px !important;\n padding: 2px 6px;\n box-shadow: none;\n outline: none !important;\n display: inline-block;\n font-weight: 400;\n line-height: 1.5;\n color: #222;\n border-radius: 0 !important;\n background-color: #fff;\n border: 1px solid #bbb;\n min-height: 24px !important;\n margin-top: 4px;\n margin-left: 4px;\n vertical-align: baseline !important;\n transition: all 0.3s cubic-bezier(.25,.8,.25,1);\n width: 135px;\n}\n\n.wpstg-excluded-filters-container tbody > tr:last-child .wpstg-exclude-rule-input {\n\tmargin-bottom: 4px;\n}\n\n.wpstg-exclude-rule-input:hover {\n border: 1px solid #999;\n}\n\n.wpstg-exclude-rule-input:focus {\n border: 1px solid #25A0F1 !important;\n box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24) !important;\n}\n\n.wpstg-file-size-exclude-select,\n.wpstg-path-exclude-select {\n width: 135px;\n}\n\n.wpstg-file-size-exclude-select-small {\n width: 52px;\n}\n\n.wpstg-file-size-exclude-input {\n width: 75px;\n}\n\n.wpstg-staging-option-title {\n margin: 15px 0 0;\n}\n\n.wpstg-swal-push-container.swal2-container {\n z-index: 9995;\n}\n\n#wpstg-scanning-files {\n padding-bottom: 5px;\n}\n\n#wpstg-scanning-files.wpstg-tab-section{\n padding-top:0;\n}\n\n.wpstg-reset-excludes-container {\n margin: 10px 0;\n}\n\n.wpstg-swal2-ajax-loader {\n width: 100%;\n height: 150px;\n overflow: hidden;\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n@keyframes wpstg-loading-icon-anim {\n\t0% {\n\t\ttransform: rotate(0);\n\t}\n\t100% {\n\t\ttransform: rotate(360deg);\n\t}\n}\n\n.wpstg-swal2-ajax-loader > img {\n width: 64px;\n height: 64px;\n animation: wpstg-loading-icon-anim 1s infinite linear;\n -webkit-animation: wpstg-loading-icon-anim 1s infinite linear;\n}\n\n.wpstg-swal2-container .wpstg-tab-section {\n width: auto !important;\n}\n\n.wpstg-is-dir-loading {\n position: absolute;\n margin-top: -2px;\n margin-left: 8px;\n display: none;\n}\n\n.wpstg-ml-8px {\n margin-left: 8px;\n}\n\n.wpstg-mb-8px {\n margin-bottom: 8px;\n}\n\n.wpstg-button.danger {\n display: inline-block;\n text-decoration: none;\n text-align: center;\n text-transform: inherit;\n background-color: #e74c3c;\n color: white;\n border-radius: 0px;\n border-color: transparent;\n}\n\n.wpstg-button.danger:hover {\n background-color: #c0392b;\n}\n\n.wpstg-swal2-container.wpstg-swal2-loading > .swal2-modal {\n height: 200px;\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container:not(.wpstg-swal2-loading) > .swal2-modal {\n max-width: 480px;\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container .swal2-header {\n display: none;\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container .swal2-content {\n height: auto;\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container > .swal2-modal > .swal2-content .wpstg-tabs-wrapper {\n overflow-y: auto;\n height: auto !important;\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container > .swal2-modal > .swal2-content {\n font-size: 13px;\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container > .swal2-modal > .swal2-content .wpstg-dir {\n margin-bottom: 4px;\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container > .swal2-modal > .swal2-content .wpstg-subdir {\n margin-top: 4px;\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container.has-collapsible-open .swal2-modal {\n height: calc(100vh - 70px);\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container.has-collapsible-open > .swal2-modal > .swal2-content .wpstg-tabs-wrapper {\n height: calc(100vh - 350px) !important;\n}\n"]}
1
+ {"version":3,"sources":["wpstg-admin.css"],"names":[],"mappings":"AAWA,eACI,aACJ,CAEA,sBACI,wBACJ,CAEA,YACI,aACJ,CAEA,gBACI,aACJ,CAEA,aACI,aACJ,CAEA,iBACI,aACJ,CAEA,cACI,aACJ,CAEA,aACI,aACJ,CAEA,iBACI,aACJ,CAIA,wBAII,kBAAmB,CACnB,UAAW,CAJX,eAAgB,CAChB,QAAS,CACT,SAGJ,CAEA,oDACI,eACJ,CAEA,0CACI,eAAiB,CACjB,oBACJ,CAEA,0BAEI,mBAAoB,CADpB,gBAEJ,CAEA,uCACI,SACJ,CAEA,wEAEI,eACJ,CAEA,cACI,WACJ,CAEA,6CACI,qBACJ,CAEA,gGAEI,YACJ,CAEA,2CAEI,aAAc,CADd,mBAEJ,CAEA,0CAOI,aAAc,CADd,cAAe,CADf,eAAiB,CADjB,eAAgB,CADhB,wBAAyB,CADzB,eAAgB,CADhB,kBAAmB,CAOnB,SACJ,CAEA,0CACI,+BACJ,CAEA,sCAMI,aAAc,CALd,aAAc,CAGd,cAAe,CADf,iBAAkB,CADlB,eAAgB,CAGhB,cAEJ,CAEA,gCACI,aACJ,CAEA,yCACI,wBACI,UACJ,CAEA,6CACI,UACJ,CAEA,sCACI,cACJ,CAEA,0FAEI,YACJ,CACJ,CAEA,2BACI,eACJ,CAEA,6BAMI,+BAA4B,CAF5B,uBAAmB,CADnB,mBAAmB,CACnB,wBAAmB,CADnB,oBAAmB,CAEnB,yBAAuB,CAGvB,aAAc,CAPd,aAAc,CAQd,eAAiB,CAPjB,0BAA2B,CAK3B,oBAGJ,CAEA,mCACI,wBAAyB,CACzB,UACJ,CAEA,YACI,aAAc,CAId,UAAW,CAHX,cAAe,CACf,gBAAiB,CACjB,WAEJ,CAEA,gBACI,eACJ,CAEA,eAGI,aAAc,CAFd,aAAc,CACd,gBAEJ,CAEA,sBACI,aACJ,CAEA,uDACI,cACJ,CAIA,yBACI,kBAAmB,CACnB,SACJ,CAEA,qCACI,yBACI,UAAW,CACX,kBACJ,CACJ,CAEA,aAEI,gBAAiB,CADjB,YAEJ,CAEA,gBACI,UAAW,CAGX,UAAW,CAFX,gBAAiB,CACjB,kBAEJ,CAEA,gBACI,wBAAyB,CACzB,iBAAkB,CAClB,oBAAqB,CAErB,WAAY,CAEZ,gBAAiB,CADjB,iBAAkB,CAFlB,UAIJ,CAEA,oBACI,eACJ,CAEA,oCACI,kBAAmB,CACnB,UACJ,CAEA,WACI,aAAc,CAGd,eAAgB,CAFhB,YAIJ,CAEA,wBALI,iBAAkB,CAElB,uCAYJ,CATA,aAKI,qBAAyB,CAEzB,iBAAkB,CAClB,4DAAoE,CAFpE,aAAc,CALd,kBAAmB,CACnB,YAOJ,CAEA,oBACI,oBACJ,CAEA,oBAGI,kBAAmB,CAFnB,YAAa,CACb,6BAEJ,CAEA,mBAMI,aAAc,CALd,oBAAqB,CACrB,cAAe,CAGf,eAAiB,CAFjB,eAAgB,CAChB,oBAGJ,CAEA,yBACI,UACJ,CAEA,qBACI,YAAa,CACb,cACJ,CAMA,6CAEI,kBAAmB,CAEnB,iBAAkB,CAElB,4DAAoE,CACpE,UAAc,CAFd,cAAe,CAFf,gBAAiB,CAFjB,oBAOJ,CAEA,mDACI,kBAAmB,CACnB,UACJ,CAEA,gBACI,iBACJ,CAEA,qCACI,eAAgB,CAOhB,iBAAkB,CAElB,4DAAoE,CARpE,YAAa,CACb,qBAAsB,CAItB,WAAY,CAHZ,iBAAkB,CAClB,OAAQ,CACR,oBAAqB,CAGrB,WAAY,CAEZ,YACJ,CAEA,uDAEI,WAAY,CADZ,QAAS,CAET,+BACJ,CAEA,2CACI,YACJ,CAEA,2CAQI,+BAAgC,CAJhC,iBAAkB,CAFlB,aAAc,CACd,eAAgB,CAGhB,iBAAkB,CADlB,oBAAqB,CAErB,gCAEJ,CAEA,uDAEI,0BACJ,CAEA,uBAEI,sBAAuB,CACvB,mBAAqB,CAErB,eAAgB,CAJhB,aAAc,CAGd,YAEJ,CAEA,0BACI,aACJ,CAEA,+BACI,WACJ,CAEA,uCACI,oBACJ,CAEA,oEAGI,eAAgB,CADhB,YAEJ,CAEA,gBACI,kBAAmB,CACnB,UAAW,CACX,oBAAqB,CACrB,gBAAiB,CACjB,oBAAqB,CAErB,8BAA+B,CAD/B,uBAEJ,CAEA,4CAII,eAAgB,CAFhB,UAAW,CACX,YAEJ,CAEA,uCACI,uBACJ,CAEA,0BACI,yBAA2B,CAC3B,2BAA6B,CAC7B,mBACJ,CAEA,mDAEI,cACJ,CAEA,8BAEI,kBAAmB,CACnB,oBACJ,CAEA,0CAKI,UAAW,CAHX,YAAa,CAEb,cAAe,CADf,gBAGJ,CAEA,0BAGI,UAAW,CAFX,oBAAqB,CACrB,eAAgB,CAEhB,oBAAqB,CACrB,gCACJ,CAEA,gCACI,aACJ,CAEA,qBACI,6BAA8B,CAC9B,YAAa,CACb,WACJ,CAEA,iBACI,YACJ,CAEA,iBACI,WACJ,CAEA,cACI,kCAAqC,CAErC,YAAa,CADb,eAEJ,CAEA,6BAGI,wBAAyB,CAIzB,iBAAkB,CAHlB,UAAY,CAFZ,kBAAmB,CADnB,aAAc,CAKd,YAAa,CADb,gBAGJ,CAEA,gBAGI,UAAW,CAEX,UAAW,CAJX,eAAgB,CAMhB,gBAAiB,CADjB,eAAgB,CAGhB,mBAAoB,CADpB,kBAAmB,CAJnB,gBAAiB,CAFjB,iBAQJ,CAEA,eAGI,aAAc,CAFd,UAAW,CAGX,gBAAiB,CAFjB,eAGJ,CAEA,kEAEI,6BAAmC,CACnC,uDAAwD,CACxD,aAAc,CAGd,cAAe,CADf,WAAY,CAMZ,MAAO,CAJP,iBAAkB,CAElB,iBAAkB,CADlB,iBAAkB,CAElB,KAAM,CANN,UAAW,CAQX,UACJ,CAEA,oCACI,4BACJ,CAEA,6CAEI,iBACJ,CAEA,0BACI,aACJ,CAEA,yCACI,aACJ,CAEA,oBAII,wBAAyB,CAFzB,WAAY,CADZ,eAAgB,CAEhB,SAEJ,CAEA,gBAEI,kBAAmB,CADnB,UAAW,CAQX,eACJ,CAEA,sCANI,UAAY,CAFZ,WAAY,CAGZ,gBAAiB,CACjB,iBAAkB,CAHlB,yBAA0B,CAF1B,OAiBJ,CARA,sBACI,kBAOJ,CAEA,0EAEI,wBAAyB,CACzB,qCACJ,CAEA,oBAGI,gBAAiB,CADjB,cAAe,CADf,WAGJ,CAEA,iBACI,kBAAmB,CACnB,oBACJ,CAEA,uBACI,kBAAmB,CACnB,oBACJ,CAEA,kBACI,gBAAiB,CACjB,WACJ,CAEA,iBACI,aACJ,CAEA,sBAEI,wBAAyB,CADzB,aAAc,CAGd,WAAY,CADZ,YAEJ,CAEA,sCACI,aAAc,CACd,cACJ,CAEA,iBACI,UAAW,CACX,eAAmB,CAEnB,QAAS,CADT,iBAEJ,CAEA,iCACI,OACJ,CAEA,sBACI,wBACJ,CAEA,qCACI,eAAgB,CAChB,uBACJ,CAKA,oBAEI,aAAc,CADd,eAEJ,CAEA,oBACI,6BAA8B,CAE9B,kBAAmB,CADnB,mBAEJ,CAEA,mBACI,4BAA6B,CAE7B,gBAAiB,CADjB,iBAAkB,CAElB,YAAa,CAEb,cAAiB,CADjB,uBAEJ,CAEA,yBAGI,UAAW,CADX,UAAW,CADX,aAGJ,CAEA,kBACI,4BAA6B,CAE7B,gBAAiB,CADjB,iBAAkB,CAElB,UAAW,CAGX,aAAc,CAFd,cAAe,CACf,eAAiB,CAEjB,YAAa,CACb,oBACJ,CAEA,oBAGI,uBAAyB,CAFzB,oBAAqB,CACrB,iBAEJ,CAEA,wBAGI,eAAgB,CAFhB,UAAW,CACX,YAEJ,CAEA,mBAEI,sBAAuB,CADvB,YAAa,CAKb,cAAe,CAFf,eAAgB,CADhB,YAAuB,CAEvB,iBAEJ,CAEA,sBACI,eAAgB,CAKhB,QAAS,CAJT,QAAS,CACT,aAAc,CACd,iBAAkB,CAClB,SAEJ,CAEA,cACI,YAAa,CACb,gBACJ,CAEA,yBACI,aAAc,CACd,gBACJ,CAEA,sBACI,UAAW,CACX,cAAe,CACf,oBACJ,CAEA,qBACI,oBAAqB,CACrB,gBACJ,CAEA,oBAEI,wBAAyB,CAIzB,UACJ,CAEA,yCARI,aAAc,CAId,eAAgB,CADhB,eAAgB,CADhB,YAYJ,CANA,qBAEI,qBAIJ,CAMA,6CACI,UACJ,CAEA,cAII,+BAAgC,CAChC,UAAW,CAFX,cAAe,CAFf,eAAgB,CAChB,iBAAkB,CAIlB,gBACJ,CAEA,mBACI,cAAe,CACf,eACJ,CAEA,mBAQI,qBAAuB,CADvB,qBAAsB,CAEtB,YAAc,CALd,qBAAsB,CACtB,cAAe,CAJf,YAAa,CAKb,gBAAiB,CAMjB,eAAgB,CAThB,eAAgB,CADhB,eAAgB,CAQhB,WAAY,CACZ,kBAEJ,CAEA,uBACI,YACJ,CAEA,sBACI,kBAAmB,CACnB,oBAAqB,CACrB,cACJ,CAEA,sBAEI,qBAAuB,CAEvB,qBAAsB,CACtB,eAAgB,CAFhB,eAAgB,CAFhB,YAKJ,CAEA,mBACI,kBACJ,CAEA,eAEI,YAAa,CADb,WAEJ,CAEA,mCACI,eACJ,CAEA,iCACI,SACJ,CAEA,8BACI,YACJ,CAEA,gCACI,eACJ,CAEA,oBACI,oBACJ,CAEA,sBACI,oBACJ,CAEA,iCAQI,yBAA0B,CAC1B,sBAAuB,CACvB,iBAAkB,CAClB,UAAW,CACX,cAAe,CAXf,sBAAuB,CAYvB,cAAe,CAXf,eAAiB,CAYjB,eAAgB,CAVhB,iBAAkB,CADlB,oBAEJ,CAYA,yCACI,wBACJ,CAEA,0CACI,wBACJ,CAEA,4CACI,wBACJ,CAEA,kIAGI,wBACJ,CAEA,mBACI,eACJ,CAEA,kBACI,cAAe,CACf,gBAAiB,CAGjB,yBAA2B,CAD3B,iBAAkB,CADlB,iBAGJ,CAEA,eAGI,qBAAuB,CADvB,iBAAkB,CADlB,eAGJ,CAEA,mBACI,eACJ,CAEA,UAGI,cAAe,CACf,kBAAmB,CAFnB,oBAAqB,CADrB,YAIJ,CAEA,yBAGI,khBAAmhB,CACnhB,uBAAwB,CAKxB,aAAc,CAJd,UAAW,CAHX,WAAY,CAMZ,MAAO,CAFP,iBAAkB,CAClB,QAAS,CANT,SASJ,CAEA,UAEI,eAAgB,CAEhB,qBAAsB,CADtB,mBAAoB,CAFpB,qBAIJ,CAEA,kBACI,UACJ,CAEA,kBACI,eACJ,CAEA,6BACI,UAAW,CAEX,iBAAkB,CADlB,eAEJ,CAEA,cACI,UAAW,CAEX,iBAAkB,CADlB,eAAgB,CAEhB,gBACJ,CAEA,gBACI,oBACJ,CAEA,iBAEI,iBAAkB,CADlB,iBAEJ,CAEA,iBACI,gBAAiB,CACjB,YACJ,CAEA,qBACI,gBACJ,CAEA,oBAEI,aAAc,CACd,cAAe,CAFf,cAGJ,CAEA,sBACI,aACJ,CAEA,uBACI,iBACJ,CAEA,YACI,eACJ,CAEA,yBAII,UAAW,CAFX,cAAe,CACf,eAAgB,CAFhB,cAIJ,CAEA,wBAII,WAAY,CAFZ,cAAe,CACf,eAAgB,CAFhB,cAIJ,CAEA,2BAII,qBAAuB,CAFvB,wBAAyB,CACzB,aAAc,CAFd,gBAIJ,CAEA,iCACI,wBAAyB,CACzB,UACJ,CAEA,oBAWI,uBAAwB,CAIxB,kBAAmB,CACnB,wBAAqB,CAJrB,iBAAkB,CAElB,qBAAsB,CAGtB,UAAW,CATX,cAAe,CAPf,oBAAqB,CAErB,cAAe,CAEf,WAAY,CACZ,QAAS,CACT,kBAAmB,CALnB,oBAAqB,CAgBrB,qFAAyF,CALzF,kBAMJ,CAEA,0BACI,wBACJ,CAEA,yBAII,qBAAsB,CAEtB,wBAAyB,CACzB,iBAAkB,CAClB,+BAAgC,CAChC,YAAa,CAJb,sBAAuB,CAJvB,iBAAkB,CASlB,OAAQ,CACR,QAAS,CART,WAAY,CADZ,WAUJ,CAEA,yBACI,yBACI,iBACJ,CACJ,CAEA,mBACI,aACJ,CAEA,oDAGI,eAAgB,CAChB,eAAgB,CAChB,iBAAkB,CAHlB,UAIJ,CAEA,mDAOI,iBAAkB,CAHlB,eAAgB,CADhB,eAAgB,CAEhB,aAAc,CACd,kBAAmB,CAEnB,iBAAkB,CAClB,cAAe,CAPf,UAQJ,CAEA,0BACI,iBAAkB,CAClB,eAAgB,CAChB,gBAAiB,CACjB,WACJ,CAEA,6BACI,cAAe,CACf,kBACJ,CAEA,qBACI,WAAY,CAEZ,eAAiB,CADjB,gBAEJ,CAEA,sBACI,eACJ,CAEA,eAGI,wBAAyB,CACzB,iBAAkB,CAHlB,qBAAsB,CACtB,0BAA2B,CAG3B,oBAAwB,CACxB,WAAY,CACZ,aAAc,CACd,eAAgB,CAChB,gBAAiB,CACjB,iBACJ,CAEA,mCACI,wBAAyB,CACzB,aAAc,CACd,cACJ,CAEA,qCACI,wBAAyB,CACzB,aACJ,CAEA,iBAEI,cAAe,CADf,YAEJ,CAEA,eAGI,wBAAyB,CACzB,UAAc,CAHd,aAAc,CAId,uBAAwB,CAHxB,YAIJ,CAEA,iBACI,UAAc,CACd,eAAiB,CACjB,yBACJ,CAEA,aAGI,kCAAoC,CAIpC,kCAAyC,CACzC,yBAA2B,CAJ3B,UAAc,CAHd,aAAc,CAId,iCAAmC,CAHnC,sBAOJ,CAEA,eACI,UAAc,CACd,eAAiB,CACjB,yBACJ,CAEA,sBACI,YACJ,CAEA,sBACI,eAAgB,CAChB,WACJ,CAEA,kBACI,eACJ,CAEA,iBAKI,4BAA6B,CAC7B,iBAAkB,CALlB,aAAc,CAGd,kBAAmB,CAFnB,cAAe,CACf,WAAY,CAKZ,iBAAkB,CADlB,oBAEJ,CAEA,mCAEI,iBAAkB,CADlB,cAAe,CAEf,eACJ,CAEA,eAEI,wBAAyB,CACzB,oBAAqB,CAFrB,aAGJ,CAEA,cAEI,wBAAyB,CACzB,oBAAqB,CAFrB,aAGJ,CAEA,6BAEI,cAAe,CADf,YAEJ,CAEA,qBACI,wBAAyB,CAEzB,UAAc,CADd,cAAe,CAEf,kBAAmB,CACnB,YACJ,CAEA,uBACI,UAAc,CACd,eACJ,CAEA,eACI,cACJ,CAEA,oBAMI,qBAAyB,CAEzB,iBAAkB,CAClB,6DAAqE,CAFrE,aAAc,CAHd,iBAAkB,CAClB,uCAKJ,CAEA,uBACI,YACJ,CAEA,0BAEI,eAAkB,CADlB,gBAEJ,CAEA,qCACI,cACJ,CAEA,sBAOI,aAAc,CAJd,cAAe,CACf,oBAAqB,CAIrB,cAAe,CAPf,eAAgB,CAKhB,sBAAmB,CAJnB,iBAUJ,CAOA,qEAJI,gCAAiC,CACjC,aAOJ,CAJA,4BACI,wBAGJ,CAEA,qBACI,YACJ,CAEA,oBACI,aACJ,CAEA,4CAEI,yBACJ,CAEA,qBACI,aACJ,CAEA,gBAGI,6BAA+B,CAD/B,oBAAqB,CAErB,gBAAiB,CAHjB,iBAIJ,CAEA,oCAGI,qBAAyB,CAIzB,iBAAkB,CAGlB,sEAAgF,CAChF,mEAA6E,CAC7E,8DAAwE,CARxE,aAAc,CAEd,YAAa,CAEb,iBAAkB,CAHlB,eAAgB,CAJhB,iBAAkB,CAClB,WAAY,CAOZ,SAIJ,CAEA,4BAGI,UAAW,CACX,iBAAkB,CAClB,cAAe,CAHf,QAAS,CADT,WAKJ,CAEA,8CACI,iCACJ,CAEA,kEAEI,kBAAmB,CADnB,YAEJ,CAMA,kDASI,4BAAuD,CAAvD,wBAAuD,CANvD,WAAY,CAFZ,WAAY,CAIZ,QAAS,CACT,gBAAiB,CAJjB,iBAQJ,CAEA,kDACI,cACJ,CAEA,wDAQI,4BAAuD,CAAvD,wBAAuD,CALvD,WAAY,CAFZ,WAAY,CAGZ,QAAS,CACT,iBAAkB,CAHlB,iBAOJ,CAEA,iCACI,gBACJ,CAMA,mBACI,wBAAyB,CACzB,iBAAkB,CAElB,kBAAmB,CADnB,WAEJ,CAEA,mBACI,iBAAkB,CAClB,eACJ,CAEA,4CAEI,kCAAmC,CACnC,sDACJ,CAEA,oBAGI,UAAW,CAGX,cAAe,CAFf,WAAY,CACZ,kBAAmB,CAGnB,mBAAoB,CADpB,YAEJ,CAEA,8CAVI,kBAAmB,CACnB,oBAYJ,CAEA,+CACI,yBACJ,CAEA,wDAEI,eAAmB,CACnB,wBAAyB,CACzB,iBAAkB,CAGlB,YAAa,CAFb,YAAa,CACb,cAAe,CAIf,aAAc,CADd,iBAAkB,CADlB,gBAAiB,CAGjB,kBACJ,CAEA,2BACI,WAAY,CACZ,gBACJ,CAEA,+BACI,cAAe,CACf,kBACJ,CAEA,gEACI,UACJ,CAEA,iEACI,aACJ,CAEA,8BACI,aAAc,CACd,cACJ,CAEA,iCAEI,aAAc,CADd,aAEJ,CAEA,6BAGI,UAAc,CADd,cAAe,CADf,eAGJ,CAEA,4DAGI,cACJ,CAMA,yEACI,aACJ,CAEA,qCACI,aACJ,CAEA,kCAEI,aAAc,CADd,cAAe,CAEf,eACJ,CAEA,sBAGI,aAAc,CADd,cAAe,CADf,eAGJ,CAEA,mDACI,eAAgB,CAChB,0BACJ,CAEA,gCACI,8BACJ,CAEA,wCAEI,6BAA8B,CAD9B,YAAa,CAEb,aACJ,CAEA,mCAGI,eAAgB,CAChB,WAAY,CAFZ,aAAc,CAGd,cAAe,CAJf,cAKJ,CAEA,6CACI,aACJ,CAEA,yJAGI,YACJ,CAEA,mCACI,cAAe,CACf,eACJ,CAEA,yCACI,aACJ,CAEA,gDACI,cACJ,CAEA,iDACI,kBACJ,CAEA,sCAMI,aAAc,CAJd,eAAgB,CADhB,iBAEJ,CAMA,iDAOI,wBAAyB,CAFzB,2BAA4B,CAH5B,kBAAmB,CACnB,WAAY,CACZ,gBAAiB,CAHjB,iBAAkB,CAKlB,mDAEJ,CAEA,sFACI,mBACJ,CAEA,kEACI,YACJ,CAEA,qDAEI,iBAAkB,CAClB,WAAY,CAFZ,SAGJ,CAEA,sDACI,cACJ,CAEA,uCAGI,iBAAkB,CAElB,WAAY,CACZ,kBAAmB,CALnB,cAAe,CACf,WAAY,CAEZ,WAGJ,CAEA,gCAEI,YAAa,CACb,sBAAuB,CAFvB,iBAGJ,CAEA,mCACI,YACJ,CAEA,uDAMI,kBAAmB,CAInB,oBAAqB,CAFrB,yBAA0B,CAC1B,gBAAiB,CAFjB,qBAAsB,CAJtB,aAAc,CADd,eAAkB,CADlB,SAAU,CAGV,iBAAkB,CAOlB,qFAAyF,CANzF,WAOJ,CAEA,0DACI,gCAAiC,CACjC,QACJ,CAEA,gEACI,wBACJ,CAEA,qEACI,kBACJ,CAEA,6CAEI,eAAgB,CAChB,WAAY,CAGZ,UAAY,CALZ,cAAe,CAMf,WAAY,CACZ,gBAAiB,CAJjB,QAAS,CACT,UAIJ,CAEA,mDACI,wBACJ,CAEA,oDAEI,YAAa,CACb,kBAAmB,CAFnB,YAGJ,CAEA,sCAEI,QAAS,CADT,eAEJ,CAEA,8DACI,iBACJ,CAEA,yCACI,QAAS,CACT,iBAAkB,CAGlB,cAAe,CAFf,cAAe,CACf,qFAEJ,CAEA,mDAEI,wBAAyB,CADzB,UAEJ,CAEA,sDAEI,wBAAyB,CADzB,UAAY,CAGZ,WAAY,CACZ,eAAgB,CAFhB,UAGJ,CAEA,8EACI,YACJ,CAEA,gEAEI,YAAa,CADb,MAAO,CAEP,qBACJ,CAEA,2DAEI,+BAAgC,CAChC,kBAAmB,CAFnB,UAGJ,CAEA,iEAKI,wBAAyB,CACzB,iBAAkB,CAClB,UAAW,CAJX,oBAAqB,CACrB,gBAAiB,CAKjB,kBAAmB,CARnB,eAAgB,CAOhB,WAAY,CANZ,sBAQJ,CAEA,uCAcI,kBAAmB,CAFnB,UAAc,CAXd,YAAa,CAEb,WAAY,CAUZ,sBAAuB,CALvB,MAAO,CAHP,kBAAmB,CADnB,eAAgB,CAOhB,eAAgB,CAThB,iBAAkB,CAOlB,eAAgB,CAFhB,KAAM,CAGN,kBAAmB,CAJnB,UASJ,CAEA,wCAEI,kBAAmB,CAGnB,iBAAkB,CAFlB,UAAY,CACZ,WAAY,CAEZ,MAAO,CALP,iBAAkB,CAMlB,KACJ,CAEA,+CACI,SACJ,CAEA,yBAEI,yBAA2B,CAC3B,eAAgB,CAFhB,UAGJ,CAEA,gBACI,iBACJ,CAMA,kBAEI,wBAAyB,CAGzB,UAAY,CAJZ,eAAiB,CAGjB,YAAe,CADf,YAGJ,CAEA,yCACI,gBACJ,CAEA,kBAII,kBAAmB,CAHnB,aAAc,CAEd,iBAAkB,CADlB,UAGJ,CAEA,wBACI,aAAc,CACd,eACJ,CAEA,wBAEI,aAAc,CACd,eAAgB,CAFhB,WAGJ,CAMA,sCACI,cAAe,CACf,eACJ,CAEA,kCAGI,iBACJ,CAEA,uDACI,UACJ,CAUA,YACI,eACJ,CAOA,4BACI,aACJ,CAEA,gBACI,aACJ,CAEA,4CAEI,kBAAmB,CAInB,iBAAkB,CADlB,cAAe,CAFf,gBAAiB,CACjB,iBAGJ,CAEA,sBACI,WACJ,CAEA,sBACI,eAAiB,CAEjB,kBAAmB,CADnB,SAEJ,CAEA,0CACI,WACJ,CAEA,aACI,cACJ,CAEA,oBACI,aACJ,CAEA,kCACI,cAAe,CACf,UACJ,CAEA,uDACI,gBACJ,CAEA,yCACI,wBACI,cAAe,CACf,UACJ,CAEA,wBACI,UACJ,CAEA,sCACI,aAAc,CACd,cACJ,CAEA,mBAEI,eAAgB,CADhB,wBAEJ,CACJ,CAEA,eACI,iBACJ,CAEA,oBACI,+BACJ,CAEA,WACI,QACJ,CAMA,8BAHI,eAMJ,CAHA,eAEI,kBACJ,CAEA,aACI,UACJ,CAEA,kBACI,qCACJ,CAEA,kBACI,UACJ,CAEA,iBACI,eACJ,CAEA,sBACI,6BACJ,CAEA,0BACI,wBAAyB,CAGzB,iBAAkB,CAFlB,UAAW,CACX,WAEJ,CAEA,cACI,iBAAkB,CAClB,cACJ,CAEA,eACI,kBACJ,CAEA,kBACI,UACJ,CAEA,mBACI,iBACJ,CAEA,eACI,eACJ,CAEA,yBACI,qBAAuB,CAEvB,kBAAmB,CADnB,YAEJ,CAEA,eACI,gBACJ,CAEA,mBACI,iBACJ,CAEA,qBACI,oBACJ,CAEA,qBACI,aAAc,CACd,iBACJ,CAEA,mCACI,WAAY,CACZ,eACJ,CAEA,sCAEI,kBACJ,CAEA,yCACI,aACJ,CAEA,0CAEI,wBACJ,CAEA,mDAEI,wBACJ,CAEA,0CAEI,wBACJ,CAEA,gEAEI,wBACJ,CAEA,0FAEI,aACJ,CAEA,mHAEI,YACJ,CAEA,+HAEI,SACJ,CAEA,6CACI,aACJ,CAEA,0CACI,iBACJ,CAEA,wCAQI,wBAAyB,CAHzB,wBAAyB,CACzB,iBAAkB,CAJlB,eAAiB,CADjB,iBAAkB,CAElB,WAAY,CACZ,YAAa,CAGb,iBAEJ,CAEA,yCACI,YAAa,CACb,eACJ,CAEA,uDAEI,eAAgB,CADhB,eAEJ,CAEA,4DACI,iBACJ,CAEA,iCACI,oBACJ,CAEA,yDAGI,wBAAyB,CACzB,wBAAyB,CAHzB,iBAAkB,CAClB,aAAc,CAKd,cAAe,CADf,WAAY,CADZ,UAGJ,CAEA,qFAEI,qBAAuB,CACvB,wBAAyB,CAFzB,WAGJ,CAEA,uGACI,kBACJ,CAEA,kDAEI,iBAAkB,CAElB,UAAW,CADX,WAAY,CAEZ,iBAAkB,CAJlB,UAKJ,CAMA,oEACI,oBACJ,CAEA,0BACI,oBAAqB,CACrB,eACJ,CAEA,+BAII,cAAe,CAFf,oBAAqB,CADrB,iBAAkB,CAElB,iBAEJ,CAEA,0CACI,eACJ,CAEA,iCAKI,wBAAyB,CACzB,wBAAyB,CACzB,iBAAkB,CAElB,cAAe,CARf,cAAe,CAEf,kBAAmB,CACnB,eAAgB,CAIhB,WAAY,CANZ,eAQJ,CAEA,uCACI,wBAAyB,CACzB,wBACJ,CAEA,oCACI,WACJ,CAEA,mBACI,eACJ,CAEA,sBACI,aACJ,CAEA,yBAEI,oBAAqB,CADrB,sBAEJ,CAEA,iCAEI,cAAe,CADf,kBAEJ,CAEA,oBAEI,mBAAoB,CADpB,gBAEJ,CAEA,sBACI,eACJ,CAEA,2BAEI,kBAAmB,CADnB,YAEJ,CAEA,mDAGI,cAAe,CADf,SAAU,CADV,SAGJ,CAMA,kCAGI,kBAAmB,CADnB,eAAgB,CAEhB,cAAe,CAHf,SAAU,CAIV,UACJ,CAEA,wCAEI,wBAAyB,CACzB,wBAAyB,CAFzB,UAGJ,CAEA,qCAGI,WAAY,CADZ,kBAAmB,CADnB,eAGJ,CAEA,qCACI,QACJ,CAEA,4BACI,YAAa,CACb,0BAA2B,CAC3B,SACJ,CAOA,4CACI,kBAAmB,CACnB,wBACJ,CAEA,oDACI,WACJ,CAEA,2BAEI,wBAAyB,CACzB,wBAAyB,CAGzB,kBAAmB,CAMnB,eAAgB,CAXhB,oBAAsB,CAetB,cAAe,CAPf,mBAAoB,CAFpB,cAAe,CAMf,eAAgB,CARhB,WAAY,CAKZ,sBAAuB,CAIvB,cAAgB,CAChB,cAAe,CAJf,YAAa,CAHb,SAAU,CAJV,UAaJ,CAEA,iCACI,wBAAyB,CACzB,oBACJ,CAEA,kBAGI,kBAAmB,CACnB,iBAAkB,CAFlB,eAAgB,CADhB,cAIJ,CAEA,iBACI,4BACJ,CAEA,gBAII,eAAgB,CADhB,qBAAsB,CAItB,aAAc,CANd,oBAAqB,CACrB,cAAe,CAIf,iBAAkB,CADlB,eAGJ,CAEA,2BAWI,kBAAmB,CATnB,wBAAyB,CACzB,wBAAyB,CAGzB,iBAAkB,CAOlB,eAAgB,CAZhB,oBAAsB,CAQtB,mBAAoB,CAFpB,cAAe,CAOf,eAAgB,CAThB,WAAY,CAKZ,sBAAuB,CAEvB,YAAa,CAJb,SAAU,CAOV,qBAAsB,CAXtB,UAYJ,CAEA,iCACI,wBAAyB,CACzB,wBACJ,CAMA,0BAUI,qBAAsB,CACtB,qBAAsB,CAFtB,yBAA2B,CAN3B,eAAgB,CAKhB,UAAW,CAHX,oBAAqB,CAJrB,wBAA0B,CAK1B,eAAgB,CAChB,eAAgB,CAOhB,eAAgB,CADhB,cAAe,CADf,yBAA2B,CAR3B,sBAAwB,CAFxB,eAAgB,CAchB,6CAAkD,CADlD,iCAAmC,CAEnC,WACJ,CAEA,gFACI,iBACJ,CAEA,gCACI,qBACJ,CAEA,gCACI,kCAAoC,CACpC,wEACJ,CAEA,2DAEI,WACJ,CAEA,sCACI,UACJ,CAEA,+BACI,UACJ,CAEA,4BACI,eACJ,CAEA,2CACI,YACJ,CAEA,sBACI,kBACJ,CAEA,6EACI,gBACJ,CAEA,gCACI,aACJ,CAEA,yBAMI,kBAAmB,CAFnB,YAAa,CAFb,YAAa,CAGb,sBAAuB,CAFvB,eAAgB,CAFhB,UAMJ,CAEA,mCACI,GACI,mBACJ,CACA,GACI,uBACJ,CACJ,CAEA,6BAGI,oDAAqD,CACrD,4DAA6D,CAF7D,WAAY,CADZ,UAIJ,CAEA,0CACI,oBACJ,CAEA,+BACI,eAAgB,CAChB,eACJ,CAEA,2BACI,eACJ,CAEA,kEACI,oBAAqB,CACrB,iBACJ,CAEA,8FACI,kBAAmB,CAEnB,cAAe,CADf,iBAEJ,CAEA,6GACI,aAAc,CACd,gBACJ,CAEA,yCACI,kEACI,UACJ,CACJ,CAEA,kEAEI,aAAc,CADd,cAEJ,CAEA,yCACI,aACJ,CAEA,6EAEI,YACJ,CAEA,oBACI,kBAAmB,CACnB,wBAAyB,CACzB,UAAY,CACZ,qFACJ,CAEA,0BACI,kBACJ,CAEA,sBAII,YAAa,CADb,eAAgB,CADhB,eAAgB,CADhB,iBAIJ,CAEA,cACI,eACJ,CAEA,cACI,iBACJ,CAGA,kBACI,wBAAyB,CACzB,wBAAyB,CACzB,UAAY,CACZ,gBACJ,CAEA,wBACI,kBAAmB,CACnB,mCACJ,CAEA,wDACI,YACJ,CAEA,uFACI,eACJ,CAEA,8DACI,YACJ,CAEA,+DACI,WACJ,CAEA,gGAEI,qBAAuB,CADvB,eAEJ,CAEA,4EACI,cACJ,CAEA,uFACI,iBACJ,CAEA,0FACI,cACJ,CAEA,kFACI,yBACJ,CAEA,qHACI,oCACJ,CAEA,4CAKI,eAAgB,CAJhB,eAAgB,CAChB,gBAAiB,CAIjB,cAAe,CAFf,gBAAoB,CADpB,wBAIJ,CAEA,kBACI,0BACJ,CAEA,mDACI,aACJ,CAEA,qDAEI,aAAc,CADd,cAEJ,CAEA,uNAGI,kBACJ,CAEA,kEACI,YACJ,CAEA,kBAEI,WAAY,CADZ,UAEJ,CAEA,uCACI,kBACJ,CAEA,qCAEI,WAAY,CADZ,UAEJ,CAEA,qCAEI,WAAY,CADZ,UAEJ,CAEA,kCAEI,kBAAmB,CADnB,YAEJ,CAEA,0FAII,kBAAmB,CAFnB,iCAAkC,CAClC,mBAEJ,CAEA,kDAGI,kBAAmB,CAFnB,iCAAkC,CAClC,YAEJ,CAEA,kDACI,oBACJ,CAEA,+CAEI,WAAY,CADZ,UAEJ,CAEA,iBACI,WACJ,CAEA,aAQI,iCAAkC,CADlC,kCAAmC,CADnC,oBAAqB,CAIrB,cAAe,CATf,oBAAqB,CAErB,QAAS,CACT,eAAgB,CAKhB,wBAA0B,CAJ1B,qBAAsB,CAHtB,OASJ,CAEA,4BACI,yBACJ,CAEA,mCAEI,aAAc,CADd,cAAe,CAEf,aACJ,CAEA,mCACI,cAAe,CAEf,eACJ,CAIA,yIAEI,yBAA6B,CAC7B,YACJ,CAEA,8BACI,iBAAkB,CAGlB,aAAc,CACd,4CAAgD,CAFhD,YAAa,CADb,YAIJ,CAEA,+BAEI,aAAc,CADd,cAEJ,CAEA,gEACI,qBAAsB,CAEtB,eAAgB,CADhB,eAEJ,CAEA,+BAEI,SAAU,CADV,OAAQ,CAER,SACJ,CAEA,qCACI,YACJ,CAEA,kEACI,wBACJ,CAEA,wCAGI,QAAS,CAFT,iBAAkB,CAGlB,cAAe,CAFf,eAAgB,CAMhB,WAAY,CADZ,kBAAmB,CAEnB,eAAgB,CAJhB,iBAAkB,CAKlB,gBAAiB,CAJjB,yBAKJ,CAEA,yEACI,eACJ,CAEA,qDAEI,eAAgB,CADhB,kCAAuC,CAEvC,aAAsB,CACtB,eAAgB,CAEhB,gBAAiB,CADjB,WAEJ,CAEA,8CACI,qCACJ,CAEA,2DACI,6BACJ,CAEA,yBAEI,cAAe,CADf,WAEJ,CAEA,+CACI,uBACJ,CAMA,iDAEI,aAAc,CADd,eAEJ,CAIA,2DAOI,yCAA0C,CAE1C,wBAAyB,CADzB,0DAAmE,CALnE,eAAgB,CAGhB,kBAAmB,CAFnB,oBAAqB,CAHrB,UAAW,CAIX,eAAgB,CAHhB,SAQJ,CAEA,+DACI,kBACJ,CAEA,gEACI,mBACJ,CAEA,gEACI,mBACJ,CAEA,gEACI,mBACJ,CAEA,gEACI,mBACJ,CAEA,gEACI,kBACJ,CAEA,+BACI,GAEI,SAAU,CADV,2BAEJ,CACA,IACI,SACJ,CACA,IAEI,SAAU,CADV,0BAEJ,CACA,GACI,SACJ,CACJ,CAIA,+CAEI,eAAgB,CADhB,aAEJ,CAEA,oEACI,YACJ,CAEA,uCACI,WACJ,CAEA,yCACI,iBACJ,CAEA,2CACI,cACJ,CAEA,qCACI,qBACJ,CAEA,qDACI,eACJ,CAEA,4BACI,iBACJ,CAEA,sCAKI,4BAA8B,CAF9B,iCAAkC,CAClC,kCAAmC,CAFnC,QAAS,CAIT,iBAAkB,CAElB,UAAW,CADX,QAAS,CANT,OAQJ,CAEA,QACI,sBACJ,CAEA,eACI,oCAAwC,CACxC,uBAA0B,CAC1B,gBACJ,CAEA,sBACI,UACJ,CAEA,8BACI,kBAAmB,CACnB,UACJ,CAMA,cAEI,iBAAkB,CAClB,cAAe,CAFf,oBAAqB,CAKrB,eAAgB,CAChB,SAAU,CAHV,gBAA0B,CAK1B,oBAAqB,CAJrB,wBAAyB,CAGzB,uCAEJ,CAEA,yBACI,wBAAyB,CACzB,UACJ,CAEA,+BACI,wBACJ,CAGA,iCAII,8BAAgC,CAHhC,wBAAyB,CACzB,qBAAsB,CACtB,UAEJ,CAEA,uCACI,wBAAyB,CACzB,wBACJ,CAEA,wBACI,UAAW,CACX,gBACJ,CAEA,qBAKI,wBAAyB,CAGzB,wBAAyB,CADzB,iBAAkB,CADlB,UAAY,CALZ,oBAAqB,CAErB,iBAAkB,CADlB,oBAAqB,CAErB,sBAKJ,CAEA,2BACI,wBACJ,CAEA,mBASI,iBAAkB,CADlB,UAAY,CAPZ,oBAAqB,CAGrB,cAAe,CAGf,eAAgB,CAJhB,eAAgB,CADhB,YAAa,CAIb,iBAAkB,CADlB,oBAKJ,CAEA,uBAUI,uBAAwB,CADxB,kCAAuC,CAEvC,iBAAkB,CAElB,qBAAsB,CACtB,aAAc,CANd,cAAe,CAPf,oBAAqB,CAErB,cAAe,CACf,sBAAuB,CAEvB,QAAS,CADT,eAAgB,CAEhB,cAAe,CALf,oBAAqB,CAUrB,kBAGJ,CAEA,6BACI,6BAAiC,CACjC,UACJ,CAEA,yBAEI,4BAA6B,CAG7B,kCAAuC,CADvC,iBAAkB,CADlB,aAAc,CAGd,cAAe,CALf,oBAAqB,CAOrB,eAAgB,CAChB,SAAU,CAFV,oBAA0B,CAI1B,oBAAqB,CADrB,uCAEJ,CAEA,mBACI,wBAAyB,CACzB,oBAAqB,CACrB,UACJ,CAEA,yBACI,wBAAyB,CACzB,oBAAqB,CACrB,UACJ,CAEA,uBACI,wBAAyB,CACzB,oBAAqB,CACrB,UACJ,CAEA,6BACI,wBAAyB,CACzB,oBAAqB,CACrB,UACJ,CAEA,oBACI,wBAAyB,CACzB,oBAAqB,CACrB,UACJ,CAEA,0BACI,wBAAyB,CACzB,oBAAqB,CACrB,UACJ,CAEA,6BACI,cACJ,CAEA,sBACI,aACJ,CAEA,iEAGI,eACJ,CAEA,oBACI,qBAAsB,CACtB,oBAAqB,CAErB,cAAe,CADf,oBAEJ,CAEA,0BAEI,oBAAqB,CACrB,mDAAyD,CACzD,2CAAiD,CAHjD,SAIJ,CAEA,iCACI,UACJ,CAEA,mCAEI,kBAAmB,CADnB,YAEJ,CAEA,yCAII,oBAAqB,CAHrB,cAAe,CACf,kBAAmB,CACnB,WAEJ,CAEA,mDAKI,iCAAoC,CADpC,oBAAqB,CAFrB,eAAgB,CADhB,cAAe,CAEf,iBAGJ,CAEA,uEAEI,WAAY,CADZ,QAEJ,CAGA,uBAII,kBAAmB,CAOnB,eAAiB,CAVjB,YAAa,CACb,qBAAsB,CAItB,YAAa,CAHb,sBAAuB,CAOvB,MAAO,CAFP,cAAe,CAHf,iBAAkB,CAIlB,KAAM,CAFN,WAAY,CAKZ,aACJ,CAEA,oCACI,eACJ,CAEA,2BACI,cAAe,CACf,eACJ,CAEA,kBACI,cACJ,CAEA,oBACI,yBACJ,CAEA,0DAEI,wBAAyB,CACzB,UAAW,CAFX,+BAGJ,CAEA,4DACI,mBACJ,CAEA,uEACI,YACJ,CAEA,yEACI,aACJ,CAEA,gEACI,YACJ,CAEA,gEAEI,aAAc,CADd,eAAgB,CAEhB,eACJ,CAEA,uBACI,eACJ,CAEA,qCACI,UACI,cACJ,CAEA,kBACI,cACJ,CACJ,CAEA,mBAGI,wBAAyB,CADzB,kBAAmB,CADnB,UAAc,CAOd,oBAAqB,CADrB,eAAiB,CAFjB,WAAY,CAIZ,UAAW,CAHX,iBAAkB,CAFlB,UAMJ,CAEA,sBACI,eACJ,CAEA,4BACI,+CAAkD,CAClD,uCACJ,CAEA,mCACI,GACI,mBACJ,CACA,GACI,kBACJ,CACJ,CAEA,2BACI,GACI,mBACJ,CACA,GACI,kBACJ,CACJ","file":"wpstg-admin.min.css","sourcesContent":["/**\n * WPSTG Admin CSS\n *\n * @package WPSTG\n * @subpackage Admin CSS\n * @copyright Copyright (c) 2021, René Hermenau\n * @license http://opensource.org/licenses/gpl-2.0.php GNU Public License\n*/\n\n/* Colors */\n\n.wpstg--violet {\n color: #9d37ae;\n}\n\n.wpstg-border--violet {\n border: 1px solid #9d37ae;\n}\n\n.wpstg--red {\n color: #E01E5A;\n}\n\n.wpstg-cta--red {\n color: #fe008f;\n}\n\n.wpstg--blue {\n color: #24a1f0;\n}\n\n.wpstg--darkblue {\n color: #0e86d9;\n}\n\n.wpstg--green {\n color: #83c11f;\n}\n\n.wpstg--grey {\n color: #3e3e3e;\n}\n\n.wpstg--darkgrey {\n color: #1b1b1b;\n}\n\n/* CSS for Tabs */\n\n#wpstg-tab-container ul {\n list-style: none;\n margin: 0;\n padding: 0;\n background: #f1f1f1;\n float: left;\n}\n\n#wpstg-tab-container ul li:first-child.selected-tab {\n border-top: none;\n}\n\n#wpstg-tab-container ul li a.selected-tab {\n font-weight: bold;\n text-decoration: none;\n}\n\n#wpstg-tab-container .row {\n padding-top: 10px;\n padding-bottom: 12px;\n}\n\n.wpstg-tabs-container .nav-tab-wrapper {\n padding: 0;\n}\n\n#wpstg-tab-container .row label strong,\n#wpstg-tab-container .row strong {\n font-weight: bold;\n}\n\n.wpstg-tabs a {\n padding: 5px;\n}\n\n#wpstg-tab-container > ul > li.wpstg-tabs.active {\n background-color: white;\n}\n\n#wpstg_settingsgeneral_header .row:nth-child(3),\n#wpstg_settingsgeneral_header .row:nth-child(4) {\n display: none;\n}\n\n#wpstg-tab-container .wpstg-settings-panel {\n padding: 0 20px 20px 20px;\n overflow: auto;\n}\n\n#wpstg-tab-container .wpstg-form-table th {\n vertical-align: top;\n text-align: left;\n padding: 20px 10px 20px 0;\n line-height: 1.3;\n font-weight: bold;\n font-size: 14px;\n color: #484848;\n width: 30%;\n}\n\n#wpstg-tab-container .wpstg-form-table tr {\n border-bottom: 1px solid #E7E7E7;\n}\n\n#wpstg-tab-container span.description {\n display: block;\n font-weight: 400;\n font-style: normal;\n font-size: 13px;\n margin-top: 7px;\n color: #484848;\n}\n\n#wpstg-tab-container .col-title {\n color: #484848;\n}\n\n@media only screen and (max-width: 680px) {\n #wpstg-tab-container ul {\n float: none;\n }\n\n #wpstg-tab-container .wpstg-form-table tr > th {\n width: 100%;\n }\n\n #wpstg-tab-container span.description {\n font-size: 14px;\n }\n\n #wpstg-tab-container .wpstg-form-table tr > th,\n #wpstg-tab-container .wpstg-form-table tr > td {\n padding: 10px;\n }\n}\n\n#wpstg-tab-container ul li {\n margin-bottom: 0;\n}\n\n#wpstg-tab-container ul li a {\n display: block;\n padding: 10px 4px 10px 14px;\n border-width: 1px 0;\n border-style: solid;\n border-top-color: white;\n border-bottom-color: #e7e7e7;\n text-decoration: none;\n color: #0097DF;\n font-weight: bold;\n}\n\n#wpstg-tab-container ul li a:hover {\n background-color: #e5e5e5;\n color: #777777;\n}\n\n.wpstg-logo {\n display: block;\n font-size: 16px;\n padding-top: 20px;\n width: 220px;\n float: left;\n}\n\n.wpstg-logo img {\n max-width: 212px;\n}\n\n.wpstg-version {\n display: block;\n padding-top: 34px;\n color: #9b9b9b;\n}\n\n.wpstg_admin .nav-tab {\n color: #3C3C3C;\n}\n\n#wpstg-tab-container table tbody tr:nth-child(1) > th > div {\n font-size: 20px;\n}\n\n/* Cloning workflow */\n\n#wpstg-clonepage-wrapper {\n margin-bottom: 20px;\n width: 98%;\n}\n\n@media screen and (min-width: 1090px) {\n #wpstg-clonepage-wrapper {\n float: left;\n margin-bottom: 20px;\n }\n}\n\n#wpstg-steps {\n margin-top: 0px;\n margin-left: 20px;\n}\n\n#wpstg-steps li {\n color: #444;\n line-height: 20px;\n padding-right: 10px;\n float: left;\n}\n\n.wpstg-step-num {\n border: 1px solid #3e3e3e;\n border-radius: 3px;\n display: inline-block;\n width: 20px;\n height: 20px;\n text-align: center;\n margin-right: 5px;\n}\n\n.wpstg-current-step {\n font-weight: bold;\n}\n\n.wpstg-current-step .wpstg-step-num {\n background: #3e3e3e;\n color: #eee;\n}\n\n.wpstg-box {\n margin: 10px 0;\n padding: 10px;\n position: relative;\n overflow: hidden;\n transition: border-color .2s ease-in-out;\n}\n\n.wpstg-clone {\n margin-bottom: 10px;\n padding: 16px;\n position: relative;\n transition: border-color .2s ease-in-out;\n background-color: #ffffff;\n color: #3e3e3e;\n border-radius: 3px;\n box-shadow: 0 0 1px rgba(0, 0, 0, .125), 0 1px 3px rgba(0, 0, 0, .1);\n}\n\n.wpstg-clone.active {\n border-color: #1d94cf;\n}\n\n.wpstg-clone-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.wpstg-clone-title {\n display: inline-block;\n font-size: 15px;\n max-width: 300px;\n text-decoration: none;\n font-weight: bold;\n color: #3e3e3e;\n}\n\n.wpstg-clone-title:hover {\n color: #111111;\n}\n\n.wpstg-clone-actions {\n display: flex;\n margin-top: 5px;\n}\n\n.wpstg-dropdown {\n position: relative;\n}\n\n.wpstg-clone-actions .wpstg-dropdown-toggler {\n text-decoration: none;\n background: #25a1f0;\n padding: 6px 10px;\n border-radius: 2px;\n font-size: 14px;\n box-shadow: 0 0 1px rgba(0, 0, 0, .125), 0 1px 3px rgba(0, 0, 0, .2);\n color: #ffffff;\n}\n\n.wpstg-clone-actions .wpstg-dropdown-toggler:hover {\n background: #002648;\n color: white;\n}\n\n.wpstg-dropdown {\n position: relative;\n}\n\n.wpstg-dropdown > .wpstg-dropdown-menu {\n background: #fff;\n display: none;\n flex-direction: column;\n position: absolute;\n right: 0;\n top: calc(100% + 4px);\n padding: 8px;\n border-radius: 2px;\n width: 100px;\n box-shadow: 0 0 1px rgba(0, 0, 0, .125), 0 1px 3px rgba(0, 0, 0, .2);\n z-index: 1000;\n}\n\n.wpstg-dropdown > .wpstg-dropdown-menu.wpstg-menu-dropup {\n top: auto;\n bottom: 100%;\n transform: translate3d(0px, -3px, 0px);\n}\n\n.wpstg-dropdown > .wpstg-dropdown-menu.shown {\n display: flex;\n}\n\n.wpstg-clone-action,\n.wpstg-dropdown-action {\n color: #3e3e3e;\n padding: 6px 8px;\n border-radius: 3px;\n text-decoration: none;\n position: relative;\n transition: color .2s ease-in-out;\n border-bottom: 1px solid #f3f3f3;\n}\n\n.wpstg-clone-action:hover,\n.wpstg-dropdown-action:hover {\n background: rgba(0, 0, 0, 0.05);\n}\n\n.wpstg-dropdown-action {\n color: #3e3e3e;\n background: transparent;\n border: 0 solid black;\n outline: none;\n box-shadow: none;\n}\n\n.wpstg-remove-clone:hover {\n color: #E01E5A;\n}\n\n.wpstg-clone-action:last-child {\n border: none;\n}\n\n.wpstg-clone:hover .wpstg-clone-action {\n display: inline-block;\n}\n\n#wpstg-show-error-details:focus,\n#wpstg-workflow .wpstg-clone-action {\n outline: none;\n box-shadow: none;\n}\n\n.wpstg-link-btn {\n background: #45a1c9;\n color: #fff;\n display: inline-block;\n padding: 5px 10px;\n text-decoration: none;\n vertical-align: baseline;\n transition: all .2s ease-in-out;\n}\n\n.wpstg-link-btn:hover,\n.wpstg-link-btn:focus {\n color: #fff;\n outline: none;\n box-shadow: none;\n}\n\n#wpstg-workflow .wpstg-link-btn:active {\n vertical-align: baseline;\n}\n\n.wpstg-link-btn[disabled] {\n background: #777 !important;\n border-color: #555 !important;\n pointer-events: none;\n}\n\n#wpstg-cancel-cloning,\n#wpstg-cancel-cloning-update {\n margin-top: 5px;\n}\n\n#wpstg-cancel-cloning.success,\n#wpstg-cancel-cloning.success {\n background: #64dd58;\n border-color: #54bd4a;\n}\n\n#wpstg-error-wrapper,\n#wpstg-error-details {\n display: none;\n padding-top: 10px;\n font-size: 13px;\n clear: both;\n}\n\n#wpstg-show-error-details {\n display: inline-block;\n margin-left: 5px;\n color: #555;\n text-decoration: none;\n transition: color .2s ease-in-out;\n}\n\n#wpstg-show-error-details:hover {\n color: #1d94cf;\n}\n\n#wpstg-error-details {\n border-left: 5px solid #E01E5A;\n padding: 10px;\n width: 500px;\n}\n\n#wpstg-try-again {\n display: none;\n}\n\n#wpstg-home-link {\n float: right;\n}\n\n.wpstg-loader {\n content: url('../../img/loading.gif');\n margin-top: 10px;\n display: none;\n}\n\n.wpstg-loader.wpstg-finished {\n display: block;\n content: \"Finished\";\n background-color: #00c89a;\n color: white;\n padding: 2px 10px;\n margin-top: 0;\n border-radius: 3px;\n}\n\n#wpstg-workflow {\n max-width: 800px;\n position: relative;\n clear: both;\n padding-top: 20px;\n float: left;\n min-width: 500px;\n min-height: 380px;\n padding-right: 20px;\n padding-bottom: 20px;\n}\n\n#wpstg-sidebar {\n float: left;\n max-width: 400px;\n display: block;\n margin-left: 10px;\n}\n\n#wpstg-workflow.loading::after,\n#wpstg-removing-clone.loading::after {\n background: rgba(255, 255, 255, .7);\n content: 'Loading... may take a while for huge websites';\n display: block;\n width: 100%;\n height: 100%;\n font-size: 20px;\n padding-top: 100px;\n text-align: center;\n position: absolute;\n top: 0;\n left: 0;\n z-index: 99;\n}\n\n#wpstg-removing-clone.loading::after {\n content: 'REMOVING' !important;\n}\n\n#wpstg-existing-clones,\n#wpstg-removing-clone {\n position: relative;\n}\n\n#wpstg-existing-clones h3 {\n color: #3e3e3e;\n}\n\n#wpstg-removing-clone .wpstg-tab-section {\n display: block;\n}\n\n.wpstg-progress-bar {\n max-width: 900px;\n height: 27px;\n padding: 0;\n background-color: #d6d8d7;\n}\n\n.wpstg-progress {\n float: left;\n background: #3fa5ee;\n width: 0;\n height: 100%;\n transition: width .6s ease;\n color: white;\n line-height: 25px;\n text-align: center;\n overflow: hidden;\n}\n\n.wpstg-progress-files {\n background: #16b4f0;\n width: 0;\n height: 100%;\n transition: width .6s ease;\n color: white;\n line-height: 25px;\n text-align: center;\n}\n\n#wpstg-new-clone-id.wpstg-error-input,\n#wpstg-clone-path.wpstg-error-input {\n border: 1px solid #E01E5A;\n box-shadow: 0 0 2px rgba(255, 66, 53, .8);\n}\n\n#wpstg-new-clone-id {\n width: 450px;\n max-width: 100%;\n margin-left: 15px;\n}\n\n#wpstg-new-clone {\n background: #25a1f0;\n border-color: #2188c9;\n}\n\n#wpstg-new-clone:hover {\n background: #259be6;\n border-color: #2188c9;\n}\n\n#wpstg-clone-path {\n margin-left: 10px;\n width: 350px;\n}\n\n.wpstg-error-msg {\n color: #E01E5A;\n}\n\n#wpstg-clone-id-error {\n display: block;\n background-color: #f0f8ff;\n padding: 10px;\n margin: 20px;\n}\n\n#wpstg-start-cloning + .wpstg-error-msg {\n display: block;\n margin-top: 5px;\n}\n\n.wpstg-size-info {\n color: #999;\n font-weight: normal;\n position: relative;\n left: 2px;\n}\n\n.wpstg-db-table .wpstg-size-info {\n top: 2px;\n}\n\n.wpstg-db-table:hover {\n background-color: #f0f8ff;\n}\n\n#wpstg-workflow #wpstg-start-cloning {\n margin-left: 5px;\n vertical-align: baseline;\n}\n\n\n/* Tabs */\n\n.wpstg-tabs-wrapper {\n max-width: 640px;\n margin: 10px 0;\n}\n\n#wpstg-path-wrapper {\n border-bottom: 2px dashed #ccc;\n padding-bottom: 10px;\n margin-bottom: 10px;\n}\n\n.wpstg-tab-section {\n border-bottom: 1px solid #ddd;\n border-right: none;\n border-left: none;\n display: none;\n width: calc(100% - 72px);\n padding: 0px 36px;\n}\n\n.wpstg-tab-section::after {\n display: block;\n content: '';\n clear: both;\n}\n\n.wpstg-tab-header {\n border-bottom: 1px solid #ddd;\n border-right: none;\n border-left: none;\n color: #444;\n font-size: 16px;\n font-weight: bold;\n display: block;\n padding: 10px;;\n text-decoration: none;\n}\n\n.wpstg-tab-triangle {\n display: inline-block;\n margin-right: 10px;\n animation: transform 0.5s;\n}\n\n.wpstg-tab-header:focus {\n color: #444;\n outline: none;\n box-shadow: none;\n}\n\n#wpstg-large-files {\n display: none;\n border: 1px dashed #ccc;\n padding: 10px 10px 10px;\n margin-top: 20px;\n position: relative;\n font-size: 12px;\n}\n\n#wpstg-large-files h3 {\n background: #fff;\n margin: 0;\n padding: 0 5px;\n position: absolute;\n top: -10px;\n left: 5px;\n}\n\n.wpstg-subdir {\n display: none;\n margin-left: 20px;\n}\n\n.wpstg-subdir.wpstg-push {\n display: block;\n margin-left: 20px;\n}\n\n.wpstg-dir a.disabled {\n color: #888;\n cursor: default;\n text-decoration: none;\n}\n\n.wpstg-check-subdirs {\n display: inline-block;\n margin-left: 10px;\n}\n\n.wpstg-notice-alert {\n display: block;\n background-color: #E01E5A;\n padding: 20px;\n max-width: 600px;\n margin-top: 10px;\n color: white;\n}\n\n.wpstg-notice--white {\n display: block;\n background-color: #ffffff;\n padding: 20px;\n max-width: 600px;\n margin-top: 10px;\n}\n\n.wpstg-notice-alert a {\n color: white;\n}\n\n.wpstg-notice-alert h3 {\n color: white;\n}\n\n.wpstg-header {\n font-weight: 400;\n line-height: 1.6em;\n font-size: 19px;\n border-bottom: 1px solid #DFDFDF;\n clear: both;\n padding-top: 10px;\n}\n\n#wpstg-clone-label {\n font-size: 14px;\n font-weight: bold;\n}\n\n.wpstg-log-details {\n height: 300px;\n overflow: scroll;\n max-width: 650px;\n font-family: monospace;\n font-size: 12px;\n line-height: 15px;\n border: 1px solid #FFF;\n background-color: black;\n color: #c0c0c0;\n padding: 3px;\n white-space: nowrap;\n margin-top: 15px;\n}\n\n#wpstg-finished-result {\n display: none;\n}\n\n#wpstg-remove-cloning {\n background: #ff3428;\n border-color: #e72f24;\n margin-top: 5px;\n}\n\n#wpstg-success-notice {\n padding: 10px;\n background-color: white;\n max-width: 900px;\n border: 1px solid #ccc;\n margin-top: 20px;\n}\n\n.wpstg_beta_notice {\n margin-bottom: 20px;\n}\n\n.wpstg-sysinfo {\n width: 700px;\n height: 700px;\n}\n\n.wpstg-form-table .col-title label {\n font-weight: 600;\n}\n\n.wpstg-form-table td:first-child {\n width: 30%;\n}\n\n.wpstg-share-button-container {\n margin: 5px 0;\n}\n\n.wpstg-share-button-container p {\n margin: 0 0 10px 0;\n}\n\n.wpstg-share-button {\n display: inline-block;\n}\n\n.wpstg-share-button a {\n text-decoration: none;\n}\n\n.wpstg-share-button .wpstg-share {\n font-family: sans-serif;\n font-weight: bold;\n text-decoration: none;\n text-align: center;\n}\n\n.wpstg-share-button .wpstg-share {\n -webkit-border-radius: 2px;\n -moz-border-radius: 2px;\n border-radius: 2px;\n color: #FFF;\n display: inline;\n font-size: 12px;\n padding: 4px 8px;\n}\n\n.wpstg-share-button-twitter .wpstg-share {\n background-color: #00ABF0;\n}\n\n.wpstg-share-button-facebook .wpstg-share {\n background-color: #3b5998;\n}\n\n.wpstg-share-button-googleplus .wpstg-share {\n background-color: #F53424;\n}\n\n.wpstg-share-button-twitter .share:active,\n.wpstg-share-button-facebook .share:active,\n.wpstg-share-button-googleplus .share:active {\n background-color: #353535;\n}\n\n#wpstg-check-space {\n margin-left: 8px;\n}\n\n#wpstg-welcome li {\n font-size: 18px;\n line-height: 29px;\n position: relative;\n padding-left: 23px;\n list-style: none !important;\n}\n\n#wpstg-welcome {\n margin-top: 20px;\n margin-right: 20px;\n background-color: white;\n}\n\n.wpstg-heading-pro {\n font-weight: bold;\n}\n\n.wpstg-h2 {\n margin-top: 0;\n margin-bottom: 1.2rem;\n font-size: 30px;\n line-height: 2.5rem;\n}\n\n#wpstg-welcome li:before {\n width: 1em;\n height: 100%;\n background: url(data:image/svg+xml;charset=utf8,%3Csvg%20width%3D%221792%22%20height%3D%221792%22%20viewBox%3D%220%200%201792%201792%22%20xmlns%3D%22http%3A%2F%2Fwww%2Ew3%2Eorg%2F2000%2Fsvg%22%3E%3Cpath%20fill%3D%22%2377B227%22%20d%3D%22M1671%20566q0%2040%2D28%2068l%2D724%20724%2D136%20136q%2D28%2028%2D68%2028t%2D68%2D28l%2D136%2D136%2D362%2D362q%2D28%2D28%2D28%2D68t28%2D68l136%2D136q28%2D28%2068%2D28t68%2028l294%20295%20656%2D657q28%2D28%2068%2D28t68%2028l136%20136q28%2028%2028%2068z%22%2F%3E%3C%2Fsvg%3E) left .4em no-repeat;\n background-size: contain;\n content: \"\";\n position: absolute;\n top: -2px;\n left: 0;\n color: #77b227;\n}\n\n.wpstg-h1 {\n margin-bottom: 1.35rem;\n font-size: 2.5em;\n line-height: 3.68rem;\n letter-spacing: normal;\n}\n\n.swal2-content h1 {\n color: #444;\n}\n\n#wpstg-welcome h2 {\n margin: 0 0 15px;\n}\n\n#wpstg-welcome .wpstg-footer {\n clear: both;\n margin-top: 20px;\n font-style: italic;\n}\n\n#wpstg-footer {\n clear: both;\n margin-top: 20px;\n margin-right: 10px;\n padding-top: 50px;\n}\n\n#wpstg-footer a {\n text-decoration: none;\n}\n\n#wpstg-footer li {\n margin-bottom: 2px;\n list-style: circle;\n}\n\n#wpstg-footer ul {\n margin-left: 15px;\n margin-top: 0px;\n}\n\n.wpstg-footer--title {\n margin-left: 15px;\n}\n\n.wpstg-staging-info {\n margin-top: 8px;\n color: #3e3e3e;\n font-size: 12px;\n}\n\n.wpstg-staging-info a {\n color: #3e3e3e;\n}\n\n.wpstg-staging-info li {\n margin-bottom: 2px;\n}\n\n.wpstg-bold {\n font-weight: 600;\n}\n\n#wpstg-processing-status {\n margin-top: 5px;\n font-size: 13px;\n font-weight: 400;\n float: left;\n}\n\n#wpstg-processing-timer {\n margin-top: 5px;\n font-size: 13px;\n font-weight: 400;\n float: right;\n}\n\n#wpstg-report-issue-button {\n margin-left: 50px;\n border: 1px solid #E01E5A;\n color: #E01E5A;\n background-color: white;\n}\n\n#wpstg-report-issue-button:hover {\n background-color: #dc2b62;\n color: #fff;\n}\n\n.wpstg-blue-primary {\n display: inline-block;\n text-decoration: none;\n font-size: 13px;\n /*line-height: 26px;*/\n height: 28px;\n margin: 0;\n padding: 0 10px 1px;\n cursor: pointer;\n border-width: 1px;\n border-style: solid;\n -webkit-appearance: none;\n border-radius: 3px;\n white-space: nowrap;\n box-sizing: border-box;\n background: #25a1f0;\n border-color: #2188c9;\n color: #fff;\n text-shadow: 0 -1px 1px #006799, 1px 0 1px #006799, 0 1px 1px #006799, -1px 0 1px #006799;\n}\n\n.wpstg-blue-primary:hover {\n background-color: #259be6;\n}\n\n.wpstg-report-issue-form {\n position: absolute;\n z-index: 999;\n width: 300px;\n background-color: #fff;\n padding: 15px 15px 10px;\n border: 1px solid #e8e8e8;\n border-radius: 3px;\n box-shadow: 0 1px 0 0 #fff inset;\n display: none;\n right: 0;\n top: 35px;\n}\n\n@media (max-width: 600px) {\n .wpstg-report-issue-form {\n position: relative;\n }\n}\n\n.wpstg-report-show {\n display: block;\n}\n\n.wpstg-field input[type=text],\n.wpstg-field textarea {\n width: 100%;\n font-weight: 400;\n line-height: 1.4;\n margin-bottom: 4px;\n}\n\n.wpstg-report-email,\n.wpstg-report-hosting-provider {\n width: 100%;\n font-weight: 400;\n font-size: .8rem;\n height: 2.3rem;\n line-height: 2.3rem;\n border-radius: 3px;\n margin-bottom: 4px;\n padding: 0 10px;\n}\n\n.wpstg-report-description {\n border-radius: 3px;\n font-size: .8rem;\n padding: 6px 10px;\n resize: none;\n}\n\n.wpstg-report-privacy-policy {\n font-size: 12px;\n margin-bottom: 15px;\n}\n\n#wpstg-report-cancel {\n float: right;\n margin-right: 5px;\n font-weight: bold;\n}\n\n#wpstg-success-button {\n font-weight: bold;\n}\n\n.wpstg-message {\n box-sizing: border-box;\n -moz-box-sizing: border-box;\n background-color: #f5e0de;\n border-radius: 3px;\n color: rgba(0, 0, 0, .6);\n height: auto;\n margin: 10px 0;\n min-height: 18px;\n padding: 6px 10px;\n position: relative;\n}\n\n.wpstg-message.wpstg-error-message {\n background-color: #f5e0de;\n color: #b65147;\n font-size: 12px;\n}\n\n.wpstg-message.wpstg-success-message {\n background-color: #d7f8e0;\n color: #515151;\n}\n\n.wpstg-message p {\n margin: 3px 0;\n font-size: 13px;\n}\n\n.wpstg-warning {\n display: block;\n padding: 10px;\n background-color: #ffb804;\n color: #ffffff;\n margin: 10px 10px 10px 0;\n}\n\n.wpstg-warning a {\n color: #ffffff;\n font-weight: bold;\n text-decoration: underline;\n}\n\n.wpstg-error {\n display: block;\n padding: 10px !important;\n background-color: #E01E5A !important;\n color: #ffffff;\n margin: 10px 10px 10px 0 !important;\n border-color: transparent !important;\n border-left-color: transparent !important;\n box-shadow: none !important;\n}\n\n.wpstg-error a {\n color: #ffffff;\n font-weight: bold;\n text-decoration: underline;\n}\n\n#wpstg-resume-cloning {\n display: none;\n}\n\n#wpstg-external-db th {\n text-align: left;\n width: 120px;\n}\n\n#wpstg-db-connect {\n font-weight: normal;\n}\n\n#wpstg-db-status {\n display: block;\n margin-top: 5px;\n padding: 5px;\n margin-bottom: 20px;\n border: 1px solid transparent;\n border-radius: 4px;\n text-decoration: none;\n text-align: center;\n}\n\n.wpstg-text-field > #wpstg-db-status {\n margin-top: 8px;\n margin-left: 150px;\n min-width: 300px;\n}\n\n.wpstg-success {\n color: #3c763d;\n background-color: #dff0d8;\n border-color: #d6e9c6;\n}\n\n.wpstg-failed {\n color: #a94442;\n background-color: #f2dede;\n border-color: #ebccd1;\n}\n\n#wpstg_select_tables_cloning {\n height: 600px;\n font-size: 13px;\n}\n\n#wpstg-update-notify {\n background-color: #E01E5A;\n font-size: 14px;\n color: #ffffff;\n line-height: normal;\n padding: 10px;\n}\n\n#wpstg-update-notify a {\n color: #ffffff;\n font-weight: bold;\n}\n\n.wpstg-pointer {\n cursor: pointer;\n}\n\n.wpstg--tab--header {\n background-color: white;\n /* margin-bottom: 10px; */\n /* padding: 16px; */\n position: relative;\n transition: border-color .2s ease-in-out;\n background-color: #ffffff;\n color: #3e3e3e;\n border-radius: 2px;\n box-shadow: 0 0 1px rgba(0, 0, 0, .125), 0 1px 3px rgba(0, 0, 0, .02);\n}\n\n.wpstg--tab--header ul {\n display: flex;\n}\n\n.wpstg--tab--header ul li {\n margin-right: 1em;\n margin-bottom: 0px;\n}\n\n.wpstg--tab--header ul li:last-child {\n margin-right: 0;\n}\n\n.wpstg--tab--header a {\n min-width: 150px;\n text-align: center;\n cursor: pointer;\n display: inline-block;\n padding: 1em 1.25em;\n padding-bottom: 9px;\n color: #c4c4c4;\n font-size: 18px;\n /*\n border: solid 1px;\n */\n}\n\n.wpstg--tab--header a.wpstg--tab--active {\n border-bottom: .4em solid #25A1F0;\n color: #25A1F0;\n}\n\n.wpstg--tab--header a:hover {\n background-color: #fefefe;\n border-bottom: 0.4em solid #25A1F0;\n color: #25A1F0;\n}\n\n.wpstg--tab--content {\n display: none;\n}\n\n.wpstg--tab--active {\n display: block;\n}\n\n.wpstg--text--strong,\n.wpstg--text--strong * {\n font-weight: bold !important;\n}\n\n.wpstg--text--danger {\n color: #a94442;\n}\n\n.wpstg--tooltip {\n position: relative;\n display: inline-block;\n border-bottom: 1px dotted black;\n margin-left: 10px;\n}\n\n.wpstg--tooltip .wpstg--tooltiptext {\n visibility: hidden;\n width: 300px;\n background-color: #ffffff;\n color: #505050;\n text-align: left;\n padding: 12px;\n border-radius: 3px;\n position: absolute;\n z-index: 1;\n -webkit-box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\n -moz-box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\n box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);\n}\n\n.wpstg--tooltiptext-backups {\n width: 120px;\n top: 100%;\n left: -150%;\n margin-left: -56px;\n margin-top: 4px;\n}\n\n.wpstg--tooltip.wpstg--exclude-rules--tooltip {\n border-bottom: 0px solid transparent;\n}\n\n.wpstg--tooltip.wpstg--exclude-rules--tooltip > .wpstg--tooltiptext {\n margin-top: 0px;\n margin-left: -150px;\n}\n\n/**\nTooltip top arrow\n */\n\n.wpstg--tooltip .wpstg--tooltiptext-backups::after {\n content: \" \";\n position: absolute;\n bottom: 100%;\n /* At the top of the tooltip */\n left: 50%;\n margin-left: 25px;\n border-width: 5px;\n border-style: solid;\n border-color: transparent transparent white transparent;\n}\n\n.wpstg--tooltip .wpstg--tooltiptext.has-top-arrow {\n margin-top: 6px;\n}\n\n.wpstg--tooltip .wpstg--tooltiptext.has-top-arrow::after {\n content: \" \";\n position: absolute;\n bottom: 100%;\n left: 50%;\n margin-left: -18px;\n border-width: 5px;\n border-style: solid;\n border-color: transparent transparent white transparent;\n}\n\n.wpstg--snaphot-restore-table tr {\n line-height: 12px;\n}\n\n.wpstg-float-left {\n float: left;\n}\n\n.wpstg-beta-notice {\n background-color: #b0e8b0;\n border-radius: 3px;\n padding: 7px;\n margin-bottom: 20px;\n}\n\n#wpstg-backup-name {\n font-size: 1.875em;\n font-weight: 600;\n}\n\n#wpstg_select_tables_cloning option:checked {\n /* Cannot use background color here because Chrome and Firefox ignore it even if set to !important */\n -webkit-appearance: menulist-button;\n background-image: linear-gradient(0deg, #1e90ff 0%, #1e90ff 100%);\n}\n\n.wpstg--btn--cancel {\n background: #ff3428;\n border-color: #e72f24;\n color: #fff;\n height: auto;\n line-height: normal;\n font-size: 16px;\n padding: .5em;\n margin-bottom: 1.5em;\n}\n\n.wpstg--btn--cancel:hover {\n background: #ff3428;\n border-color: #e72f24;\n}\n\n.wpstg--process--content > .swal2-html-container {\n padding: 4em 2em !important;\n}\n\n.wpstg--modal--process--logs,\n.wpstg--modal--error--logs {\n background: #ffffff;\n border: 1px solid #a8a8a8;\n border-radius: 3px;\n height: 300px;\n margin-top: 1em;\n display: none;\n padding-top: 10px;\n padding-left: 10px;\n overflow: auto;\n text-align: justify;\n}\n\n.wpstg--modal--error--logs {\n height: auto;\n max-height: 300px;\n}\n\n.wpstg--modal--process--logs p {\n font-size: 12px;\n white-space: nowrap;\n}\n\n.wpstg--modal--process--logs p.wpstg--modal--process--msg--info {\n color: #222222;\n}\n\n.wpstg--modal--process--logs p.wpstg--modal--process--msg--debug {\n color: #757575;\n}\n\n.wpstg--modal--process--title {\n color: #565656;\n margin: .25em 0;\n}\n\n.wpstg--modal--process--subtitle {\n margin: .5em 0;\n color: #565656;\n}\n\n.wpstg--modal--error--logs > p {\n text-align: left;\n font-size: 14px;\n color: #222222;\n}\n\n.wpstg--modal--process--logs p,\n.wpstg--modal--error--logs p {\n margin: 0px;\n margin-bottom: 2px;\n}\n\n.wpstg--modal--process--msg--error {\n color: #E01E5A;\n}\n\n.wpstg--modal--process--msg--critical {\n color: #E01E5A;\n}\n\n.wpstg--modal--process--msg--warning {\n color: darkorange;\n}\n\n.wpstg--modal--process--msg-found {\n font-size: 16px;\n color: #E01E5A;\n font-weight: bold;\n}\n\n.wpstg--modal--delete {\n text-align: left;\n margin-top: 8px;\n color: #565656;\n}\n\n.wpstg-swal-popup .swal2-cancel.wpstg--btn--cancel {\n margin-bottom: 0;\n text-shadow: none !important;\n}\n\n.wpstg-swal-popup .wpstg-loader {\n display: inline-block !important;\n}\n\n.wpstg--modal--process--generic-problem {\n display: none;\n border-left: 5px solid #E01E5A;\n margin: .5em 0;\n}\n\n.wpstg--modal--process--logs--tail {\n font-size: 16px;\n color: #565656;\n background: none;\n border: none;\n cursor: pointer;\n}\n\n.wpstg--modal--backup--import--upload--title {\n color: #565656;\n}\n\n.wpstg--modal--backup--import--configure,\n.wpstg--modal--backup--import--upload--status,\n.wpstg--modal--backup--import--upload--container input[type=\"file\"] {\n display: none;\n}\n\n#wpstg--backups--import--file-list {\n font-size: 14px;\n font-weight: bold;\n}\n\n#wpstg--backups--import--file-list-empty {\n color: #E01E5A;\n}\n\n.wpstg--modal--backup--import--filesystem label {\n font-size: 14px;\n}\n\n.wpstg--modal--backup--import--filesystem button {\n margin-bottom: 20px;\n}\n\n.wpstg--modal--backup--import--upload {\n position: relative;\n min-height: 30px;\n}\n\n.wpstg--modal--backup--import--upload {\n color: #505050;\n}\n\n.wpstg--modal--backup--import--upload--container {\n position: relative;\n border-radius: 10px;\n margin: .5em;\n padding: 1em .5em;\n border: 3.5px dashed #dedede;\n transition: background-color 0.3s ease, color 0.3s ease;\n background-color: #f4fbff;\n}\n\n.wpstg--modal--backup--import--upload--container.wpstg--has-dragover span.wpstg--drop {\n display: inline-flex;\n}\n\n.wpstg--modal--backup--import--upload--container input[type='file'] {\n display: none;\n}\n\n.wpstg--modal--backup--import--upload--container img {\n width: 4em;\n align-self: center;\n border: none;\n}\n\n.wpstg--modal--backup--import--upload--container span {\n margin-top: 1em;\n}\n\n.wpstg--backup--import--options > button {\n margin-top: 1em;\n padding: 1em;\n align-self: center;\n width: 185px;\n height: auto;\n line-height: normal;\n}\n\n.wpstg--backup--import--options {\n position: relative;\n display: flex;\n justify-content: center;\n}\n\n.wpstg--backup--import--options ul {\n display: none;\n}\n\n.wpstg--backup--import--options.wpstg--show-options ul {\n padding: 0;\n margin: 54px 0 0 0;\n display: block;\n position: absolute;\n width: 185px;\n background: #25a1f0;\n box-sizing: border-box;\n border-radius: 0 0 3px 3px;\n border-width: 1px;\n border-color: #2188c9;\n text-shadow: 0 -1px 1px #006799, 1px 0 1px #006799, 0 1px 1px #006799, -1px 0 1px #006799;\n}\n\n.wpstg--backup--import--options.wpstg--show-options ul li {\n border-bottom: .1em solid #25a1f0;\n margin: 0;\n}\n\n.wpstg--backup--import--options.wpstg--show-options ul li:hover {\n background-color: #25a1f0;\n}\n\n.wpstg--backup--import--options.wpstg--show-options ul li:last-child {\n border-bottom: none;\n}\n\n.wpstg--backup--import--options ul li button {\n cursor: pointer;\n background: none;\n border: none;\n margin: 0;\n width: 100%;\n color: white;\n height: 40px;\n line-height: 40px;\n}\n\n.wpstg--backup--import--options ul li button:hover {\n background-color: #259be6;\n}\n\n.wpstg--modal--backup--import--search-replace--info {\n margin: 1em 0;\n display: flex;\n flex-direction: row;\n}\n\n.wpstg--modal--backup--import--info p {\n text-align: left;\n margin: 0;\n}\n\n.wpstg--modal--backup--import--search-replace--wrapper button {\n align-self: center;\n}\n\n.wpstg--import--advanced-options--button {\n border: 0;\n border-radius: 3px;\n font-size: 18px;\n text-shadow: 0 -1px 1px #006799, 1px 0 1px #006799, 0 1px 1px #006799, -1px 0 1px #006799;\n cursor: pointer;\n}\n\n.wpstg--modal--backup--import--search-replace--new {\n color: white;\n background-color: #25a1f0;\n}\n\n.wpstg--modal--backup--import--search-replace--remove {\n color: white;\n background-color: #25a1f0;\n width: 22px;\n height: 22px;\n margin-left: 5px;\n}\n\n.wpstg--modal--backup--import--search-replace--input-group:first-child button {\n display: none;\n}\n\n.wpstg--modal--backup--import--search-replace--input--container {\n flex: 1;\n display: flex;\n flex-direction: column;\n}\n\n.wpstg--modal--backup--import--search-replace--input-group {\n width: 100%;\n border-bottom: 6px solid #f1f1f1;\n margin-bottom: 10px;\n}\n\n.wpstg--modal--backup--import--search-replace--input-group input {\n min-width: 250px;\n width: calc(50% - 4px - 11px - 5px); /* -4px is half of the padding; -11px is half of the button; -5 is the margin left of the button */\n display: inline-block;\n line-height: 10px;\n border: 1px solid #dedede;\n border-radius: 3px;\n color: #666;\n padding: 8px;\n margin-bottom: 12px;\n}\n\n.wpstg--modal--import--upload--process {\n display: none;\n position: relative;\n height: 30px;\n margin-top: 20px;\n margin-bottom: 20px;\n width: 100%;\n top: 0;\n left: 0;\n text-indent: 1em;\n white-space: nowrap;\n overflow: hidden;\n color: #333333;\n justify-content: center;\n align-items: center;\n}\n\n.wpstg--modal--import--upload--progress {\n position: absolute;\n background: #98d452;\n color: white;\n height: 100%;\n border-radius: 4px;\n left: 0;\n top: 0;\n}\n\n.wpstg--modal--import--upload--progress--title {\n z-index: 9;\n}\n\n.wpstg-fieldset:disabled {\n opacity: 0.8;\n border-top: 1px solid white;\n margin-top: 20px;\n}\n\n.wpstg-fieldset {\n padding-left: 20px;\n}\n\n.wpstg-fs-14 {\n font-size: 14px;\n}\n\n.wpstg-dark-alert {\n font-weight: bold;\n background-color: #0e86d9;\n padding: 15px;\n margin-top: 0px;\n color: white;\n}\n\n.wpstg-dark-alert .wpstg-button--cta-red {\n margin-left:10px;\n}\n\n.wpstg-form-group {\n display: block;\n width: 100%;\n margin-bottom: 8px;\n align-items: center;\n}\n\n.wpstg-form-group > label {\n display: block;\n font-weight: 700;\n}\n\n.wpstg-text-field > input {\n width: 300px;\n display: block;\n line-height: 1.5;\n}\n\n.wpstg-code-segment {\n display: block;\n}\n\n.wpstg-text-field > .wpstg-code-segment {\n margin-top: 4px;\n min-width: 300px;\n}\n\n.wpstg-form-group > .wpstg-checkbox {\n min-width: 100%;\n width: 100%;\n position: relative;\n}\n\n.wpstg-form-group > .wpstg-checkbox > input[type='checkbox'] {\n left: 150px;\n}\n\n.wpstg-rounded {\n border-radius: 3px;\n}\n\n.wpstg-white-border {\n border: 1px solid white !important;\n}\n\n.wpstg-ml-4 {\n margin-left: 4px;\n}\n\n#wpstg-confirm-backup-restore-data {\n margin: 40px;\n text-align: left;\n}\n\n#wpstg-advanced-settings hr {\n margin: 20px 0;\n}\n\n.wpstg-form-row {\n display: block;\n}\n\n.wpstg-form-row label,\n.wpstg-form-row input {\n display: table-cell;\n padding-left: 5px;\n padding-right: 5px;\n margin-top: 3px;\n margin-bottom: 3px;\n}\n\n.wpstg-form-row input {\n width: 400px;\n}\n\n.wpstg-form-row label {\n font-weight: bold;\n width: 1px;\n white-space: nowrap;\n}\n\n#wpstg-db-connect-output #wpstg-db-status {\n width: 390px;\n}\n\n.wpstg-fs-14 {\n font-size: 14px;\n}\n\n.wpstg-code-segment {\n display: block;\n}\n\n.wpstg-form-group > .wpstg-checkbox {\n min-width: 100%;\n width: 100%;\n}\n\n.wpstg-form-group > .wpstg-checkbox > input[type='checkbox'] {\n margin-left: 10px;\n}\n\n@media only screen and (max-width: 768px) {\n .wpstg-form-group > label {\n min-width: auto;\n width: auto;\n }\n\n .wpstg-text-field > input {\n width: 100%;\n }\n\n .wpstg-text-field > .wpstg-code-segment {\n margin-left: 0;\n min-width: 100%;\n }\n\n .wpstg-tab-section {\n width: calc(100vw - 60px);\n max-width: 450px;\n }\n}\n\n.wpstg-rounded {\n border-radius: 3px;\n}\n\n.wpstg-white-border {\n border: 1px solid white !important;\n}\n\n.wpstg-m-0 {\n margin: 0;\n}\n\n.wpstg-mt-10px {\n margin-top: 10px;\n}\n\n.wpstg-my-10px {\n margin-top: 10px;\n margin-bottom: 10px;\n}\n\n.wpstg-w-100 {\n width: 100%;\n}\n\n.wpstg-box-shadow {\n box-shadow: 0 1px 1px 0 rgba(0, 0, 0, .1);\n}\n\n.wpstg-float-left {\n float: left;\n}\n\n.wpstg-bold-text {\n font-weight: bold;\n}\n\n.wpstg-warning.notice {\n border-left: 4px solid #ffba00;\n}\n\n.wpstg-confirmation-label {\n background-color: #5b9dd9;\n color: #fff;\n padding: 2px;\n border-radius: 3px;\n}\n\n.wpstg-my-6px {\n margin-bottom: 6px;\n margin-top: 6px;\n}\n\n.wpstg-mb-10px {\n margin-bottom: 10px;\n}\n\n.wpstg-clear-both {\n clear: both;\n}\n\n.wpstg-font-italic {\n font-style: italic;\n}\n\n.wpstg-mt-20px {\n margin-top: 20px;\n}\n\n.wpstg-welcome-container {\n border: 2px solid white;\n padding: 20px;\n margin-bottom: 20px;\n}\n\n.wpstg-ml-30px {\n margin-left: 30px;\n}\n\n.wpstg-text-center {\n text-align: center;\n}\n\n.wpstg-feedback-link {\n text-decoration: none;\n}\n\n.wpstg-feedback-span {\n display: block;\n margin-bottom: 3px;\n}\n\n#wpstg-confirm-backup-restore-data {\n margin: 40px;\n text-align: left;\n}\n\n#wpstg-confirm-backup-restore-wrapper {\n margin: 30px;\n margin-top: 0;\n}\n\n#wpstg-confirm-backup-restore-wrapper h3 {\n color: #E01E5A;\n}\n\n#wpstg-progress-db,\n#wpstg-progress-backup {\n background-color: #3fa5ee;\n}\n\n#wpstg-progress-sr,\n#wpstg-progress-files.wpstg-pro {\n background-color: #3c9ee4;\n}\n\n#wpstg-progress-dirs,\n#wpstg-progress-data {\n background-color: #3a96d7;\n}\n\n#wpstg-progress-files:not(.wpstg-pro),\n#wpstg-progress-finishing {\n background-color: #378cc9;\n}\n\n.wpstg-issue-resubmit-confirmation.swal2-container,\n.wpstg-swal2-container.swal2-container {\n z-index: 10500;\n}\n\n.wpstg-swal2-container.wpstg-swal2-loading .swal2-actions,\n.wpstg-swal2-container.wpstg-swal2-loading .swal2-header {\n display: none;\n}\n\nbody.toplevel_page_wpstg_backup .swal2-container .swal2-content,\nbody.toplevel_page_wpstg_clone .swal2-container .swal2-content {\n z-index: 2;\n}\n\n.toplevel_page_wpstg_clone #swal2-content h2 {\n color: #565656;\n}\n\n.toplevel_page_wpstg_clone #swal2-content {\n line-height: 1.5em;\n}\n\ndiv#exportUploadsWithoutDatabaseWarning {\n font-style: italic;\n font-size: 0.9rem;\n margin: 10px;\n padding: 10px;\n border: 1px solid #e3e3e3;\n border-radius: 5px;\n text-align: center;\n background-color: #fafafa;\n}\n\n.wpstg-advanced-options-dropdown-wrapper {\n display: none; /* ENABLE WHEN WE HAVE ADVANCED OPTIONS FOR EXPORTING */\n margin-top: 20px;\n}\n\n.wpstg--modal--backup--import--search-replace--wrapper {\n text-align: left;\n margin-top: 20px;\n}\n\n.wpstg--modal--backup--import--search-replace--new--wrapper {\n text-align: center;\n}\n\n.wpstg-import-backup-contains li {\n display: inline-block;\n}\n\n.wpstg-import-backup-contains li .wpstg-backups-contains {\n border-radius: 3px;\n color: #979797;\n background-color: #e3e3e3;\n border: 1px solid #c2c2c2;\n width: 17px;\n height: 17px;\n font-size: 17px;\n}\n\n.wpstg-import-backup-contains.wpstg-listing-single-backup li .wpstg-backups-contains {\n padding: 2px;\n background-color: white;\n border: 1px solid #c2c2c2;\n}\n\n.wpstg-import-backup-contains.wpstg-listing-single-backup li .wpstg-backups-contains > .wpstg--dashicons {\n filter: invert(50%);\n}\n\n.wpstg-import-backup-contains .wpstg--tooltiptext {\n width: 50px;\n font-size: x-small;\n padding: 5px;\n left: -25px;\n text-align: center;\n}\n\n.wpstg-import-backup-contains-title {\n display: inline-block;\n}\n\nul.wpstg-import-backup-contains {\n display: inline-block;\n}\n\n.wpstg-import-backup-name {\n display: inline-block;\n font-weight: bold;\n}\n\n.wpstg-backup-more-info-toggle {\n font-size: x-small;\n display: inline-block;\n font-style: italic;\n cursor: pointer;\n}\n\n.wpstg-backup-more-info-toggle::selection {\n background: none;\n}\n\nul.wpstg-import-backup-more-info {\n font-size: 14px;\n text-align: left;\n margin-bottom: 30px;\n margin-top: 10px;\n background-color: #f6f6f6;\n border: 1px solid #878787;\n border-radius: 3px;\n padding: 7px;\n cursor: pointer;\n}\n\nul.wpstg-import-backup-more-info:hover {\n background-color: #def2ff;\n border: 1px solid #25a1f0;\n}\n\nul.wpstg-import-backup-more-info li {\n height: 20px;\n}\n\n.wpstg-backup-list {\n max-width: 800px;\n}\n\n.wpstg-backup-list h3 {\n color:#3e3e3e;\n}\n\n.wpstg-backup-list ul ul {\n margin-block-start: 1em;\n margin-block-end: 1em;\n}\n\n.wpstg-push-confirmation-message {\n text-align: justify;\n font-size: 15px;\n}\n\n.wpstg-settings-row {\n padding-top: 10px;\n padding-bottom: 10px;\n}\n\n.wpstg-settings-title {\n font-weight: 600;\n}\n\n.wpstg-settings-form-group {\n display: flex;\n align-items: center;\n}\n\n.wpstg-settings-form-group > .wpstg-settings-message {\n width: 30%;\n padding: 0;\n margin: 7px 0 0;\n}\n\n/**\n * WP STAGING EXCLUSION RULES TABLE LAYOUT\n */\n\n.wpstg-excluded-filters-container {\n padding: 0;\n margin-top: 10px;\n margin-bottom: 10px;\n max-width: 100%;\n width: 100%;\n}\n\n.wpstg-excluded-filters-container > table {\n width: 100%;\n border-collapse: collapse;\n border-color: transparent;\n}\n\n.wpstg-excluded-filters-container td {\n padding-top: 4px;\n padding-bottom: 4px;\n height: 20px;\n}\n\n.wpstg-excluded-filters-container h4 {\n margin: 0;\n}\n\n.wpstg-exclude-filters-foot {\n display: flex;\n justify-content: flex-start;\n padding: 0;\n}\n\n/**\n * WP STAGING EXCLUSION RULE DROPDOWN STYLE\n */\n\n\n.wpstg-exclude-filter-dropdown > button:hover {\n background: #135e96;;\n border: 1px solid #135e96;;\n}\n\n.wpstg-exclude-filter-dropdown > .wpstg-dropdown-menu {\n width: 128px;\n}\n\n.wpstg-remove-exclude-rule {\n color: #fff !important;\n background-color: #e01e5a;\n border: 1px solid #e01e5a;\n width: 20px;\n height: 20px;\n border-radius: 10px;\n font-size: 24px;\n padding: 0;\n display: inline-flex;\n justify-content: center;\n outline: none;\n box-shadow: none;\n font-weight: 400;\n line-height: 0.7;\n margin-top: 5px;\n cursor: pointer;\n}\n\n.wpstg-remove-exclude-rule:hover {\n background-color: #E01E5A;\n border-color: #E01E5A;\n}\n\n.wpstg-code-block {\n margin-top: 4px;\n font-size: 1.2em;\n background: #f8f8f8;\n border-radius: 2px;\n}\n\n.wpstg-rule-info {\n background: #f8f8f8 !important;\n}\n\ncode.wpstg-code {\n display: inline-block;\n font-size: 11px;\n border: 1px solid #aaa;\n background: #fff;\n padding: 2px 4px;\n margin-bottom: 1px;\n color: #E01E5A;\n}\n\n.wpstg-exclusion-rule-info {\n color: #fff !important;\n background-color: #ffc107;\n border: 1px solid #ffc107;\n width: 14px;\n height: 14px;\n border-radius: 7px;\n font-size: 14px;\n padding: 0;\n display: inline-flex;\n justify-content: center;\n align-items: center;\n outline: none;\n box-shadow: none;\n font-weight: 400;\n vertical-align: middle;\n}\n\n.wpstg-exclusion-rule-info:hover {\n background-color: #ffba0c;\n border: 1px solid #ffba0c;\n}\n\n/**\n * WP STAGING INPUTS EXCLUSION RULES\n */\n\n.wpstg-exclude-rule-input {\n font-size: 12px !important;\n padding: 2px 6px;\n box-shadow: none;\n outline: none !important;\n display: inline-block;\n font-weight: 400;\n line-height: 1.5;\n color: #222;\n border-radius: 0 !important;\n background-color: #fff;\n border: 1px solid #bbb;\n min-height: 24px !important;\n margin-top: 4px;\n margin-left: 4px;\n vertical-align: baseline !important;\n transition: all 0.3s cubic-bezier(.25, .8, .25, 1);\n width: 135px;\n}\n\n.wpstg-excluded-filters-container tbody > tr:last-child .wpstg-exclude-rule-input {\n margin-bottom: 4px;\n}\n\n.wpstg-exclude-rule-input:hover {\n border: 1px solid #999;\n}\n\n.wpstg-exclude-rule-input:focus {\n border: 1px solid #25A0F1 !important;\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24) !important;\n}\n\n.wpstg-file-size-exclude-select,\n.wpstg-path-exclude-select {\n width: 135px;\n}\n\n.wpstg-file-size-exclude-select-small {\n width: 52px;\n}\n\n.wpstg-file-size-exclude-input {\n width: 75px;\n}\n\n.wpstg-staging-option-title {\n margin: 15px 0 0;\n}\n\n.wpstg-swal-push-container.swal2-container {\n z-index: 9995;\n}\n\n#wpstg-scanning-files {\n padding-bottom: 5px;\n}\n\n#wpstg-scanning-files.wpstg-tab-section, #wpstg-scanning-db.wpstg-tab-section {\n padding-top: 10px;\n}\n\n.wpstg-reset-excludes-container {\n margin: 10px 0;\n}\n\n.wpstg-swal2-ajax-loader {\n width: 100%;\n height: 150px;\n overflow: hidden;\n display: flex;\n justify-content: center;\n align-items: center;\n}\n\n@keyframes wpstg-loading-icon-anim {\n 0% {\n transform: rotate(0);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n\n.wpstg-swal2-ajax-loader > img {\n width: 64px;\n height: 64px;\n animation: wpstg-loading-icon-anim 1s infinite linear;\n -webkit-animation: wpstg-loading-icon-anim 1s infinite linear;\n}\n\n.wpstg-swal2-container .wpstg-tab-section {\n width: auto !important;\n}\n\n#wpstg-no-staging-site-results {\n margin-top: 10px;\n max-width: 375px;\n}\n\nli#wpstg-backup-no-results {\n max-width: 500px;\n}\n\nli#wpstg-backup-no-results div, #wpstg-no-staging-site-results div {\n display: inline-block;\n text-align: center;\n}\n\nli#wpstg-backup-no-results .wpstg--dashicons, #wpstg-no-staging-site-results .wpstg--dashicons {\n filter: invert(50%);\n position: absolute;\n margin-top: 1px;\n}\n\nli#wpstg-backup-no-results .no-backups-found-text, #wpstg-no-staging-site-results .no-staging-site-found-text {\n color: #5d5d5d;\n margin-left: 20px;\n}\n\n@media only screen and (max-width: 680px) {\n li#wpstg-backup-no-results div, #wpstg-no-staging-site-results div {\n width: 100%;\n }\n}\n\n#wpstg--modal--backup--download-inner p.wpstg-download-modal-text {\n font-size: 16px;\n color: #565656;\n}\n\n#wpstg--modal--backup--download-inner h2 {\n color: #565656;\n}\n\n.wpstg-backup-restore-contains-database,\n.wpstg-backup-restore-contains-files {\n display: none;\n}\n\n.wpstg-green-button {\n background: #8bc34a;\n border: 1px solid #78a93f;\n color: white;\n text-shadow: 0 -1px 1px #78a93f, 1px 0 1px #78a93f, 0 1px 1px #40c921, -1px 0 1px #78a93f;\n}\n\n.wpstg-green-button:hover {\n background: #78a93f;\n}\n\n.wpstg-is-dir-loading {\n position: absolute;\n margin-top: -2px;\n margin-left: 8px;\n display: none;\n}\n\n.wpstg-ml-8px {\n margin-left: 8px;\n}\n\n.wpstg-mb-8px {\n margin-bottom: 8px;\n}\n\n\n.wpstg-btn-danger {\n background-color: #E01E5A;\n border: 1px solid #E01E5A;\n color: white;\n text-shadow: none;\n}\n\n.wpstg-btn-danger:hover {\n background: #c0194d;\n box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);\n}\n\n.wpstg-swal2-container.wpstg-swal2-loading > .swal2-modal {\n height: 200px;\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container:not(.wpstg-swal2-loading) > .swal2-modal {\n max-width: 480px;\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container .swal2-header {\n display: none;\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container .swal2-content {\n height: auto;\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container > .swal2-modal > .swal2-content .wpstg-tabs-wrapper {\n overflow-y: auto;\n height: auto !important;\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container > .swal2-modal > .swal2-content {\n font-size: 13px;\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container > .swal2-modal > .swal2-content .wpstg-dir {\n margin-bottom: 4px;\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container > .swal2-modal > .swal2-content .wpstg-subdir {\n margin-top: 4px;\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container.has-collapsible-open .swal2-modal {\n height: calc(100vh - 70px);\n}\n\n.wpstg-reset-confirmation.wpstg-swal2-container.has-collapsible-open > .swal2-modal > .swal2-content .wpstg-tabs-wrapper {\n height: calc(100vh - 350px) !important;\n}\n\n.swal2-actions.wpstg--modal--actions > button {\n margin-left: 4px;\n margin-right: 4px;\n text-transform: uppercase;\n text-shadow: initial;\n font-weight: 500;\n min-width: 80px;\n}\n\n.wpstg-swal-popup {\n max-width: 1200px !important;\n}\n\n.wpstg-swal-popup.wpstg-push-finished .swal2-title {\n color: #a8a8a8;\n}\n\n.wpstg-swal-popup.wpstg-push-finished .swal2-content {\n margin-top: 8px;\n color: #a8a8a8;\n}\n\n.wpstg-swal-popup .swal2-progress-steps .swal2-progress-step.swal2-active-progress-step,\n.wpstg-swal-popup .swal2-progress-steps .swal2-progress-step,\n.wpstg-swal-popup .swal2-progress-steps .swal2-progress-step-line {\n background: #25a1f0;\n}\n\n.wpstg-swal-popup .swal2-progress-steps .swal2-progress-step-line {\n width: 2.75em;\n}\n\n.wpstg--dashicons {\n width: 16px;\n height: 16px;\n}\n\n.wpstg--dashicons.wpstg-dashicons-grey {\n filter: invert(20%);\n}\n\n.wpstg--dashicons.wpstg-dashicons-19 {\n width: 19px;\n height: 19px;\n}\n\n.wpstg--dashicons.wpstg-dashicons-21 {\n width: 21px;\n height: 21px;\n}\n\n#wpstg--tab--backup #wpstg-step-1 {\n display: flex;\n align-items: center;\n}\n\n.wpstg-advanced-options .wpstg--tooltip,\n#wpstg--tab--backup #wpstg-step-1 .wpstg--tooltip {\n border-bottom: 0 solid transparent;\n display: inline-flex;\n align-items: center;\n}\n\n#wpstg--tab--backup #wpstg-step-1 .wpstg--tooltip {\n border-bottom: 0 solid transparent;\n display: flex;\n align-items: center;\n}\n\n.wpstg--tooltip .wpstg--tooltiptext-backups::after {\n left: calc(20% + 2px);\n}\n\n.wpstg-listing-single-backup .wpstg--dashicons {\n width: 17px;\n height: 17px;\n}\n\n.wpstg-100-width {\n width: 100px;\n}\n\n.wpstg-caret {\n display: inline-block;\n width: 0;\n height: 0;\n margin-left: 2px;\n vertical-align: middle;\n border-top: 4px solid;\n border-right: 4px solid transparent;\n border-left: 4px solid transparent;\n transition: transform 0.2s;\n cursor: pointer;\n}\n\n.wpstg-caret.wpstg-caret-up {\n transform: rotate(-180deg);\n}\n\n.wpstg-advanced-options-site label {\n font-size: 16px;\n display: block;\n margin: .5em 0;\n}\n\n#wpstg-confirm-backup-restore-data {\n font-size: 18px;\n margin: 0;\n margin-top: 30px;\n}\n\n/* Sweetalert WP STAGING Theme */\n\nbody.toplevel_page_wpstg_backup .swal2-container.swal2-backdrop-show,\nbody.toplevel_page_wpstg_clone .swal2-container.swal2-backdrop-show {\n background: rgba(0, 0, 0, .6);\n z-index: 9995;\n}\n\n.wpstg-swal-popup.swal2-popup {\n border-radius: 8px;\n z-index: 9999;\n padding: 24px;\n color: #565656;\n font-family: Verdana, Geneva, Tahoma, sans-serif;\n}\n\n.wpstg-swal-popup .swal2-title {\n font-size: 22px;\n color: #565656;\n}\n\n.wpstg-swal-popup.swal2-popup:not(.centered-modal) .swal2-title {\n align-self: flex-start; /* For an actual Swal title */\n text-align: left; /* Manually adding this class to a non flex display */\n margin-bottom: 0;\n}\n\n.wpstg-swal-popup .swal2-close {\n top: 8px;\n right: 8px;\n z-index: 5;\n}\n\n.wpstg-swal-popup .swal2-close:focus {\n outline: none;\n}\n\n.wpstg-swal-popup.swal2-popup:not(.centered-modal) .swal2-actions {\n justify-content: flex-end;\n}\n\n.wpstg-swal-popup .swal2-actions > button {\n border-radius: 4px;\n font-weight: 900;\n border: 0;\n font-size: 15px;\n padding: 10px 12px;\n text-transform: capitalize;\n line-height: normal;\n height: 40px;\n min-width: 100px;\n text-shadow: none;\n}\n\n.wpstg-swal-popup.swal2-popup:not(.centered-modal) .swal2-actions > button {\n margin-left: 8px;\n}\n\n.wpstg-swal-popup .swal2-actions > button.swal2-cancel {\n border: 1px solid rgba(29, 28, 29, 0.3);\n background: #fff;\n color: rgb(29, 28, 29);\n font-weight: 500;\n width: 100px;\n text-shadow: none;\n}\n\n.wpstg-swal-popup .swal2-actions > button:hover {\n box-shadow: 0 1px 3px 0 rgba(0 0 0 .1);\n}\n\n.wpstg-swal-popup .swal2-actions > button.swal2-cancel:hover {\n background: rgba(28, 29, 28, .04);\n}\n\n#wpstg-backup-name-input {\n height: 44px;\n font-size: 18px;\n}\n\n.wpstg-restore-finished-container .swal2-title {\n color: #565656 !important;\n}\n\n/*#wpstg-restore-success {\n color: #565656;\n}*/\n\n.wpstg-restore-finished-container .swal2-content {\n margin-top: 20px;\n color: #a8a8a8;\n}\n\n/* WP Staging Implementation of Windows Style Linear Loader */\n\n.wpstg-linear-loader > span[class*=\"wpstg-linear-loader-item\"] {\n height: 6px;\n width: 6px;\n background: #333;\n display: inline-block;\n margin: 12px 2px;\n border-radius: 100%;\n animation: wpstg_linear_loader 3s infinite;\n animation-timing-function: cubic-bezier(0.030, 0.615, 0.995, 0.415);\n animation-fill-mode: both;\n}\n\n.wpstg-linear-loader > span.wpstg-linear-loader-item:nth-child(1) {\n animation-delay: 1s;\n}\n\n.wpstg-linear-loader > span.wpstg-linear-loader-item:nth-child(2) {\n animation-delay: 0.8s;\n}\n\n.wpstg-linear-loader > span.wpstg-linear-loader-item:nth-child(3) {\n animation-delay: 0.6s;\n}\n\n.wpstg-linear-loader > span.wpstg-linear-loader-item:nth-child(4) {\n animation-delay: 0.4s;\n}\n\n.wpstg-linear-loader > span.wpstg-linear-loader-item:nth-child(5) {\n animation-delay: 0.2s;\n}\n\n.wpstg-linear-loader > span.wpstg-linear-loader-item:nth-child(6) {\n animation-delay: 0s;\n}\n\n@keyframes wpstg_linear_loader {\n 0% {\n transform: translateX(-30px);\n opacity: 0;\n }\n 25% {\n opacity: 1;\n }\n 50% {\n transform: translateX(30px);\n opacity: 0;\n }\n 100% {\n opacity: 0;\n }\n}\n\n/* END - Windows Style Linear Loader */\n\n.wpstg--modal--backup--import--upload--content {\n padding: .75em;\n margin: 1em auto;\n}\n\n.wpstg--modal--backup--import--upload--content .wpstg-linear-loader {\n display: none;\n}\n\n#wpstg-multisite-disabled .wpstg-clone {\n width: 355px;\n}\n\n#wpstg-free-version-backups .wpstg-clone {\n text-align: center;\n}\n\n#wpstg-free-version-backups .wpstg-clone p {\n font-size: 16px;\n}\n\n.wpstg-staging-info li .backup-notes {\n word-break: break-word;\n}\n\n.wpstg--modal--import--upload--progress--title small {\n font-weight: normal;\n}\n\n#wpstg-report-issue-wrapper {\n position: relative;\n}\n\n#wpstg-report-issue-wrapper .arrow-up {\n width: 0;\n height: 0;\n border-left: 8px solid transparent;\n border-right: 8px solid transparent;\n border-bottom: 8px solid white;\n position: absolute;\n top: -8px;\n right: 40px;\n}\n\n.notice {\n margin: 10px 20px 0 2px;\n}\n\n.wpstg--notice {\n box-shadow: 0 1px 1px rgba(0, 0, 0, .04);\n margin: 20px 20px 20px 0px;\n padding: 1px 12px;\n}\n\n.wpstg--error a:hover {\n color: #eeeeee;\n}\n\n.wpstg--error, .wpstg--error a {\n background: #E01E5A;\n color: white;\n}\n\n/**\n * Buttons\n */\n\n.wpstg-button {\n display: inline-block;\n border-radius: 2px;\n cursor: pointer;\n padding: 2px 10px 2px 10px;\n text-transform: uppercase;\n font-weight: 500;\n outline: 0;\n transition: background-color .1s ease-in;\n text-decoration: none;\n}\n\n.wpstg-button.wpstg-save {\n background-color: #1687A7;\n color: white;\n}\n\n.wpstg-button.wpstg-save:hover {\n background-color: #276678;\n}\n\n\n.wpstg-button.wpstg-button-light {\n background-color: #f8f8f8;\n border: 1px solid #eee;\n color: #333;\n animation: background-color 0.3s;\n}\n\n.wpstg-button.wpstg-button-light:hover {\n background-color: #e0e0e0;\n border: 1px solid #e0e0e0;\n}\n\n.wpstg-buttons .spinner {\n float: none;\n margin: 0 0 0 5px;\n}\n\n.wpstg-button.danger {\n display: inline-block;\n text-decoration: none;\n text-align: center;\n text-transform: inherit;\n background-color: #E01E5A;\n color: white;\n border-radius: 2px;\n border-color: transparent;\n}\n\n.wpstg-button.danger:hover {\n background-color: #c0194d;\n}\n\n.wpstg-button--big {\n display: inline-block;\n padding: 10px;\n min-width: 170px;\n font-size: 16px;\n text-decoration: none;\n text-align: center;\n margin-top: 20px;\n color: white;\n border-radius: 3px;\n}\n\n.wpstg-button--primary {\n display: inline-block;\n text-decoration: none;\n font-size: 13px;\n line-height: 2.15384615;\n min-height: 30px;\n margin: 0;\n padding: 0 10px;\n cursor: pointer;\n border: 1px solid rgba(29, 28, 29, 0.3);\n -webkit-appearance: none;\n border-radius: 2px;\n white-space: nowrap;\n box-sizing: border-box;\n color: #171717;\n}\n\n.wpstg-button--primary:hover {\n background: rgba(28, 29, 28, .04);\n color: black;\n}\n\n.wpstg-button--secondary {\n display: inline-block;\n background-color: transparent;\n color: #95a5a6;\n border-radius: 2px;\n border: 1px solid rgba(29, 28, 29, 0.3);\n cursor: pointer;\n padding: 4px 10px 2px 10px;\n font-weight: 500;\n outline: 0;\n transition: background-color .1s ease-in;\n text-decoration: none;\n}\n\n.wpstg-button--red {\n background-color: #E01E5A;\n border-color: #E01E5A;\n color: white;\n}\n\n.wpstg-button--red:hover {\n background-color: #d02358;\n border-color: #e0255f;\n color: white;\n}\n\n.wpstg-button--cta-red {\n background-color: #fe008f;\n border-color: #E01E5A;\n color: white;\n}\n\n.wpstg-button--cta-red:hover {\n background-color: #f31391;\n border-color: #e0255f;\n color: white;\n}\n\n.wpstg-button--blue {\n background-color: #25A0F1;\n border-color: #25A0F1;\n color: white;\n}\n\n.wpstg-button--blue:hover {\n background-color: #259be6;\n border-color: #259be6;\n color: white;\n}\n\n#wpstg-button-backup-upgrade {\n font-size: 16px;\n}\n\n.wpstg-staging-status {\n color: #E01E5A;\n}\n\n#wpstg-push-changes,\n#wpstg-start-updating,\n#wpstg-save-clone-data {\n margin-left: 5px;\n}\n\ninput.wpstg-textbox {\n border: 1px solid #aaa;\n border-radius: .25rem;\n padding: 0.25rem 0.5rem;\n font-size: 14px;\n}\n\ninput.wpstg-textbox:focus {\n outline: 0;\n border-color: #259be6;\n -webkit-box-shadow: 0 0 0 0.1rem rgba(221, 221, 221, .35);\n box-shadow: 0 0 0 0.1rem rgba(221, 221, 221, .35);\n}\n\ninput.wpstg-textbox::placeholder {\n color: #888;\n}\n\n.wpstg--advance-settings--checkbox {\n display: flex;\n align-items: center;\n}\n\n.wpstg--advance-settings--checkbox > label {\n font-size: 14px;\n font-weight: bolder;\n width: 165px;\n display: inline-block;\n}\n\n.wpstg--advance-settings--checkbox > .wpstg--tooltip {\n margin-top: 5px;\n margin-left: 5px;\n position: relative;\n display: inline-block;\n border-bottom: 0px solid transparent;\n}\n\n.wpstg--advance-settings--checkbox > .wpstg--tooltip > .wpstg--tooltiptext {\n top: 18px;\n left: -150px;\n}\n\n\ndiv#wpstg-restore-wait {\n display: none;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n text-align: center;\n height: 100vh;\n width: 100vw;\n position: fixed;\n top: 0;\n left: 0;\n background: white;\n z-index: 99999;\n}\n\ndiv#wpstg-restore-wait .wpstg-title {\n font-weight: bold;\n}\n\ndiv#wpstg-restore-wait div {\n font-size: 16px;\n margin-top: 12px;\n}\n\n.resumable-browse {\n cursor: pointer;\n}\n\n.resumable-browse a {\n text-decoration: underline;\n}\n\n.wpstg--modal--backup--import--upload--container.dragover {\n transition: background-color 0.7s;\n background-color: #94dc96;\n color: #FFF;\n}\n\n.wpstg--modal--backup--import--upload--container.dragover * {\n pointer-events: none; /* Avoids flickering when dragging to drop a file */\n}\n\n.wpstg--modal--backup--import--upload--container.dragover .upload-text {\n display: none;\n}\n\n.wpstg--modal--backup--import--upload--container.dragover .dragover-text {\n display: block;\n}\n\n.wpstg--modal--backup--import--upload--container .dragover-text {\n display: none;\n}\n\n#wpstg-invalid-license-message, #wpstg-invalid-license-message a {\n font-weight: 500;\n color: #E01E5A;\n margin-left: 6px;\n}\n\n#wpstg-sidebar--banner {\n max-width: 200px;\n}\n\n@media screen and (max-width: 1234px) {\n .wpstg-h2 {\n font-size: 24px;\n }\n\n #wpstg-welcome li {\n font-size: 14px;\n }\n}\n\n.wpstg-exclamation {\n color: #ffffff;\n border-radius: 100%;\n background-color: #E01E5A;\n width: 20px;\n height: 20px;\n text-align: center;\n font-weight: bold;\n display: inline-block;\n margin: 6px;\n}\n\n.wpstg--tab--contents {\n padding-top: 1px;\n}\n\n.wpstg-swal-show.swal2-show {\n -webkit-animation: wpstg-swal-show 0.2s !important;\n animation: wpstg-swal-show 0.2s !important;\n}\n\n@-webkit-keyframes wpstg-swal-show {\n 0% {\n transform: scale(0.3);\n }\n 100% {\n transform: scale(1);\n }\n}\n\n@keyframes wpstg-swal-show {\n 0% {\n transform: scale(0.3);\n }\n 100% {\n transform: scale(1);\n }\n}\n"]}
assets/img/loading_v1.gif DELETED
Binary file
assets/img/logo-wp-staging-1468x230.png ADDED
Binary file
assets/img/wp-staging274x463-1.png ADDED
Binary file
assets/img/wpstaging-banner200x400-tryout.gif DELETED
Binary file
assets/img/wpstaging-banner200x400.gif DELETED
Binary file
assets/js/dist/wpstg-admin-rating.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"wpstg-admin-rating.js","sources":["../src/wpstg-admin-rating.js"],"sourcesContent":["let wpstgTimesWaited = 0;\n\n/*\nLet's wait for jQuery to be available to show the rating.\nWe need it to dispatch AJAX requests.\n */\nvar wpstgWaitForJQuery = setInterval(function() {\n if (wpstgTimesWaited > 100) {\n // Give up waiting.\n clearInterval(wpstgWaitForJQuery);\n }\n if (typeof jQuery != 'undefined') {\n wpstgRegisterRatingEvents();\n\n clearInterval(wpstgWaitForJQuery);\n }\n wpstgTimesWaited = wpstgTimesWaited + 1;\n}, 100);\n\nfunction wpstgRegisterRatingEvents() {\n // Show the rating once jQuery is loaded.\n jQuery('.wpstg_fivestar').show();\n\n /**\n * Dispatch the request to hide the video after user clicks to rate the plugin.\n */\n jQuery(document).on('click', '#wpstg_clicked_deserved_it', function(e) {\n jQuery.ajax({\n url: ajaxurl,\n type: 'POST',\n data: {action: 'wpstg_hide_rating'},\n error: function(xhr, textStatus, errorThrown) {\n console.log(xhr.status + ' ' + xhr.statusText + '---' + textStatus);\n console.log(textStatus);\n\n alert(\n 'Unknown error. Please get in contact with us to solve it support@wp-staging.com',\n );\n },\n success: function(data) {\n jQuery('.wpstg_fivestar').slideUp('fast');\n return true;\n },\n statusCode: {\n 404: function() {\n alert('Something went wrong; can\\'t find ajax request URL! Please get in contact with us to solve it support@wp-staging.com');\n },\n 500: function() {\n alert('Something went wrong; internal server error while processing the request! Please get in contact with us to solve it support@wp-staging.com');\n },\n },\n });\n });\n\n jQuery('.wpstg_hide_rating').on('click', function(e) {\n e.preventDefault();\n\n jQuery.ajax({\n url: ajaxurl,\n type: 'POST',\n data: {action: 'wpstg_hide_rating'},\n error: function(xhr, textStatus, errorThrown) {\n console.log(xhr.status + ' ' + xhr.statusText + '---' + textStatus);\n console.log(textStatus);\n\n alert(\n 'Unknown error. Please get in contact with us to solve it support@wp-staging.com',\n );\n },\n success: function(data) {\n jQuery('.wpstg_fivestar').slideUp('fast');\n return true;\n },\n statusCode: {\n 404: function() {\n alert('Something went wrong; can\\'t find ajax request URL! Please get in contact with us to solve it support@wp-staging.com');\n },\n 500: function() {\n alert('Something went wrong; internal server error while processing the request! Please get in contact with us to solve it support@wp-staging.com');\n },\n },\n });\n });\n\n jQuery('.wpstg_rate_later').on('click', function(e) {\n e.preventDefault();\n\n jQuery.ajax({\n url: ajaxurl,\n type: 'POST',\n data: {action: 'wpstg_hide_later'},\n error: function(xhr, textStatus, errorThrown) {\n console.log(xhr.status + ' ' + xhr.statusText + '---' + textStatus);\n console.log(textStatus);\n\n alert(\n 'Unknown error. Please get in contact with us to solve it support@wp-staging.com',\n );\n },\n success: function(data) {\n jQuery('.wpstg_fivestar').slideUp('fast');\n return true;\n },\n statusCode: {\n 404: function() {\n alert('Something went wrong; can\\'t find ajax request URL! Please get in contact with us to solve it support@wp-staging.com');\n },\n 500: function() {\n alert('Something went wrong; internal server error while processing the request! Please get in contact with us to solve it support@wp-staging.com');\n },\n },\n });\n });\n}\n\ndocument.styleSheets[0].insertRule('@media only screen and (max-width:600px){.wpstg-welcome-box{display:block !important}.wpstg-welcome-video-container{width:100% !important;height:auto !important}.wpstg-welcome-text{padding-left:8px !important}}', '');\n\ndocument.addEventListener('DOMContentLoaded', function() {\n let player;\n let accepted = wpstgYouTubeConfig.accepted;\n const playerPlaceholder = document.getElementById('welcomeNoticeFree');\n playerPlaceholder.addEventListener('click', function() {\n if (!accepted) {\n const message = wpstgYouTubeConfig.message + '\\n \\n' + wpstgYouTubeConfig.regards;\n const conf = confirm(message);\n if (conf) {\n accepted = true;\n wpstgFetchVideo();\n }\n }\n });\n});\n\nfunction wpstgFetchVideo() {\n const tag = document.createElement('script');\n\n tag.src = 'https://www.youtube.com/iframe_api';\n const firstScriptTag = document.getElementsByTagName('script')[0];\n firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);\n}\n\nfunction onYouTubeIframeAPIReady() {\n player = new YT.Player('welcomeNoticeFree', {\n height: '225',\n width: '400',\n videoId: 'fsC9ZvbRQ5Y',\n playerVars: {\n rel: 0,\n showinfo: 0,\n ecver: 2,\n },\n events: {\n 'onReady': onPlayerReady,\n },\n });\n}\n\nfunction onPlayerReady(event) {\n event.target.playVideo();\n}\n"],"names":["wpstgTimesWaited","wpstgWaitForJQuery","setInterval","clearInterval","jQuery","wpstgRegisterRatingEvents","show","document","on","e","ajax","url","ajaxurl","type","data","action","error","xhr","textStatus","errorThrown","console","log","status","statusText","alert","success","slideUp","statusCode","preventDefault","styleSheets","insertRule","addEventListener","accepted","wpstgYouTubeConfig","playerPlaceholder","getElementById","message","regards","conf","confirm","wpstgFetchVideo","tag","createElement","src","firstScriptTag","getElementsByTagName","parentNode","insertBefore"],"mappings":"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"}
1
+ {"version":3,"file":"wpstg-admin-rating.js","sources":["../src/wpstg-admin-rating.js"],"sourcesContent":["let wpstgTimesWaited = 0;\n\n/*\nLet's wait for jQuery to be available to show the rating.\nWe need it to dispatch AJAX requests.\n */\nvar wpstgWaitForJQuery = setInterval(function() {\n if (wpstgTimesWaited > 100) {\n // Give up waiting.\n clearInterval(wpstgWaitForJQuery);\n }\n if (typeof jQuery != 'undefined') {\n wpstgRegisterRatingEvents();\n\n clearInterval(wpstgWaitForJQuery);\n }\n wpstgTimesWaited = wpstgTimesWaited + 1;\n}, 100);\n\nfunction wpstgRegisterRatingEvents() {\n // Show the rating once jQuery is loaded.\n jQuery('.wpstg_fivestar').show();\n\n /**\n * Dispatch the request to hide the video after user clicks to rate the plugin.\n */\n jQuery(document).on('click', '#wpstg_clicked_deserved_it', function(e) {\n jQuery.ajax({\n url: ajaxurl,\n type: 'POST',\n data: {action: 'wpstg_hide_rating'},\n error: function(xhr, textStatus, errorThrown) {\n console.log(xhr.status + ' ' + xhr.statusText + '---' + textStatus);\n console.log(textStatus);\n\n alert(\n 'Unknown error. Please get in contact with us to solve it support@wp-staging.com',\n );\n },\n success: function(data) {\n jQuery('.wpstg_fivestar').slideUp('fast');\n return true;\n },\n statusCode: {\n 404: function() {\n alert('Something went wrong; can\\'t find ajax request URL! Please get in contact with us to solve it support@wp-staging.com');\n },\n 500: function() {\n alert('Something went wrong; internal server error while processing the request! Please get in contact with us to solve it support@wp-staging.com');\n },\n },\n });\n });\n\n jQuery('.wpstg_hide_rating').on('click', function(e) {\n e.preventDefault();\n\n jQuery.ajax({\n url: ajaxurl,\n type: 'POST',\n data: {action: 'wpstg_hide_rating'},\n error: function(xhr, textStatus, errorThrown) {\n console.log(xhr.status + ' ' + xhr.statusText + '---' + textStatus);\n console.log(textStatus);\n\n alert(\n 'Unknown error. Please get in contact with us to solve it support@wp-staging.com',\n );\n },\n success: function(data) {\n jQuery('.wpstg_fivestar').slideUp('fast');\n return true;\n },\n statusCode: {\n 404: function() {\n alert('Something went wrong; can\\'t find ajax request URL! Please get in contact with us to solve it support@wp-staging.com');\n },\n 500: function() {\n alert('Something went wrong; internal server error while processing the request! Please get in contact with us to solve it support@wp-staging.com');\n },\n },\n });\n });\n\n jQuery('.wpstg_rate_later').on('click', function(e) {\n e.preventDefault();\n\n jQuery.ajax({\n url: ajaxurl,\n type: 'POST',\n data: {action: 'wpstg_hide_later'},\n error: function(xhr, textStatus, errorThrown) {\n console.log(xhr.status + ' ' + xhr.statusText + '---' + textStatus);\n console.log(textStatus);\n\n alert(\n 'Unknown error. Please get in contact with us to solve it support@wp-staging.com',\n );\n },\n success: function(data) {\n jQuery('.wpstg_fivestar').slideUp('fast');\n return true;\n },\n statusCode: {\n 404: function() {\n alert('Something went wrong; can\\'t find ajax request URL! Please get in contact with us to solve it support@wp-staging.com');\n },\n 500: function() {\n alert('Something went wrong; internal server error while processing the request! Please get in contact with us to solve it support@wp-staging.com');\n },\n },\n });\n });\n}\n\ndocument.styleSheets[0].insertRule('@media only screen and (max-width:600px){.wpstg-welcome-box{display:block !important}.wpstg-welcome-video-container{width:100% !important;height:auto !important}.wpstg-welcome-text{padding-left:8px !important}}', '');\n\ndocument.addEventListener('DOMContentLoaded', function() {\n let player;\n let accepted = wpstgYouTubeConfig.accepted;\n const playerPlaceholder = document.getElementById('welcomeNoticeFree');\n playerPlaceholder.addEventListener('click', function() {\n if (!accepted) {\n const message = wpstgYouTubeConfig.message + '\\n \\n' + wpstgYouTubeConfig.regards;\n const conf = confirm(message);\n if (conf) {\n accepted = true;\n wpstgFetchVideo();\n }\n }\n });\n});\n\nfunction wpstgFetchVideo() {\n const tag = document.createElement('script');\n\n tag.src = 'https://www.youtube.com/iframe_api';\n const firstScriptTag = document.getElementsByTagName('script')[0];\n firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);\n}\n\nfunction onYouTubeIframeAPIReady() {\n player = new YT.Player('welcomeNoticeFree', {\n height: '225',\n width: '400',\n videoId: 'il5y6kPprR8',\n playerVars: {\n rel: 0,\n showinfo: 0,\n ecver: 2,\n },\n events: {\n 'onReady': onPlayerReady,\n },\n });\n}\n\nfunction onPlayerReady(event) {\n event.target.playVideo();\n}\n"],"names":["wpstgTimesWaited","wpstgWaitForJQuery","setInterval","clearInterval","jQuery","wpstgRegisterRatingEvents","show","document","on","e","ajax","url","ajaxurl","type","data","action","error","xhr","textStatus","errorThrown","console","log","status","statusText","alert","success","slideUp","statusCode","preventDefault","styleSheets","insertRule","addEventListener","accepted","wpstgYouTubeConfig","playerPlaceholder","getElementById","message","regards","conf","confirm","wpstgFetchVideo","tag","createElement","src","firstScriptTag","getElementsByTagName","parentNode","insertBefore"],"mappings":"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"}
assets/js/dist/wpstg-admin-rating.min.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"wpstg-admin-rating.min.js","sources":["../src/wpstg-admin-rating.js"],"sourcesContent":["let wpstgTimesWaited = 0;\n\n/*\nLet's wait for jQuery to be available to show the rating.\nWe need it to dispatch AJAX requests.\n */\nvar wpstgWaitForJQuery = setInterval(function() {\n if (wpstgTimesWaited > 100) {\n // Give up waiting.\n clearInterval(wpstgWaitForJQuery);\n }\n if (typeof jQuery != 'undefined') {\n wpstgRegisterRatingEvents();\n\n clearInterval(wpstgWaitForJQuery);\n }\n wpstgTimesWaited = wpstgTimesWaited + 1;\n}, 100);\n\nfunction wpstgRegisterRatingEvents() {\n // Show the rating once jQuery is loaded.\n jQuery('.wpstg_fivestar').show();\n\n /**\n * Dispatch the request to hide the video after user clicks to rate the plugin.\n */\n jQuery(document).on('click', '#wpstg_clicked_deserved_it', function(e) {\n jQuery.ajax({\n url: ajaxurl,\n type: 'POST',\n data: {action: 'wpstg_hide_rating'},\n error: function(xhr, textStatus, errorThrown) {\n console.log(xhr.status + ' ' + xhr.statusText + '---' + textStatus);\n console.log(textStatus);\n\n alert(\n 'Unknown error. Please get in contact with us to solve it support@wp-staging.com',\n );\n },\n success: function(data) {\n jQuery('.wpstg_fivestar').slideUp('fast');\n return true;\n },\n statusCode: {\n 404: function() {\n alert('Something went wrong; can\\'t find ajax request URL! Please get in contact with us to solve it support@wp-staging.com');\n },\n 500: function() {\n alert('Something went wrong; internal server error while processing the request! Please get in contact with us to solve it support@wp-staging.com');\n },\n },\n });\n });\n\n jQuery('.wpstg_hide_rating').on('click', function(e) {\n e.preventDefault();\n\n jQuery.ajax({\n url: ajaxurl,\n type: 'POST',\n data: {action: 'wpstg_hide_rating'},\n error: function(xhr, textStatus, errorThrown) {\n console.log(xhr.status + ' ' + xhr.statusText + '---' + textStatus);\n console.log(textStatus);\n\n alert(\n 'Unknown error. Please get in contact with us to solve it support@wp-staging.com',\n );\n },\n success: function(data) {\n jQuery('.wpstg_fivestar').slideUp('fast');\n return true;\n },\n statusCode: {\n 404: function() {\n alert('Something went wrong; can\\'t find ajax request URL! Please get in contact with us to solve it support@wp-staging.com');\n },\n 500: function() {\n alert('Something went wrong; internal server error while processing the request! Please get in contact with us to solve it support@wp-staging.com');\n },\n },\n });\n });\n\n jQuery('.wpstg_rate_later').on('click', function(e) {\n e.preventDefault();\n\n jQuery.ajax({\n url: ajaxurl,\n type: 'POST',\n data: {action: 'wpstg_hide_later'},\n error: function(xhr, textStatus, errorThrown) {\n console.log(xhr.status + ' ' + xhr.statusText + '---' + textStatus);\n console.log(textStatus);\n\n alert(\n 'Unknown error. Please get in contact with us to solve it support@wp-staging.com',\n );\n },\n success: function(data) {\n jQuery('.wpstg_fivestar').slideUp('fast');\n return true;\n },\n statusCode: {\n 404: function() {\n alert('Something went wrong; can\\'t find ajax request URL! Please get in contact with us to solve it support@wp-staging.com');\n },\n 500: function() {\n alert('Something went wrong; internal server error while processing the request! Please get in contact with us to solve it support@wp-staging.com');\n },\n },\n });\n });\n}\n\ndocument.styleSheets[0].insertRule('@media only screen and (max-width:600px){.wpstg-welcome-box{display:block !important}.wpstg-welcome-video-container{width:100% !important;height:auto !important}.wpstg-welcome-text{padding-left:8px !important}}', '');\n\ndocument.addEventListener('DOMContentLoaded', function() {\n let player;\n let accepted = wpstgYouTubeConfig.accepted;\n const playerPlaceholder = document.getElementById('welcomeNoticeFree');\n playerPlaceholder.addEventListener('click', function() {\n if (!accepted) {\n const message = wpstgYouTubeConfig.message + '\\n \\n' + wpstgYouTubeConfig.regards;\n const conf = confirm(message);\n if (conf) {\n accepted = true;\n wpstgFetchVideo();\n }\n }\n });\n});\n\nfunction wpstgFetchVideo() {\n const tag = document.createElement('script');\n\n tag.src = 'https://www.youtube.com/iframe_api';\n const firstScriptTag = document.getElementsByTagName('script')[0];\n firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);\n}\n\nfunction onYouTubeIframeAPIReady() {\n player = new YT.Player('welcomeNoticeFree', {\n height: '225',\n width: '400',\n videoId: 'fsC9ZvbRQ5Y',\n playerVars: {\n rel: 0,\n showinfo: 0,\n ecver: 2,\n },\n events: {\n 'onReady': onPlayerReady,\n },\n });\n}\n\nfunction onPlayerReady(event) {\n event.target.playVideo();\n}\n"],"names":["wpstgTimesWaited","wpstgWaitForJQuery","setInterval","clearInterval","jQuery","show","document","on","e","ajax","url","ajaxurl","type","data","action","error","xhr","textStatus","errorThrown","console","log","status","statusText","alert","success","slideUp","statusCode","preventDefault","styleSheets","insertRule","addEventListener","accepted","wpstgYouTubeConfig","getElementById","message","regards","confirm","tag","createElement","src","firstScriptTag","getElementsByTagName","parentNode","insertBefore","wpstgFetchVideo"],"mappings":"yBAAA,IAAIA,EAAmB,EAMnBC,EAAqBC,aAAY,WAC/BF,EAAmB,KAErBG,cAAcF,GAEK,oBAAVG,SAUXA,OAAO,mBAAmBC,OAK1BD,OAAOE,UAAUC,GAAG,QAAS,8BAA8B,SAASC,GAClEJ,OAAOK,KAAK,CACVC,IAAKC,QACLC,KAAM,OACNC,KAAM,CAACC,OAAQ,qBACfC,MAAO,SAASC,EAAKC,EAAYC,GAC/BC,QAAQC,IAAIJ,EAAIK,OAAS,IAAML,EAAIM,WAAa,MAAQL,GACxDE,QAAQC,IAAIH,GAEZM,MACI,oFAGNC,QAAS,SAASX,UAChBT,OAAO,mBAAmBqB,QAAQ,SAC3B,GAETC,WAAY,KACL,WACHH,MAAM,4HAEH,WACHA,MAAM,qJAMdnB,OAAO,sBAAsBG,GAAG,SAAS,SAASC,GAChDA,EAAEmB,iBAEFvB,OAAOK,KAAK,CACVC,IAAKC,QACLC,KAAM,OACNC,KAAM,CAACC,OAAQ,qBACfC,MAAO,SAASC,EAAKC,EAAYC,GAC/BC,QAAQC,IAAIJ,EAAIK,OAAS,IAAML,EAAIM,WAAa,MAAQL,GACxDE,QAAQC,IAAIH,GAEZM,MACI,oFAGNC,QAAS,SAASX,UAChBT,OAAO,mBAAmBqB,QAAQ,SAC3B,GAETC,WAAY,KACL,WACHH,MAAM,4HAEH,WACHA,MAAM,qJAMdnB,OAAO,qBAAqBG,GAAG,SAAS,SAASC,GAC/CA,EAAEmB,iBAEFvB,OAAOK,KAAK,CACVC,IAAKC,QACLC,KAAM,OACNC,KAAM,CAACC,OAAQ,oBACfC,MAAO,SAASC,EAAKC,EAAYC,GAC/BC,QAAQC,IAAIJ,EAAIK,OAAS,IAAML,EAAIM,WAAa,MAAQL,GACxDE,QAAQC,IAAIH,GAEZM,MACI,oFAGNC,QAAS,SAASX,UAChBT,OAAO,mBAAmBqB,QAAQ,SAC3B,GAETC,WAAY,KACL,WACHH,MAAM,4HAEH,WACHA,MAAM,qJA9FZpB,cAAcF,IAEhBD,GAAsC,IACrC,KAkGHM,SAASsB,YAAY,GAAGC,WAAW,qNAAsN,IAEzPvB,SAASwB,iBAAiB,oBAAoB,eAExCC,EAAWC,mBAAmBD,SACRzB,SAAS2B,eAAe,qBAChCH,iBAAiB,SAAS,eACrCC,EAAU,KACPG,EAAUF,mBAAmBE,QAAU,QAAUF,mBAAmBG,QAC7DC,QAAQF,KAEnBH,GAAW,EAOnB,eACQM,EAAM/B,SAASgC,cAAc,UAEnCD,EAAIE,IAAM,yCACJC,EAAiBlC,SAASmC,qBAAqB,UAAU,GAC/DD,EAAeE,WAAWC,aAAaN,EAAKG,GAXtCI"}
1
+ {"version":3,"file":"wpstg-admin-rating.min.js","sources":["../src/wpstg-admin-rating.js"],"sourcesContent":["let wpstgTimesWaited = 0;\n\n/*\nLet's wait for jQuery to be available to show the rating.\nWe need it to dispatch AJAX requests.\n */\nvar wpstgWaitForJQuery = setInterval(function() {\n if (wpstgTimesWaited > 100) {\n // Give up waiting.\n clearInterval(wpstgWaitForJQuery);\n }\n if (typeof jQuery != 'undefined') {\n wpstgRegisterRatingEvents();\n\n clearInterval(wpstgWaitForJQuery);\n }\n wpstgTimesWaited = wpstgTimesWaited + 1;\n}, 100);\n\nfunction wpstgRegisterRatingEvents() {\n // Show the rating once jQuery is loaded.\n jQuery('.wpstg_fivestar').show();\n\n /**\n * Dispatch the request to hide the video after user clicks to rate the plugin.\n */\n jQuery(document).on('click', '#wpstg_clicked_deserved_it', function(e) {\n jQuery.ajax({\n url: ajaxurl,\n type: 'POST',\n data: {action: 'wpstg_hide_rating'},\n error: function(xhr, textStatus, errorThrown) {\n console.log(xhr.status + ' ' + xhr.statusText + '---' + textStatus);\n console.log(textStatus);\n\n alert(\n 'Unknown error. Please get in contact with us to solve it support@wp-staging.com',\n );\n },\n success: function(data) {\n jQuery('.wpstg_fivestar').slideUp('fast');\n return true;\n },\n statusCode: {\n 404: function() {\n alert('Something went wrong; can\\'t find ajax request URL! Please get in contact with us to solve it support@wp-staging.com');\n },\n 500: function() {\n alert('Something went wrong; internal server error while processing the request! Please get in contact with us to solve it support@wp-staging.com');\n },\n },\n });\n });\n\n jQuery('.wpstg_hide_rating').on('click', function(e) {\n e.preventDefault();\n\n jQuery.ajax({\n url: ajaxurl,\n type: 'POST',\n data: {action: 'wpstg_hide_rating'},\n error: function(xhr, textStatus, errorThrown) {\n console.log(xhr.status + ' ' + xhr.statusText + '---' + textStatus);\n console.log(textStatus);\n\n alert(\n 'Unknown error. Please get in contact with us to solve it support@wp-staging.com',\n );\n },\n success: function(data) {\n jQuery('.wpstg_fivestar').slideUp('fast');\n return true;\n },\n statusCode: {\n 404: function() {\n alert('Something went wrong; can\\'t find ajax request URL! Please get in contact with us to solve it support@wp-staging.com');\n },\n 500: function() {\n alert('Something went wrong; internal server error while processing the request! Please get in contact with us to solve it support@wp-staging.com');\n },\n },\n });\n });\n\n jQuery('.wpstg_rate_later').on('click', function(e) {\n e.preventDefault();\n\n jQuery.ajax({\n url: ajaxurl,\n type: 'POST',\n data: {action: 'wpstg_hide_later'},\n error: function(xhr, textStatus, errorThrown) {\n console.log(xhr.status + ' ' + xhr.statusText + '---' + textStatus);\n console.log(textStatus);\n\n alert(\n 'Unknown error. Please get in contact with us to solve it support@wp-staging.com',\n );\n },\n success: function(data) {\n jQuery('.wpstg_fivestar').slideUp('fast');\n return true;\n },\n statusCode: {\n 404: function() {\n alert('Something went wrong; can\\'t find ajax request URL! Please get in contact with us to solve it support@wp-staging.com');\n },\n 500: function() {\n alert('Something went wrong; internal server error while processing the request! Please get in contact with us to solve it support@wp-staging.com');\n },\n },\n });\n });\n}\n\ndocument.styleSheets[0].insertRule('@media only screen and (max-width:600px){.wpstg-welcome-box{display:block !important}.wpstg-welcome-video-container{width:100% !important;height:auto !important}.wpstg-welcome-text{padding-left:8px !important}}', '');\n\ndocument.addEventListener('DOMContentLoaded', function() {\n let player;\n let accepted = wpstgYouTubeConfig.accepted;\n const playerPlaceholder = document.getElementById('welcomeNoticeFree');\n playerPlaceholder.addEventListener('click', function() {\n if (!accepted) {\n const message = wpstgYouTubeConfig.message + '\\n \\n' + wpstgYouTubeConfig.regards;\n const conf = confirm(message);\n if (conf) {\n accepted = true;\n wpstgFetchVideo();\n }\n }\n });\n});\n\nfunction wpstgFetchVideo() {\n const tag = document.createElement('script');\n\n tag.src = 'https://www.youtube.com/iframe_api';\n const firstScriptTag = document.getElementsByTagName('script')[0];\n firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);\n}\n\nfunction onYouTubeIframeAPIReady() {\n player = new YT.Player('welcomeNoticeFree', {\n height: '225',\n width: '400',\n videoId: 'il5y6kPprR8',\n playerVars: {\n rel: 0,\n showinfo: 0,\n ecver: 2,\n },\n events: {\n 'onReady': onPlayerReady,\n },\n });\n}\n\nfunction onPlayerReady(event) {\n event.target.playVideo();\n}\n"],"names":["wpstgTimesWaited","wpstgWaitForJQuery","setInterval","clearInterval","jQuery","show","document","on","e","ajax","url","ajaxurl","type","data","action","error","xhr","textStatus","errorThrown","console","log","status","statusText","alert","success","slideUp","statusCode","preventDefault","styleSheets","insertRule","addEventListener","accepted","wpstgYouTubeConfig","getElementById","message","regards","confirm","tag","createElement","src","firstScriptTag","getElementsByTagName","parentNode","insertBefore","wpstgFetchVideo"],"mappings":"yBAAA,IAAIA,EAAmB,EAMnBC,EAAqBC,aAAY,WAC/BF,EAAmB,KAErBG,cAAcF,GAEK,oBAAVG,SAUXA,OAAO,mBAAmBC,OAK1BD,OAAOE,UAAUC,GAAG,QAAS,8BAA8B,SAASC,GAClEJ,OAAOK,KAAK,CACVC,IAAKC,QACLC,KAAM,OACNC,KAAM,CAACC,OAAQ,qBACfC,MAAO,SAASC,EAAKC,EAAYC,GAC/BC,QAAQC,IAAIJ,EAAIK,OAAS,IAAML,EAAIM,WAAa,MAAQL,GACxDE,QAAQC,IAAIH,GAEZM,MACI,oFAGNC,QAAS,SAASX,UAChBT,OAAO,mBAAmBqB,QAAQ,SAC3B,GAETC,WAAY,KACL,WACHH,MAAM,4HAEH,WACHA,MAAM,qJAMdnB,OAAO,sBAAsBG,GAAG,SAAS,SAASC,GAChDA,EAAEmB,iBAEFvB,OAAOK,KAAK,CACVC,IAAKC,QACLC,KAAM,OACNC,KAAM,CAACC,OAAQ,qBACfC,MAAO,SAASC,EAAKC,EAAYC,GAC/BC,QAAQC,IAAIJ,EAAIK,OAAS,IAAML,EAAIM,WAAa,MAAQL,GACxDE,QAAQC,IAAIH,GAEZM,MACI,oFAGNC,QAAS,SAASX,UAChBT,OAAO,mBAAmBqB,QAAQ,SAC3B,GAETC,WAAY,KACL,WACHH,MAAM,4HAEH,WACHA,MAAM,qJAMdnB,OAAO,qBAAqBG,GAAG,SAAS,SAASC,GAC/CA,EAAEmB,iBAEFvB,OAAOK,KAAK,CACVC,IAAKC,QACLC,KAAM,OACNC,KAAM,CAACC,OAAQ,oBACfC,MAAO,SAASC,EAAKC,EAAYC,GAC/BC,QAAQC,IAAIJ,EAAIK,OAAS,IAAML,EAAIM,WAAa,MAAQL,GACxDE,QAAQC,IAAIH,GAEZM,MACI,oFAGNC,QAAS,SAASX,UAChBT,OAAO,mBAAmBqB,QAAQ,SAC3B,GAETC,WAAY,KACL,WACHH,MAAM,4HAEH,WACHA,MAAM,qJA9FZpB,cAAcF,IAEhBD,GAAsC,IACrC,KAkGHM,SAASsB,YAAY,GAAGC,WAAW,qNAAsN,IAEzPvB,SAASwB,iBAAiB,oBAAoB,eAExCC,EAAWC,mBAAmBD,SACRzB,SAAS2B,eAAe,qBAChCH,iBAAiB,SAAS,eACrCC,EAAU,KACPG,EAAUF,mBAAmBE,QAAU,QAAUF,mBAAmBG,QAC7DC,QAAQF,KAEnBH,GAAW,EAOnB,eACQM,EAAM/B,SAASgC,cAAc,UAEnCD,EAAIE,IAAM,yCACJC,EAAiBlC,SAASmC,qBAAqB,UAAU,GAC/DD,EAAeE,WAAWC,aAAaN,EAAKG,GAXtCI"}
assets/js/dist/wpstg-admin.js CHANGED
@@ -1,42 +1,6 @@
1
  (function () {
2
  'use strict';
3
 
4
- function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
5
- try {
6
- var info = gen[key](arg);
7
- var value = info.value;
8
- } catch (error) {
9
- reject(error);
10
- return;
11
- }
12
-
13
- if (info.done) {
14
- resolve(value);
15
- } else {
16
- Promise.resolve(value).then(_next, _throw);
17
- }
18
- }
19
-
20
- function _asyncToGenerator(fn) {
21
- return function () {
22
- var self = this,
23
- args = arguments;
24
- return new Promise(function (resolve, reject) {
25
- var gen = fn.apply(self, args);
26
-
27
- function _next(value) {
28
- asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
29
- }
30
-
31
- function _throw(err) {
32
- asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
33
- }
34
-
35
- _next(undefined);
36
- });
37
- };
38
- }
39
-
40
  function _extends() {
41
  _extends = Object.assign || function (target) {
42
  for (var i = 1; i < arguments.length; i++) {
@@ -55,50 +19,8 @@
55
  return _extends.apply(this, arguments);
56
  }
57
 
58
- function _unsupportedIterableToArray(o, minLen) {
59
- if (!o) return;
60
- if (typeof o === "string") return _arrayLikeToArray(o, minLen);
61
- var n = Object.prototype.toString.call(o).slice(8, -1);
62
- if (n === "Object" && o.constructor) n = o.constructor.name;
63
- if (n === "Map" || n === "Set") return Array.from(o);
64
- if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
65
- }
66
-
67
- function _arrayLikeToArray(arr, len) {
68
- if (len == null || len > arr.length) len = arr.length;
69
-
70
- for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
71
-
72
- return arr2;
73
- }
74
-
75
- function _createForOfIteratorHelperLoose(o, allowArrayLike) {
76
- var it;
77
-
78
- if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) {
79
- if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
80
- if (it) o = it;
81
- var i = 0;
82
- return function () {
83
- if (i >= o.length) return {
84
- done: true
85
- };
86
- return {
87
- done: false,
88
- value: o[i++]
89
- };
90
- };
91
- }
92
-
93
- throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
94
- }
95
-
96
- it = o[Symbol.iterator]();
97
- return it.next.bind(it);
98
- }
99
-
100
  /**
101
- * WP Staging basic jQuery replacement
102
  */
103
 
104
  /**
@@ -788,6 +710,507 @@
788
  return WpstgModal;
789
  }();
790
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
791
  /**
792
  * Manage RESET MODAL
793
  */
@@ -901,16 +1324,15 @@
901
  };
902
 
903
  _proto.loadModal = function loadModal() {
904
- return Swal.fire({
 
 
 
905
  title: '',
906
  icon: 'warning',
907
  html: this.getAjaxLoader(),
908
- width: '300px',
909
  focusConfirm: false,
910
- customClass: {
911
- confirmButton: this.resetButtonClass,
912
- container: 'wpstg-swal2-container wpstg-swal2-loading ' + this.resetModalContainerClass
913
- },
914
  confirmButtonText: this.wpstgObject.i18n.resetClone,
915
  showCancelButton: true
916
  });
@@ -949,7 +1371,15 @@
949
  html: _this2.wpstgObject.i18n['somethingWentWrong'],
950
  width: '500px',
951
  confirmButtonText: 'Ok',
952
- showCancelButton: false
 
 
 
 
 
 
 
 
953
  }, data.swalOptions), {
954
  type: data.type
955
  });
@@ -958,7 +1388,7 @@
958
 
959
  var modal = qs('.wpstg-reset-confirmation');
960
  modal.classList.remove('wpstg-swal2-loading');
961
- modal.querySelector('.swal2-popup').style.width = 'auto';
962
  modal.querySelector('.swal2-content').innerHTML = data.html;
963
  _this2.directoryNavigator = new WpstgDirectoryNavigation();
964
  _this2.excludeFilters = new WpstgExcludeFilters();
@@ -1071,36 +1501,126 @@
1071
  return WpstgResetModal;
1072
  }();
1073
 
1074
- var WPStaging = function ($) {
1075
- var that = {
1076
- isCancelled: false,
1077
- isFinished: false,
1078
- getLogs: false,
1079
- time: 1,
1080
- executionTime: false,
1081
- progressBar: 0,
1082
- cloneExcludeFilters: null,
1083
- directoryNavigator: null,
1084
- notyf: new Notyf({
1085
- duration: 10000,
1086
- position: {
1087
- x: 'center',
1088
- y: 'bottom'
1089
- },
1090
- dismissible: true,
1091
- types: [{
1092
- type: 'warning',
1093
- background: 'orange',
1094
- icon: false
1095
- }]
1096
- })
1097
- };
1098
- var cache = {
1099
- elements: []
1100
- };
1101
- var ajaxSpinner;
1102
- /**
1103
- * Get / Set Cache for Selector
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1104
  * @param {String} selector
1105
  * @return {*}
1106
  */
@@ -1152,22 +1672,6 @@
1152
  event.returnValue = 'You MUST leave this window open while cloning/pushing. Please wait...';
1153
  return null;
1154
  };
1155
- /**
1156
- *
1157
- * @param obj
1158
- * @return {boolean}
1159
- */
1160
-
1161
-
1162
- function isEmpty(obj) {
1163
- for (var prop in obj) {
1164
- if (obj.hasOwnProperty(prop)) {
1165
- return false;
1166
- }
1167
- }
1168
-
1169
- return true;
1170
- }
1171
  /**
1172
  *
1173
  * @param response the error object
@@ -1183,31 +1687,17 @@
1183
 
1184
  if (response === false) {
1185
  showError(prependMessage + ' Error: No response.' + appendMessage);
1186
- window.removeEventListener('beforeunload', WPStaging.warnIfClosingDuringProcess);
1187
  return;
1188
  }
1189
 
1190
  if (typeof response.error !== 'undefined' && response.error) {
1191
  console.error(response.message);
1192
  showError(prependMessage + ' Error: ' + response.message + appendMessage);
1193
- window.removeEventListener('beforeunload', WPStaging.warnIfClosingDuringProcess);
1194
  return;
1195
  }
1196
  };
1197
- /**
1198
- *
1199
- * @param response
1200
- * @return {{ok}|*}
1201
- */
1202
-
1203
-
1204
- var handleFetchErrors = function handleFetchErrors(response) {
1205
- if (!response.ok) {
1206
- showError('Error: ' + response.status + ' - ' + response.statusText + '. Please try again or contact support.');
1207
- }
1208
-
1209
- return response;
1210
- };
1211
  /** Hide and reset previous thrown visible errors */
1212
 
1213
 
@@ -1762,7 +2252,7 @@
1762
  render += '<tr><td>' + x.name + '</td><td>' + x.production + '</td><td>' + x.staging + '</td><td>' + icon + '</td></tr>';
1763
  });
1764
  render += '</tbody></table><p>Note: Some mySQL properties do not match. You may proceed but the staging site may not work as expected.</p>';
1765
- Swal.fire({
1766
  title: 'Different Database Properties',
1767
  icon: 'warning',
1768
  html: render,
@@ -1778,7 +2268,7 @@
1778
  return;
1779
  }
1780
 
1781
- Swal.fire({
1782
  title: 'Different Database Properties',
1783
  icon: 'error',
1784
  html: response.message,
@@ -1890,7 +2380,15 @@
1890
  html: wpstg.i18n['somethingWentWrong'],
1891
  width: '500px',
1892
  confirmButtonText: 'Ok',
1893
- showCancelButton: false
 
 
 
 
 
 
 
 
1894
  }, response.swalOptions), {
1895
  type: response.type
1896
  });
@@ -1994,10 +2492,13 @@
1994
 
1995
  if (response["delete"] === 'finished') {
1996
  $('.wpstg-clone#' + clone).remove();
1997
- }
 
 
1998
 
1999
- if ($('.wpstg-clone').length < 1) {
2000
  cache.get('#wpstg-existing-clones').find('h3').text('');
 
2001
  }
2002
 
2003
  cache.get('.wpstg-loader').hide();
@@ -2140,7 +2641,7 @@
2140
  }
2141
 
2142
  if (value.type === 'ERROR') {
2143
- cache.get('.wpstg-log-details').append('<span style="color:red;">[' + value.type + ']</span>-' + '[' + value.date + '] ' + value.message + '</br>');
2144
  } else {
2145
  cache.get('.wpstg-log-details').append('[' + value.type + ']-' + '[' + value.date + '] ' + value.message + '</br>');
2146
  }
@@ -2177,33 +2678,11 @@
2177
  } // Show required disk space
2178
 
2179
 
2180
- cache.get('#wpstg-clone-id-error').html('Estimated necessary disk space: ' + response.usedspace + '<br> <span style="color:#444;">Before you proceed ensure your account has enough free disk space to hold the entire instance of the production site. You can check the available space from your hosting account (cPanel or similar).</span>').show();
2181
  cache.get('.wpstg-loader').hide();
2182
  }, 'json', false);
2183
  });
2184
  };
2185
-
2186
- var mainTabs = function mainTabs() {
2187
- $('.wpstg--tab--header a[data-target]').on('click', function () {
2188
- var $this = $(this);
2189
- var target = $this.attr('data-target');
2190
- var $wrapper = $this.parents('.wpstg--tab--wrapper');
2191
- var $menuItems = $wrapper.find('.wpstg--tab--header a[data-target]');
2192
- var $contents = $wrapper.find('.wpstg--tab--contents > .wpstg--tab--content');
2193
- $contents.filter('.wpstg--tab--active:not(.wpstg--tab--active' + target + ')').removeClass('wpstg--tab--active');
2194
- $menuItems.not($this).removeClass('wpstg--tab--active');
2195
- $this.addClass('wpstg--tab--active');
2196
- $(target).addClass('wpstg--tab--active');
2197
-
2198
- if ('#wpstg--tab--backup' === target) {
2199
- that.backups.init();
2200
- }
2201
-
2202
- if ('#wpstg--tab--database-backups' === target) {
2203
- window.dispatchEvent(new Event('database-backups-tab'));
2204
- }
2205
- });
2206
- };
2207
  /**
2208
  * Show or hide animated loading icon
2209
  * @param isLoading bool
@@ -2286,7 +2765,7 @@
2286
 
2287
  setTimeout(function () {
2288
  // cloneDatabase();
2289
- window.addEventListener('beforeunload', WPStaging.warnIfClosingDuringProcess);
2290
  processing();
2291
  }, wpstg.delayReq);
2292
  that.timer('start');
@@ -2299,7 +2778,7 @@
2299
 
2300
  var processing = function processing() {
2301
  if (true === that.isCancelled) {
2302
- window.removeEventListener('beforeunload', WPStaging.warnIfClosingDuringProcess);
2303
  return false;
2304
  }
2305
 
@@ -2314,7 +2793,7 @@
2314
 
2315
 
2316
  cache.get('.wpstg-log-details').show();
2317
- WPStaging.ajax({
2318
  action: 'wpstg_processing',
2319
  accessToken: wpstg.accessToken,
2320
  nonce: wpstg.nonce,
@@ -2341,7 +2820,7 @@
2341
  progressBar(response);
2342
  processing();
2343
  } else if ('finished' === response.status || 'undefined' !== typeof response.job_done && response.job_done) {
2344
- window.removeEventListener('beforeunload', WPStaging.warnIfClosingDuringProcess);
2345
  finish(response);
2346
  }
2347
  }, 'json', false);
@@ -2386,7 +2865,10 @@
2386
  }
2387
 
2388
  if (that.data.action === 'wpstg_update' || that.data.action === 'wpstg_reset') {
2389
- Swal.fire({
 
 
 
2390
  title: '',
2391
  icon: 'success',
2392
  html: msg,
@@ -2464,8 +2946,23 @@
2464
  elements();
2465
  stepButtons();
2466
  tabs();
2467
- mainTabs();
 
2468
  new WpstgCloneStaging();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2469
  };
2470
  /**
2471
  * Ajax call
@@ -2476,1330 +2973,36 @@
2476
  that.ajax = ajax;
2477
  that.showError = showError;
2478
  that.getLogs = getLogs;
2479
- that.loadOverview = loadOverview; // TODO RPoC (too big, scattered and unorganized)
2480
-
2481
- that.backups = {
2482
- type: null,
2483
- isCancelled: false,
2484
- processInfo: {
2485
- title: null,
2486
- interval: null
2487
- },
2488
- modal: {
2489
- create: {
2490
- html: null,
2491
- confirmBtnTxt: null
2492
- },
2493
- process: {
2494
- html: null,
2495
- cancelBtnTxt: null,
2496
- modal: null
2497
- },
2498
- download: {
2499
- html: null
2500
- },
2501
- "import": {
2502
- html: null,
2503
- btnTxtNext: null,
2504
- btnTxtConfirm: null,
2505
- btnTxtCancel: null,
2506
- searchReplaceForm: null,
2507
- file: null,
2508
- containerUpload: null,
2509
- containerFilesystem: null,
2510
- setFile: function setFile(file, upload) {
2511
- if (upload === void 0) {
2512
- upload = true;
2513
- }
2514
-
2515
- var toUnit = function toUnit(bytes) {
2516
- var i = Math.floor(Math.log(bytes) / Math.log(1024));
2517
- return (bytes / Math.pow(1024, i)).toFixed(2) * 1 + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i];
2518
- };
2519
-
2520
- if (!file) {
2521
- return;
2522
- }
2523
-
2524
- that.backups.modal["import"].file = file;
2525
- that.backups.modal["import"].data.file = file.name;
2526
- $('.wpstg--backup--import--selected-file').html(file.name + " <br /> (" + toUnit(file.size) + ")").show();
2527
- $('.wpstg--drag').hide();
2528
- $('.wpstg--drag-or-upload').show();
2529
-
2530
- if (upload) {
2531
- $('.wpstg--modal--actions .swal2-confirm').prop('disabled', true);
2532
- that.backups.upload.start();
2533
- }
2534
- },
2535
- baseDirectory: null,
2536
- data: {
2537
- file: null,
2538
- search: [],
2539
- replace: []
2540
- }
2541
- }
2542
- },
2543
- messages: {
2544
- WARNING: 'warning',
2545
- ERROR: 'error',
2546
- INFO: 'info',
2547
- DEBUG: 'debug',
2548
- CRITICAL: 'critical',
2549
- data: {
2550
- all: [],
2551
- // TODO RPoC
2552
- info: [],
2553
- error: [],
2554
- critical: [],
2555
- warning: [],
2556
- debug: []
2557
- },
2558
- shouldWarn: function shouldWarn() {
2559
- return that.backups.messages.data.error.length > 0 || that.backups.messages.data.critical.length > 0;
2560
- },
2561
- countByType: function countByType(type) {
2562
- if (type === void 0) {
2563
- type = that.backups.messages.ERROR;
2564
- }
2565
-
2566
- return that.backups.messages.data[type].length;
2567
- },
2568
- addMessage: function addMessage(message) {
2569
- if (Array.isArray(message)) {
2570
- message.forEach(function (item) {
2571
- that.backups.messages.addMessage(item);
2572
- });
2573
- return;
2574
- }
2575
-
2576
- var type = message.type.toLowerCase() || 'info';
2577
-
2578
- if (!that.backups.messages.data[type]) {
2579
- that.backups.messages.data[type] = [];
2580
- }
2581
-
2582
- that.backups.messages.data.all.push(message); // TODO RPoC
2583
-
2584
- that.backups.messages.data[type].push(message);
2585
- },
2586
- reset: function reset() {
2587
- that.backups.messages.data = {
2588
- all: [],
2589
- info: [],
2590
- error: [],
2591
- critical: [],
2592
- warning: [],
2593
- debug: []
2594
- };
2595
- }
2596
- },
2597
- timer: {
2598
- totalSeconds: 0,
2599
- interval: null,
2600
- start: function start() {
2601
- if (null !== that.backups.timer.interval) {
2602
- return;
2603
- }
2604
-
2605
- var prettify = function prettify(seconds) {
2606
- // If potentially anything can exceed 24h execution time than that;
2607
- // const _seconds = parseInt(seconds, 10)
2608
- // const hours = Math.floor(_seconds / 3600)
2609
- // const minutes = Math.floor(_seconds / 60) % 60
2610
- // seconds = _seconds % 60
2611
- //
2612
- // return [hours, minutes, seconds]
2613
- // .map(v => v < 10 ? '0' + v : v)
2614
- // .filter((v,i) => v !== '00' || i > 0)
2615
- // .join(':')
2616
- // ;
2617
- // Are we sure we won't create anything that exceeds 24h execution time? If not then this;
2618
- return "" + new Date(seconds * 1000).toISOString().substr(11, 8);
2619
- };
2620
-
2621
- that.backups.timer.interval = setInterval(function () {
2622
- $('.wpstg--modal--process--elapsed-time').text(prettify(that.backups.timer.totalSeconds));
2623
- that.backups.timer.totalSeconds++;
2624
- }, 1000);
2625
- },
2626
- stop: function stop() {
2627
- that.backups.timer.totalSeconds = 0;
2628
-
2629
- if (that.backups.timer.interval) {
2630
- clearInterval(that.backups.timer.interval);
2631
- that.backups.timer.interval = null;
2632
- }
2633
- }
2634
- },
2635
- upload: {
2636
- reader: null,
2637
- file: null,
2638
- iop: 1000 * 1024,
2639
- uploadInfo: function uploadInfo(isShow) {
2640
- var $containerUpload = $('.wpstg--modal--import--upload--process');
2641
- var $containerUploader = $('.wpstg--uploader');
2642
-
2643
- if (isShow) {
2644
- $containerUpload.css('display', 'flex');
2645
- $containerUploader.hide();
2646
- return;
2647
- }
2648
-
2649
- $containerUploader.css('display', 'flex');
2650
- $containerUpload.hide();
2651
- },
2652
- start: function start() {
2653
- that.backups.upload.reader = new FileReader();
2654
- that.backups.upload.file = that.backups.modal["import"].file;
2655
- that.backups.upload.uploadInfo(true);
2656
- that.backups.upload.sendChunk();
2657
- },
2658
- sendChunk: function sendChunk(startsAt) {
2659
- if (startsAt === void 0) {
2660
- startsAt = 0;
2661
- }
2662
-
2663
- if (!that.backups.upload.file) {
2664
- return;
2665
- }
2666
-
2667
- var isReset = startsAt < 1;
2668
- var endsAt = startsAt + that.backups.upload.iop + 1;
2669
- var blob = that.backups.upload.file.slice(startsAt, endsAt);
2670
-
2671
- that.backups.upload.reader.onloadend = function (event) {
2672
- if (event.target.readyState !== FileReader.DONE) {
2673
- return;
2674
- }
2675
-
2676
- var body = new FormData();
2677
- body.append('accessToken', wpstg.accessToken);
2678
- body.append('nonce', wpstg.nonce);
2679
- body.append('data', event.target.result);
2680
- body.append('filename', that.backups.upload.file.name);
2681
- body.append('reset', isReset ? '1' : '0');
2682
- fetch(ajaxurl + "?action=wpstg--backups--import--file-upload", {
2683
- method: 'POST',
2684
- body: body
2685
- }).then(handleFetchErrors).then(function (res) {
2686
- return res.json();
2687
- }).then(function (res) {
2688
- showAjaxFatalError(res, '', 'Submit an error report.');
2689
- var writtenBytes = startsAt + that.backups.upload.iop;
2690
- var percent = Math.floor(writtenBytes / that.backups.upload.file.size * 100);
2691
-
2692
- if (endsAt >= that.backups.upload.file.size) {
2693
- that.backups.upload.uploadInfo(false);
2694
- isLoading(false);
2695
- that.backups.switchModalToConfigure();
2696
- return;
2697
- }
2698
-
2699
- $('.wpstg--modal--import--upload--progress--title > span').text(percent);
2700
- $('.wpstg--modal--import--upload--progress').css('width', percent + "%");
2701
- that.backups.upload.sendChunk(endsAt);
2702
- })["catch"](function (e) {
2703
- return showAjaxFatalError(e, '', 'Submit an error report.');
2704
- });
2705
- };
2706
-
2707
- that.backups.upload.reader.readAsDataURL(blob);
2708
- }
2709
- },
2710
- status: {
2711
- hasResponse: null,
2712
- reTryAfter: 5000
2713
- },
2714
- init: function init() {
2715
- this.create();
2716
- this["delete"]();
2717
- this.edit(); // noinspection JSIgnoredPromiseFromCall
2718
-
2719
- that.backups.fetchListing();
2720
- $('body').on('click', '.wpstg--backup--download', function () {
2721
- var url = this.getAttribute('data-url');
2722
-
2723
- if (url.length > 0) {
2724
- window.location.href = url;
2725
- return;
2726
- }
2727
-
2728
- that.backups.downloadModal({
2729
- titleExport: this.getAttribute('data-title-export'),
2730
- title: this.getAttribute('data-title'),
2731
- id: this.getAttribute('data-id'),
2732
- btnTxtCancel: this.getAttribute('data-btn-cancel-txt'),
2733
- btnTxtConfirm: this.getAttribute('data-btn-download-txt')
2734
- });
2735
- }).on('click', '.wpstg--backup--import', function () {
2736
- // Clicked "Import" on the backup list
2737
- that.backups.importModal();
2738
- that.backups.modal["import"].data.file = this.getAttribute('data-filePath');
2739
- that.backups.switchModalToConfigure(); // $('.wpstg--modal--actions .swal2-confirm').show();
2740
- // $('.wpstg--modal--actions .swal2-confirm').prop('disabled', false);
2741
- }).off('click', '#wpstg-import-backup').on('click', '#wpstg-import-backup', function () {
2742
- that.backups.importModal();
2743
- }) // Import
2744
- .off('click', '.wpstg--backup--import--choose-option').on('click', '.wpstg--backup--import--choose-option', function () {
2745
- var $this = $(this);
2746
- var $parent = $this.parent();
2747
-
2748
- if (!$parent.hasClass('wpstg--show-options')) {
2749
- $parent.addClass('wpstg--show-options');
2750
- $this.text($this.attr('data-txtChoose'));
2751
- } else {
2752
- $parent.removeClass('wpstg--show-options');
2753
- $this.text($this.attr('data-txtOther'));
2754
- }
2755
- }).off('click', '.wpstg--modal--backup--import--search-replace--new').on('click', '.wpstg--modal--backup--import--search-replace--new', function (e) {
2756
- e.preventDefault();
2757
- var $container = $(Swal.getContainer()).find('.wpstg--modal--backup--import--search-replace--input--container');
2758
- var total = $container.find('.wpstg--modal--backup--import--search-replace--input-group').length;
2759
- $container.append(that.backups.modal["import"].searchReplaceForm.replace(/{i}/g, total));
2760
- }).off('click', '.wpstg--modal--backup--import--search-replace--remove').on('click', '.wpstg--modal--backup--import--search-replace--remove', function (e) {
2761
- e.preventDefault();
2762
- $(e.target).closest('.wpstg--modal--backup--import--search-replace--input-group').remove();
2763
- }).off('input', '.wpstg--backup--import--search').on('input', '.wpstg--backup--import--search', function () {
2764
- var index = parseInt(this.getAttribute('data-index'));
2765
-
2766
- if (!isNaN(index)) {
2767
- that.backups.modal["import"].data.search[index] = this.value;
2768
- }
2769
- }).off('input', '.wpstg--backup--import--replace').on('input', '.wpstg--backup--import--replace', function () {
2770
- var index = parseInt(this.getAttribute('data-index'));
2771
-
2772
- if (!isNaN(index)) {
2773
- that.backups.modal["import"].data.replace[index] = this.value;
2774
- }
2775
- }) // Other Options
2776
- .off('click', '.wpstg--backup--import--option[data-option]').on('click', '.wpstg--backup--import--option[data-option]', function () {
2777
- var option = this.getAttribute('data-option');
2778
-
2779
- if (option === 'file') {
2780
- $('input[type="file"][name="wpstg--backup--import--upload--file"]').trigger('click');
2781
- return;
2782
- }
2783
-
2784
- if (option === 'upload') {
2785
- that.backups.modal["import"].containerFilesystem.hide();
2786
- that.backups.modal["import"].containerUpload.show();
2787
- }
2788
-
2789
- if (option !== 'filesystem') {
2790
- return;
2791
- }
2792
-
2793
- that.backups.modal["import"].containerUpload.hide();
2794
- var $containerFilesystem = that.backups.modal["import"].containerFilesystem;
2795
- $containerFilesystem.show();
2796
- fetch(ajaxurl + "?action=wpstg--backups--import--file-list&_=" + Math.random() + "&accessToken=" + wpstg.accessToken + "&nonce=" + wpstg.nonce).then(handleFetchErrors).then(function (res) {
2797
- return res.json();
2798
- }).then(function (res) {
2799
- var $ul = $('.wpstg--modal--backup--import--filesystem ul');
2800
- $ul.empty();
2801
-
2802
- if (!res || isEmpty(res)) {
2803
- $ul.append("<span id=\"wpstg--backups--import--file-list-empty\">" + wpstg.i18n.noImportFileFound + "</span><br />");
2804
- $('.wpstg--modal--backup--import--search-replace--wrapper').hide();
2805
- return;
2806
- }
2807
-
2808
- $ul.append("<span id=\"wpstg--backups--import--file-list\">" + wpstg.i18n.selectFileToImport + "</span><br />");
2809
- res.forEach(function (file, index) {
2810
- $ul.append("\n<li data-filepath=\"" + file.fullPath + "\" class=\"wpstg--backups--import--file-list--sigle-item\">\n <ul class=\"wpstg-import-backup-more-info wpstg-import-backup-more-info-" + index + ("\">\n <li style=\"font-weight: bold\">" + file.backupName + "</li>\n <li>Created on: " + file.dateCreatedFormatted + "</li>\n <li>Size: " + file.size + "</li>\n <li>\n <div class=\"wpstg-import-backup-contains-title\">This backup contains:</div>\n <ul class=\"wpstg-import-backup-contains\">\n ") + (file.isExportingDatabase ? '<li><span class="dashicons dashicons-database wpstg--tooltip"><div class=\'wpstg--tooltiptext\'>Database</div></span></li>' : '') + "\n " + (file.isExportingPlugins ? '<li><span class="dashicons dashicons-admin-plugins wpstg--tooltip"><div class=\'wpstg--tooltiptext\'>Plugins</div></span></li>' : '') + "\n " + (file.isExportingMuPlugins ? '<li><span class="dashicons dashicons-plugins-checked wpstg--tooltip"><div class=\'wpstg--tooltiptext\'>Mu-plugins</div></span></li>' : '') + "\n " + (file.isExportingThemes ? '<li><span class="dashicons dashicons-layout wpstg--tooltip"><div class=\'wpstg--tooltiptext\'>Themes</div></span></li>' : '') + "\n " + (file.isExportingUploads ? '<li><span class="dashicons dashicons-images-alt wpstg--tooltip"><div class=\'wpstg--tooltiptext\'>Uploads</div></span></li>' : '') + "\n " + (file.isExportingOtherWpContentFiles ? '<li><span class="dashicons dashicons-admin-generic wpstg--tooltip"><div class=\'wpstg--tooltiptext\'>Other files in wp-content</div></span></li>' : '') + ("\n </ul>\n </li>\n <li>Filename: " + file.name + "</li>\n </ul>\n</li>\n"));
2811
- });
2812
- return res;
2813
- })["catch"](function (e) {
2814
- return showAjaxFatalError(e, '', 'Submit an error report.');
2815
- });
2816
- }).off('change', 'input[type="file"][name="wpstg--backup--import--upload--file"]').on('change', 'input[type="file"][name="wpstg--backup--import--upload--file"]', function () {
2817
- that.backups.modal["import"].setFile(this.files[0] || null);
2818
- }).off('change', 'input[type="radio"][name="backup_import_file"]').on('change', 'input[type="radio"][name="backup_import_file"]', function () {
2819
- $('.wpstg--modal--actions .swal2-confirm').show();
2820
- $('.wpstg--modal--actions .swal2-confirm').prop('disabled', false);
2821
- that.backups.modal["import"].data.file = this.value;
2822
- }) // Drag & Drop
2823
- .on('drag dragstart dragend dragover dragenter dragleave drop', '.wpstg--modal--backup--import--upload--container', function (e) {
2824
- e.preventDefault();
2825
- e.stopPropagation();
2826
- }).on('dragover dragenter', '.wpstg--modal--backup--import--upload--container', function () {
2827
- $(this).addClass('wpstg--has-dragover');
2828
- }).on('dragleave dragend drop', '.wpstg--modal--backup--import--upload--container', function () {
2829
- $(this).removeClass('wpstg--has-dragover');
2830
- }).on('drop', '.wpstg--modal--backup--import--upload--container', function (e) {
2831
- // Uploaded a file through the "Import Backup modal"
2832
- that.backups.modal["import"].setFile(e.originalEvent.dataTransfer.files[0] || null);
2833
- }).on('click', '.wpstg--modal--backup--import--filesystem li', function (e) {
2834
- // Selected an existing backup in the Import Backup modal
2835
- var fullPath = $(e.target).closest('.wpstg--backups--import--file-list--sigle-item').data().filepath;
2836
-
2837
- if (!fullPath.length) {
2838
- alert('Error: Could not get file path.');
2839
- return;
2840
- }
2841
-
2842
- that.backups.modal["import"].data.file = fullPath;
2843
- that.backups.switchModalToConfigure(); // $('.wpstg--modal--actions .swal2-confirm').prop('disabled', false);
2844
- // that.backups.modal.gotoStart();
2845
- }).on('change', '.wpstg-advanced-options-site input[type="checkbox"]', function (e) {
2846
- /*
2847
- * We use a timeout here to simulate an "afterChange" event.
2848
- * This allows us to read from the DOM whether the checkbox is checked or not,
2849
- * instead of having to read from the event, which would require a lengthier code
2850
- * to account for all elements we might want to read.
2851
- */
2852
- setTimeout(function (e) {
2853
- // Reset
2854
- document.getElementById('exportUploadsWithoutDatabaseWarning').style.display = 'none'; // Exporting Media Library without Database
2855
-
2856
- var databaseChecked = document.getElementById('includeDatabaseInBackup').checked;
2857
- var mediaLibraryChecked = document.getElementById('includeMediaLibraryInBackup').checked;
2858
-
2859
- if (mediaLibraryChecked && !databaseChecked) {
2860
- document.getElementById('exportUploadsWithoutDatabaseWarning').style.display = 'block';
2861
- }
2862
- }, 100);
2863
- });
2864
- },
2865
- fetchListing: function fetchListing(isResetErrors) {
2866
- if (isResetErrors === void 0) {
2867
- isResetErrors = true;
2868
- }
2869
-
2870
- isLoading(true);
2871
-
2872
- if (isResetErrors) {
2873
- resetErrors();
2874
- }
2875
-
2876
- return fetch(ajaxurl + "?action=wpstg--backups--listing&_=" + Math.random() + "&accessToken=" + wpstg.accessToken + "&nonce=" + wpstg.nonce).then(handleFetchErrors).then(function (res) {
2877
- return res.json();
2878
- }).then(function (res) {
2879
- showAjaxFatalError(res, '', 'Submit an error report.');
2880
- cache.get('#wpstg--tab--backup').html(res);
2881
- isLoading(false);
2882
- window.dispatchEvent(new Event('backupListingFinished'));
2883
- return res;
2884
- })["catch"](function (e) {
2885
- return showAjaxFatalError(e, '', 'Submit an error report.');
2886
- });
2887
- },
2888
- "delete": function _delete() {
2889
- $('#wpstg--tab--backup').off('click', '.wpstg-delete-backup[data-md5]').on('click', '.wpstg-delete-backup[data-md5]', function (e) {
2890
- e.preventDefault();
2891
- resetErrors();
2892
-
2893
- if (!confirm('Are you sure you want to delete this backup?')) {
2894
- return;
2895
- }
2896
-
2897
- isLoading(true);
2898
- cache.get('#wpstg-existing-backups').hide();
2899
- var md5 = this.getAttribute('data-md5');
2900
- that.ajax({
2901
- action: 'wpstg--backups--delete',
2902
- md5: md5,
2903
- accessToken: wpstg.accessToken,
2904
- nonce: wpstg.nonce
2905
- }, function (response) {
2906
- showAjaxFatalError(response, '', ' Please submit an error report by using the REPORT ISSUE button.');
2907
- isLoading(false);
2908
- that.backups.fetchListing();
2909
- });
2910
- }); // Force delete if backup tables do not exist
2911
- // TODO This is bloated, no need extra ID, use existing one?
2912
-
2913
- $('#wpstg-error-wrapper').off('click', '#wpstg-backup-force-delete').on('click', '#wpstg-backup-force-delete', function (e) {
2914
- e.preventDefault();
2915
- resetErrors();
2916
- isLoading(true);
2917
- var id = this.getAttribute('data-id');
2918
-
2919
- if (!confirm('Do you want to delete this backup ' + id + ' from the listed backups?')) {
2920
- isLoading(false);
2921
- return false;
2922
- }
2923
-
2924
- that.ajax({
2925
- action: 'wpstg--backups--delete',
2926
- id: id,
2927
- accessToken: wpstg.accessToken,
2928
- nonce: wpstg.nonce
2929
- }, function (response) {
2930
- showAjaxFatalError(response, '', ' Please submit an error report by using the REPORT ISSUE button.'); // noinspection JSIgnoredPromiseFromCall
2931
-
2932
- that.backups.fetchListing();
2933
- isLoading(false);
2934
- });
2935
- });
2936
- },
2937
- create: function create() {
2938
- var prepareBackup = function prepareBackup(data) {
2939
- WPStaging.ajax({
2940
- action: 'wpstg--backups--prepare-export',
2941
- accessToken: wpstg.accessToken,
2942
- nonce: wpstg.nonce,
2943
- wpstgExportData: data
2944
- }, function (response) {
2945
- if (response.success) {
2946
- that.backups.timer.start();
2947
- createBackup();
2948
- } else {
2949
- showAjaxFatalError(response.data, '', 'Submit an error report.');
2950
- }
2951
- }, 'json', false, 0, 1.25);
2952
- };
2953
-
2954
- var createBackup = function createBackup() {
2955
- resetErrors();
2956
-
2957
- if (that.backups.isCancelled) {
2958
- // Swal.close();
2959
- return;
2960
- }
2961
-
2962
- var statusStop = function statusStop() {
2963
- clearInterval(that.backups.processInfo.interval);
2964
- that.backups.processInfo.interval = null;
2965
- };
2966
-
2967
- var status = function status() {
2968
- if (that.backups.processInfo.interval !== null) {
2969
- return;
2970
- }
2971
-
2972
- that.backups.processInfo.interval = setInterval(function () {
2973
- if (true === that.backups.isCancelled) {
2974
- statusStop();
2975
- return;
2976
- }
2977
-
2978
- if (that.backups.status.hasResponse === false) {
2979
- return;
2980
- }
2981
-
2982
- that.backups.status.hasResponse = false;
2983
- fetch(ajaxurl + "?action=wpstg--backups--status&accessToken=" + wpstg.accessToken + "&nonce=" + wpstg.nonce).then(function (res) {
2984
- return res.json();
2985
- }).then(function (res) {
2986
- that.backups.status.hasResponse = true;
2987
-
2988
- if (typeof res === 'undefined') {
2989
- statusStop();
2990
- }
2991
-
2992
- if (that.backups.processInfo.title === res.currentStatusTitle) {
2993
- return;
2994
- }
2995
-
2996
- that.backups.processInfo.title = res.currentStatusTitle;
2997
- var $container = $(Swal.getContainer());
2998
- $container.find('.wpstg--modal--process--title').text(res.currentStatusTitle);
2999
- $container.find('.wpstg--modal--process--percent').text('0');
3000
- })["catch"](function (e) {
3001
- that.backups.status.hasResponse = true;
3002
- showAjaxFatalError(e, '', 'Submit an error report.');
3003
- });
3004
- }, 5000);
3005
- };
3006
-
3007
- WPStaging.ajax({
3008
- action: 'wpstg--backups--export',
3009
- accessToken: wpstg.accessToken,
3010
- nonce: wpstg.nonce
3011
- }, function (response) {
3012
- if (typeof response === 'undefined') {
3013
- setTimeout(function () {
3014
- createBackup();
3015
- }, wpstg.delayReq);
3016
- return;
3017
- }
3018
-
3019
- that.backups.processResponse(response);
3020
-
3021
- if (!that.backups.processInfo.interval) {
3022
- status();
3023
- }
3024
-
3025
- if (response.status === false) {
3026
- createBackup();
3027
- } else if (response.status === true) {
3028
- $('#wpstg--progress--status').text('Backup successfully created!');
3029
- that.backups.type = null;
3030
-
3031
- if (that.backups.messages.shouldWarn()) {
3032
- // noinspection JSIgnoredPromiseFromCall
3033
- that.backups.fetchListing();
3034
- that.backups.logsModal();
3035
- return;
3036
- }
3037
-
3038
- statusStop();
3039
- Swal.close();
3040
- that.backups.fetchListing().then(function () {
3041
- if (!response.backupMd5) {
3042
- showError('Failed to get backup md5 from response');
3043
- return;
3044
- } // Wait for fetchListing to populate the DOM with the backup data that we want to read
3045
-
3046
-
3047
- var $el = '';
3048
- var timesWaited = 0;
3049
- var intervalWaitForBackupInDom = setInterval(function () {
3050
- timesWaited++;
3051
- $el = $(".wpstg--backup--download[data-md5=\"" + response.backupMd5 + "\"]"); // Could not find element, let's try again...
3052
-
3053
- if (!$el.length) {
3054
- if (timesWaited >= 10) {
3055
- // Bail: We tried too many times and couldn't find.
3056
- clearInterval(intervalWaitForBackupInDom);
3057
- }
3058
-
3059
- return;
3060
- } // Found it. No more need for the interval.
3061
-
3062
-
3063
- clearInterval(intervalWaitForBackupInDom);
3064
- var backupSize = response.hasOwnProperty('backupSize') ? ' (' + response.backupSize + ')' : '';
3065
- that.backups.downloadModal({
3066
- id: $el.data('id'),
3067
- url: $el.data('url'),
3068
- title: $el.data('title'),
3069
- titleExport: $el.data('title-export'),
3070
- btnTxtCancel: $el.data('btn-cancel-txt'),
3071
- btnTxtConfirm: $el.data('btn-download-txt') + backupSize
3072
- });
3073
- $('.wpstg--modal--download--logs--wrapper').show();
3074
- var $logsContainer = $('.wpstg--modal--process--logs');
3075
- that.backups.messages.data.all.forEach(function (message) {
3076
- var msgClass = "wpstg--modal--process--msg--" + message.type.toLowerCase();
3077
- $logsContainer.append("<p class=\"" + msgClass + "\">[" + message.type + "] - [" + message.date + "] - " + message.message + "</p>");
3078
- });
3079
- }, 200);
3080
- });
3081
- } else {
3082
- setTimeout(function () {
3083
- createBackup();
3084
- }, wpstg.delayReq);
3085
- }
3086
- }, 'json', false, 0, // Don't retry upon failure
3087
- 1.25);
3088
- };
3089
-
3090
- var $body = $('body');
3091
- $body.off('click', '.wpstg--tab--toggle').on('click', '.wpstg--tab--toggle', function () {
3092
- var $this = $(this);
3093
- var $target = $($this.attr('data-target'));
3094
- $target.toggle();
3095
-
3096
- if ($target.is(':visible')) {
3097
- $this.find('span').text('▼');
3098
- } else {
3099
- $this.find('span').text('►');
3100
- }
3101
- }).off('change', '[name="includedDirectories\[\]"], input#includeDatabaseInBackup, input#includeOtherFilesInWpContent').on('change', '[type="checkbox"][name="includedDirectories\[\]"], input#includeDatabaseInBackup, input#includeOtherFilesInWpContent', function () {
3102
- var isExportingAnyDir = $('[type="checkbox"][name="includedDirectories\[\]"]:checked').length > 0;
3103
- var isExportingDatabase = $('input#includeDatabaseInBackup:checked').length === 1;
3104
- var isExportingOtherFilesInWpContent = $('input#includeOtherFilesInWpContent:checked').length === 1;
3105
-
3106
- if (!isExportingAnyDir && !isExportingDatabase && !isExportingOtherFilesInWpContent) {
3107
- $('.swal2-confirm').prop('disabled', true);
3108
- } else {
3109
- $('.swal2-confirm').prop('disabled', false);
3110
- }
3111
- }); // Add backup name and notes
3112
-
3113
- $('#wpstg--tab--backup').off('click', '#wpstg-new-backup').on('click', '#wpstg-new-backup', /*#__PURE__*/function () {
3114
- var _ref = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee(e) {
3115
- var $newBackupModal, html, btnTxt, _yield$Swal$fire, formValues;
3116
-
3117
- return regeneratorRuntime.wrap(function _callee$(_context) {
3118
- while (1) {
3119
- switch (_context.prev = _context.next) {
3120
- case 0:
3121
- resetErrors();
3122
- e.preventDefault();
3123
- that.backups.isCancelled = false;
3124
-
3125
- if (!that.backups.modal.create.html || !that.backups.modal.create.confirmBtnTxt) {
3126
- $newBackupModal = $('#wpstg--modal--backup--new');
3127
- html = $newBackupModal.html();
3128
- btnTxt = $newBackupModal.attr('data-confirmButtonText');
3129
- that.backups.modal.create.html = html || null;
3130
- that.backups.modal.create.confirmBtnTxt = btnTxt || null;
3131
- $newBackupModal.remove();
3132
- }
3133
-
3134
- _context.next = 6;
3135
- return Swal.fire({
3136
- title: '',
3137
- html: that.backups.modal.create.html,
3138
- focusConfirm: false,
3139
- confirmButtonText: that.backups.modal.create.confirmBtnTxt,
3140
- showCancelButton: true,
3141
- preConfirm: function preConfirm() {
3142
- var container = Swal.getContainer();
3143
- return {
3144
- name: container.querySelector('input[name="backup_name"]').value || null,
3145
- isExportingPlugins: container.querySelector('#includePluginsInBackup:checked') !== null,
3146
- isExportingMuPlugins: container.querySelector('#includeMuPluginsInBackup:checked') !== null,
3147
- isExportingThemes: container.querySelector('#includeThemesInBackup:checked') !== null,
3148
- isExportingUploads: container.querySelector('#includeMediaLibraryInBackup:checked') !== null,
3149
- isExportingOtherWpContentFiles: container.querySelector('#includeOtherFilesInWpContent:checked') !== null,
3150
- isExportingDatabase: container.querySelector('#includeDatabaseInBackup:checked') !== null
3151
- };
3152
- }
3153
- });
3154
-
3155
- case 6:
3156
- _yield$Swal$fire = _context.sent;
3157
- formValues = _yield$Swal$fire.value;
3158
-
3159
- if (formValues) {
3160
- _context.next = 10;
3161
- break;
3162
- }
3163
-
3164
- return _context.abrupt("return");
3165
-
3166
- case 10:
3167
- that.backups.process({
3168
- execute: function execute() {
3169
- that.backups.messages.reset();
3170
- prepareBackup(formValues);
3171
- }
3172
- });
3173
-
3174
- case 11:
3175
- case "end":
3176
- return _context.stop();
3177
- }
3178
- }
3179
- }, _callee);
3180
- }));
3181
-
3182
- return function (_x) {
3183
- return _ref.apply(this, arguments);
3184
- };
3185
- }());
3186
- },
3187
- switchModalToConfigure: function switchModalToConfigure() {
3188
- that.backups.modal["import"].containerUpload.hide();
3189
- that.backups.modal["import"].containerFilesystem.hide();
3190
- that.backups.modal["import"].containerConfigure.show();
3191
- },
3192
- // Edit backups name and notes
3193
- edit: function edit() {
3194
- $('#wpstg--tab--backup').off('click', '.wpstg--backup--edit[data-md5]').on('click', '.wpstg--backup--edit[data-md5]', /*#__PURE__*/function () {
3195
- var _ref2 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(e) {
3196
- var $this, name, notes, _yield$Swal$fire2, formValues;
3197
-
3198
- return regeneratorRuntime.wrap(function _callee2$(_context2) {
3199
- while (1) {
3200
- switch (_context2.prev = _context2.next) {
3201
- case 0:
3202
- e.preventDefault();
3203
- $this = $(this);
3204
- name = $this.data('name');
3205
- notes = $this.data('notes');
3206
- _context2.next = 6;
3207
- return Swal.fire({
3208
- title: '',
3209
- 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 ",
3210
- focusConfirm: false,
3211
- confirmButtonText: 'Update Backup',
3212
- showCancelButton: true,
3213
- preConfirm: function preConfirm() {
3214
- return {
3215
- name: document.getElementById('wpstg-backup-edit-name-input').value || null,
3216
- notes: document.getElementById('wpstg-backup-edit-notes-textarea').value || null
3217
- };
3218
- }
3219
- });
3220
-
3221
- case 6:
3222
- _yield$Swal$fire2 = _context2.sent;
3223
- formValues = _yield$Swal$fire2.value;
3224
-
3225
- if (formValues) {
3226
- _context2.next = 10;
3227
- break;
3228
- }
3229
-
3230
- return _context2.abrupt("return");
3231
-
3232
- case 10:
3233
- that.ajax({
3234
- action: 'wpstg--backups--edit',
3235
- accessToken: wpstg.accessToken,
3236
- nonce: wpstg.nonce,
3237
- md5: $this.data('md5'),
3238
- name: formValues.name,
3239
- notes: formValues.notes
3240
- }, function (response) {
3241
- showAjaxFatalError(response, '', 'Submit an error report.'); // noinspection JSIgnoredPromiseFromCall
3242
-
3243
- that.backups.fetchListing();
3244
- });
3245
-
3246
- case 11:
3247
- case "end":
3248
- return _context2.stop();
3249
- }
3250
- }
3251
- }, _callee2, this);
3252
- }));
3253
-
3254
- return function (_x2) {
3255
- return _ref2.apply(this, arguments);
3256
- };
3257
- }());
3258
- },
3259
- cancel: function cancel() {
3260
- that.backups.timer.stop();
3261
- that.backups.isCancelled = true;
3262
- Swal.close();
3263
- setTimeout(function () {
3264
- return that.ajax({
3265
- action: 'wpstg--backups--cancel',
3266
- accessToken: wpstg.accessToken,
3267
- nonce: wpstg.nonce,
3268
- type: that.backups.type
3269
- }, function (response) {
3270
- showAjaxFatalError(response, '', 'Submit an error report.');
3271
- });
3272
- }, 500);
3273
- },
3274
-
3275
- /**
3276
- * If process.execute exists, process.data and process.onResponse is not used
3277
- * process = { data: {}, onResponse: (resp) => {}, onAfterClose: () => {}, execute: () => {}, isShowCancelButton: bool }
3278
- * @param {object} process
3279
- */
3280
- process: function process(_process) {
3281
- if (typeof _process.execute !== 'function' && (!_process.data || !_process.onResponse)) {
3282
- Swal.close();
3283
- showError('process.data and / or process.onResponse is not set');
3284
- return;
3285
- } // TODO move to backend and get the contents as xhr response?
3286
-
3287
-
3288
- if (!that.backups.modal.process.html || !that.backups.modal.process.cancelBtnTxt) {
3289
- var $modal = $('#wpstg--modal--backup--process');
3290
- var html = $modal.html();
3291
- var btnTxt = $modal.attr('data-cancelButtonText');
3292
- that.backups.modal.process.html = html || null;
3293
- that.backups.modal.process.cancelBtnTxt = btnTxt || null;
3294
- $modal.remove();
3295
- }
3296
-
3297
- $('body').off('click', '.wpstg--modal--process--logs--tail').on('click', '.wpstg--modal--process--logs--tail', function (e) {
3298
- e.preventDefault();
3299
- var container = Swal.getContainer();
3300
- var $logs = $(container).find('.wpstg--modal--process--logs');
3301
- $logs.toggle();
3302
-
3303
- if ($logs.is(':visible')) {
3304
- container.childNodes[0].style.width = '100%';
3305
- container.style['z-index'] = 9999;
3306
- } else {
3307
- container.childNodes[0].style.width = '600px';
3308
- }
3309
- });
3310
- _process.isShowCancelButton = false !== _process.isShowCancelButton;
3311
- that.backups.modal.process.modal = Swal.mixin({
3312
- customClass: {
3313
- cancelButton: 'wpstg--btn--cancel wpstg-blue-primary wpstg-link-btn',
3314
- content: 'wpstg--process--content'
3315
- },
3316
- buttonsStyling: false
3317
- }).fire({
3318
- html: that.backups.modal.process.html,
3319
- cancelButtonText: that.backups.modal.process.cancelBtnTxt,
3320
- showCancelButton: _process.isShowCancelButton,
3321
- showConfirmButton: false,
3322
- allowOutsideClick: false,
3323
- allowEscapeKey: false,
3324
- width: 600,
3325
- onRender: function onRender() {
3326
- var _btnCancel = Swal.getContainer().getElementsByClassName('swal2-cancel wpstg--btn--cancel')[0];
3327
-
3328
- var btnCancel = _btnCancel.cloneNode(true);
3329
-
3330
- _btnCancel.parentNode.replaceChild(btnCancel, _btnCancel);
3331
-
3332
- btnCancel.addEventListener('click', function (e) {
3333
- if (confirm('Are You Sure? This will cancel the process!')) {
3334
- Swal.close();
3335
- }
3336
- });
3337
-
3338
- if (typeof _process.execute === 'function') {
3339
- _process.execute();
3340
-
3341
- return;
3342
- }
3343
-
3344
- if (!_process.data || !_process.onResponse) {
3345
- Swal.close();
3346
- showError('process.data and / or process.onResponse is not set');
3347
- return;
3348
- }
3349
-
3350
- that.ajax(_process.data, _process.onResponse);
3351
- },
3352
- onAfterClose: function onAfterClose() {
3353
- return typeof _process.onAfterClose === 'function' && _process.onAfterClose();
3354
- },
3355
- onClose: function onClose() {
3356
- that.backups.cancel();
3357
- }
3358
- });
3359
- },
3360
- processResponse: function processResponse(response, useTitle) {
3361
- if (response === null) {
3362
- Swal.close();
3363
- showError('Invalid Response; null');
3364
- throw new Error("Invalid Response; " + response);
3365
- }
3366
-
3367
- var $container = $(Swal.getContainer());
3368
-
3369
- var title = function title() {
3370
- if ((response.title || response.statusTitle) && useTitle === true) {
3371
- $container.find('.wpstg--modal--process--title').text(response.title || response.statusTitle);
3372
- }
3373
- };
3374
-
3375
- var percentage = function percentage() {
3376
- if (response.percentage) {
3377
- $container.find('.wpstg--modal--process--percent').text(response.percentage);
3378
- }
3379
- };
3380
-
3381
- var logs = function logs() {
3382
- if (!response.messages) {
3383
- return;
3384
- }
3385
-
3386
- var $logsContainer = $container.find('.wpstg--modal--process--logs');
3387
- var stoppingTypes = [that.backups.messages.ERROR, that.backups.messages.CRITICAL];
3388
-
3389
- var appendMessage = function appendMessage(message) {
3390
- if (Array.isArray(message)) {
3391
- for (var _iterator = _createForOfIteratorHelperLoose(message), _step; !(_step = _iterator()).done;) {
3392
- var item = _step.value;
3393
- appendMessage(item);
3394
- }
3395
-
3396
- return;
3397
- }
3398
-
3399
- var msgClass = "wpstg--modal--process--msg--" + message.type.toLowerCase();
3400
- $logsContainer.append("<p class=\"" + msgClass + "\">[" + message.type + "] - [" + message.date + "] - " + message.message + "</p>");
3401
-
3402
- if (stoppingTypes.includes(message.type.toLowerCase())) {
3403
- that.backups.cancel();
3404
- setTimeout(that.backups.logsModal, 500);
3405
- }
3406
- };
3407
-
3408
- for (var _iterator2 = _createForOfIteratorHelperLoose(response.messages), _step2; !(_step2 = _iterator2()).done;) {
3409
- var message = _step2.value;
3410
-
3411
- if (!message) {
3412
- continue;
3413
- }
3414
-
3415
- that.backups.messages.addMessage(message);
3416
- appendMessage(message);
3417
- }
3418
-
3419
- if ($logsContainer.is(':visible')) {
3420
- $logsContainer.scrollTop($logsContainer[0].scrollHeight);
3421
- }
3422
-
3423
- if (!that.backups.messages.shouldWarn()) {
3424
- return;
3425
- }
3426
-
3427
- var $btnShowLogs = $container.find('.wpstg--modal--process--logs--tail');
3428
- $btnShowLogs.html($btnShowLogs.attr('data-txt-bad'));
3429
- $btnShowLogs.find('.wpstg--modal--logs--critical-count').text(that.backups.messages.countByType(that.backups.messages.CRITICAL));
3430
- $btnShowLogs.find('.wpstg--modal--logs--error-count').text(that.backups.messages.countByType(that.backups.messages.ERROR));
3431
- $btnShowLogs.find('.wpstg--modal--logs--warning-count').text(that.backups.messages.countByType(that.backups.messages.WARNING));
3432
- };
3433
-
3434
- title();
3435
- percentage();
3436
- logs();
3437
-
3438
- if (response.status === true && response.job_done === true) {
3439
- that.backups.timer.stop();
3440
- that.backups.isCancelled = true;
3441
- }
3442
- },
3443
- requestData: function requestData(notation, data) {
3444
- var obj = {};
3445
- var keys = notation.split('.');
3446
- var lastIndex = keys.length - 1;
3447
- keys.reduce(function (accumulated, current, index) {
3448
- return accumulated[current] = index >= lastIndex ? data : {};
3449
- }, obj);
3450
- return obj;
3451
- },
3452
- logsModal: function logsModal() {
3453
- Swal.fire({
3454
- html: "<div class=\"wpstg--modal--error--logs\" style=\"display:block\"></div><div class=\"wpstg--modal--process--logs\" style=\"display:block\"></div>",
3455
- width: '95%',
3456
- onRender: function onRender() {
3457
- var $container = $(Swal.getContainer());
3458
- $container[0].style['z-index'] = 9999;
3459
- var $logsContainer = $container.find('.wpstg--modal--process--logs');
3460
- var $errorContainer = $container.find('.wpstg--modal--error--logs');
3461
- var $translations = $('#wpstg--js--translations');
3462
- var messages = that.backups.messages;
3463
- 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));
3464
- $errorContainer.before("<h3>" + title + "</h3>");
3465
- var warnings = [that.backups.messages.CRITICAL, that.backups.messages.ERROR, that.backups.messages.WARNING];
3466
-
3467
- if (!that.backups.messages.shouldWarn()) {
3468
- $errorContainer.hide();
3469
- }
3470
-
3471
- for (var _iterator3 = _createForOfIteratorHelperLoose(messages.data.all), _step3; !(_step3 = _iterator3()).done;) {
3472
- var message = _step3.value;
3473
- var msgClass = "wpstg--modal--process--msg--" + message.type.toLowerCase(); // TODO RPoC
3474
-
3475
- if (warnings.includes(message.type)) {
3476
- $errorContainer.append("<p class=\"" + msgClass + "\">[" + message.type + "] - [" + message.date + "] - " + message.message + "</p>");
3477
- }
3478
-
3479
- $logsContainer.append("<p class=\"" + msgClass + "\">[" + message.type + "] - [" + message.date + "] - " + message.message + "</p>");
3480
- }
3481
- },
3482
- onOpen: function onOpen(container) {
3483
- var $logsContainer = $(container).find('.wpstg--modal--process--logs');
3484
- $logsContainer.scrollTop($logsContainer[0].scrollHeight);
3485
- }
3486
- });
3487
- },
3488
- downloadModal: function downloadModal(_ref3) {
3489
- var _ref3$title = _ref3.title,
3490
- title = _ref3$title === void 0 ? null : _ref3$title,
3491
- _ref3$titleExport = _ref3.titleExport,
3492
- titleExport = _ref3$titleExport === void 0 ? null : _ref3$titleExport,
3493
- _ref3$id = _ref3.id,
3494
- id = _ref3$id === void 0 ? null : _ref3$id,
3495
- _ref3$url = _ref3.url,
3496
- url = _ref3$url === void 0 ? null : _ref3$url,
3497
- _ref3$btnTxtCancel = _ref3.btnTxtCancel,
3498
- btnTxtCancel = _ref3$btnTxtCancel === void 0 ? 'Cancel' : _ref3$btnTxtCancel,
3499
- _ref3$btnTxtConfirm = _ref3.btnTxtConfirm,
3500
- btnTxtConfirm = _ref3$btnTxtConfirm === void 0 ? 'Download' : _ref3$btnTxtConfirm;
3501
-
3502
- if (null === that.backups.modal.download.html) {
3503
- var $el = $('#wpstg--modal--backup--download');
3504
- that.backups.modal.download.html = $el.html();
3505
- $el.remove();
3506
- }
3507
-
3508
- var exportModal = function exportModal() {
3509
- return Swal.fire({
3510
- html: "<h2>" + titleExport + "</h2><span class=\"wpstg-loader\"></span>",
3511
- showCancelButton: false,
3512
- showConfirmButton: false,
3513
- onRender: function onRender() {
3514
- that.ajax({
3515
- action: 'wpstg--backups--export',
3516
- accessToken: wpstg.accessToken,
3517
- nonce: wpstg.nonce,
3518
- id: id
3519
- }, function (response) {
3520
- if (!response || !response.success || !response.data || response.data.length < 1) {
3521
- return;
3522
- }
3523
-
3524
- var a = document.createElement('a');
3525
- a.style.display = 'none';
3526
- a.href = response.data;
3527
- document.body.appendChild(a);
3528
- a.click();
3529
- document.body.removeChild(a);
3530
- Swal.close();
3531
- });
3532
- }
3533
- });
3534
- };
3535
-
3536
- Swal.mixin({
3537
- customClass: {
3538
- cancelButton: 'wpstg--btn--cancel wpstg-blue-primary wpstg-link-btn',
3539
- confirmButton: 'wpstg--btn--confirm wpstg-blue-primary wpstg-button wpstg-link-btn',
3540
- actions: 'wpstg--modal--actions'
3541
- },
3542
- buttonsStyling: false
3543
- }).fire({
3544
- icon: 'success',
3545
- html: that.backups.modal.download.html.replace('{title}', title).replace('{btnTxtLog}', 'Show Logs'),
3546
- cancelButtonText: btnTxtCancel,
3547
- confirmButtonText: btnTxtConfirm,
3548
- showCancelButton: true,
3549
- showConfirmButton: true
3550
- }).then(function (isConfirm) {
3551
- if (!isConfirm || !isConfirm.value) {
3552
- return;
3553
- }
3554
-
3555
- if (url && url.length > 0) {
3556
- window.location.href = url;
3557
- return;
3558
- }
3559
-
3560
- exportModal();
3561
- });
3562
- },
3563
- importModal: function importModal() {
3564
- var importSiteBackup = function importSiteBackup(data) {
3565
- resetErrors();
3566
-
3567
- if (that.backups.isCancelled) {
3568
- // Swal.close();
3569
- return;
3570
- }
3571
-
3572
- that.backups.timer.start();
3573
-
3574
- var statusStop = function statusStop() {
3575
- clearInterval(that.backups.processInfo.interval);
3576
- that.backups.processInfo.interval = null;
3577
- };
3578
-
3579
- var status = function status() {
3580
- if (that.backups.processInfo.interval !== null) {
3581
- return;
3582
- }
3583
-
3584
- that.backups.processInfo.interval = setInterval(function () {
3585
- if (true === that.backups.isCancelled) {
3586
- statusStop();
3587
- return;
3588
- }
3589
-
3590
- if (that.backups.status.hasResponse === false) {
3591
- return;
3592
- }
3593
-
3594
- that.backups.status.hasResponse = false;
3595
- fetch(ajaxurl + "?action=wpstg--backups--status&process=restore&accessToken=" + wpstg.accessToken + "&nonce=" + wpstg.nonce).then(function (res) {
3596
- return res.json();
3597
- }).then(function (res) {
3598
- that.backups.status.hasResponse = true;
3599
-
3600
- if (typeof res === 'undefined') {
3601
- statusStop();
3602
- }
3603
-
3604
- if (that.backups.processInfo.title === res.currentStatusTitle) {
3605
- return;
3606
- }
3607
-
3608
- that.backups.processInfo.title = res.currentStatusTitle;
3609
- var $container = $(Swal.getContainer());
3610
- $container.find('.wpstg--modal--process--title').text(res.currentStatusTitle);
3611
- $container.find('.wpstg--modal--process--percent').text('0');
3612
- })["catch"](function (e) {
3613
- that.backups.status.hasResponse = true;
3614
- showAjaxFatalError(e, '', 'Submit an error report.');
3615
- });
3616
- }, 5000);
3617
- };
3618
-
3619
- WPStaging.ajax({
3620
- action: 'wpstg--backups--import',
3621
- accessToken: wpstg.accessToken,
3622
- nonce: wpstg.nonce
3623
- }, function (response) {
3624
- if (typeof response === 'undefined') {
3625
- setTimeout(function () {
3626
- importSiteBackup();
3627
- }, wpstg.delayReq);
3628
- return;
3629
- }
3630
-
3631
- that.backups.processResponse(response, true);
3632
-
3633
- if (!that.backups.processInfo.interval) {
3634
- status();
3635
- }
3636
-
3637
- if (response.status === false) {
3638
- importSiteBackup();
3639
- } else if (response.status === true) {
3640
- $('#wpstg--progress--status').text('Backup successfully imported!');
3641
- that.backups.type = null;
3642
-
3643
- if (that.backups.messages.shouldWarn()) {
3644
- // noinspection JSIgnoredPromiseFromCall
3645
- that.backups.fetchListing();
3646
- that.backups.logsModal();
3647
- return;
3648
- }
3649
-
3650
- statusStop();
3651
- var logEntries = $('.wpstg--modal--process--logs').get(1).innerHTML;
3652
- var html = '<div class="wpstg--modal--process--logs">' + logEntries + '</div>';
3653
- var issueFound = html.includes('wpstg--modal--process--msg--warning') || html.includes('wpstg--modal--process--msg--error') ? 'Issues(s) found! ' : ''; // var errorMessage = html.includes('wpstg--modal--process--msg--error') ? 'Errors(s) found! ' : '';
3654
- // var Message = warningMessage + errorMessage;
3655
- // Swal.close();
3656
-
3657
- Swal.fire({
3658
- icon: 'success',
3659
- title: 'Finished',
3660
- html: 'System imported 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
3661
- }); // noinspection JSIgnoredPromiseFromCall
3662
-
3663
- that.backups.fetchListing();
3664
- } else {
3665
- setTimeout(function () {
3666
- importSiteBackup();
3667
- }, wpstg.delayReq);
3668
- }
3669
- }, 'json', false, 0, // Don't retry upon failure
3670
- 1.25);
3671
- };
3672
-
3673
- if (!that.backups.modal["import"].html) {
3674
- var $modal = $('#wpstg--modal--backup--import'); // Search & Replace Form
3675
-
3676
- var $form = $modal.find('.wpstg--modal--backup--import--search-replace--input--container');
3677
- that.backups.modal["import"].searchReplaceForm = $form.html();
3678
- $form.find('.wpstg--modal--backup--import--search-replace--input-group').remove();
3679
- $form.html(that.backups.modal["import"].searchReplaceForm.replace(/{i}/g, 0));
3680
- that.backups.modal["import"].html = $modal.html();
3681
- that.backups.modal["import"].baseDirectory = $modal.attr('data-baseDirectory');
3682
- that.backups.modal["import"].btnTxtNext = $modal.attr('data-nextButtonText');
3683
- that.backups.modal["import"].btnTxtConfirm = $modal.attr('data-confirmButtonText');
3684
- that.backups.modal["import"].btnTxtCancel = $modal.attr('data-cancelButtonText');
3685
- $modal.remove();
3686
- }
3687
-
3688
- that.backups.modal["import"].data.search = [];
3689
- that.backups.modal["import"].data.replace = [];
3690
- Swal.mixin({
3691
- customClass: {
3692
- confirmButton: 'wpstg--btn--confirm wpstg-blue-primary wpstg-button wpstg-link-btn',
3693
- cancelButton: 'wpstg--btn--cancel wpstg-blue-primary wpstg-link-btn',
3694
- actions: 'wpstg--modal--actions'
3695
- },
3696
- buttonsStyling: false // progressSteps: ['1', '2']
3697
-
3698
- }).queue([{
3699
- html: that.backups.modal["import"].html,
3700
- confirmButtonText: that.backups.modal["import"].btnTxtNext,
3701
- showCancelButton: false,
3702
- showConfirmButton: true,
3703
- showLoaderOnConfirm: true,
3704
- width: 650,
3705
- onRender: function onRender() {
3706
- // $('.wpstg--modal--actions .swal2-confirm').hide();
3707
- // todo: hide this again
3708
- $('.wpstg--modal--actions .swal2-confirm').show();
3709
- $('.wpstg--modal--actions .swal2-confirm').prop('disabled', false);
3710
- that.backups.modal["import"].containerUpload = $('.wpstg--modal--backup--import--upload');
3711
- that.backups.modal["import"].containerFilesystem = $('.wpstg--modal--backup--import--filesystem');
3712
- that.backups.modal["import"].containerConfigure = $('.wpstg--modal--backup--import--configure');
3713
- },
3714
- preConfirm: function preConfirm() {
3715
- var body = new FormData();
3716
- body.append('accessToken', wpstg.accessToken);
3717
- body.append('nonce', wpstg.nonce);
3718
- body.append('filePath', that.backups.modal["import"].data.file);
3719
- that.backups.modal["import"].data.search.forEach(function (item, index) {
3720
- body.append("search[" + index + "]", item);
3721
- });
3722
- that.backups.modal["import"].data.replace.forEach(function (item, index) {
3723
- body.append("replace[" + index + "]", item);
3724
- });
3725
- return fetch(ajaxurl + "?action=wpstg--backups--import--file-info", {
3726
- method: 'POST',
3727
- body: body
3728
- }).then(handleFetchErrors).then(function (res) {
3729
- return res.json();
3730
- }).then(function (html) {
3731
- return Swal.insertQueueStep({
3732
- html: html,
3733
- confirmButtonText: that.backups.modal["import"].btnTxtConfirm,
3734
- cancelButtonText: that.backups.modal["import"].btnTxtCancel,
3735
- showCancelButton: true
3736
- });
3737
- })["catch"](function (e) {
3738
- return showAjaxFatalError(e, '', 'Submit an error report.');
3739
- });
3740
- }
3741
- }]).then(function (res) {
3742
- if (!res || !res.value || !res.value[1] || res.value[1] !== true) {
3743
- return;
3744
- }
3745
-
3746
- that.backups.isCancelled = false;
3747
- var data = that.backups.modal["import"].data;
3748
- data['file'] = that.backups.modal["import"].baseDirectory + data['file'];
3749
- WPStaging.ajax({
3750
- action: 'wpstg--backups--prepare-import',
3751
- accessToken: wpstg.accessToken,
3752
- nonce: wpstg.nonce,
3753
- wpstgImportData: data
3754
- }, function (response) {
3755
- if (response.success) {
3756
- that.backups.process({
3757
- execute: function execute() {
3758
- that.backups.messages.reset();
3759
- importSiteBackup();
3760
- }
3761
- });
3762
- } else {
3763
- showAjaxFatalError(response.data, '', 'Submit an error report.');
3764
- }
3765
- }, 'json', false, 0, 1.25);
3766
- });
3767
- }
3768
- };
3769
- window.addEventListener('backupListingFinished', function () {
3770
- fetch(ajaxurl + "?action=wpstg--backups--import--file-list&_=" + Math.random() + "&accessToken=" + wpstg.accessToken + "&nonce=" + wpstg.nonce + "&withTemplate=true").then(handleFetchErrors).then(function (res) {
3771
- return res.json();
3772
- }).then(function (res) {
3773
- var $ul = $('.wpstg-backup-list ul');
3774
- $ul.empty();
3775
- $ul.html(res);
3776
- })["catch"](function (e) {
3777
- return showAjaxFatalError(e, '', 'Submit an error report.');
3778
- });
3779
- });
3780
  return that;
3781
  }(jQuery);
3782
 
3783
  jQuery(document).ready(function () {
3784
- WPStaging.init(); // This is necessary to make WPStaging var accessibile in WP Staging PRO js script
3785
 
3786
- window.WPStaging = WPStaging;
3787
  });
3788
  /**
3789
  * Report Issue modal
3790
  */
3791
 
3792
  jQuery(document).ready(function ($) {
3793
- $('#wpstg-report-issue-button').on('click', function (e) {
3794
- $('.wpstg-report-issue-form').toggleClass('wpstg-report-show');
 
3795
  e.preventDefault();
3796
  });
3797
  $('body').on('click', '#wpstg-backups-report-issue-button', function (e) {
3798
- $('.wpstg-report-issue-form').toggleClass('wpstg-report-show');
3799
  e.preventDefault();
3800
  });
3801
- $('#wpstg-report-cancel').on('click', function (e) {
3802
- $('.wpstg-report-issue-form').removeClass('wpstg-report-show');
 
 
 
 
 
3803
  e.preventDefault();
3804
  });
3805
  /*
@@ -3817,11 +3020,11 @@
3817
  }
3818
 
3819
  var spinner = button.next();
3820
- var email = $('.wpstg-report-email').val();
3821
- var hosting_provider = $('.wpstg-report-hosting-provider').val();
3822
- var message = $('.wpstg-report-description').val();
3823
- var syslog = $('.wpstg-report-syslog').is(':checked');
3824
- var terms = $('.wpstg-report-terms').is(':checked');
3825
  button.attr('disabled', true);
3826
  spinner.css('visibility', 'visible');
3827
  $.ajax({
@@ -3845,19 +3048,18 @@
3845
  spinner.css('visibility', 'hidden');
3846
 
3847
  if (data.errors.length > 0) {
3848
- $('.wpstg-report-issue-form .wpstg-message').remove();
3849
  var errorMessage = $('<div />').addClass('wpstg-message wpstg-error-message');
3850
  $.each(data.errors, function (key, value) {
3851
  if (value.status === 'already_submitted') {
3852
- errorMessage = '';
3853
- Swal.fire({
 
 
 
3854
  title: '',
3855
- customClass: {
3856
- container: 'wpstg-issue-resubmit-confirmation'
3857
- },
3858
  icon: 'warning',
3859
  html: value.message,
3860
- showCloseButton: true,
3861
  showCancelButton: true,
3862
  focusConfirm: false,
3863
  confirmButtonText: 'Yes',
@@ -3871,29 +3073,33 @@
3871
  errorMessage.append('<p>' + value + '</p>');
3872
  }
3873
  });
3874
- $('.wpstg-report-issue-form').prepend(errorMessage);
3875
  } else {
3876
  var successMessage = $('<div />').addClass('wpstg-message wpstg-success-message');
3877
  successMessage.append('<p>Thanks for submitting your request! You should receive an auto reply mail with your ticket ID immediately for confirmation!<br><br>If you do not get that mail please contact us directly at <strong>support@wp-staging.com</strong></p>');
3878
- $('.wpstg-report-issue-form').html(successMessage);
3879
- $('.wpstg-success-message').append('<div style="float:right;margin-top:10px;"><a id="wpstg-success-button" href="#">Close</a></div>'); // Hide message
3880
 
3881
  setTimeout(function () {
3882
- $('.wpstg-report-issue-form').removeClass('wpstg-report-active');
3883
  }, 2000);
3884
  }
3885
  });
3886
- }
3887
 
3888
- $('#wpstg-report-submit').on('click', function (e) {
3889
- var self = $(this);
3890
- sendIssueReport(self, 'false');
3891
- e.preventDefault();
3892
- }); // Open/close actions drop down menu
3893
 
3894
  $(document).on('click', '.wpstg-dropdown>.wpstg-dropdown-toggler', function (e) {
3895
  e.preventDefault();
3896
  $(e.target).next('.wpstg-dropdown-menu').toggleClass('shown');
 
 
 
 
 
 
 
 
 
3897
  }); // Close action drop down menu if clicked anywhere outside
3898
 
3899
  document.addEventListener('click', function (event) {
@@ -3905,6 +3111,8 @@
3905
  for (var i = 0; i < dropDown.length; i++) {
3906
  dropDown[i].classList.remove('shown');
3907
  }
 
 
3908
  }
3909
  });
3910
  });
1
  (function () {
2
  'use strict';
3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  function _extends() {
5
  _extends = Object.assign || function (target) {
6
  for (var i = 1; i < arguments.length; i++) {
19
  return _extends.apply(this, arguments);
20
  }
21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  /**
23
+ * WP STAGING basic jQuery replacement
24
  */
25
 
26
  /**
710
  return WpstgModal;
711
  }();
712
 
713
+ /**
714
+ * This is a namespaced port of https://github.com/tristen/hoverintent,
715
+ * with slight modification to accept selector with dynamically added element in dom,
716
+ * instead of just already present element.
717
+ *
718
+ * @param {HTMLElement} parent
719
+ * @param {string} selector
720
+ * @param {CallableFunction} onOver
721
+ * @param {CallableFunction} onOut
722
+ *
723
+ * @return {object}
724
+ */
725
+
726
+ function wpstgHoverIntent (parent, selector, onOver, onOut) {
727
+ var x;
728
+ var y;
729
+ var pX;
730
+ var pY;
731
+ var mouseOver = false;
732
+ var focused = false;
733
+ var h = {};
734
+ var state = 0;
735
+ var timer = 0;
736
+ var options = {
737
+ sensitivity: 7,
738
+ interval: 100,
739
+ timeout: 0,
740
+ handleFocus: false
741
+ };
742
+
743
+ function delay(el, e) {
744
+ if (timer) {
745
+ timer = clearTimeout(timer);
746
+ }
747
+
748
+ state = 0;
749
+ return focused ? undefined : onOut(el, e);
750
+ }
751
+
752
+ function tracker(e) {
753
+ x = e.clientX;
754
+ y = e.clientY;
755
+ }
756
+
757
+ function compare(el, e) {
758
+ if (timer) timer = clearTimeout(timer);
759
+
760
+ if (Math.abs(pX - x) + Math.abs(pY - y) < options.sensitivity) {
761
+ state = 1;
762
+ return focused ? undefined : onOver(el, e);
763
+ } else {
764
+ pX = x;
765
+ pY = y;
766
+ timer = setTimeout(function () {
767
+ compare(el, e);
768
+ }, options.interval);
769
+ }
770
+ } // Public methods
771
+
772
+
773
+ h.options = function (opt) {
774
+ var focusOptionChanged = opt.handleFocus !== options.handleFocus;
775
+ options = Object.assign({}, options, opt);
776
+
777
+ if (focusOptionChanged) {
778
+ options.handleFocus ? addFocus() : removeFocus();
779
+ }
780
+
781
+ return h;
782
+ };
783
+
784
+ function dispatchOver(el, e) {
785
+ mouseOver = true;
786
+
787
+ if (timer) {
788
+ timer = clearTimeout(timer);
789
+ }
790
+
791
+ el.removeEventListener('mousemove', tracker, false);
792
+
793
+ if (state !== 1) {
794
+ pX = e.clientX;
795
+ pY = e.clientY;
796
+ el.addEventListener('mousemove', tracker, false);
797
+ timer = setTimeout(function () {
798
+ compare(el, e);
799
+ }, options.interval);
800
+ }
801
+
802
+ return this;
803
+ }
804
+ /**
805
+ * Newly added method,
806
+ * A wrapper around dispatchOver to support dynamically added elements to dom
807
+ */
808
+
809
+
810
+ function onMouseOver(event) {
811
+ if (event.target.matches(selector + ', ' + selector + ' *')) {
812
+ dispatchOver(event.target.closest(selector), event);
813
+ }
814
+ }
815
+
816
+ function dispatchOut(el, e) {
817
+ mouseOver = false;
818
+
819
+ if (timer) {
820
+ timer = clearTimeout(timer);
821
+ }
822
+
823
+ el.removeEventListener('mousemove', tracker, false);
824
+
825
+ if (state === 1) {
826
+ timer = setTimeout(function () {
827
+ delay(el, e);
828
+ }, options.timeout);
829
+ }
830
+
831
+ return this;
832
+ }
833
+ /**
834
+ * Newly added method,
835
+ * A wrapper around dispatchOut to support dynamically added elements to dom
836
+ */
837
+
838
+
839
+ function onMouseOut(event) {
840
+ if (event.target.matches(selector + ', ' + selector + ' *')) {
841
+ dispatchOut(event.target.closest(selector), event);
842
+ }
843
+ }
844
+
845
+ function dispatchFocus(el, e) {
846
+ if (!mouseOver) {
847
+ focused = true;
848
+ onOver(el, e);
849
+ }
850
+ }
851
+ /**
852
+ * Newly added method,
853
+ * A wrapper around dispatchFocus to support dynamically added elements to dom
854
+ */
855
+
856
+
857
+ function onFocus(event) {
858
+ if (event.target.matches(selector + ', ' + selector + ' *')) {
859
+ dispatchFocus(event.target.closest(selector), event);
860
+ }
861
+ }
862
+
863
+ function dispatchBlur(el, e) {
864
+ if (!mouseOver && focused) {
865
+ focused = false;
866
+ onOut(el, e);
867
+ }
868
+ }
869
+ /**
870
+ * Newly added method,
871
+ * A wrapper around dispatchBlur to support dynamically added elements to dom
872
+ */
873
+
874
+
875
+ function onBlur(event) {
876
+ if (event.target.matches(selector + ', ' + selector + ' *')) {
877
+ dispatchBlur(event.target.closest(selector), event);
878
+ }
879
+ }
880
+ /**
881
+ * Modified to support dynamically added element
882
+ */
883
+
884
+ function addFocus() {
885
+ parent.addEventListener('focus', onFocus, false);
886
+ parent.addEventListener('blur', onBlur, false);
887
+ }
888
+ /**
889
+ * Modified to support dynamically added element
890
+ */
891
+
892
+
893
+ function removeFocus() {
894
+ parent.removeEventListener('focus', onFocus, false);
895
+ parent.removeEventListener('blur', onBlur, false);
896
+ }
897
+ /**
898
+ * Modified to support dynamically added element
899
+ */
900
+
901
+
902
+ h.remove = function () {
903
+ if (!parent) {
904
+ return;
905
+ }
906
+
907
+ parent.removeEventListener('mouseover', onMouseOver, false);
908
+ parent.removeEventListener('mouseout', onMouseOut, false);
909
+ removeFocus();
910
+ };
911
+ /**
912
+ * Modified to support dynamically added element
913
+ */
914
+
915
+
916
+ if (parent) {
917
+ parent.addEventListener('mouseover', onMouseOver, false);
918
+ parent.addEventListener('mouseout', onMouseOut, false);
919
+ }
920
+
921
+ return h;
922
+ }
923
+
924
+ var WPStagingCommon = (function ($) {
925
+ var WPStagingCommon = {
926
+ continueErrorHandle: true,
927
+ cache: {
928
+ elements: [],
929
+ get: function get(selector) {
930
+ // It is already cached!
931
+ if ($.inArray(selector, this.elements) !== -1) {
932
+ return this.elements[selector];
933
+ } // Create cache and return
934
+
935
+
936
+ this.elements[selector] = $(selector);
937
+ return this.elements[selector];
938
+ },
939
+ refresh: function refresh(selector) {
940
+ selector.elements[selector] = $(selector);
941
+ }
942
+ },
943
+ listenTooltip: function listenTooltip() {
944
+ wpstgHoverIntent(document, '.wpstg--tooltip', function (target, event) {
945
+ target.querySelector('.wpstg--tooltiptext').style.visibility = 'visible';
946
+ }, function (target, event) {
947
+ target.querySelector('.wpstg--tooltiptext').style.visibility = 'hidden';
948
+ });
949
+ },
950
+ isEmpty: function isEmpty(obj) {
951
+ for (var prop in obj) {
952
+ if (obj.hasOwnProperty(prop)) {
953
+ return false;
954
+ }
955
+ }
956
+
957
+ return true;
958
+ },
959
+ // Get the custom themed Swal Modal for WP Staging
960
+ // Easy to maintain now in one place now
961
+ getSwalModal: function getSwalModal(isContentCentered, customClasses) {
962
+ if (isContentCentered === void 0) {
963
+ isContentCentered = false;
964
+ }
965
+
966
+ if (customClasses === void 0) {
967
+ customClasses = {};
968
+ }
969
+
970
+ // common style for all swal modal used in WP Staging
971
+ var defaultCustomClasses = {
972
+ confirmButton: 'wpstg--btn--confirm wpstg-blue-primary wpstg-button wpstg-link-btn wpstg-100-width',
973
+ cancelButton: 'wpstg--btn--cancel wpstg-blue-primary wpstg-link-btn wpstg-100-width',
974
+ actions: 'wpstg--modal--actions',
975
+ popup: isContentCentered ? 'wpstg-swal-popup centered-modal' : 'wpstg-swal-popup'
976
+ }; // If a attribute exists in both default and additional attributes,
977
+ // The class(es) of the additional attribute will overrite the default one.
978
+
979
+ var options = {
980
+ customClass: Object.assign(defaultCustomClasses, customClasses),
981
+ buttonsStyling: false,
982
+ reverseButtons: true,
983
+ showClass: {
984
+ popup: 'swal2-show wpstg-swal-show'
985
+ }
986
+ };
987
+ return Swal.mixin(options);
988
+ },
989
+ showSuccessModal: function showSuccessModal(htmlContent) {
990
+ this.getSwalModal().fire({
991
+ showConfirmButton: false,
992
+ showCancelButton: true,
993
+ cancelButtonText: 'OK',
994
+ icon: 'success',
995
+ title: 'Success!',
996
+ html: '<div class="wpstg--grey" style="text-align: left; margin-top: 8px;">' + htmlContent + '</div>'
997
+ });
998
+ },
999
+ showWarningModal: function showWarningModal(htmlContent) {
1000
+ this.getSwalModal().fire({
1001
+ showConfirmButton: false,
1002
+ showCancelButton: true,
1003
+ cancelButtonText: 'OK',
1004
+ icon: 'warning',
1005
+ title: '',
1006
+ html: '<div class="wpstg--grey" style="text-align: left; margin-top: 8px;">' + htmlContent + '</div>'
1007
+ });
1008
+ },
1009
+ showErrorModal: function showErrorModal(htmlContent) {
1010
+ this.getSwalModal().fire({
1011
+ showConfirmButton: false,
1012
+ showCancelButton: true,
1013
+ cancelButtonText: 'OK',
1014
+ icon: 'error',
1015
+ title: 'Error!',
1016
+ html: '<div class="wpstg--grey" style="text-align: left; margin-top: 8px;">' + htmlContent + '</div>'
1017
+ });
1018
+ },
1019
+
1020
+ /**
1021
+ * Treats a default response object generated by WordPress's
1022
+ * wp_send_json_success() or wp_send_json_error() functions in
1023
+ * PHP, parses it in JavaScript, and either throws if it's an error,
1024
+ * or returns the data if the response is successful.
1025
+ *
1026
+ * @param {object} response
1027
+ * @return {*}
1028
+ */
1029
+ getDataFromWordPressResponse: function getDataFromWordPressResponse(response) {
1030
+ if (typeof response !== 'object') {
1031
+ throw new Error('Unexpected response (ERR 1341)');
1032
+ }
1033
+
1034
+ if (!response.hasOwnProperty('success')) {
1035
+ throw new Error('Unexpected response (ERR 1342)');
1036
+ }
1037
+
1038
+ if (!response.hasOwnProperty('data')) {
1039
+ throw new Error('Unexpected response (ERR 1343)');
1040
+ }
1041
+
1042
+ if (response.success === false) {
1043
+ if (response.data instanceof Array && response.data.length > 0) {
1044
+ throw new Error(response.data.shift());
1045
+ } else {
1046
+ throw new Error('Response was not successful');
1047
+ }
1048
+ } else {
1049
+ // Successful response. Return the data.
1050
+ return response.data;
1051
+ }
1052
+ },
1053
+ isLoading: function isLoading(_isLoading) {
1054
+ if (!_isLoading || _isLoading === false) {
1055
+ WPStagingCommon.cache.get('.wpstg-loader').hide();
1056
+ } else {
1057
+ WPStagingCommon.cache.get('.wpstg-loader').show();
1058
+ }
1059
+ },
1060
+ showAjaxFatalError: function showAjaxFatalError(response, prependMessage, appendMessage) {
1061
+ prependMessage = prependMessage ? prependMessage + '<br/><br/>' : 'Something went wrong! <br/><br/>';
1062
+ 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.';
1063
+
1064
+ if (response === false) {
1065
+ WPStagingCommon.showErro(prependMessage + ' Error: No response.' + appendMessage);
1066
+ window.removeEventListener('beforeunload', WPStaging.warnIfClosingDuringProcess);
1067
+ return;
1068
+ }
1069
+
1070
+ if (typeof response.error !== 'undefined' && response.error) {
1071
+ WPStagingCommon.showError(prependMessage + ' Error: ' + response.message + appendMessage);
1072
+ window.removeEventListener('beforeunload', WPStaging.warnIfClosingDuringProcess);
1073
+ return;
1074
+ }
1075
+ },
1076
+ handleFetchErrors: function handleFetchErrors(response) {
1077
+ if (!response.ok) {
1078
+ WPStagingCommon.showErro('Error: ' + response.status + ' - ' + response.statusText + '. Please try again or contact support.');
1079
+ }
1080
+
1081
+ return response;
1082
+ },
1083
+ showError: function showError(message) {
1084
+ WPStagingCommon.cache.get('#wpstg-try-again').css('display', 'inline-block');
1085
+ WPStagingCommon.cache.get('#wpstg-cancel-cloning').text('Reset');
1086
+ WPStagingCommon.cache.get('#wpstg-resume-cloning').show();
1087
+ WPStagingCommon.cache.get('#wpstg-error-wrapper').show();
1088
+ WPStagingCommon.cache.get('#wpstg-error-details').show().html(message);
1089
+ WPStagingCommon.cache.get('#wpstg-removing-clone').removeClass('loading');
1090
+ WPStagingCommon.cache.get('.wpstg-loader').hide();
1091
+ $('.wpstg--modal--process--generic-problem').show().html(message);
1092
+ },
1093
+ resetErrors: function resetErrors() {
1094
+ WPStagingCommon.cache.get('#wpstg-error-details').hide().html('');
1095
+ },
1096
+
1097
+ /**
1098
+ * Ajax Requests
1099
+ * @param {Object} data
1100
+ * @param {Function} callback
1101
+ * @param {string} dataType
1102
+ * @param {bool} showErrors
1103
+ * @param {int} tryCount
1104
+ * @param {float} incrementRatio
1105
+ * @param errorCallback
1106
+ */
1107
+ ajax: function ajax(data, callback, dataType, showErrors, tryCount, incrementRatio, errorCallback) {
1108
+ if (incrementRatio === void 0) {
1109
+ incrementRatio = null;
1110
+ }
1111
+
1112
+ if (errorCallback === void 0) {
1113
+ errorCallback = null;
1114
+ }
1115
+
1116
+ if ('undefined' === typeof dataType) {
1117
+ dataType = 'json';
1118
+ }
1119
+
1120
+ if (false !== showErrors) {
1121
+ showErrors = true;
1122
+ }
1123
+
1124
+ tryCount = 'undefined' === typeof tryCount ? 0 : tryCount;
1125
+ var retryLimit = 10;
1126
+ var retryTimeout = 10000 * tryCount;
1127
+ incrementRatio = parseInt(incrementRatio);
1128
+
1129
+ if (!isNaN(incrementRatio)) {
1130
+ retryTimeout *= incrementRatio;
1131
+ }
1132
+
1133
+ $.ajax({
1134
+ url: ajaxurl + '?action=wpstg_processing&_=' + Date.now() / 1000,
1135
+ type: 'POST',
1136
+ dataType: dataType,
1137
+ cache: false,
1138
+ data: data,
1139
+ error: function error(xhr, textStatus, errorThrown) {
1140
+ console.log(xhr.status + ' ' + xhr.statusText + '---' + textStatus);
1141
+
1142
+ if (typeof errorCallback === 'function') {
1143
+ // Custom error handler
1144
+ errorCallback(xhr, textStatus, errorThrown);
1145
+
1146
+ if (!WPStagingCommon.continueErrorHandle) {
1147
+ // Reset state
1148
+ WPStagingCommon.continueErrorHandle = true;
1149
+ return;
1150
+ }
1151
+ } // Default error handler
1152
+
1153
+
1154
+ tryCount++;
1155
+
1156
+ if (tryCount <= retryLimit) {
1157
+ setTimeout(function () {
1158
+ WPStagingCommon.ajax(data, callback, dataType, showErrors, tryCount, incrementRatio);
1159
+ return;
1160
+ }, retryTimeout);
1161
+ } else {
1162
+ var errorCode = 'undefined' === typeof xhr.status ? 'Unknown' : xhr.status;
1163
+ WPStagingCommon.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.');
1164
+ }
1165
+ },
1166
+ success: function success(data) {
1167
+ if ('function' === typeof callback) {
1168
+ callback(data);
1169
+ }
1170
+ },
1171
+ statusCode: {
1172
+ 404: function _() {
1173
+ if (tryCount >= retryLimit) {
1174
+ WPStagingCommon.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.');
1175
+ }
1176
+ },
1177
+ 500: function _() {
1178
+ if (tryCount >= retryLimit) {
1179
+ WPStagingCommon.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.');
1180
+ }
1181
+ },
1182
+ 504: function _() {
1183
+ if (tryCount > retryLimit) {
1184
+ WPStagingCommon.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\ ');
1185
+ }
1186
+ },
1187
+ 502: function _() {
1188
+ if (tryCount >= retryLimit) {
1189
+ WPStagingCommon.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\ ');
1190
+ }
1191
+ },
1192
+ 503: function _() {
1193
+ if (tryCount >= retryLimit) {
1194
+ WPStagingCommon.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\ ');
1195
+ }
1196
+ },
1197
+ 429: function _() {
1198
+ if (tryCount >= retryLimit) {
1199
+ WPStagingCommon.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\ ');
1200
+ }
1201
+ },
1202
+ 403: function _() {
1203
+ if (tryCount >= retryLimit) {
1204
+ WPStagingCommon.showError('Refresh page or login again! The process should be finished successfully. \n\ ');
1205
+ }
1206
+ }
1207
+ }
1208
+ });
1209
+ }
1210
+ };
1211
+ return WPStagingCommon;
1212
+ })(jQuery);
1213
+
1214
  /**
1215
  * Manage RESET MODAL
1216
  */
1324
  };
1325
 
1326
  _proto.loadModal = function loadModal() {
1327
+ return WPStagingCommon.getSwalModal(false, {
1328
+ confirmButton: this.resetButtonClass + ' wpstg-confirm-reset-clone wpstg--btn--confirm wpstg-blue-primary wpstg-button wpstg-link-btn',
1329
+ container: this.resetModalContainerClass + ' wpstg-swal2-container wpstg-swal2-loading'
1330
+ }).fire({
1331
  title: '',
1332
  icon: 'warning',
1333
  html: this.getAjaxLoader(),
1334
+ width: '400px',
1335
  focusConfirm: false,
 
 
 
 
1336
  confirmButtonText: this.wpstgObject.i18n.resetClone,
1337
  showCancelButton: true
1338
  });
1371
  html: _this2.wpstgObject.i18n['somethingWentWrong'],
1372
  width: '500px',
1373
  confirmButtonText: 'Ok',
1374
+ showCancelButton: false,
1375
+ customClass: {
1376
+ confirmButton: 'wpstg--btn--confirm wpstg-blue-primary wpstg-button wpstg-link-btn',
1377
+ cancelButton: 'wpstg--btn--cancel wpstg-blue-primary wpstg-link-btn',
1378
+ actions: 'wpstg--modal--actions',
1379
+ popup: 'wpstg-swal-popup centered-modal'
1380
+ },
1381
+ buttonsStyling: false,
1382
+ reverseButtons: true
1383
  }, data.swalOptions), {
1384
  type: data.type
1385
  });
1388
 
1389
  var modal = qs('.wpstg-reset-confirmation');
1390
  modal.classList.remove('wpstg-swal2-loading');
1391
+ modal.querySelector('.swal2-popup').style.width = '500px';
1392
  modal.querySelector('.swal2-content').innerHTML = data.html;
1393
  _this2.directoryNavigator = new WpstgDirectoryNavigation();
1394
  _this2.excludeFilters = new WpstgExcludeFilters();
1501
  return WpstgResetModal;
1502
  }();
1503
 
1504
+ /**
1505
+ * Handle toggle of advance settings checkboxes
1506
+ */
1507
+
1508
+ var WpstgCloningAdvanceSettings = /*#__PURE__*/function () {
1509
+ function WpstgCloningAdvanceSettings(baseContainerSelector) {
1510
+ if (baseContainerSelector === void 0) {
1511
+ baseContainerSelector = '#wpstg-clonepage-wrapper';
1512
+ }
1513
+
1514
+ this.baseContainer = qs(baseContainerSelector);
1515
+ this.checkBoxSettingTogglerSelector = '.wpstg-toggle-advance-settings-section';
1516
+ this.init();
1517
+ }
1518
+ /**
1519
+ * Add events
1520
+ * @return {void}
1521
+ */
1522
+
1523
+
1524
+ var _proto = WpstgCloningAdvanceSettings.prototype;
1525
+
1526
+ _proto.addEvents = function addEvents() {
1527
+ var _this = this;
1528
+
1529
+ if (this.baseContainer === null) {
1530
+ return;
1531
+ }
1532
+
1533
+ addEvent(this.baseContainer, 'change', this.checkBoxSettingTogglerSelector, function (element) {
1534
+ _this.toggleSettings(element);
1535
+ });
1536
+ }
1537
+ /**
1538
+ * @return {void}
1539
+ */
1540
+ ;
1541
+
1542
+ _proto.init = function init() {
1543
+ this.addEvents();
1544
+ }
1545
+ /**
1546
+ * Expand/Collapse checkbox content on change
1547
+ * @return {void}
1548
+ */
1549
+ ;
1550
+
1551
+ _proto.toggleSettings = function toggleSettings(element) {
1552
+ var target = qs('#' + element.getAttribute('data-id'));
1553
+
1554
+ if (element.checked) {
1555
+ slideDown(target);
1556
+ } else {
1557
+ slideUp(target);
1558
+ }
1559
+ };
1560
+
1561
+ return WpstgCloningAdvanceSettings;
1562
+ }();
1563
+
1564
+ var WpstgMainMenu = /*#__PURE__*/function () {
1565
+ function WpstgMainMenu() {
1566
+ this.mainMenu();
1567
+ this.activeTabClass = 'wpstg--tab--active';
1568
+ }
1569
+
1570
+ var _proto = WpstgMainMenu.prototype;
1571
+
1572
+ _proto.mainMenu = function mainMenu() {
1573
+ var _this = this;
1574
+
1575
+ addEvent(qs('.wpstg--tab--header'), 'click', '.wpstg-button', function (element) {
1576
+ var $this = element;
1577
+ var target = $this.getAttribute('data-target');
1578
+ var targetElements = all(target);
1579
+ var menuItems = all('.wpstg--tab--header a[data-target]');
1580
+ var contents = all('.wpstg--tab--contents > .wpstg--tab--content');
1581
+ contents.forEach(function (content) {
1582
+ // active tab class is without the css dot class prefix
1583
+ if (content.matches('.' + _this.activeTabClass + ':not(' + target + ')')) {
1584
+ content.classList.remove(_this.activeTabClass);
1585
+ }
1586
+ });
1587
+ menuItems.forEach(function (menuItem) {
1588
+ if (menuItem !== $this) {
1589
+ menuItem.classList.remove(_this.activeTabClass);
1590
+ }
1591
+ });
1592
+ $this.classList.add(_this.activeTabClass);
1593
+ targetElements.forEach(function (targetElement) {
1594
+ targetElement.classList.add(_this.activeTabClass);
1595
+ });
1596
+
1597
+ if ('#wpstg--tab--backup' === target) {
1598
+ window.dispatchEvent(new Event('backups-tab'));
1599
+ }
1600
+ });
1601
+ };
1602
+
1603
+ return WpstgMainMenu;
1604
+ }();
1605
+
1606
+ var WPStaging$1 = function ($) {
1607
+ var that = {
1608
+ isCancelled: false,
1609
+ isFinished: false,
1610
+ getLogs: false,
1611
+ time: 1,
1612
+ executionTime: false,
1613
+ progressBar: 0,
1614
+ cloneExcludeFilters: null,
1615
+ directoryNavigator: null,
1616
+ notyf: null
1617
+ };
1618
+ var cache = {
1619
+ elements: []
1620
+ };
1621
+ var ajaxSpinner;
1622
+ /**
1623
+ * Get / Set Cache for Selector
1624
  * @param {String} selector
1625
  * @return {*}
1626
  */
1672
  event.returnValue = 'You MUST leave this window open while cloning/pushing. Please wait...';
1673
  return null;
1674
  };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1675
  /**
1676
  *
1677
  * @param response the error object
1687
 
1688
  if (response === false) {
1689
  showError(prependMessage + ' Error: No response.' + appendMessage);
1690
+ window.removeEventListener('beforeunload', WPStaging$1.warnIfClosingDuringProcess);
1691
  return;
1692
  }
1693
 
1694
  if (typeof response.error !== 'undefined' && response.error) {
1695
  console.error(response.message);
1696
  showError(prependMessage + ' Error: ' + response.message + appendMessage);
1697
+ window.removeEventListener('beforeunload', WPStaging$1.warnIfClosingDuringProcess);
1698
  return;
1699
  }
1700
  };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1701
  /** Hide and reset previous thrown visible errors */
1702
 
1703
 
2252
  render += '<tr><td>' + x.name + '</td><td>' + x.production + '</td><td>' + x.staging + '</td><td>' + icon + '</td></tr>';
2253
  });
2254
  render += '</tbody></table><p>Note: Some mySQL properties do not match. You may proceed but the staging site may not work as expected.</p>';
2255
+ WPStagingCommon.getSwalModal().fire({
2256
  title: 'Different Database Properties',
2257
  icon: 'warning',
2258
  html: render,
2268
  return;
2269
  }
2270
 
2271
+ WPStagingCommon.getSwalModal(true).fire({
2272
  title: 'Different Database Properties',
2273
  icon: 'error',
2274
  html: response.message,
2380
  html: wpstg.i18n['somethingWentWrong'],
2381
  width: '500px',
2382
  confirmButtonText: 'Ok',
2383
+ showCancelButton: false,
2384
+ customClass: {
2385
+ confirmButton: 'wpstg--btn--confirm wpstg-blue-primary wpstg-button wpstg-link-btn',
2386
+ cancelButton: 'wpstg--btn--cancel wpstg-blue-primary wpstg-link-btn',
2387
+ actions: 'wpstg--modal--actions',
2388
+ popup: 'wpstg-swal-popup centered-modal'
2389
+ },
2390
+ buttonsStyling: false,
2391
+ reverseButtons: true
2392
  }, response.swalOptions), {
2393
  type: response.type
2394
  });
2492
 
2493
  if (response["delete"] === 'finished') {
2494
  $('.wpstg-clone#' + clone).remove();
2495
+ } // No staging site message is also of type/class .wpstg-class but hidden
2496
+ // We have just excluded that from search when counting no of clones
2497
+
2498
 
2499
+ if ($('#wpstg-existing-clones .wpstg-clone').length < 1) {
2500
  cache.get('#wpstg-existing-clones').find('h3').text('');
2501
+ cache.get('#wpstg-no-staging-site-results').show();
2502
  }
2503
 
2504
  cache.get('.wpstg-loader').hide();
2641
  }
2642
 
2643
  if (value.type === 'ERROR') {
2644
+ cache.get('.wpstg-log-details').append('<span class="wpstg--red">[' + value.type + ']</span>-' + '[' + value.date + '] ' + value.message + '</br>');
2645
  } else {
2646
  cache.get('.wpstg-log-details').append('[' + value.type + ']-' + '[' + value.date + '] ' + value.message + '</br>');
2647
  }
2678
  } // Show required disk space
2679
 
2680
 
2681
+ cache.get('#wpstg-clone-id-error').html('Estimated necessary disk space: ' + response.requiredSpace + (response.errorMessage !== null ? '<br>' + response.errorMessage : '') + '<br> <span style="color:#444;">Before you proceed ensure your account has enough free disk space to hold the entire instance of the production site. You can check the available space from your hosting account (cPanel or similar).</span>').show();
2682
  cache.get('.wpstg-loader').hide();
2683
  }, 'json', false);
2684
  });
2685
  };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2686
  /**
2687
  * Show or hide animated loading icon
2688
  * @param isLoading bool
2765
 
2766
  setTimeout(function () {
2767
  // cloneDatabase();
2768
+ window.addEventListener('beforeunload', WPStaging$1.warnIfClosingDuringProcess);
2769
  processing();
2770
  }, wpstg.delayReq);
2771
  that.timer('start');
2778
 
2779
  var processing = function processing() {
2780
  if (true === that.isCancelled) {
2781
+ window.removeEventListener('beforeunload', WPStaging$1.warnIfClosingDuringProcess);
2782
  return false;
2783
  }
2784
 
2793
 
2794
 
2795
  cache.get('.wpstg-log-details').show();
2796
+ WPStaging$1.ajax({
2797
  action: 'wpstg_processing',
2798
  accessToken: wpstg.accessToken,
2799
  nonce: wpstg.nonce,
2820
  progressBar(response);
2821
  processing();
2822
  } else if ('finished' === response.status || 'undefined' !== typeof response.job_done && response.job_done) {
2823
+ window.removeEventListener('beforeunload', WPStaging$1.warnIfClosingDuringProcess);
2824
  finish(response);
2825
  }
2826
  }, 'json', false);
2865
  }
2866
 
2867
  if (that.data.action === 'wpstg_update' || that.data.action === 'wpstg_reset') {
2868
+ // TODO: remove default custom classes
2869
+ WPStagingCommon.getSwalModal(true, {
2870
+ confirmButton: 'wpstg--btn--confirm wpstg-green-button wpstg-button wpstg-link-btn wpstg-100-width'
2871
+ }).fire({
2872
  title: '',
2873
  icon: 'success',
2874
  html: msg,
2946
  elements();
2947
  stepButtons();
2948
  tabs();
2949
+ WPStagingCommon.listenTooltip();
2950
+ new WpstgMainMenu();
2951
  new WpstgCloneStaging();
2952
+ new WpstgCloningAdvanceSettings();
2953
+ that.notyf = new Notyf({
2954
+ duration: 10000,
2955
+ position: {
2956
+ x: 'center',
2957
+ y: 'bottom'
2958
+ },
2959
+ dismissible: true,
2960
+ types: [{
2961
+ type: 'warning',
2962
+ background: 'orange',
2963
+ icon: false
2964
+ }]
2965
+ });
2966
  };
2967
  /**
2968
  * Ajax call
2973
  that.ajax = ajax;
2974
  that.showError = showError;
2975
  that.getLogs = getLogs;
2976
+ that.loadOverview = loadOverview;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2977
  return that;
2978
  }(jQuery);
2979
 
2980
  jQuery(document).ready(function () {
2981
+ WPStaging$1.init(); // This is necessary to make WPStaging var accessibile in WP Staging PRO js script
2982
 
2983
+ window.WPStaging = WPStaging$1;
2984
  });
2985
  /**
2986
  * Report Issue modal
2987
  */
2988
 
2989
  jQuery(document).ready(function ($) {
2990
+ $('body').on('click', '#wpstg-report-issue-button', function (e) {
2991
+ console.log('REPORT');
2992
+ $('.wpstg--tab--active .wpstg-report-issue-form').toggleClass('wpstg-report-show');
2993
  e.preventDefault();
2994
  });
2995
  $('body').on('click', '#wpstg-backups-report-issue-button', function (e) {
2996
+ $('.wpstg--tab--active .wpstg-report-issue-form').toggleClass('wpstg-report-show');
2997
  e.preventDefault();
2998
  });
2999
+ $('body').on('click', '#wpstg-report-cancel', function (e) {
3000
+ $('.wpstg--tab--active .wpstg-report-issue-form').removeClass('wpstg-report-show');
3001
+ e.preventDefault();
3002
+ });
3003
+ $('body').on('click', '.wpstg--tab--active #wpstg-report-submit', function (e) {
3004
+ var self = $(this);
3005
+ sendIssueReport(self, 'false');
3006
  e.preventDefault();
3007
  });
3008
  /*
3020
  }
3021
 
3022
  var spinner = button.next();
3023
+ var email = $('.wpstg--tab--active .wpstg-report-email').val();
3024
+ var hosting_provider = $('.wpstg--tab--active .wpstg-report-hosting-provider').val();
3025
+ var message = $('.wpstg--tab--active .wpstg-report-description').val();
3026
+ var syslog = $('.wpstg--tab--active .wpstg-report-syslog').is(':checked');
3027
+ var terms = $('.wpstg--tab--active .wpstg-report-terms').is(':checked');
3028
  button.attr('disabled', true);
3029
  spinner.css('visibility', 'visible');
3030
  $.ajax({
3048
  spinner.css('visibility', 'hidden');
3049
 
3050
  if (data.errors.length > 0) {
3051
+ $('.wpstg--tab--active .wpstg-report-issue-form .wpstg-message').remove();
3052
  var errorMessage = $('<div />').addClass('wpstg-message wpstg-error-message');
3053
  $.each(data.errors, function (key, value) {
3054
  if (value.status === 'already_submitted') {
3055
+ errorMessage = ''; // TODO: remove default custom classes
3056
+
3057
+ WPStagingCommon.getSwalModal(true, {
3058
+ container: 'wpstg-issue-resubmit-confirmation'
3059
+ }).fire({
3060
  title: '',
 
 
 
3061
  icon: 'warning',
3062
  html: value.message,
 
3063
  showCancelButton: true,
3064
  focusConfirm: false,
3065
  confirmButtonText: 'Yes',
3073
  errorMessage.append('<p>' + value + '</p>');
3074
  }
3075
  });
3076
+ $('.wpstg--tab--active .wpstg-report-issue-form').prepend(errorMessage);
3077
  } else {
3078
  var successMessage = $('<div />').addClass('wpstg-message wpstg-success-message');
3079
  successMessage.append('<p>Thanks for submitting your request! You should receive an auto reply mail with your ticket ID immediately for confirmation!<br><br>If you do not get that mail please contact us directly at <strong>support@wp-staging.com</strong></p>');
3080
+ $('.wpstg--tab--active .wpstg-report-issue-form').html(successMessage);
3081
+ $('.wpstg--tab--active .wpstg-success-message').append('<div style="float:right;margin-top:10px;"><a id="wpstg-success-button" href="#" class="wpstg--red">[X] CLOSE</a></div>'); // Hide message
3082
 
3083
  setTimeout(function () {
3084
+ $('.wpstg--tab--active .wpstg-report-issue-form').removeClass('wpstg-report-active');
3085
  }, 2000);
3086
  }
3087
  });
3088
+ } // Open/close actions drop down menu
3089
 
 
 
 
 
 
3090
 
3091
  $(document).on('click', '.wpstg-dropdown>.wpstg-dropdown-toggler', function (e) {
3092
  e.preventDefault();
3093
  $(e.target).next('.wpstg-dropdown-menu').toggleClass('shown');
3094
+ $(e.target).find('.wpstg-caret').toggleClass('wpstg-caret-up');
3095
+ });
3096
+ $(document).on('click', '.wpstg-caret', function (e) {
3097
+ e.preventDefault();
3098
+ var toggler = $(e.target).closest('.wpstg-dropdown-toggler');
3099
+
3100
+ if (toggler) {
3101
+ toggler.trigger('click');
3102
+ }
3103
  }); // Close action drop down menu if clicked anywhere outside
3104
 
3105
  document.addEventListener('click', function (event) {
3111
  for (var i = 0; i < dropDown.length; i++) {
3112
  dropDown[i].classList.remove('shown');
3113
  }
3114
+
3115
+ $('.wpstg-caret').removeClass('wpstg-caret-up');
3116
  }
3117
  });
3118
  });
assets/js/dist/wpstg-admin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"wpstg-admin.js","sources":["../src/modules/wpstg-dom-utils.js","../src/modules/wpstg-clone-staging.js","../src/modules/wpstg-directory-navigation.js","../src/modules/wpstg-exclude-filters.js","../src/modules/wpstg-modal.js","../src/modules/wpstg-reset-modal.js","../src/wpstg-admin.js"],"sourcesContent":["/**\n * WP Staging basic jQuery replacement\n */\n\n/**\n * Shortcut for document.querySelector() or jQuery's $()\n * Return single element only\n */\nexport function qs(selector) {\n return document.querySelector(selector);\n}\n\n/**\n * Shortcut for document.querySelector() or jQuery's $()\n * Return collection of elements\n */\nexport function all(selector) {\n return document.querySelectorAll(selector);\n}\n\n/**\n * alternative of jQuery - $(parent).on(event, selector, handler)\n */\nexport function addEvent(parent, evt, selector, handler) {\n parent.addEventListener(evt, function(event) {\n if (event.target.matches(selector + ', ' + selector + ' *')) {\n handler(event.target.closest(selector), event);\n }\n }, false);\n}\n\nexport function slideDown(element, duration = 400) {\n element.style.display = 'block';\n element.style.overflow = 'hidden';\n const height = element.offsetHeight;\n element.style.height = '0px';\n element.style.transitionProperty = 'height';\n element.style.transitionDuration = duration + 'ms';\n setTimeout(() => {\n element.style.height = height + 'px';\n window.setTimeout(() => {\n element.style.removeProperty('height');\n element.style.removeProperty('overflow');\n element.style.removeProperty('transition-duration');\n element.style.removeProperty('transition-property');\n }, duration);\n }, 0);\n}\n\nexport function slideUp(element, duration = 400) {\n element.style.display = 'block';\n element.style.overflow = 'hidden';\n const height = element.offsetHeight;\n element.style.height = height + 'px';\n element.style.transitionProperty = 'height';\n element.style.transitionDuration = duration + 'ms';\n setTimeout(() => {\n element.style.height = '0px';\n window.setTimeout(() => {\n element.style.display = 'none';\n element.style.removeProperty('height');\n element.style.removeProperty('overflow');\n element.style.removeProperty('transition-duration');\n element.style.removeProperty('transition-property');\n }, duration);\n }, 0);\n}\n\nexport function getNextSibling(element, selector) {\n let sibling = element.nextElementSibling;\n\n while (sibling) {\n if (sibling.matches(selector)) {\n return sibling;\n }\n\n sibling = sibling.nextElementSibling;\n }\n};\n\nexport function getParents(element, selector) {\n const result = [];\n for (let parent = element && element.parentElement; parent; parent = parent.parentElement) {\n if (parent.matches(selector)) {\n result.push(parent);\n }\n }\n\n return result;\n}\n","import * as dom from './wpstg-dom-utils.js';\n\n/**\n * Enable/Disable cloning for staging site\n */\nexport default class WpstgCloneStaging {\n constructor(\n pageWrapperId = '#wpstg-clonepage-wrapper',\n wpstgObject = wpstg,\n ) {\n this.pageWrapper = dom.qs(pageWrapperId);\n this.wpstgObject = wpstgObject;\n this.enableButtonId = '#wpstg-enable-staging-cloning';\n this.enableAction = 'wpstg_enable_staging_cloning';\n\n this.notyf = new Notyf({\n duration: 10000,\n position: {\n x: 'center',\n y: 'bottom',\n },\n dismissible: true,\n types: [\n {\n type: 'warning',\n background: 'orange',\n icon: false,\n },\n ],\n });\n this.init();\n }\n\n addEvents() {\n if (this.pageWrapper === null) {\n return;\n }\n\n dom.addEvent(this.pageWrapper, 'click', this.enableButtonId, () => {\n this.sendRequest(this.enableAction);\n });\n }\n\n init() {\n this.addEvents();\n }\n\n sendRequest(action) {\n fetch(this.wpstgObject.ajaxUrl, {\n method: 'POST',\n credentials: 'same-origin',\n body: new URLSearchParams({\n action: action,\n accessToken: this.wpstgObject.accessToken,\n nonce: this.wpstgObject.nonce,\n }),\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n }).then((response) => {\n if (response.ok) {\n return response.json();\n }\n\n return Promise.reject(response);\n }).then((data) => {\n // Reload current page if successful.\n if ('undefined' !== typeof (data.success) && data.success) {\n location.reload();\n return;\n }\n\n // There will be message probably in case of error\n if ('undefined' !== typeof (data.message)) {\n this.notyf.error(data.message);\n return;\n }\n\n this.notyf.error(this.wpstgObject.i18n['somethingWentWrong']);\n }).catch((error) => {\n console.warn(this.wpstgObject.i18n['somethingWentWrong'], error);\n });\n }\n}\n","import * as dom from './wpstg-dom-utils.js';\n\n/**\n * Fetch directory direct child directories\n */\nexport default class WpstgDirectoryNavigation {\n constructor(\n directoryListingSelector = '#wpstg-directories-listing',\n wpstgObject = wpstg,\n notyf = null,\n ) {\n this.directoryListingContainer = dom.qs(directoryListingSelector);\n this.wpstgObject = wpstgObject;\n this.dirCheckboxSelector = '.wpstg-check-dir';\n this.dirExpandSelector = '.wpstg-expand-dirs';\n this.unselectAllDirsSelector = '.wpstg-unselect-dirs';\n this.selectDefaultDirsSelector = '.wpstg-select-dirs-default';\n this.fetchChildrenAction = 'wpstg_fetch_dir_childrens';\n this.currentCheckboxElement = null;\n this.currentParentDiv = null;\n this.currentLoader = null;\n this.existingExcludes = [];\n this.excludedDirectories = [];\n this.isDefaultSelected = false;\n this.notyf = notyf;\n\n this.init();\n }\n\n addEvents() {\n if (this.directoryListingContainer === null) {\n console.log('Error: directory navigation add events');\n return;\n }\n\n dom.addEvent(this.directoryListingContainer, 'click', this.dirExpandSelector, (element, event) => {\n event.preventDefault();\n if (this.toggleDirExpand(element)) {\n this.sendRequest(this.fetchChildrenAction, element);\n }\n });\n\n dom.addEvent(this.directoryListingContainer, 'click', this.unselectAllDirsSelector, () => {\n this.unselectAll();\n });\n\n dom.addEvent(this.directoryListingContainer, 'click', this.selectDefaultDirsSelector, () => {\n this.selectDefault();\n });\n }\n\n init() {\n this.addEvents();\n this.parseExcludes();\n }\n\n /**\n * Toggle Dir Expand,\n * Return true if children aren't fetched\n * @param {HTMLElement} element\n * @return {boolean}\n */\n toggleDirExpand(element) {\n this.currentParentDiv = element.parentElement;\n this.currentCheckboxElement = element.previousSibling;\n this.currentLoader = this.currentParentDiv.querySelector('.wpstg-is-dir-loading');\n if (this.currentCheckboxElement.getAttribute('data-navigateable', 'false') === 'false') {\n return false;\n }\n\n if (this.currentCheckboxElement.getAttribute('data-scanned', 'false') === 'false') {\n return true;\n }\n\n return false;\n }\n\n sendRequest(action) {\n if (this.currentLoader !== null) {\n this.currentLoader.style.display = 'inline-block';\n }\n\n fetch(this.wpstgObject.ajaxUrl, {\n method: 'POST',\n credentials: 'same-origin',\n body: new URLSearchParams({\n action: action,\n accessToken: this.wpstgObject.accessToken,\n nonce: this.wpstgObject.nonce,\n dirPath: this.currentCheckboxElement.value,\n isChecked: this.currentCheckboxElement.checked,\n forceDefault: this.isDefaultSelected,\n }),\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n }).then((response) => {\n if (response.ok) {\n return response.json();\n }\n\n return Promise.reject(response);\n }).then((data) => {\n if ('undefined' !== typeof (data.success) && data.success) {\n this.currentCheckboxElement.setAttribute('data-scanned', true);\n const dirContainer = document.createElement('div');\n dirContainer.classList.add('wpstg-dir');\n dirContainer.classList.add('wpstg-subdir');\n dirContainer.innerHTML = JSON.parse(data.directoryListing);\n this.currentParentDiv.appendChild(dirContainer);\n if (this.currentLoader !== null) {\n this.currentLoader.style.display = 'none';\n }\n\n dom.slideDown(dirContainer);\n\n return;\n }\n\n if (this.notyf !== null) {\n this.notyf.error(this.wpstgObject.i18n['somethingWentWrong']);\n } else {\n alert('Error: ' + this.wpstgObject.i18n['somethingWentWrong']);\n }\n }).catch((error) => {\n console.warn(this.wpstgObject.i18n['somethingWentWrong'], error);\n });\n }\n\n getExcludedDirectories() {\n this.excludedDirectories = [];\n this.directoryListingContainer.querySelectorAll('.wpstg-dir input:not(:checked)').forEach((element) => {\n if (!this.isParentExcluded(element.value)) {\n this.excludedDirectories.push(element.value);\n }\n });\n\n this.existingExcludes.forEach((exclude) => {\n if (!this.isParentExcluded(exclude) && !this.isExcludeScanned(exclude)) {\n this.excludedDirectories.push(exclude);\n }\n });\n\n return this.excludedDirectories.join(this.wpstgObject.settings.directorySeparator);\n }\n\n /**\n * @param {string} path\n * @return {bool}\n */\n isParentExcluded(path) {\n let isParentAlreadyExcluded = false;\n this.excludedDirectories.forEach((dir) => {\n if (path.startsWith(dir + '/')) {\n isParentAlreadyExcluded = true;\n }\n });\n\n return isParentAlreadyExcluded;\n }\n\n getExtraDirectoriesRootOnly() {\n this.getExcludedDirectories();\n const extraDirectories = [];\n this.directoryListingContainer.querySelectorAll(':not(.wpstg-subdir)>.wpstg-dir>input.wpstg-wp-non-core-dir:checked').forEach((element) => {\n extraDirectories.push(element.value);\n });\n\n // Check if extra directories text area exists\n // TODO: remove extraCustomDirectories code if no one require extraCustomDirectories...\n const extraDirectoriesTextArea = dom.qs('#wpstg_extraDirectories');\n if (extraDirectoriesTextArea === null || extraDirectoriesTextArea.value === '') {\n return extraDirectories.join(this.wpstgObject.settings.directorySeparator);\n }\n\n const extraCustomDirectories = extraDirectoriesTextArea.value.split(/\\r?\\n/);\n\n return extraDirectories.concat(extraCustomDirectories).join(this.wpstgObject.settings.directorySeparator);\n }\n\n unselectAll() {\n this.directoryListingContainer.querySelectorAll('.wpstg-dir input').forEach((element) => {\n element.checked = false;\n });\n }\n\n selectDefault() {\n // unselect all checkboxes\n this.unselectAll();\n\n // only select those checkboxes whose class is wpstg-wp-core-dir\n this.directoryListingContainer.querySelectorAll('.wpstg-dir input.wpstg-wp-core-dir').forEach((element) => {\n element.checked = true;\n });\n\n // then unselect those checkboxes whose parent has wpstg extra checkbox\n this.directoryListingContainer.querySelectorAll('.wpstg-dir > .wpstg-wp-non-core-dir').forEach((element) => {\n element.parentElement.querySelectorAll('input.wpstg-wp-core-dir').forEach((element) => {\n element.checked = false;\n });\n });\n\n this.isDefaultSelected = true;\n }\n\n parseExcludes() {\n this.existingExcludes = this.directoryListingContainer.getAttribute('data-existing-excludes', []);\n if (this.existingExcludes === '') {\n this.existingExcludes = [];\n }\n\n if (this.existingExcludes.length !== 0) {\n this.existingExcludes = this.existingExcludes.split(',');\n }\n }\n\n isExcludeScanned(exclude) {\n this.directoryListingContainer.querySelectorAll('.wpstg-dir input').forEach((element) => {\n if (element.value === exclude) {\n return true;\n }\n });\n\n return false;\n }\n}\n","import * as dom from './wpstg-dom-utils.js';\n\n/**\n * Rich Exclude Filter Module\n */\nexport default class WpstgExcludeFilters {\n constructor(\n excludeFilterContainerSelector = '#wpstg-exclude-filters-container',\n wpstgObject = wpstg,\n ) {\n this.excludeContainer = dom.qs(excludeFilterContainerSelector);\n this.excludeTableBody = dom.qs(`${excludeFilterContainerSelector} tbody`);\n this.wpstgObject = wpstgObject;\n this.init();\n }\n\n addEvents() {\n dom.addEvent(this.excludeContainer, 'click', '.wpstg-file-size-rule', () => {\n this.addFileSizeExclude();\n });\n\n dom.addEvent(this.excludeContainer, 'click', '.wpstg-file-ext-rule', () => {\n this.addFileExtExclude();\n });\n\n dom.addEvent(this.excludeContainer, 'click', '.wpstg-file-name-rule', () => {\n this.addFileNameExclude();\n });\n\n dom.addEvent(this.excludeContainer, 'click', '.wpstg-dir-name-rule', () => {\n this.addDirNameExclude();\n });\n\n dom.addEvent(this.excludeContainer, 'click', '.wpstg-clear-all-rules', () => {\n this.clearExcludes();\n });\n\n dom.addEvent(this.excludeContainer, 'click', '.wpstg-remove-exclude-rule', (target) => {\n this.removeExclude(target);\n });\n }\n\n init() {\n if (this.excludeContainer === null) {\n console.log('Error: Given table selector not found!');\n return;\n }\n\n this.addEvents();\n }\n\n addFileSizeExclude() {\n this.addExcludeRuleRow('#wpstg-file-size-exclude-filter-template');\n }\n\n addFileExtExclude() {\n this.addExcludeRuleRow('#wpstg-file-ext-exclude-filter-template');\n }\n\n addFileNameExclude() {\n this.addExcludeRuleRow('#wpstg-file-name-exclude-filter-template');\n }\n\n addDirNameExclude() {\n this.addExcludeRuleRow('#wpstg-dir-name-exclude-filter-template');\n }\n\n addExcludeRuleRow(templateName) {\n const excludeRowTemplate = dom.qs(templateName);\n if (excludeRowTemplate !== null) {\n const clone = excludeRowTemplate.content.cloneNode(true);\n const excludeRow = clone.querySelector('tr');\n\n this.excludeTableBody.appendChild(excludeRow);\n dom.all('.wpstg-has-exclude-rules').forEach((e) => {\n e.style.display = 'inherit';\n });\n }\n }\n\n clearExcludes() {\n this.excludeTableBody.innerHTML = '';\n dom.all('.wpstg-has-exclude-rules').forEach((e) => {\n e.style.display = 'none';\n });\n }\n\n removeExclude(target) {\n if (target.parentElement !== null && target.parentElement.parentElement !== null) {\n this.excludeTableBody.removeChild(target.parentElement.parentElement);\n }\n\n if (this.excludeTableBody.innerHTML.trim() === '') {\n dom.all('.wpstg-has-exclude-rules').forEach((e) => {\n e.style.display = 'none';\n });\n }\n }\n\n /**\n * Converts all the exclude filters arrays into one single string to keep size of post request small\n * @return {string}\n */\n getExcludeFilters() {\n const globExcludes = [];\n const sizeExcludes = [];\n\n const sizeCompares = this.excludeTableBody.querySelectorAll('select[name=\"wpstgFileSizeExcludeRuleCompare[]\"]');\n const sizeSizes = this.excludeTableBody.querySelectorAll('input[name=\"wpstgFileSizeExcludeRuleSize[]\"]');\n const sizeByte = this.excludeTableBody.querySelectorAll('select[name=\"wpstgFileSizeExcludeRuleByte[]\"]');\n for (const [key, sizeInput] of Object.entries(sizeSizes)) {\n if (sizeInput.value !== '') {\n sizeExcludes.push(sizeCompares[key].value + ' ' + sizeInput.value + sizeByte[key].value);\n }\n }\n\n const extensionInputs = this.excludeTableBody.querySelectorAll('input[name=\"wpstgFileExtExcludeRule[]\"]');\n extensionInputs.forEach((x) => {\n const ext = this.cleanStringForGlob(x.value);\n if (ext !== '') {\n globExcludes.push('ext:' + ext.trim());\n }\n });\n\n const fileNamesPos = this.excludeTableBody.querySelectorAll('select[name=\"wpstgFileNameExcludeRulePos[]\"]');\n const fileNames = this.excludeTableBody.querySelectorAll('input[name=\"wpstgFileNameExcludeRulePath[]\"]');\n for (const [key, fileInput] of Object.entries(fileNames)) {\n const fileName = this.cleanStringForGlob(fileInput.value);\n if (fileName !== '') {\n globExcludes.push('file:' + fileNamesPos[key].value + ' ' + fileName.trim());\n }\n }\n\n const dirNamesPos = this.excludeTableBody.querySelectorAll('select[name=\"wpstgDirNameExcludeRulePos[]\"]');\n const dirNames = this.excludeTableBody.querySelectorAll('input[name=\"wpstgDirNameExcludeRulePath[]\"]');\n for (const [key, dirInput] of Object.entries(dirNames)) {\n const dirName = this.cleanStringForGlob(dirInput.value);\n if (dirName !== '') {\n globExcludes.push('dir:' + dirNamesPos[key].value + ' ' + dirName.trim());\n }\n }\n\n return {\n 'sizes': sizeExcludes.filter(this.onlyUnique).join(','),\n // return set of unique rules\n 'globs': globExcludes.filter(this.onlyUnique).join(','),\n };\n }\n\n onlyUnique(value, index, self) {\n return self.indexOf(value) === index;\n }\n\n /**\n * Remove most of the comment glob characters from the string\n * @param {String} value\n * @return {String}\n */\n cleanStringForGlob(value) {\n // will replace character like * ^ / \\ ! ? [ from the string\n return value.replace(/[*^//!\\.[?]/g, '');\n }\n}\n","/**\n * Basic WP Staging Modal implemented with help of Sweetalerts\n */\nexport default class WpstgModal {\n constructor(\n confirmAction,\n wpstgObject = wpstg,\n ) {\n this.confirmAction = confirmAction;\n this.wpstgObject = wpstgObject;\n }\n\n show(swalOptions, additionalParams = {}, callback = null) {\n Swal.fire(swalOptions).then((result) => {\n if (result.value && this.error !== null) {\n this.triggerConfirmAction(additionalParams, callback);\n }\n });\n }\n\n triggerConfirmAction(additionalParams = {}, callback = null) {\n fetch(this.wpstgObject.ajaxUrl, {\n method: 'POST',\n credentials: 'same-origin',\n body: new URLSearchParams(Object.assign({\n action: this.confirmAction,\n accessToken: this.wpstgObject.accessToken,\n nonce: this.wpstgObject.nonce,\n }, additionalParams)),\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n }).then((response) => {\n if (response.ok) {\n return response.json();\n }\n\n return Promise.reject(response);\n }).then((response) => {\n if (callback !== null) {\n callback(response);\n }\n }).catch((error) => {\n console.log(this.wpstgObject.i18n['somethingWentWrong'], error);\n });\n }\n}\n","\nimport * as dom from './wpstg-dom-utils.js';\nimport WpstgDirectoryNavigation from './wpstg-directory-navigation.js';\nimport WpstgExcludeFilters from './wpstg-exclude-filters.js';\nimport WpstgModal from './wpstg-modal.js';\n\n/**\n * Manage RESET MODAL\n */\nexport default class WpstgResetModal {\n constructor(\n cloneID,\n workflowSelector = '#wpstg-workflow',\n fetchExcludeSettingsAction = 'wpstg_clone_excludes_settings',\n modalErrorAction = 'wpstg_modal_error',\n wpstgObject = wpstg,\n ) {\n this.cloneID = cloneID;\n this.workflow = dom.qs(workflowSelector);\n this.wpstgObject = wpstgObject;\n this.fetchExcludeSettingsAction = fetchExcludeSettingsAction;\n this.modalErrorAction = modalErrorAction;\n this.resetButtonClass = 'wpstg-confirm-reset-clone';\n this.resetModalContainerClass = 'wpstg-reset-confirmation';\n this.resetTabSelector = '.wpstg-reset-exclude-tab';\n this.directoryNavigator = null;\n this.excludeFilters = null;\n this.isAllTablesChecked = true;\n }\n\n addEvents() {\n const resetModalContainer = dom.qs('.' + this.resetModalContainerClass);\n if (resetModalContainer === null) {\n console.log('Exit');\n return;\n }\n\n dom.addEvent(resetModalContainer, 'click', this.resetTabSelector, (target) => {\n this.toggleContent(target);\n });\n\n dom.addEvent(resetModalContainer, 'click', '.wpstg-button-select', () => {\n this.selectDefaultTables();\n });\n\n dom.addEvent(resetModalContainer, 'click', '.wpstg-button-unselect', () => {\n this.toggleTableSelection();\n });\n\n dom.addEvent(resetModalContainer, 'click', '.wpstg-expand-dirs', (target, event) => {\n event.preventDefault();\n this.toggleDirectoryNavigation(target);\n });\n\n dom.addEvent(resetModalContainer, 'change', 'input.wpstg-check-dir', (target) => {\n this.updateDirectorySelection(target);\n });\n }\n\n init() {\n this.addEvents();\n }\n\n toggleContent(target) {\n const resetModalContainer = dom.qs('.' + this.resetModalContainerClass);\n const contentId = target.getAttribute('data-id');\n const tabTriangle = target.querySelector('.wpstg-tab-triangle');\n const isCollapsed = target.getAttribute('data-collapsed', 'true');\n const content = dom.qs(contentId);\n if (isCollapsed === 'true') {\n if (resetModalContainer.classList.contains('has-collapsible-open')) {\n resetModalContainer.classList.add('has-collapsible-open-2');\n } else {\n resetModalContainer.classList.add('has-collapsible-open');\n }\n\n dom.slideDown(content);\n tabTriangle.style.transform = 'rotate(90deg)';\n target.setAttribute('data-collapsed', 'false');\n } else {\n if (resetModalContainer.classList.contains('has-collapsible-open-2')) {\n resetModalContainer.classList.remove('has-collapsible-open-2');\n } else {\n resetModalContainer.classList.remove('has-collapsible-open');\n }\n\n dom.slideUp(content);\n tabTriangle.style.removeProperty('transform');\n target.setAttribute('data-collapsed', 'true');\n }\n }\n\n /**\n * Show Swal alert with loader and send ajax request to fetch content of alert.\n * @return Promise\n */\n showModal() {\n const swalPromise = this.loadModal();\n this.init();\n this.fetchCloneExcludes();\n return swalPromise;\n }\n\n loadModal() {\n return Swal.fire({\n title: '',\n icon: 'warning',\n html: this.getAjaxLoader(),\n width: '300px',\n focusConfirm: false,\n customClass: {\n confirmButton: this.resetButtonClass,\n container: 'wpstg-swal2-container wpstg-swal2-loading ' + this.resetModalContainerClass,\n },\n confirmButtonText: this.wpstgObject.i18n.resetClone,\n showCancelButton: true,\n });\n }\n\n fetchCloneExcludes() {\n this.error = null;\n // send ajax request and fetch preserved exclude settings\n fetch(this.wpstgObject.ajaxUrl, {\n method: 'POST',\n credentials: 'same-origin',\n body: new URLSearchParams({\n action: this.fetchExcludeSettingsAction,\n accessToken: this.wpstgObject.accessToken,\n nonce: this.wpstgObject.nonce,\n clone: this.cloneID,\n job: 'resetting',\n }),\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n }).then((response) => {\n if (response.ok) {\n return response.json();\n }\n\n return Promise.reject(response);\n }).then((data) => {\n if (!data.success) {\n const errorModal = new WpstgModal(this.modalErrorAction, this.wpstgObject);\n errorModal.show(Object.assign({\n title: 'Error',\n icon: 'error',\n html: this.wpstgObject.i18n['somethingWentWrong'],\n width: '500px',\n confirmButtonText: 'Ok',\n showCancelButton: false,\n }, data.swalOptions), {\n type: data.type,\n });\n\n return;\n }\n\n const modal = dom.qs('.wpstg-reset-confirmation');\n modal.classList.remove('wpstg-swal2-loading');\n modal.querySelector('.swal2-popup').style.width = 'auto';\n modal.querySelector('.swal2-content').innerHTML = data.html;\n this.directoryNavigator = new WpstgDirectoryNavigation();\n this.excludeFilters = new WpstgExcludeFilters();\n }).catch((error) => {\n this.renderError({\n 'html': this.wpstgObject.i18n['somethingWentWrong'] + ' ' + error,\n });\n });\n }\n\n getDirectoryNavigator() {\n return this.directoryNavigator;\n }\n\n getExcludeFilters() {\n return this.excludeFilters;\n }\n\n getAjaxLoader() {\n return '<div class=\"wpstg-swal2-ajax-loader\"><img src=\"' + this.wpstgObject.wpstgIcon + '\" /></div>';\n }\n\n toggleDirectoryNavigation(element) {\n const cbElement = element.previousSibling;\n if (cbElement.getAttribute('data-navigateable', 'false') === 'false') {\n return;\n }\n\n if (cbElement.getAttribute('data-scanned', 'false') === 'false') {\n return;\n }\n\n const subDirectories = dom.getNextSibling(element, '.wpstg-subdir');\n\n if (subDirectories.style.display === 'none') {\n dom.slideDown(subDirectories);\n } else {\n dom.slideUp(subDirectories);\n }\n }\n\n updateDirectorySelection(element) {\n const parent = element.parentElement;\n if (element.checked) {\n dom.getParents(parent, '.wpstg-dir').forEach((parElem) => {\n for (let i = 0; i < parElem.children.length; i++) {\n if (parElem.children[i].matches('.wpstg-check-dir')) {\n parElem.children[i].checked = true;\n }\n }\n });\n parent.querySelectorAll('.wpstg-expand-dirs').forEach((x) => {\n x.classList.remove('disabled');\n });\n parent.querySelectorAll('.wpstg-subdir .wpstg-check-dir').forEach((x) => {\n x.checked = true;\n });\n } else {\n parent.querySelectorAll('.wpstg-expand-dirs, .wpstg-check-subdirs').forEach((x) => {\n x.classList.add('disabled');\n });\n parent.querySelectorAll('.wpstg-dir .wpstg-check-dir').forEach((x) => {\n x.checked = false;\n });\n }\n }\n\n selectDefaultTables() {\n const resetModalContainer = dom.qs('.' + this.resetModalContainerClass);\n const options = resetModalContainer.querySelectorAll('#wpstg_select_tables_cloning .wpstg-db-table');\n const multisitePattern = '^' + this.wpstgObject.tblprefix + '([^0-9])_*';\n const singleSitePattern = '^' + this.wpstgObject.tblprefix;\n options.forEach((option) => {\n const name = option.getAttribute('name', '');\n if (this.wpstgObject.isMultisite === '1' && name.match(multisitePattern)) {\n option.setAttribute('selected', 'selected');\n } else if (this.wpstgObject.isMultisite === '' && name.match(singleSitePattern)) {\n option.setAttribute('selected', 'selected');\n } else {\n option.removeAttribute('selected');\n }\n });\n }\n\n toggleTableSelection() {\n const resetModalContainer = dom.qs('.' + this.resetModalContainerClass);\n if (false === this.isAllTablesChecked) {\n resetModalContainer.querySelectorAll('#wpstg_select_tables_cloning .wpstg-db-table').forEach((option) => {\n option.setAttribute('selected', 'selected');\n });\n resetModalContainer.querySelector('.wpstg-button-unselect').innerHTML = 'Unselect All';\n // cache.get('.wpstg-db-table-checkboxes').prop('checked', true);\n this.isAllTablesChecked = true;\n } else {\n resetModalContainer.querySelectorAll('#wpstg_select_tables_cloning .wpstg-db-table').forEach((option) => {\n option.removeAttribute('selected');\n });\n resetModalContainer.querySelector('.wpstg-button-unselect').innerHTML = 'Select All';\n // cache.get('.wpstg-db-table-checkboxes').prop('checked', false);\n this.isAllTablesChecked = false;\n }\n }\n}\n","import WpstgCloneStaging from './modules/wpstg-clone-staging.js';\nimport WpstgDirectoryNavigation from './modules/wpstg-directory-navigation.js';\nimport WpstgExcludeFilters from './modules/wpstg-exclude-filters.js';\nimport WpstgResetModal from './modules/wpstg-reset-modal.js';\nimport WpstgModal from './modules/wpstg-modal.js';\n\nvar WPStaging = (function($) {\n const that = {\n isCancelled: false,\n isFinished: false,\n getLogs: false,\n time: 1,\n executionTime: false,\n progressBar: 0,\n cloneExcludeFilters: null,\n directoryNavigator: null,\n notyf: new Notyf({\n duration: 10000,\n position: {\n x: 'center',\n y: 'bottom',\n },\n dismissible: true,\n types: [\n {\n type: 'warning',\n background: 'orange',\n icon: false,\n },\n ],\n }),\n };\n const cache = {elements: []};\n let timeout; let ajaxSpinner;\n\n /**\n * Get / Set Cache for Selector\n * @param {String} selector\n * @return {*}\n */\n cache.get = function(selector) {\n // It is already cached!\n if ($.inArray(selector, cache.elements) !== -1) {\n return cache.elements[selector];\n }\n\n // Create cache and return\n cache.elements[selector] = jQuery(selector);\n\n return cache.elements[selector];\n };\n\n /**\n * Refreshes given cache\n * @param {String} selector\n */\n cache.refresh = function(selector) {\n selector.elements[selector] = jQuery(selector);\n };\n\n /**\n * Show and Log Error Message\n * @param {String} message\n */\n const showError = function(message) {\n cache.get('#wpstg-try-again').css('display', 'inline-block');\n cache.get('#wpstg-cancel-cloning').text('Reset');\n cache.get('#wpstg-resume-cloning').show();\n cache.get('#wpstg-error-wrapper').show();\n cache.get('#wpstg-error-details').show().html(message);\n cache.get('#wpstg-removing-clone').removeClass('loading');\n cache.get('.wpstg-loader').hide();\n $('.wpstg--modal--process--generic-problem').show().html(message);\n };\n\n /**\n * Show warning during cloning or push process when closing tab or browser, or changing page\n * @param {beforeunload} event\n * @return {null}\n */\n that.warnIfClosingDuringProcess = function(event) {\n // Only some browsers show the message below, most say something like \"Changes you made may not be saved\" (Chrome) or \"You have unsaved changes. Exit?\"\n event.returnValue = 'You MUST leave this window open while cloning/pushing. Please wait...';\n return null;\n };\n\n /**\n *\n * @param obj\n * @return {boolean}\n */\n function isEmpty(obj) {\n for (const prop in obj) {\n if (obj.hasOwnProperty(prop)) {\n return false;\n }\n }\n\n return true;\n }\n\n /**\n *\n * @param response the error object\n * @param prependMessage Overwrite default error message at beginning\n * @param appendMessage Overwrite default error message at end\n * @returns void\n */\n\n const showAjaxFatalError = function(response, prependMessage, appendMessage) {\n prependMessage = prependMessage ? prependMessage + '<br/><br/>' : 'Something went wrong! <br/><br/>';\n 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.';\n\n if (response === false) {\n showError(prependMessage + ' Error: No response.' + appendMessage);\n window.removeEventListener('beforeunload', WPStaging.warnIfClosingDuringProcess);\n return;\n }\n\n if (typeof response.error !== 'undefined' && response.error) {\n console.error(response.message);\n showError(prependMessage + ' Error: ' + response.message + appendMessage);\n window.removeEventListener('beforeunload', WPStaging.warnIfClosingDuringProcess);\n return;\n }\n };\n\n /**\n *\n * @param response\n * @return {{ok}|*}\n */\n const handleFetchErrors = function(response) {\n if (!response.ok) {\n showError('Error: ' + response.status + ' - ' + response.statusText + '. Please try again or contact support.');\n }\n return response;\n };\n\n /** Hide and reset previous thrown visible errors */\n const resetErrors = function() {\n cache.get('#wpstg-error-details').hide().html('');\n };\n\n const slugify = function(url) {\n return url.toString()\n .toLowerCase()\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '')\n .replace(/\\s+/g, '-')\n .replace(/&/g, '-and-')\n .replace(/[^a-z0-9\\-]/g, '')\n .replace(/-+/g, '-')\n .replace(/^-*/, '')\n .replace(/-*$/, '')\n ;\n };\n\n\n /**\n * Common Elements\n */\n const elements = function() {\n const $workFlow = cache.get('#wpstg-workflow');\n let isAllChecked = true;\n let urlSpinner = ajaxurl.replace('/admin-ajax.php', '') + '/images/spinner';\n let timer;\n\n if (2 < window.devicePixelRatio) {\n urlSpinner += '-2x';\n }\n\n urlSpinner += '.gif';\n\n ajaxSpinner = '<img src=\\'\\'' + urlSpinner + '\\' alt=\\'\\' class=\\'ajax-spinner general-spinner\\' />';\n\n const getBaseValues = function() {\n const path = $('#wpstg-use-target-dir').data('base-path');\n const uri = $('#wpstg-use-target-hostname').data('base-uri');\n return {\n path,\n };\n };\n\n $workFlow\n // Check / Un-check All Database Tables New\n .on('click', '.wpstg-button-unselect', function(e) {\n e.preventDefault();\n\n if (false === isAllChecked) {\n cache.get('#wpstg_select_tables_cloning .wpstg-db-table').prop('selected', 'selected');\n cache.get('.wpstg-button-unselect').text('Unselect All');\n cache.get('.wpstg-db-table-checkboxes').prop('checked', true);\n isAllChecked = true;\n } else {\n cache.get('#wpstg_select_tables_cloning .wpstg-db-table').prop('selected', false);\n cache.get('.wpstg-button-unselect').text('Select All');\n cache.get('.wpstg-db-table-checkboxes').prop('checked', false);\n isAllChecked = false;\n }\n })\n\n /**\n * Select tables with certain tbl prefix | NEW\n * @param obj e\n * @returns {undefined}\n */\n .on('click', '.wpstg-button-select', function(e) {\n e.preventDefault();\n $('#wpstg_select_tables_cloning .wpstg-db-table').each(function() {\n if (wpstg.isMultisite == 1) {\n if ($(this).attr('name').match('^' + wpstg.tblprefix + '([^0-9])_*')) {\n $(this).prop('selected', 'selected');\n } else {\n $(this).prop('selected', false);\n }\n }\n\n if (wpstg.isMultisite == 0) {\n if ($(this).attr('name').match('^' + wpstg.tblprefix)) {\n $(this).prop('selected', 'selected');\n } else {\n $(this).prop('selected', false);\n }\n }\n });\n })\n // Expand Directories\n .on('click', '.wpstg-expand-dirs', function(e) {\n e.preventDefault();\n\n const $this = $(this);\n\n $this.siblings('.wpstg-subdir').slideToggle();\n })\n // When a directory checkbox is Selected\n .on('change', 'input.wpstg-check-dir', function() {\n const $directory = $(this).parent('.wpstg-dir');\n\n if (this.checked) {\n $directory.parents('.wpstg-dir').children('.wpstg-check-dir').prop('checked', true);\n $directory.find('.wpstg-expand-dirs').removeClass('disabled');\n $directory.find('.wpstg-subdir .wpstg-check-dir').prop('checked', true);\n } else {\n $directory.find('.wpstg-dir .wpstg-check-dir').prop('checked', false);\n $directory.find('.wpstg-expand-dirs, .wpstg-check-subdirs').addClass('disabled');\n $directory.find('.wpstg-check-subdirs').data('action', 'check').text('check');\n }\n })\n // When a directory name is Selected\n .on('change', 'href.wpstg-check-dir', function() {\n const $directory = $(this).parent('.wpstg-dir');\n\n if (this.checked) {\n $directory.parents('.wpstg-dir').children('.wpstg-check-dir').prop('checked', true);\n $directory.find('.wpstg-expand-dirs').removeClass('disabled');\n $directory.find('.wpstg-subdir .wpstg-check-dir').prop('checked', true);\n } else {\n $directory.find('.wpstg-dir .wpstg-check-dir').prop('checked', false);\n $directory.find('.wpstg-expand-dirs, .wpstg-check-subdirs').addClass('disabled');\n $directory.find('.wpstg-check-subdirs').data('action', 'check').text('check');\n }\n })\n // Check the max length of the clone name and if the clone name already exists\n .on('keyup', '#wpstg-new-clone-id', function() {\n // Hide previous errors\n document.getElementById('wpstg-error-details').style.display = 'none';\n\n // This request was already sent, clear it up!\n if ('number' === typeof (timer)) {\n clearInterval(timer);\n }\n\n const cloneID = this.value;\n\n timer = setTimeout(\n function() {\n ajax(\n {\n action: 'wpstg_check_clone',\n accessToken: wpstg.accessToken,\n nonce: wpstg.nonce,\n cloneID: cloneID,\n },\n function(response) {\n if (response.status === 'success') {\n cache.get('#wpstg-new-clone-id').removeClass('wpstg-error-input');\n cache.get('#wpstg-start-cloning').removeAttr('disabled');\n cache.get('#wpstg-clone-id-error').text('').hide();\n } else {\n cache.get('#wpstg-new-clone-id').addClass('wpstg-error-input');\n cache.get('#wpstg-start-cloning').prop('disabled', true);\n cache.get('#wpstg-clone-id-error').text(response.message).show();\n }\n },\n );\n },\n 500,\n );\n })\n // Restart cloning process\n .on('click', '#wpstg-start-cloning', function() {\n resetErrors();\n that.isCancelled = false;\n that.getLogs = false;\n that.progressBar = 0;\n })\n .on('input', '#wpstg-new-clone-id', function() {\n if ($('#wpstg-clone-directory').length < 1) {\n return;\n }\n\n const slug = slugify(this.value);\n const $targetDir = $('#wpstg-use-target-dir');\n const $targetUri = $('#wpstg-use-target-hostname');\n let path = $targetDir.data('base-path');\n let uri = $targetUri.data('base-uri');\n\n if (path) {\n path = path.replace(/\\/+$/g, '') + '/' + slug + '/';\n }\n\n if (uri) {\n uri = uri.replace(/\\/+$/g, '') + '/' + slug;\n }\n\n\n $('.wpstg-use-target-dir--value').text(path);\n $('.wpstg-use-target-hostname--value').text(uri);\n\n $targetDir.attr('data-path', path);\n $targetUri.attr('data-uri', uri);\n $('#wpstg_clone_dir').attr('placeholder', path);\n $('#wpstg_clone_hostname').attr('placeholder', uri);\n })\n .on('input', '#wpstg_clone_hostname', function() {\n if ($(this).val() === '' || validateTargetHost()) {\n $('#wpstg_clone_hostname_error').remove();\n return;\n }\n if (!validateTargetHost() && !$('#wpstg_clone_hostname_error').length) {\n $('#wpstg-clone-directory tr:last-of-type').after('<tr><td>&nbsp;</td><td><p id=\"wpstg_clone_hostname_error\" style=\"color: red;\">&nbsp;Invalid host name. Please provide it in a format like http://example.com</p></td></tr>');\n }\n })\n ;\n\n cloneActions();\n };\n\n /* @returns {boolean} */\n var validateTargetHost = function() {\n const the_domain = $('#wpstg_clone_hostname').val();\n\n if (the_domain === '') {\n return true;\n }\n\n const reg = /^http(s)?:\\/\\/.*$/;\n if (reg.test(the_domain) === false) {\n return false;\n }\n return true;\n };\n\n /**\n * Clone actions\n */\n var cloneActions = function() {\n const $workFlow = cache.get('#wpstg-workflow');\n\n $workFlow\n // Cancel cloning\n .on('click', '#wpstg-cancel-cloning', function() {\n if (!confirm('Are you sure you want to cancel cloning process?')) {\n return false;\n }\n\n const $this = $(this);\n\n $('#wpstg-try-again, #wpstg-home-link').hide();\n $this.prop('disabled', true);\n\n that.isCancelled = true;\n that.progressBar = 0;\n\n $('#wpstg-processing-status').text('Please wait...this can take up a while.');\n $('.wpstg-loader, #wpstg-show-log-button').hide();\n\n $this.parent().append(ajaxSpinner);\n\n cancelCloning();\n })\n // Resume cloning\n .on('click', '#wpstg-resume-cloning', function() {\n resetErrors();\n const $this = $(this);\n\n $('#wpstg-try-again, #wpstg-home-link').hide();\n\n that.isCancelled = false;\n\n $('#wpstg-processing-status').text('Try to resume cloning process...');\n $('#wpstg-error-details').hide();\n $('.wpstg-loader').show();\n\n $this.parent().append(ajaxSpinner);\n\n that.startCloning();\n })\n // Cancel update cloning\n .on('click', '#wpstg-cancel-cloning-update', function() {\n resetErrors();\n\n const $this = $(this);\n\n $('#wpstg-try-again, #wpstg-home-link').hide();\n $this.prop('disabled', true);\n\n that.isCancelled = true;\n\n $('#wpstg-cloning-result').text('Please wait...this can take up a while.');\n $('.wpstg-loader, #wpstg-show-log-button').hide();\n\n $this.parent().append(ajaxSpinner);\n\n cancelCloningUpdate();\n })\n // Restart cloning\n .on('click', '#wpstg-restart-cloning', function() {\n resetErrors();\n\n const $this = $(this);\n\n $('#wpstg-try-again, #wpstg-home-link').hide();\n $this.prop('disabled', true);\n\n that.isCancelled = true;\n\n $('#wpstg-cloning-result').text('Please wait...this can take up a while.');\n $('.wpstg-loader, #wpstg-show-log-button').hide();\n\n $this.parent().append(ajaxSpinner);\n\n restart();\n })\n // Delete clone - confirmation\n .on('click', '.wpstg-remove-clone[data-clone]', function(e) {\n resetErrors();\n e.preventDefault();\n\n const $existingClones = cache.get('#wpstg-existing-clones');\n\n $workFlow.removeClass('active');\n\n cache.get('.wpstg-loader').show();\n\n ajax(\n {\n action: 'wpstg_confirm_delete_clone',\n accessToken: wpstg.accessToken,\n nonce: wpstg.nonce,\n clone: $(this).data('clone'),\n },\n function(response) {\n cache.get('#wpstg-removing-clone').html(response);\n\n $existingClones.children('img').remove();\n\n cache.get('.wpstg-loader').hide();\n\n $('html, body').animate({\n // This logic is meant to be a \"scrollBottom\"\n scrollTop: $('#wpstg-remove-clone').offset().top - $(window).height() +\n $('#wpstg-remove-clone').height() + 50,\n }, 100);\n },\n 'HTML',\n );\n })\n // Delete clone - confirmed\n .on('click', '#wpstg-remove-clone', function(e) {\n resetErrors();\n e.preventDefault();\n\n cache.get('#wpstg-removing-clone').addClass('loading');\n\n cache.get('.wpstg-loader').show();\n\n deleteClone($(this).data('clone'));\n })\n // Cancel deleting clone\n .on('click', '#wpstg-cancel-removing', function(e) {\n e.preventDefault();\n $('.wpstg-clone').removeClass('active');\n cache.get('#wpstg-removing-clone').html('');\n })\n // Update\n .on('click', '.wpstg-execute-clone', function(e) {\n e.preventDefault();\n\n const clone = $(this).data('clone');\n\n $workFlow.addClass('loading');\n that.cloneExcludeFilters = null;\n ajax(\n {\n action: 'wpstg_scanning',\n clone: clone,\n accessToken: wpstg.accessToken,\n nonce: wpstg.nonce,\n },\n function(response) {\n if (response.length < 1) {\n showError(\n 'Something went wrong! Error: No response. 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.',\n );\n }\n\n const jsonResponse = tryParseJson(response);\n if (jsonResponse !== false && jsonResponse.success === false) {\n $workFlow.removeClass('loading');\n showErrorModal(jsonResponse);\n\n return;\n }\n\n $workFlow.removeClass('loading').html(response);\n // register check disk space function for clone update process.\n checkDiskSpace();\n that.directoryNavigator = new WpstgDirectoryNavigation('#wpstg-directories-listing', wpstg, that.notyf);\n that.cloneExcludeFilters = new WpstgExcludeFilters();\n that.switchStep(2);\n },\n 'HTML',\n );\n })\n // Reset Clone\n .on('click', '.wpstg-reset-clone', function(e) {\n e.preventDefault();\n const clone = $(this).data('clone');\n const resetModal = new WpstgResetModal(clone);\n const promise = resetModal.showModal();\n\n promise.then((result) => {\n if (result.value) {\n const dirNavigator = resetModal.getDirectoryNavigator();\n const exclFilters = resetModal.getExcludeFilters().getExcludeFilters();\n resetClone(clone, {\n includedTables: getIncludedTables(),\n excludeSizeRules: encodeURIComponent(exclFilters.sizes),\n excludeGlobRules: encodeURIComponent(exclFilters.globs),\n excludedDirectories: dirNavigator.getExcludedDirectories(),\n extraDirectories: dirNavigator.getExtraDirectoriesRootOnly(),\n });\n }\n });\n\n return;\n });\n };\n\n /**\n * Ajax Requests\n * @param Object data\n * @param Function callback\n * @param string dataType\n * @param bool showErrors\n * @param int tryCount\n * @param float incrementRatio\n */\n var ajax = function(data, callback, dataType, showErrors, tryCount, incrementRatio = null) {\n if ('undefined' === typeof (dataType)) {\n dataType = 'json';\n }\n\n if (false !== showErrors) {\n showErrors = true;\n }\n\n tryCount = 'undefined' === typeof (tryCount) ? 0 : tryCount;\n\n const retryLimit = 10;\n\n let retryTimeout = 10000 * tryCount;\n\n incrementRatio = parseInt(incrementRatio);\n if (!isNaN(incrementRatio)) {\n retryTimeout *= incrementRatio;\n }\n\n $.ajax({\n url: ajaxurl + '?action=wpstg_processing&_=' + (Date.now() / 1000),\n type: 'POST',\n dataType: dataType,\n cache: false,\n data: data,\n error: function(xhr, textStatus, errorThrown) {\n // try again after 10 seconds\n tryCount++;\n if (tryCount <= retryLimit) {\n setTimeout(function() {\n ajax(data, callback, dataType, showErrors, tryCount, incrementRatio);\n return;\n }, retryTimeout);\n } else {\n const errorCode = 'undefined' === typeof (xhr.status) ? 'Unknown' : xhr.status;\n showError(\n '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.',\n );\n }\n },\n success: function(data) {\n if ('function' === typeof (callback)) {\n callback(data);\n }\n },\n statusCode: {\n 404: function() {\n if (tryCount >= retryLimit) {\n 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.');\n }\n },\n 500: function() {\n if (tryCount >= retryLimit) {\n 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.');\n }\n },\n 504: function() {\n if (tryCount > retryLimit) {\n 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\\ ');\n }\n },\n 502: function() {\n if (tryCount >= retryLimit) {\n 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\\ ');\n }\n },\n 503: function() {\n if (tryCount >= retryLimit) {\n 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\\ ');\n }\n },\n 429: function() {\n if (tryCount >= retryLimit) {\n 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\\ ');\n }\n },\n 403: function() {\n if (tryCount >= retryLimit) {\n showError('Refresh page or login again! The process should be finished successfully. \\n\\ ');\n }\n },\n },\n });\n };\n\n /**\n * Next / Previous Step Clicks to Navigate Through Staging Job\n */\n const stepButtons = function() {\n const $workFlow = cache.get('#wpstg-workflow');\n\n $workFlow\n // Next Button\n .on('click', '.wpstg-next-step-link', function(e) {\n e.preventDefault();\n\n const $this = $(this);\n const isScan = false;\n\n if ($('#wpstg_clone_hostname').length && !validateTargetHost()) {\n $('#wpstg_clone_hostname').focus();\n return false;\n }\n\n if ($this.data('action') === 'wpstg_update' || $this.data('action') === 'wpstg_reset') {\n // Update / Reset Clone - confirmed\n let onlyUpdateMessage = '';\n if ($this.data('action') === 'wpstg_update') {\n onlyUpdateMessage = ' \\n\\nExclude all tables and folders you do not want to overwrite, first! \\n\\nDo not cancel the updating process! This can break your staging site. \\n\\n\\Create a backup of your staging website before you proceed.';\n }\n\n if (!confirm('STOP! This will overwrite your staging site with all selected data from the production site! This should be used only if you want to clone again your production site. Are you sure you want to do this?' + onlyUpdateMessage)) {\n return false;\n }\n }\n\n // Button is disabled\n if ($this.attr('disabled')) {\n return false;\n }\n\n if ($this.data('action') === 'wpstg_cloning') {\n // Verify External Database If Checked and Not Skipped\n if ($('#wpstg-ext-db').is(':checked')) {\n verifyExternalDatabase($this, $workFlow);\n return;\n }\n }\n\n proceedCloning($this, $workFlow);\n })\n // Previous Button\n .on('click', '.wpstg-prev-step-link', function(e) {\n e.preventDefault();\n cache.get('.wpstg-loader').removeClass('wpstg-finished');\n cache.get('.wpstg-loader').hide();\n loadOverview();\n });\n };\n\n /**\n * Get Included (Checked) Database Tables\n * @return {Array}\n */\n const getIncludedTables = function() {\n const includedTables = [];\n\n $('#wpstg_select_tables_cloning option:selected').each(function() {\n includedTables.push(this.value);\n });\n\n return includedTables;\n };\n\n /**\n * Get Excluded (Unchecked) Database Tables\n * Not used anymore!\n * @return {Array}\n */\n const getExcludedTables = function() {\n const excludedTables = [];\n\n $('.wpstg-db-table input:not(:checked)').each(function() {\n excludedTables.push(this.name);\n });\n\n return excludedTables;\n };\n\n /**\n * Verify External Database for Cloning\n */\n var verifyExternalDatabase = function($this, workflow) {\n cache.get('.wpstg-loader').show();\n ajax(\n {\n action: 'wpstg_database_verification',\n accessToken: wpstg.accessToken,\n nonce: wpstg.nonce,\n databaseUser: cache.get('#wpstg_db_username').val(),\n databasePassword: cache.get('#wpstg_db_password').val(),\n databaseServer: cache.get('#wpstg_db_server').val(),\n databaseDatabase: cache.get('#wpstg_db_database').val(),\n },\n function(response) {\n // Undefined Error\n if (false === response) {\n showError(\n 'Something went wrong! Error: No response.' +\n 'Please try again. If that does not help, ' +\n '<a href=\\'https://wp-staging.com/support/\\' target=\\'_blank\\'>open a support ticket</a> ',\n );\n cache.get('.wpstg-loader').hide();\n return;\n }\n\n // Throw Error\n if ('undefined' === typeof (response.success)) {\n showError(\n 'Something went wrong! Error: Invalid response.' +\n 'Please try again. If that does not help, ' +\n '<a href=\\'https://wp-staging.com/support/\\' target=\\'_blank\\'>open a support ticket</a> ',\n );\n cache.get('.wpstg-loader').hide();\n return;\n }\n\n if (response.success) {\n cache.get('.wpstg-loader').hide();\n proceedCloning($this, workflow);\n return;\n }\n\n if (response.error_type === 'comparison') {\n cache.get('.wpstg-loader').hide();\n let render = '<table style=\"width: 100%;\"><thead><tr><th>Property</th><th>Production DB</th><th>Staging DB</th><th>Status</th></tr></thead><tbody>';\n response.checks.forEach((x) => {\n let icon = '<i style=\"color: #00ff00\">✔</i>';\n if (x.production !== x.staging) {\n icon = '<i style=\"color: #ff0000\">❌</i>';\n }\n render += '<tr><td>' + x.name + '</td><td>' + x.production + '</td><td>' + x.staging + '</td><td>' + icon + '</td></tr>';\n });\n render += '</tbody></table><p>Note: Some mySQL properties do not match. You may proceed but the staging site may not work as expected.</p>';\n Swal.fire({\n title: 'Different Database Properties',\n icon: 'warning',\n html: render,\n width: '650px',\n focusConfirm: false,\n confirmButtonText: 'Proceed Anyway',\n showCancelButton: true,\n }).then(function(result) {\n if (result.value) {\n proceedCloning($this, workflow);\n }\n });\n return;\n }\n\n Swal.fire({\n title: 'Different Database Properties',\n icon: 'error',\n html: response.message,\n focusConfirm: true,\n confirmButtonText: 'Ok',\n showCancelButton: false,\n });\n cache.get('.wpstg-loader').hide();\n },\n 'json',\n false,\n );\n };\n\n /**\n * Get Cloning Step Data\n */\n const getCloningData = function() {\n if ('wpstg_cloning' !== that.data.action && 'wpstg_update' !== that.data.action && 'wpstg_reset' !== that.data.action) {\n return;\n }\n\n that.data.cloneID = $('#wpstg-new-clone-id').val() || new Date().getTime().toString();\n // Remove this to keep &_POST[] small otherwise mod_security will throw error 404\n // that.data.excludedTables = getExcludedTables();\n\n if (that.directoryNavigator !== null) {\n that.data.excludedDirectories = encodeURIComponent(that.directoryNavigator.getExcludedDirectories());\n that.data.extraDirectories = encodeURIComponent(that.directoryNavigator.getExtraDirectoriesRootOnly());\n }\n\n that.data.excludeGlobRules = '';\n that.data.excludeSizeRules = '';\n if (that.cloneExcludeFilters instanceof WpstgExcludeFilters) {\n const rules = that.cloneExcludeFilters.getExcludeFilters();\n that.data.excludeGlobRules = encodeURIComponent(rules.globs);\n that.data.excludeSizeRules = encodeURIComponent(rules.sizes);\n }\n\n that.data.includedTables = getIncludedTables();\n that.data.databaseServer = $('#wpstg_db_server').val();\n that.data.databaseUser = $('#wpstg_db_username').val();\n that.data.databasePassword = $('#wpstg_db_password').val();\n that.data.databaseDatabase = $('#wpstg_db_database').val();\n that.data.databasePrefix = $('#wpstg_db_prefix').val();\n const cloneDir = $('#wpstg_clone_dir').val();\n that.data.cloneDir = encodeURIComponent($.trim(cloneDir));\n that.data.cloneHostname = $('#wpstg_clone_hostname').val();\n that.data.emailsAllowed = $('#wpstg_allow_emails').is(':checked');\n that.data.uploadsSymlinked = $('#wpstg_symlink_upload').is(':checked');\n that.data.cleanPluginsThemes = $('#wpstg-clean-plugins-themes').is(':checked');\n that.data.cleanUploadsDir = $('#wpstg-clean-uploads').is(':checked');\n };\n\n var proceedCloning = function($this, workflow) {\n // Add loading overlay\n workflow.addClass('loading');\n\n // Prepare data\n that.data = {\n action: $this.data('action'),\n accessToken: wpstg.accessToken,\n nonce: wpstg.nonce,\n };\n\n // Cloning data\n getCloningData();\n\n sendCloningAjax(workflow);\n };\n\n var sendCloningAjax = function(workflow) {\n // Send ajax request\n ajax(\n that.data,\n function(response) {\n // Undefined Error\n if (false === response) {\n showError(\n 'Something went wrong!<br/><br/> Go to WP Staging > Settings and lower \\'File Copy Limit\\' and \\'DB Query Limit\\'. Also set \\'CPU Load Priority to low \\'' +\n 'and try again. If that does not help, ' +\n '<a href=\\'https://wp-staging.com/support/\\' target=\\'_blank\\'>open a support ticket</a> ',\n );\n }\n\n\n if (response.length < 1) {\n showError(\n 'Something went wrong! No response. Go to WP Staging > Settings and lower \\'File Copy Limit\\' and \\'DB Query Limit\\'. Also set \\'CPU Load Priority to low \\'' +\n 'and try again. If that does not help, ' +\n '<a href=\\'https://wp-staging.com/support/\\' target=\\'_blank\\'>open a support ticket</a> ',\n );\n }\n\n const jsonResponse = tryParseJson(response);\n if (jsonResponse !== false && jsonResponse.success === false) {\n workflow.removeClass('loading');\n showErrorModal(jsonResponse);\n\n return;\n }\n\n // Styling of elements\n workflow.removeClass('loading').html(response);\n that.cloneExcludeFilters = null;\n if (that.data.action === 'wpstg_scanning') {\n that.directoryNavigator = new WpstgDirectoryNavigation('#wpstg-directories-listing', wpstg, that.notyf);\n that.switchStep(2);\n that.cloneExcludeFilters = new WpstgExcludeFilters();\n } else if (that.data.action === 'wpstg_cloning' || that.data.action === 'wpstg_update' || that.data.action === 'wpstg_reset') {\n that.switchStep(3);\n }\n\n // Start cloning\n that.startCloning();\n },\n 'HTML',\n );\n };\n\n var showErrorModal = function(response) {\n const errorModal = new WpstgModal('wpstg_modal_error', wpstg);\n errorModal.show(Object.assign({\n title: 'Error',\n icon: 'error',\n html: wpstg.i18n['somethingWentWrong'],\n width: '500px',\n confirmButtonText: 'Ok',\n showCancelButton: false,\n }, response.swalOptions), {\n type: response.type,\n });\n };\n\n const tryParseJson = function(json) {\n // early bail if not string\n if (!json) {\n return false;\n }\n\n try {\n const object = JSON.parse(json);\n if (object && typeof object === 'object') {\n return object;\n }\n } catch (e) {\n // do nothing on catch\n }\n\n return false;\n };\n\n var resetClone = function(clone, excludeOptions) {\n that.data = {\n action: 'wpstg_reset',\n accessToken: wpstg.accessToken,\n nonce: wpstg.nonce,\n cloneID: clone,\n };\n\n that.data = {...that.data, ...excludeOptions};\n\n const $workFlow = cache.get('#wpstg-workflow');\n sendCloningAjax($workFlow);\n };\n\n /**\n * Loads Overview (first step) of Staging Job\n */\n var loadOverview = function() {\n const $workFlow = cache.get('#wpstg-workflow');\n\n $workFlow.addClass('loading');\n\n ajax(\n {\n action: 'wpstg_overview',\n accessToken: wpstg.accessToken,\n nonce: wpstg.nonce,\n },\n function(response) {\n if (response.length < 1) {\n showError(\n 'Something went wrong! No response. 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.',\n );\n }\n\n const $currentStep = cache.get('.wpstg-current-step');\n\n // Styling of elements\n $workFlow.removeClass('loading').html(response);\n },\n 'HTML',\n );\n\n that.switchStep(1);\n cache.get('.wpstg-step3-cloning').show();\n cache.get('.wpstg-step3-pushing').hide();\n };\n\n /**\n * Load Tabs\n */\n const tabs = function() {\n cache.get('#wpstg-workflow').on('click', '.wpstg-tab-header', function(e) {\n e.preventDefault();\n\n const $this = $(this);\n const $section = cache.get($this.data('id'));\n\n $this.toggleClass('expand');\n\n $section.slideToggle();\n\n if ($this.hasClass('expand')) {\n $this.find('.wpstg-tab-triangle').html('&#9660;');\n } else {\n $this.find('.wpstg-tab-triangle').html('&#9658;');\n }\n });\n };\n\n /**\n * Delete Clone\n * @param {String} clone\n */\n var deleteClone = function(clone) {\n const deleteDir = $('#deleteDirectory:checked').data('deletepath');\n\n ajax(\n {\n action: 'wpstg_delete_clone',\n clone: clone,\n accessToken: wpstg.accessToken,\n nonce: wpstg.nonce,\n excludedTables: getExcludedTables(),\n deleteDir: deleteDir,\n },\n function(response) {\n if (response) {\n showAjaxFatalError(response);\n\n // Finished\n if ('undefined' !== typeof response.delete && (response.delete === 'finished' || response.delete === 'unfinished')) {\n cache.get('#wpstg-removing-clone').removeClass('loading').html('');\n\n if (response.delete === 'finished') {\n $('.wpstg-clone#' + clone).remove();\n }\n\n if ($('.wpstg-clone').length < 1) {\n cache.get('#wpstg-existing-clones').find('h3').text('');\n }\n\n cache.get('.wpstg-loader').hide();\n return;\n }\n }\n // continue\n if (true !== response) {\n deleteClone(clone);\n return;\n }\n },\n );\n };\n\n /**\n * Cancel Cloning Process\n */\n var cancelCloning = function() {\n that.timer('stop');\n\n\n if (true === that.isFinished) {\n return true;\n }\n\n ajax(\n {\n action: 'wpstg_cancel_clone',\n clone: that.data.cloneID,\n accessToken: wpstg.accessToken,\n nonce: wpstg.nonce,\n },\n function(response) {\n if (response && 'undefined' !== typeof (response.delete) && response.delete === 'finished') {\n cache.get('.wpstg-loader').hide();\n // Load overview\n loadOverview();\n return;\n }\n\n if (true !== response) {\n // continue\n cancelCloning();\n return;\n }\n\n // Load overview\n loadOverview();\n },\n );\n };\n\n /**\n * Cancel Cloning Process\n */\n var cancelCloningUpdate = function() {\n if (true === that.isFinished) {\n return true;\n }\n\n ajax(\n {\n action: 'wpstg_cancel_update',\n clone: that.data.cloneID,\n accessToken: wpstg.accessToken,\n nonce: wpstg.nonce,\n },\n function(response) {\n if (response && 'undefined' !== typeof (response.delete) && response.delete === 'finished') {\n // Load overview\n loadOverview();\n return;\n }\n\n if (true !== response) {\n // continue\n cancelCloningUpdate();\n return;\n }\n\n // Load overview\n loadOverview();\n },\n );\n };\n\n /**\n * Cancel Cloning Process\n */\n var restart = function() {\n if (true === that.isFinished) {\n return true;\n }\n\n ajax(\n {\n action: 'wpstg_restart',\n // clone: that.data.cloneID,\n accessToken: wpstg.accessToken,\n nonce: wpstg.nonce,\n },\n function(response) {\n if (response && 'undefined' !== typeof (response.delete) && response.delete === 'finished') {\n // Load overview\n loadOverview();\n return;\n }\n\n if (true !== response) {\n // continue\n cancelCloningUpdate();\n return;\n }\n\n // Load overview\n loadOverview();\n },\n );\n };\n\n /**\n * Scroll the window log to bottom\n * @return void\n */\n const logscroll = function() {\n const $div = cache.get('.wpstg-log-details');\n if ('undefined' !== typeof ($div[0])) {\n $div.scrollTop($div[0].scrollHeight);\n }\n };\n\n /**\n * Append the log to the logging window\n * @param string log\n * @return void\n */\n const getLogs = function(log) {\n if (log != null && 'undefined' !== typeof (log)) {\n if (log.constructor === Array) {\n $.each(log, function(index, value) {\n if (value === null) {\n return;\n }\n if (value.type === 'ERROR') {\n cache.get('.wpstg-log-details').append('<span style=\"color:red;\">[' + value.type + ']</span>-' + '[' + value.date + '] ' + value.message + '</br>');\n } else {\n cache.get('.wpstg-log-details').append('[' + value.type + ']-' + '[' + value.date + '] ' + value.message + '</br>');\n }\n });\n } else {\n cache.get('.wpstg-log-details').append('[' + log.type + ']-' + '[' + log.date + '] ' + log.message + '</br>');\n }\n }\n logscroll();\n };\n\n /**\n * Check diskspace\n * @return string json\n */\n var checkDiskSpace = function() {\n cache.get('#wpstg-check-space').on('click', function(e) {\n cache.get('.wpstg-loader').show();\n const excludedDirectories = encodeURIComponent(that.directoryNavigator.getExcludedDirectories());\n const extraDirectories = encodeURIComponent(that.directoryNavigator.getExtraDirectoriesRootOnly());\n\n ajax(\n {\n action: 'wpstg_check_disk_space',\n accessToken: wpstg.accessToken,\n nonce: wpstg.nonce,\n excludedDirectories: excludedDirectories,\n extraDirectories: extraDirectories,\n },\n function(response) {\n if (false === response) {\n cache.get('#wpstg-clone-id-error').text('Can not detect required disk space').show();\n cache.get('.wpstg-loader').hide();\n return;\n }\n\n // Show required disk space\n cache.get('#wpstg-clone-id-error').html('Estimated necessary disk space: ' + response.usedspace + '<br> <span style=\"color:#444;\">Before you proceed ensure your account has enough free disk space to hold the entire instance of the production site. You can check the available space from your hosting account (cPanel or similar).</span>').show();\n cache.get('.wpstg-loader').hide();\n },\n 'json',\n false,\n );\n });\n };\n\n const mainTabs = function() {\n $('.wpstg--tab--header a[data-target]').on('click', function() {\n const $this = $(this);\n const target = $this.attr('data-target');\n const $wrapper = $this.parents('.wpstg--tab--wrapper');\n const $menuItems = $wrapper.find('.wpstg--tab--header a[data-target]');\n const $contents = $wrapper.find('.wpstg--tab--contents > .wpstg--tab--content');\n\n $contents.filter('.wpstg--tab--active:not(.wpstg--tab--active' + target + ')').removeClass('wpstg--tab--active');\n $menuItems.not($this).removeClass('wpstg--tab--active');\n $this.addClass('wpstg--tab--active');\n $(target).addClass('wpstg--tab--active');\n\n if ('#wpstg--tab--backup' === target) {\n that.backups.init();\n }\n\n if ('#wpstg--tab--database-backups' === target) {\n window.dispatchEvent(new Event('database-backups-tab'));\n }\n });\n };\n\n /**\n * Show or hide animated loading icon\n * @param isLoading bool\n */\n const isLoading = function(isLoading) {\n if (!isLoading || isLoading === false) {\n cache.get('.wpstg-loader').hide();\n } else {\n cache.get('.wpstg-loader').show();\n }\n };\n\n /**\n * Count up processing execution time\n * @param string status\n * @return html\n */\n that.timer = function(status) {\n if (status === 'stop') {\n const time = that.time;\n that.time = 1;\n clearInterval(that.executionTime);\n return that.convertSeconds(time);\n }\n\n\n that.executionTime = setInterval(function() {\n if (null !== document.getElementById('wpstg-processing-timer')) {\n document.getElementById('wpstg-processing-timer').innerHTML = 'Elapsed Time: ' + that.convertSeconds(that.time);\n }\n that.time++;\n if (status === 'stop') {\n that.time = 1;\n clearInterval(that.executionTime);\n }\n }, 1000);\n };\n\n /**\n * Convert seconds to hourly format\n * @param int seconds\n * @return string\n */\n that.convertSeconds = function(seconds) {\n const date = new Date(null);\n date.setSeconds(seconds); // specify value for SECONDS here\n return date.toISOString().substr(11, 8);\n };\n\n /**\n * Start Cloning Process\n * @type {Function}\n */\n that.startCloning = (function() {\n resetErrors();\n\n // Register function for checking disk space\n checkDiskSpace();\n\n if ('wpstg_cloning' !== that.data.action && 'wpstg_update' !== that.data.action && 'wpstg_reset' !== that.data.action) {\n return;\n }\n\n that.isCancelled = false;\n\n // Start the process\n start();\n\n // Functions\n // Start\n function start() {\n cache.get('.wpstg-loader').show();\n cache.get('#wpstg-cancel-cloning').text('Cancel');\n cache.get('#wpstg-resume-cloning').hide();\n cache.get('#wpstg-error-details').hide();\n\n\n // Clone Database\n setTimeout(function() {\n // cloneDatabase();\n window.addEventListener('beforeunload', WPStaging.warnIfClosingDuringProcess);\n processing();\n }, wpstg.delayReq);\n\n that.timer('start');\n }\n\n\n /**\n * Start ajax processing\n * @return string\n */\n var processing = function() {\n if (true === that.isCancelled) {\n window.removeEventListener('beforeunload', WPStaging.warnIfClosingDuringProcess);\n return false;\n }\n\n isLoading(true);\n\n let excludedDirectories = '';\n let extraDirectories = '';\n if (that.directoryNavigator !== null) {\n excludedDirectories = that.directoryNavigator.getExcludedDirectories();\n extraDirectories = that.directoryNavigator.getExtraDirectoriesRootOnly();\n }\n\n // Show logging window\n cache.get('.wpstg-log-details').show();\n\n WPStaging.ajax(\n {\n action: 'wpstg_processing',\n accessToken: wpstg.accessToken,\n nonce: wpstg.nonce,\n excludedTables: getExcludedTables(),\n excludedDirectories: encodeURIComponent(excludedDirectories),\n extraDirectories: encodeURIComponent(extraDirectories),\n },\n function(response) {\n showAjaxFatalError(response);\n\n // Add Log messages\n if ('undefined' !== typeof (response.last_msg) && response.last_msg) {\n getLogs(response.last_msg);\n }\n // Continue processing\n if (false === response.status) {\n progressBar(response);\n\n setTimeout(function() {\n cache.get('.wpstg-loader').show();\n processing();\n }, wpstg.delayReq);\n } else if (true === response.status && 'finished' !== response.status) {\n cache.get('#wpstg-error-details').hide();\n cache.get('#wpstg-error-wrapper').hide();\n progressBar(response, true);\n processing();\n } else if ('finished' === response.status || ('undefined' !== typeof (response.job_done) && response.job_done)) {\n window.removeEventListener('beforeunload', WPStaging.warnIfClosingDuringProcess);\n finish(response);\n }\n ;\n },\n 'json',\n false,\n );\n };\n\n // Finish\n function finish(response) {\n if (true === that.getLogs) {\n getLogs();\n }\n\n progressBar(response);\n\n // Add Log\n if ('undefined' !== typeof (response.last_msg)) {\n getLogs(response.last_msg);\n }\n\n cache.get('.wpstg-loader').hide();\n cache.get('#wpstg-processing-header').html('Processing Complete');\n $('#wpstg-processing-status').text('Succesfully finished');\n\n cache.get('#wpstg_staging_name').html(that.data.cloneID);\n cache.get('#wpstg-finished-result').show();\n cache.get('#wpstg-cancel-cloning').hide();\n cache.get('#wpstg-resume-cloning').hide();\n cache.get('#wpstg-cancel-cloning-update').prop('disabled', true);\n\n const $link1 = cache.get('#wpstg-clone-url-1');\n const $link = cache.get('#wpstg-clone-url');\n $link1.attr('href', response.url);\n $link1.html(response.url);\n $link.attr('href', response.url);\n\n cache.get('#wpstg-remove-clone').data('clone', that.data.cloneID);\n\n // Finished\n that.isFinished = true;\n that.timer('stop');\n\n\n cache.get('.wpstg-loader').hide();\n cache.get('#wpstg-processing-header').html('Processing Complete');\n\n // show alert\n let msg = wpstg.i18n.cloneResetComplete;\n if (that.data.action === 'wpstg_update') {\n msg = wpstg.i18n.cloneUpdateComplete;\n }\n\n if (that.data.action === 'wpstg_update' || that.data.action === 'wpstg_reset') {\n Swal.fire({\n title: '',\n icon: 'success',\n html: msg,\n width: '500px',\n focusConfirm: true,\n });\n }\n\n return false;\n }\n\n /**\n * Add percentage progress bar\n * @param object response\n * @return {Boolean}\n */\n var progressBar = function(response, restart) {\n if ('undefined' === typeof (response.percentage)) {\n return false;\n }\n\n if (response.job === 'database') {\n cache.get('#wpstg-progress-db').width(response.percentage * 0.2 + '%').html(response.percentage + '%');\n cache.get('#wpstg-processing-status').html(response.percentage.toFixed(0) + '%' + ' - Step 1 of 4 Cloning Database Tables...');\n }\n\n if (response.job === 'SearchReplace') {\n cache.get('#wpstg-progress-db').css('background-color', '#3bc36b');\n cache.get('#wpstg-progress-db').html('1. Database');\n // Assumption: All previous steps are done.\n // This avoids bugs where some steps are skipped and the progress bar is incomplete as a result\n cache.get('#wpstg-progress-db').width('20%');\n\n cache.get('#wpstg-progress-sr').width(response.percentage * 0.1 + '%').html(response.percentage + '%');\n cache.get('#wpstg-processing-status').html(response.percentage.toFixed(0) + '%' + ' - Step 2 of 4 Preparing Database Data...');\n }\n\n if (response.job === 'directories') {\n cache.get('#wpstg-progress-sr').css('background-color', '#3bc36b');\n cache.get('#wpstg-progress-sr').html('2. Data');\n cache.get('#wpstg-progress-sr').width('10%');\n\n cache.get('#wpstg-progress-dirs').width(response.percentage * 0.1 + '%').html(response.percentage + '%');\n cache.get('#wpstg-processing-status').html(response.percentage.toFixed(0) + '%' + ' - Step 3 of 4 Getting files...');\n }\n if (response.job === 'files') {\n cache.get('#wpstg-progress-dirs').css('background-color', '#3bc36b');\n cache.get('#wpstg-progress-dirs').html('3. Files');\n cache.get('#wpstg-progress-dirs').width('10%');\n\n cache.get('#wpstg-progress-files').width(response.percentage * 0.6 + '%').html(response.percentage + '%');\n cache.get('#wpstg-processing-status').html(response.percentage.toFixed(0) + '%' + ' - Step 4 of 4 Copy files...');\n }\n if (response.job === 'finish') {\n cache.get('#wpstg-progress-files').css('background-color', '#3bc36b');\n cache.get('#wpstg-progress-files').html('4. Copy Files');\n cache.get('#wpstg-progress-files').width('60%');\n\n cache.get('#wpstg-processing-status').html(response.percentage.toFixed(0) + '%' + ' - Cloning Process Finished');\n }\n };\n });\n\n that.switchStep = function(step) {\n cache.get('.wpstg-current-step')\n .removeClass('wpstg-current-step');\n cache.get('.wpstg-step' + step)\n .addClass('wpstg-current-step');\n };\n\n /**\n * Initiation\n * @type {Function}\n */\n that.init = (function() {\n loadOverview();\n elements();\n stepButtons();\n tabs();\n mainTabs();\n new WpstgCloneStaging();\n });\n\n /**\n * Ajax call\n * @type {ajax}\n */\n that.ajax = ajax;\n that.showError = showError;\n that.getLogs = getLogs;\n that.loadOverview = loadOverview;\n\n // TODO RPoC (too big, scattered and unorganized)\n that.backups = {\n type: null,\n isCancelled: false,\n processInfo: {\n title: null,\n interval: null,\n },\n modal: {\n create: {\n html: null,\n confirmBtnTxt: null,\n },\n process: {\n html: null,\n cancelBtnTxt: null,\n modal: null,\n },\n download: {\n html: null,\n },\n import: {\n html: null,\n btnTxtNext: null,\n btnTxtConfirm: null,\n btnTxtCancel: null,\n searchReplaceForm: null,\n file: null,\n containerUpload: null,\n containerFilesystem: null,\n setFile: (file, upload = true) => {\n const toUnit = (bytes) => {\n const i = Math.floor(Math.log(bytes) / Math.log(1024));\n return (bytes / Math.pow(1024, i)).toFixed(2) * 1 + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i];\n };\n\n if (!file) {\n return;\n }\n\n that.backups.modal.import.file = file;\n that.backups.modal.import.data.file = file.name;\n\n $('.wpstg--backup--import--selected-file').html(`${file.name} <br /> (${toUnit(file.size)})`).show();\n $('.wpstg--drag').hide();\n $('.wpstg--drag-or-upload').show();\n\n if (upload) {\n $('.wpstg--modal--actions .swal2-confirm').prop('disabled', true);\n that.backups.upload.start();\n }\n },\n baseDirectory: null,\n data: {\n file: null,\n search: [],\n replace: [],\n },\n },\n },\n messages: {\n WARNING: 'warning',\n ERROR: 'error',\n INFO: 'info',\n DEBUG: 'debug',\n CRITICAL: 'critical',\n data: {\n all: [], // TODO RPoC\n info: [],\n error: [],\n critical: [],\n warning: [],\n debug: [],\n },\n shouldWarn() {\n return that.backups.messages.data.error.length > 0 ||\n that.backups.messages.data.critical.length > 0\n ;\n },\n countByType(type = that.backups.messages.ERROR) {\n return that.backups.messages.data[type].length;\n },\n addMessage(message) {\n if (Array.isArray(message)) {\n message.forEach((item) => {\n that.backups.messages.addMessage(item);\n });\n return;\n }\n const type = message.type.toLowerCase() || 'info';\n if (!that.backups.messages.data[type]) {\n that.backups.messages.data[type] = [];\n }\n that.backups.messages.data.all.push(message); // TODO RPoC\n that.backups.messages.data[type].push(message);\n },\n reset() {\n that.backups.messages.data = {\n all: [],\n info: [],\n error: [],\n critical: [],\n warning: [],\n debug: [],\n };\n },\n },\n timer: {\n totalSeconds: 0,\n interval: null,\n start() {\n if (null !== that.backups.timer.interval) {\n return;\n }\n\n const prettify = (seconds) => {\n // If potentially anything can exceed 24h execution time than that;\n // const _seconds = parseInt(seconds, 10)\n // const hours = Math.floor(_seconds / 3600)\n // const minutes = Math.floor(_seconds / 60) % 60\n // seconds = _seconds % 60\n //\n // return [hours, minutes, seconds]\n // .map(v => v < 10 ? '0' + v : v)\n // .filter((v,i) => v !== '00' || i > 0)\n // .join(':')\n // ;\n // Are we sure we won't create anything that exceeds 24h execution time? If not then this;\n return `${(new Date(seconds * 1000)).toISOString().substr(11, 8)}`;\n };\n\n that.backups.timer.interval = setInterval(() => {\n $('.wpstg--modal--process--elapsed-time').text(prettify(that.backups.timer.totalSeconds));\n that.backups.timer.totalSeconds++;\n }, 1000);\n },\n stop() {\n that.backups.timer.totalSeconds = 0;\n if (that.backups.timer.interval) {\n clearInterval(that.backups.timer.interval);\n that.backups.timer.interval = null;\n }\n },\n },\n upload: {\n reader: null,\n file: null,\n iop: 1000 * 1024,\n uploadInfo(isShow) {\n const $containerUpload = $('.wpstg--modal--import--upload--process');\n const $containerUploader = $('.wpstg--uploader');\n if (isShow) {\n $containerUpload.css('display', 'flex');\n $containerUploader.hide();\n return;\n }\n\n $containerUploader.css('display', 'flex');\n $containerUpload.hide();\n },\n start() {\n that.backups.upload.reader = new FileReader();\n that.backups.upload.file = that.backups.modal.import.file;\n that.backups.upload.uploadInfo(true);\n that.backups.upload.sendChunk();\n },\n sendChunk(startsAt = 0) {\n if (!that.backups.upload.file) {\n return;\n }\n const isReset = startsAt < 1;\n const endsAt = startsAt + that.backups.upload.iop + 1;\n const blob = that.backups.upload.file.slice(startsAt, endsAt);\n that.backups.upload.reader.onloadend = function(event) {\n if (event.target.readyState !== FileReader.DONE) {\n return;\n }\n\n const body = new FormData();\n body.append('accessToken', wpstg.accessToken);\n body.append('nonce', wpstg.nonce);\n body.append('data', event.target.result);\n body.append('filename', that.backups.upload.file.name);\n body.append('reset', isReset ? '1' : '0');\n\n\n fetch(`${ajaxurl}?action=wpstg--backups--import--file-upload`, {\n method: 'POST',\n body,\n }).then(handleFetchErrors)\n .then((res) => res.json())\n .then((res) => {\n showAjaxFatalError(res, '', 'Submit an error report.');\n const writtenBytes = startsAt + that.backups.upload.iop;\n const percent = Math.floor((writtenBytes / that.backups.upload.file.size) * 100);\n if (endsAt >= that.backups.upload.file.size) {\n that.backups.upload.uploadInfo(false);\n isLoading(false);\n that.backups.switchModalToConfigure();\n return;\n }\n $('.wpstg--modal--import--upload--progress--title > span').text(percent);\n $('.wpstg--modal--import--upload--progress').css('width', `${percent}%`);\n that.backups.upload.sendChunk(endsAt);\n })\n .catch((e) => showAjaxFatalError(e, '', 'Submit an error report.'))\n ;\n };\n that.backups.upload.reader.readAsDataURL(blob);\n },\n },\n status: {\n hasResponse: null,\n reTryAfter: 5000,\n },\n init() {\n this.create();\n this.delete();\n this.edit();\n\n // noinspection JSIgnoredPromiseFromCall\n that.backups.fetchListing();\n\n $('body')\n .on('click', '.wpstg--backup--download', function() {\n const url = this.getAttribute('data-url');\n if (url.length > 0) {\n window.location.href = url;\n return;\n }\n that.backups.downloadModal({\n titleExport: this.getAttribute('data-title-export'),\n title: this.getAttribute('data-title'),\n id: this.getAttribute('data-id'),\n btnTxtCancel: this.getAttribute('data-btn-cancel-txt'),\n btnTxtConfirm: this.getAttribute('data-btn-download-txt'),\n });\n })\n .on('click', '.wpstg--backup--import', function() {\n // Clicked \"Import\" on the backup list\n that.backups.importModal();\n that.backups.modal.import.data.file = this.getAttribute('data-filePath');\n that.backups.switchModalToConfigure();\n // $('.wpstg--modal--actions .swal2-confirm').show();\n // $('.wpstg--modal--actions .swal2-confirm').prop('disabled', false);\n })\n .off('click', '#wpstg-import-backup')\n .on('click', '#wpstg-import-backup', function() {\n that.backups.importModal();\n })\n // Import\n .off('click', '.wpstg--backup--import--choose-option')\n .on('click', '.wpstg--backup--import--choose-option', function() {\n const $this = $(this);\n const $parent = $this.parent();\n if (!$parent.hasClass('wpstg--show-options')) {\n $parent.addClass('wpstg--show-options');\n $this.text($this.attr('data-txtChoose'));\n } else {\n $parent.removeClass('wpstg--show-options');\n $this.text($this.attr('data-txtOther'));\n }\n })\n .off('click', '.wpstg--modal--backup--import--search-replace--new')\n .on('click', '.wpstg--modal--backup--import--search-replace--new', function(e) {\n e.preventDefault();\n const $container = $(Swal.getContainer()).find('.wpstg--modal--backup--import--search-replace--input--container');\n const total = $container.find('.wpstg--modal--backup--import--search-replace--input-group').length;\n $container.append(that.backups.modal.import.searchReplaceForm.replace(/{i}/g, total));\n })\n .off('click', '.wpstg--modal--backup--import--search-replace--remove')\n .on('click', '.wpstg--modal--backup--import--search-replace--remove', function(e) {\n e.preventDefault();\n $(e.target).closest('.wpstg--modal--backup--import--search-replace--input-group').remove();\n })\n .off('input', '.wpstg--backup--import--search')\n .on('input', '.wpstg--backup--import--search', function() {\n const index = parseInt(this.getAttribute('data-index'));\n if (!isNaN(index)) {\n that.backups.modal.import.data.search[index] = this.value;\n }\n })\n .off('input', '.wpstg--backup--import--replace')\n .on('input', '.wpstg--backup--import--replace', function() {\n const index = parseInt(this.getAttribute('data-index'));\n if (!isNaN(index)) {\n that.backups.modal.import.data.replace[index] = this.value;\n }\n })\n // Other Options\n .off('click', '.wpstg--backup--import--option[data-option]')\n .on('click', '.wpstg--backup--import--option[data-option]', function() {\n const option = this.getAttribute('data-option');\n\n if (option === 'file') {\n $('input[type=\"file\"][name=\"wpstg--backup--import--upload--file\"]').trigger('click');\n return;\n }\n\n if (option === 'upload') {\n that.backups.modal.import.containerFilesystem.hide();\n that.backups.modal.import.containerUpload.show();\n }\n\n if (option !== 'filesystem') {\n return;\n }\n\n that.backups.modal.import.containerUpload.hide();\n const $containerFilesystem = that.backups.modal.import.containerFilesystem;\n $containerFilesystem.show();\n\n fetch(`${ajaxurl}?action=wpstg--backups--import--file-list&_=${Math.random()}&accessToken=${wpstg.accessToken}&nonce=${wpstg.nonce}`)\n .then(handleFetchErrors)\n .then((res) => res.json())\n .then((res) => {\n const $ul = $('.wpstg--modal--backup--import--filesystem ul');\n $ul.empty();\n\n if (!res || isEmpty(res)) {\n $ul.append(`<span id=\"wpstg--backups--import--file-list-empty\">`+ wpstg.i18n.noImportFileFound +`</span><br />`);\n $('.wpstg--modal--backup--import--search-replace--wrapper').hide();\n return;\n }\n\n $ul.append(`<span id=\"wpstg--backups--import--file-list\">`+ wpstg.i18n.selectFileToImport +`</span><br />`);\n res.forEach(function(file, index) {\n $ul.append(`\n<li data-filepath=\"${file.fullPath}\" class=\"wpstg--backups--import--file-list--sigle-item\">\n <ul class=\"wpstg-import-backup-more-info wpstg-import-backup-more-info-` + index + `\">\n <li style=\"font-weight: bold\">${file.backupName}</li>\n <li>Created on: ${file.dateCreatedFormatted}</li>\n <li>Size: ${file.size}</li>\n <li>\n <div class=\"wpstg-import-backup-contains-title\">This backup contains:</div>\n <ul class=\"wpstg-import-backup-contains\">\n ` + (file.isExportingDatabase ? '<li><span class=\"dashicons dashicons-database wpstg--tooltip\"><div class=\\'wpstg--tooltiptext\\'>Database</div></span></li>' : '') + `\n ` + (file.isExportingPlugins ? '<li><span class=\"dashicons dashicons-admin-plugins wpstg--tooltip\"><div class=\\'wpstg--tooltiptext\\'>Plugins</div></span></li>' : '') + `\n ` + (file.isExportingMuPlugins ? '<li><span class=\"dashicons dashicons-plugins-checked wpstg--tooltip\"><div class=\\'wpstg--tooltiptext\\'>Mu-plugins</div></span></li>' : '') + `\n ` + (file.isExportingThemes ? '<li><span class=\"dashicons dashicons-layout wpstg--tooltip\"><div class=\\'wpstg--tooltiptext\\'>Themes</div></span></li>' : '') + `\n ` + (file.isExportingUploads ? '<li><span class=\"dashicons dashicons-images-alt wpstg--tooltip\"><div class=\\'wpstg--tooltiptext\\'>Uploads</div></span></li>' : '') + `\n ` + (file.isExportingOtherWpContentFiles ? '<li><span class=\"dashicons dashicons-admin-generic wpstg--tooltip\"><div class=\\'wpstg--tooltiptext\\'>Other files in wp-content</div></span></li>' : '') + `\n </ul>\n </li>\n <li>Filename: ${file.name}</li>\n </ul>\n</li>\n`);\n });\n return res;\n })\n .catch((e) => showAjaxFatalError(e, '', 'Submit an error report.'))\n ;\n })\n .off('change', 'input[type=\"file\"][name=\"wpstg--backup--import--upload--file\"]')\n .on('change', 'input[type=\"file\"][name=\"wpstg--backup--import--upload--file\"]', function() {\n that.backups.modal.import.setFile(this.files[0] || null);\n })\n .off('change', 'input[type=\"radio\"][name=\"backup_import_file\"]')\n .on('change', 'input[type=\"radio\"][name=\"backup_import_file\"]', function() {\n $('.wpstg--modal--actions .swal2-confirm').show();\n $('.wpstg--modal--actions .swal2-confirm').prop('disabled', false);\n that.backups.modal.import.data.file = this.value;\n })\n // Drag & Drop\n .on('drag dragstart dragend dragover dragenter dragleave drop', '.wpstg--modal--backup--import--upload--container', function(e) {\n e.preventDefault();\n e.stopPropagation();\n })\n .on('dragover dragenter', '.wpstg--modal--backup--import--upload--container', function() {\n $(this).addClass('wpstg--has-dragover');\n })\n .on('dragleave dragend drop', '.wpstg--modal--backup--import--upload--container', function() {\n $(this).removeClass('wpstg--has-dragover');\n })\n .on('drop', '.wpstg--modal--backup--import--upload--container', function(e) {\n // Uploaded a file through the \"Import Backup modal\"\n that.backups.modal.import.setFile(e.originalEvent.dataTransfer.files[0] || null);\n })\n .on('click', '.wpstg--modal--backup--import--filesystem li', function(e) {\n // Selected an existing backup in the Import Backup modal\n const fullPath = $(e.target).closest('.wpstg--backups--import--file-list--sigle-item').data().filepath;\n if (!fullPath.length) {\n alert('Error: Could not get file path.');\n return;\n }\n that.backups.modal.import.data.file = fullPath;\n that.backups.switchModalToConfigure();\n // $('.wpstg--modal--actions .swal2-confirm').prop('disabled', false);\n // that.backups.modal.gotoStart();\n })\n .on('change', '.wpstg-advanced-options-site input[type=\"checkbox\"]', function(e) {\n /*\n * We use a timeout here to simulate an \"afterChange\" event.\n * This allows us to read from the DOM whether the checkbox is checked or not,\n * instead of having to read from the event, which would require a lengthier code\n * to account for all elements we might want to read.\n */\n setTimeout(function(e) {\n // Reset\n document.getElementById('exportUploadsWithoutDatabaseWarning').style.display = 'none';\n\n // Exporting Media Library without Database\n const databaseChecked = document.getElementById('includeDatabaseInBackup').checked;\n const mediaLibraryChecked = document.getElementById('includeMediaLibraryInBackup').checked;\n if (mediaLibraryChecked && !databaseChecked) {\n document.getElementById('exportUploadsWithoutDatabaseWarning').style.display = 'block';\n }\n }, 100);\n })\n ;\n },\n fetchListing(isResetErrors = true) {\n isLoading(true);\n\n if (isResetErrors) {\n resetErrors();\n }\n\n return fetch(`${ajaxurl}?action=wpstg--backups--listing&_=${Math.random()}&accessToken=${wpstg.accessToken}&nonce=${wpstg.nonce}`)\n .then(handleFetchErrors)\n .then((res) => res.json())\n .then((res) => {\n showAjaxFatalError(res, '', 'Submit an error report.');\n cache.get('#wpstg--tab--backup').html(res);\n isLoading(false);\n window.dispatchEvent(new Event('backupListingFinished'));\n return res;\n })\n .catch((e) => showAjaxFatalError(e, '', 'Submit an error report.'))\n ;\n },\n delete() {\n $('#wpstg--tab--backup')\n .off('click', '.wpstg-delete-backup[data-md5]')\n .on('click', '.wpstg-delete-backup[data-md5]', function(e) {\n e.preventDefault();\n resetErrors();\n\n if (!confirm('Are you sure you want to delete this backup?')) {\n return;\n }\n\n isLoading(true);\n cache.get('#wpstg-existing-backups').hide();\n const md5 = this.getAttribute('data-md5');\n that.ajax(\n {\n action: 'wpstg--backups--delete',\n md5: md5,\n accessToken: wpstg.accessToken,\n nonce: wpstg.nonce,\n },\n function(response) {\n showAjaxFatalError(response, '', ' Please submit an error report by using the REPORT ISSUE button.');\n isLoading(false);\n that.backups.fetchListing();\n },\n );\n })\n ;\n\n // Force delete if backup tables do not exist\n // TODO This is bloated, no need extra ID, use existing one?\n $('#wpstg-error-wrapper')\n .off('click', '#wpstg-backup-force-delete')\n .on('click', '#wpstg-backup-force-delete', function(e) {\n e.preventDefault();\n resetErrors();\n isLoading(true);\n const id = this.getAttribute('data-id');\n\n if (!confirm('Do you want to delete this backup ' + id + ' from the listed backups?')) {\n isLoading(false);\n return false;\n }\n\n that.ajax(\n {\n action: 'wpstg--backups--delete',\n id: id,\n accessToken: wpstg.accessToken,\n nonce: wpstg.nonce,\n },\n function(response) {\n showAjaxFatalError(response, '', ' Please submit an error report by using the REPORT ISSUE button.');\n // noinspection JSIgnoredPromiseFromCall\n that.backups.fetchListing();\n isLoading(false);\n },\n );\n })\n ;\n },\n create() {\n const prepareBackup = function(data) {\n WPStaging.ajax(\n {\n action: 'wpstg--backups--prepare-export',\n accessToken: wpstg.accessToken,\n nonce: wpstg.nonce,\n wpstgExportData: data,\n },\n function(response) {\n if (response.success) {\n that.backups.timer.start();\n\n createBackup();\n } else {\n showAjaxFatalError(response.data, '', 'Submit an error report.');\n }\n },\n 'json',\n false,\n 0,\n 1.25,\n );\n };\n const createBackup = function() {\n resetErrors();\n\n if (that.backups.isCancelled) {\n // Swal.close();\n return;\n }\n\n const statusStop = () => {\n clearInterval(that.backups.processInfo.interval);\n that.backups.processInfo.interval = null;\n };\n const status = () => {\n if (that.backups.processInfo.interval !== null) {\n return;\n }\n that.backups.processInfo.interval = setInterval(() => {\n if (true === that.backups.isCancelled) {\n statusStop();\n return;\n }\n\n if (that.backups.status.hasResponse === false) {\n return;\n }\n\n that.backups.status.hasResponse = false;\n fetch(`${ajaxurl}?action=wpstg--backups--status&accessToken=${wpstg.accessToken}&nonce=${wpstg.nonce}`)\n .then((res) => res.json())\n .then((res) => {\n that.backups.status.hasResponse = true;\n if (typeof res === 'undefined') {\n statusStop();\n }\n\n if (that.backups.processInfo.title === res.currentStatusTitle) {\n return;\n }\n\n that.backups.processInfo.title = res.currentStatusTitle;\n const $container = $(Swal.getContainer());\n $container.find('.wpstg--modal--process--title').text(res.currentStatusTitle);\n $container.find('.wpstg--modal--process--percent').text('0');\n })\n .catch((e) => {\n that.backups.status.hasResponse = true;\n showAjaxFatalError(e, '', 'Submit an error report.');\n })\n ;\n }, 5000);\n };\n WPStaging.ajax(\n {\n action: 'wpstg--backups--export',\n accessToken: wpstg.accessToken,\n nonce: wpstg.nonce,\n },\n function(response) {\n if (typeof response === 'undefined') {\n setTimeout(function() {\n createBackup();\n }, wpstg.delayReq);\n return;\n }\n\n that.backups.processResponse(response);\n if (!that.backups.processInfo.interval) {\n status();\n }\n\n if (response.status === false) {\n createBackup();\n } else if (response.status === true) {\n $('#wpstg--progress--status').text('Backup successfully created!');\n that.backups.type = null;\n if (that.backups.messages.shouldWarn()) {\n // noinspection JSIgnoredPromiseFromCall\n that.backups.fetchListing();\n that.backups.logsModal();\n return;\n }\n statusStop();\n Swal.close();\n that.backups.fetchListing()\n .then(() => {\n if (!response.backupMd5) {\n showError('Failed to get backup md5 from response');\n return;\n }\n\n // Wait for fetchListing to populate the DOM with the backup data that we want to read\n let $el = '';\n let timesWaited = 0;\n const intervalWaitForBackupInDom = setInterval(function() {\n timesWaited++;\n $el = $(`.wpstg--backup--download[data-md5=\"${response.backupMd5}\"]`);\n\n // Could not find element, let's try again...\n if (!$el.length) {\n if (timesWaited >= 10) {\n // Bail: We tried too many times and couldn't find.\n clearInterval(intervalWaitForBackupInDom);\n }\n return;\n }\n\n // Found it. No more need for the interval.\n clearInterval(intervalWaitForBackupInDom);\n\n const backupSize = response.hasOwnProperty('backupSize') ? ' (' + response.backupSize + ')' : '';\n\n that.backups.downloadModal({\n id: $el.data('id'),\n url: $el.data('url'),\n title: $el.data('title'),\n titleExport: $el.data('title-export'),\n btnTxtCancel: $el.data('btn-cancel-txt'),\n btnTxtConfirm: $el.data('btn-download-txt') + backupSize,\n });\n $('.wpstg--modal--download--logs--wrapper').show();\n const $logsContainer = $('.wpstg--modal--process--logs');\n that.backups.messages.data.all.forEach((message) => {\n const msgClass = `wpstg--modal--process--msg--${message.type.toLowerCase()}`;\n $logsContainer\n .append(`<p class=\"${msgClass}\">[${message.type}] - [${message.date}] - ${message.message}</p>`)\n ;\n });\n }, 200);\n })\n ;\n } else {\n setTimeout(function() {\n createBackup();\n }, wpstg.delayReq);\n }\n },\n 'json',\n false,\n 0, // Don't retry upon failure\n 1.25,\n );\n };\n\n const $body = $('body');\n\n $body\n .off('click', '.wpstg--tab--toggle')\n .on('click', '.wpstg--tab--toggle', function() {\n const $this = $(this);\n const $target = $($this.attr('data-target'));\n $target.toggle();\n if ($target.is(':visible')) {\n $this.find('span').text('▼');\n } else {\n $this.find('span').text('►');\n }\n })\n .off('change', '[name=\"includedDirectories\\[\\]\"], input#includeDatabaseInBackup, input#includeOtherFilesInWpContent')\n .on('change', '[type=\"checkbox\"][name=\"includedDirectories\\[\\]\"], input#includeDatabaseInBackup, input#includeOtherFilesInWpContent', function() {\n const isExportingAnyDir = $('[type=\"checkbox\"][name=\"includedDirectories\\[\\]\"]:checked').length > 0;\n const isExportingDatabase = $('input#includeDatabaseInBackup:checked').length === 1;\n const isExportingOtherFilesInWpContent = $('input#includeOtherFilesInWpContent:checked').length === 1;\n if (!isExportingAnyDir && !isExportingDatabase && !isExportingOtherFilesInWpContent) {\n $('.swal2-confirm').prop('disabled', true);\n } else {\n $('.swal2-confirm').prop('disabled', false);\n }\n })\n ;\n\n // Add backup name and notes\n $('#wpstg--tab--backup')\n .off('click', '#wpstg-new-backup')\n .on('click', '#wpstg-new-backup', async function(e) {\n resetErrors();\n e.preventDefault();\n that.backups.isCancelled = false;\n\n if (!that.backups.modal.create.html || !that.backups.modal.create.confirmBtnTxt) {\n const $newBackupModal = $('#wpstg--modal--backup--new');\n const html = $newBackupModal.html();\n const btnTxt = $newBackupModal.attr('data-confirmButtonText');\n that.backups.modal.create.html = html || null;\n that.backups.modal.create.confirmBtnTxt = btnTxt || null;\n $newBackupModal.remove();\n }\n\n const {value: formValues} = await Swal.fire({\n title: '',\n html: that.backups.modal.create.html,\n focusConfirm: false,\n confirmButtonText: that.backups.modal.create.confirmBtnTxt,\n showCancelButton: true,\n preConfirm: () => {\n const container = Swal.getContainer();\n\n return {\n name: container.querySelector('input[name=\"backup_name\"]').value || null,\n isExportingPlugins: container.querySelector('#includePluginsInBackup:checked') !== null,\n isExportingMuPlugins: container.querySelector('#includeMuPluginsInBackup:checked') !== null,\n isExportingThemes: container.querySelector('#includeThemesInBackup:checked') !== null,\n isExportingUploads: container.querySelector('#includeMediaLibraryInBackup:checked') !== null,\n isExportingOtherWpContentFiles: container.querySelector('#includeOtherFilesInWpContent:checked') !== null,\n isExportingDatabase: container.querySelector('#includeDatabaseInBackup:checked') !== null,\n };\n },\n });\n\n if (!formValues) {\n return;\n }\n\n that.backups.process({\n execute: () => {\n that.backups.messages.reset();\n prepareBackup(formValues);\n },\n });\n })\n ;\n },\n switchModalToConfigure() {\n that.backups.modal.import.containerUpload.hide();\n that.backups.modal.import.containerFilesystem.hide();\n that.backups.modal.import.containerConfigure.show();\n },\n // Edit backups name and notes\n edit() {\n $('#wpstg--tab--backup')\n .off('click', '.wpstg--backup--edit[data-md5]')\n .on('click', '.wpstg--backup--edit[data-md5]', async function(e) {\n e.preventDefault();\n\n const $this = $(this);\n const name = $this.data('name');\n const notes = $this.data('notes');\n\n const {value: formValues} = await Swal.fire({\n title: '',\n 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 `,\n focusConfirm: false,\n confirmButtonText: 'Update Backup',\n showCancelButton: true,\n preConfirm: () => ({\n name: document.getElementById('wpstg-backup-edit-name-input').value || null,\n notes: document.getElementById('wpstg-backup-edit-notes-textarea').value || null,\n }),\n });\n\n if (!formValues) {\n return;\n }\n\n that.ajax(\n {\n action: 'wpstg--backups--edit',\n accessToken: wpstg.accessToken,\n nonce: wpstg.nonce,\n md5: $this.data('md5'),\n name: formValues.name,\n notes: formValues.notes,\n },\n function(response) {\n showAjaxFatalError(response, '', 'Submit an error report.');\n // noinspection JSIgnoredPromiseFromCall\n that.backups.fetchListing();\n },\n );\n })\n ;\n },\n cancel() {\n that.backups.timer.stop();\n that.backups.isCancelled = true;\n Swal.close();\n setTimeout(() => that.ajax(\n {\n action: 'wpstg--backups--cancel',\n accessToken: wpstg.accessToken,\n nonce: wpstg.nonce,\n type: that.backups.type,\n },\n function(response) {\n showAjaxFatalError(response, '', 'Submit an error report.');\n },\n ), 500);\n },\n /**\n * If process.execute exists, process.data and process.onResponse is not used\n * process = { data: {}, onResponse: (resp) => {}, onAfterClose: () => {}, execute: () => {}, isShowCancelButton: bool }\n * @param {object} process\n */\n process(process) {\n if (typeof process.execute !== 'function' && (!process.data || !process.onResponse)) {\n Swal.close();\n showError('process.data and / or process.onResponse is not set');\n return;\n }\n\n // TODO move to backend and get the contents as xhr response?\n if (!that.backups.modal.process.html || !that.backups.modal.process.cancelBtnTxt) {\n const $modal = $('#wpstg--modal--backup--process');\n const html = $modal.html();\n const btnTxt = $modal.attr('data-cancelButtonText');\n that.backups.modal.process.html = html || null;\n that.backups.modal.process.cancelBtnTxt = btnTxt || null;\n $modal.remove();\n }\n\n $('body')\n .off('click', '.wpstg--modal--process--logs--tail')\n .on('click', '.wpstg--modal--process--logs--tail', function(e) {\n e.preventDefault();\n const container = Swal.getContainer();\n const $logs = $(container).find('.wpstg--modal--process--logs');\n $logs.toggle();\n if ($logs.is(':visible')) {\n container.childNodes[0].style.width = '100%';\n container.style['z-index'] = 9999;\n } else {\n container.childNodes[0].style.width = '600px';\n }\n })\n ;\n\n process.isShowCancelButton = false !== process.isShowCancelButton;\n\n that.backups.modal.process.modal = Swal.mixin({\n customClass: {\n cancelButton: 'wpstg--btn--cancel wpstg-blue-primary wpstg-link-btn',\n content: 'wpstg--process--content',\n },\n buttonsStyling: false,\n }).fire({\n html: that.backups.modal.process.html,\n cancelButtonText: that.backups.modal.process.cancelBtnTxt,\n showCancelButton: process.isShowCancelButton,\n showConfirmButton: false,\n allowOutsideClick: false,\n allowEscapeKey: false,\n width: 600,\n onRender: () => {\n const _btnCancel = Swal.getContainer().getElementsByClassName('swal2-cancel wpstg--btn--cancel')[0];\n const btnCancel = _btnCancel.cloneNode(true);\n _btnCancel.parentNode.replaceChild(btnCancel, _btnCancel);\n\n btnCancel.addEventListener('click', function(e) {\n if (confirm('Are You Sure? This will cancel the process!')) {\n Swal.close();\n }\n });\n\n if (typeof process.execute === 'function') {\n process.execute();\n return;\n }\n\n if (!process.data || !process.onResponse) {\n Swal.close();\n showError('process.data and / or process.onResponse is not set');\n return;\n }\n\n that.ajax(process.data, process.onResponse);\n },\n onAfterClose: () => typeof process.onAfterClose === 'function' && process.onAfterClose(),\n onClose: () => {\n that.backups.cancel();\n },\n });\n },\n processResponse(response, useTitle) {\n if (response === null) {\n Swal.close();\n showError('Invalid Response; null');\n throw new Error(`Invalid Response; ${response}`);\n }\n\n const $container = $(Swal.getContainer());\n const title = () => {\n if ((response.title || response.statusTitle) && useTitle === true) {\n $container.find('.wpstg--modal--process--title').text(response.title || response.statusTitle);\n }\n };\n const percentage = () => {\n if (response.percentage) {\n $container.find('.wpstg--modal--process--percent').text(response.percentage);\n }\n };\n const logs = () => {\n if (!response.messages) {\n return;\n }\n const $logsContainer = $container.find('.wpstg--modal--process--logs');\n const stoppingTypes = [\n that.backups.messages.ERROR,\n that.backups.messages.CRITICAL,\n ];\n const appendMessage = (message) => {\n if (Array.isArray(message)) {\n for (const item of message) {\n appendMessage(item);\n }\n return;\n }\n const msgClass = `wpstg--modal--process--msg--${message.type.toLowerCase()}`;\n $logsContainer.append(`<p class=\"${msgClass}\">[${message.type}] - [${message.date}] - ${message.message}</p>`);\n\n if (stoppingTypes.includes(message.type.toLowerCase())) {\n that.backups.cancel();\n setTimeout(that.backups.logsModal, 500);\n }\n };\n for (const message of response.messages) {\n if (!message) {\n continue;\n }\n that.backups.messages.addMessage(message);\n appendMessage(message);\n }\n\n if ($logsContainer.is(':visible')) {\n $logsContainer.scrollTop($logsContainer[0].scrollHeight);\n }\n\n if (!that.backups.messages.shouldWarn()) {\n return;\n }\n\n const $btnShowLogs = $container.find('.wpstg--modal--process--logs--tail');\n $btnShowLogs.html($btnShowLogs.attr('data-txt-bad'));\n\n $btnShowLogs\n .find('.wpstg--modal--logs--critical-count')\n .text(that.backups.messages.countByType(that.backups.messages.CRITICAL))\n ;\n\n $btnShowLogs\n .find('.wpstg--modal--logs--error-count')\n .text(that.backups.messages.countByType(that.backups.messages.ERROR))\n ;\n\n $btnShowLogs\n .find('.wpstg--modal--logs--warning-count')\n .text(that.backups.messages.countByType(that.backups.messages.WARNING))\n ;\n };\n\n title();\n percentage();\n logs();\n\n if (response.status === true && response.job_done === true) {\n that.backups.timer.stop();\n that.backups.isCancelled = true;\n }\n },\n requestData(notation, data) {\n const obj = {};\n const keys = notation.split('.');\n const lastIndex = keys.length - 1;\n keys.reduce((accumulated, current, index) => {\n return accumulated[current] = index >= lastIndex ? data : {};\n }, obj);\n return obj;\n },\n logsModal() {\n Swal.fire({\n html: `<div class=\"wpstg--modal--error--logs\" style=\"display:block\"></div><div class=\"wpstg--modal--process--logs\" style=\"display:block\"></div>`,\n width: '95%',\n onRender: () => {\n const $container = $(Swal.getContainer());\n $container[0].style['z-index'] = 9999;\n\n const $logsContainer = $container.find('.wpstg--modal--process--logs');\n const $errorContainer = $container.find('.wpstg--modal--error--logs');\n const $translations = $('#wpstg--js--translations');\n const messages = that.backups.messages;\n const title = $translations.attr('data-modal-logs-title')\n .replace('{critical}', messages.countByType(messages.CRITICAL))\n .replace('{errors}', messages.countByType(messages.ERROR))\n .replace('{warnings}', messages.countByType(messages.WARNING))\n ;\n\n $errorContainer.before(`<h3>${title}</h3>`);\n const warnings = [\n that.backups.messages.CRITICAL,\n that.backups.messages.ERROR,\n that.backups.messages.WARNING,\n ];\n\n if (!that.backups.messages.shouldWarn()) {\n $errorContainer.hide();\n }\n\n for (const message of messages.data.all) {\n const msgClass = `wpstg--modal--process--msg--${message.type.toLowerCase()}`;\n // TODO RPoC\n if (warnings.includes(message.type)) {\n $errorContainer.append(\n `<p class=\"${msgClass}\">[${message.type}] - [${message.date}] - ${message.message}</p>`,\n );\n }\n $logsContainer.append(\n `<p class=\"${msgClass}\">[${message.type}] - [${message.date}] - ${message.message}</p>`,\n );\n }\n },\n onOpen: (container) => {\n const $logsContainer = $(container).find('.wpstg--modal--process--logs');\n $logsContainer.scrollTop($logsContainer[0].scrollHeight);\n },\n });\n },\n downloadModal({title = null, titleExport = null, id = null, url = null, btnTxtCancel = 'Cancel', btnTxtConfirm = 'Download'}) {\n if (null === that.backups.modal.download.html) {\n const $el = $('#wpstg--modal--backup--download');\n that.backups.modal.download.html = $el.html();\n $el.remove();\n }\n\n const exportModal = () => Swal.fire({\n html: `<h2>${titleExport}</h2><span class=\"wpstg-loader\"></span>`,\n showCancelButton: false,\n showConfirmButton: false,\n onRender: () => {\n that.ajax(\n {\n action: 'wpstg--backups--export',\n accessToken: wpstg.accessToken,\n nonce: wpstg.nonce,\n id,\n },\n function(response) {\n if (!response || !response.success || !response.data || response.data.length < 1) {\n return;\n }\n\n const a = document.createElement('a');\n a.style.display = 'none';\n a.href = response.data;\n document.body.appendChild(a);\n a.click();\n document.body.removeChild(a);\n\n Swal.close();\n },\n );\n },\n });\n\n Swal.mixin({\n customClass: {\n cancelButton: 'wpstg--btn--cancel wpstg-blue-primary wpstg-link-btn',\n confirmButton: 'wpstg--btn--confirm wpstg-blue-primary wpstg-button wpstg-link-btn',\n actions: 'wpstg--modal--actions',\n },\n buttonsStyling: false,\n })\n .fire({\n icon: 'success',\n html: that.backups.modal.download.html.replace('{title}', title).replace('{btnTxtLog}', 'Show Logs'),\n cancelButtonText: btnTxtCancel,\n confirmButtonText: btnTxtConfirm,\n showCancelButton: true,\n showConfirmButton: true,\n })\n .then((isConfirm) => {\n if (!isConfirm || !isConfirm.value) {\n return;\n }\n\n if (url && url.length > 0) {\n window.location.href = url;\n return;\n }\n\n exportModal();\n })\n ;\n },\n importModal() {\n const importSiteBackup = (data) => {\n resetErrors();\n\n if (that.backups.isCancelled) {\n // Swal.close();\n return;\n }\n\n that.backups.timer.start();\n\n const statusStop = () => {\n clearInterval(that.backups.processInfo.interval);\n that.backups.processInfo.interval = null;\n };\n const status = () => {\n if (that.backups.processInfo.interval !== null) {\n return;\n }\n that.backups.processInfo.interval = setInterval(() => {\n if (true === that.backups.isCancelled) {\n statusStop();\n return;\n }\n\n if (that.backups.status.hasResponse === false) {\n return;\n }\n\n that.backups.status.hasResponse = false;\n fetch(`${ajaxurl}?action=wpstg--backups--status&process=restore&accessToken=${wpstg.accessToken}&nonce=${wpstg.nonce}`)\n .then((res) => res.json())\n .then((res) => {\n that.backups.status.hasResponse = true;\n if (typeof res === 'undefined') {\n statusStop();\n }\n\n if (that.backups.processInfo.title === res.currentStatusTitle) {\n return;\n }\n\n that.backups.processInfo.title = res.currentStatusTitle;\n const $container = $(Swal.getContainer());\n $container.find('.wpstg--modal--process--title').text(res.currentStatusTitle);\n $container.find('.wpstg--modal--process--percent').text('0');\n })\n .catch((e) => {\n that.backups.status.hasResponse = true;\n showAjaxFatalError(e, '', 'Submit an error report.');\n })\n ;\n }, 5000);\n };\n\n WPStaging.ajax(\n {\n action: 'wpstg--backups--import',\n accessToken: wpstg.accessToken,\n nonce: wpstg.nonce,\n },\n function(response) {\n if (typeof response === 'undefined') {\n setTimeout(function() {\n importSiteBackup(data);\n }, wpstg.delayReq);\n return;\n }\n\n that.backups.processResponse(response, true);\n if (!that.backups.processInfo.interval) {\n status();\n }\n\n if (response.status === false) {\n importSiteBackup(data);\n } else if (response.status === true) {\n $('#wpstg--progress--status').text('Backup successfully imported!');\n that.backups.type = null;\n if (that.backups.messages.shouldWarn()) {\n // noinspection JSIgnoredPromiseFromCall\n that.backups.fetchListing();\n that.backups.logsModal();\n return;\n }\n statusStop();\n const logEntries = $('.wpstg--modal--process--logs').get(1).innerHTML;\n const html = '<div class=\"wpstg--modal--process--logs\">' + logEntries + '</div>';\n const issueFound = html.includes('wpstg--modal--process--msg--warning') || html.includes('wpstg--modal--process--msg--error') ? 'Issues(s) found! ' : '';\n // var errorMessage = html.includes('wpstg--modal--process--msg--error') ? 'Errors(s) found! ' : '';\n // var Message = warningMessage + errorMessage;\n\n // Swal.close();\n Swal.fire({\n icon: 'success',\n title: 'Finished',\n html: 'System imported 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,\n },\n );\n\n // noinspection JSIgnoredPromiseFromCall\n that.backups.fetchListing();\n } else {\n setTimeout(function() {\n importSiteBackup(data);\n }, wpstg.delayReq);\n }\n },\n 'json',\n false,\n 0, // Don't retry upon failure\n 1.25,\n );\n };\n\n if (!that.backups.modal.import.html) {\n const $modal = $('#wpstg--modal--backup--import');\n\n // Search & Replace Form\n const $form = $modal.find('.wpstg--modal--backup--import--search-replace--input--container');\n that.backups.modal.import.searchReplaceForm = $form.html();\n $form.find('.wpstg--modal--backup--import--search-replace--input-group').remove();\n $form.html(that.backups.modal.import.searchReplaceForm.replace(/{i}/g, 0));\n\n that.backups.modal.import.html = $modal.html();\n that.backups.modal.import.baseDirectory = $modal.attr('data-baseDirectory');\n that.backups.modal.import.btnTxtNext = $modal.attr('data-nextButtonText');\n that.backups.modal.import.btnTxtConfirm = $modal.attr('data-confirmButtonText');\n that.backups.modal.import.btnTxtCancel = $modal.attr('data-cancelButtonText');\n $modal.remove();\n }\n\n that.backups.modal.import.data.search = [];\n that.backups.modal.import.data.replace = [];\n\n const $btnConfirm = null;\n Swal\n .mixin({\n customClass: {\n confirmButton: 'wpstg--btn--confirm wpstg-blue-primary wpstg-button wpstg-link-btn',\n cancelButton: 'wpstg--btn--cancel wpstg-blue-primary wpstg-link-btn',\n actions: 'wpstg--modal--actions',\n },\n buttonsStyling: false,\n // progressSteps: ['1', '2']\n })\n .queue([{\n html: that.backups.modal.import.html,\n confirmButtonText: that.backups.modal.import.btnTxtNext,\n showCancelButton: false,\n showConfirmButton: true,\n showLoaderOnConfirm: true,\n width: 650,\n onRender() {\n // $('.wpstg--modal--actions .swal2-confirm').hide();\n\n // todo: hide this again\n $('.wpstg--modal--actions .swal2-confirm').show();\n $('.wpstg--modal--actions .swal2-confirm').prop('disabled', false);\n\n that.backups.modal.import.containerUpload = $('.wpstg--modal--backup--import--upload');\n that.backups.modal.import.containerFilesystem = $('.wpstg--modal--backup--import--filesystem');\n that.backups.modal.import.containerConfigure = $('.wpstg--modal--backup--import--configure');\n },\n preConfirm() {\n const body = new FormData;\n body.append('accessToken', wpstg.accessToken);\n body.append('nonce', wpstg.nonce);\n body.append('filePath', that.backups.modal.import.data.file);\n\n that.backups.modal.import.data.search.forEach((item, index) => {\n body.append(`search[${index}]`, item);\n });\n that.backups.modal.import.data.replace.forEach((item, index) => {\n body.append(`replace[${index}]`, item);\n });\n\n return fetch(`${ajaxurl}?action=wpstg--backups--import--file-info`, {\n method: 'POST',\n body,\n }).then(handleFetchErrors)\n .then((res) => res.json())\n .then((html) => {\n return Swal.insertQueueStep({\n html: html,\n confirmButtonText: that.backups.modal.import.btnTxtConfirm,\n cancelButtonText: that.backups.modal.import.btnTxtCancel,\n showCancelButton: true,\n });\n })\n .catch((e) => showAjaxFatalError(e, '', 'Submit an error report.'))\n ;\n },\n }])\n .then((res) => {\n if (!res || !res.value || !res.value[1] || res.value[1] !== true) {\n return;\n }\n\n that.backups.isCancelled = false;\n const data = that.backups.modal.import.data;\n data['file'] = that.backups.modal.import.baseDirectory + data['file'];\n\n WPStaging.ajax(\n {\n action: 'wpstg--backups--prepare-import',\n accessToken: wpstg.accessToken,\n nonce: wpstg.nonce,\n wpstgImportData: data,\n },\n function(response) {\n if (response.success) {\n that.backups.process({\n execute: () => {\n that.backups.messages.reset();\n importSiteBackup(data);\n },\n });\n } else {\n showAjaxFatalError(response.data, '', 'Submit an error report.');\n }\n },\n 'json',\n false,\n 0,\n 1.25,\n );\n });\n },\n };\n\n window.addEventListener('backupListingFinished', function() {\n fetch(`${ajaxurl}?action=wpstg--backups--import--file-list&_=${Math.random()}&accessToken=${wpstg.accessToken}&nonce=${wpstg.nonce}&withTemplate=true`)\n .then(handleFetchErrors)\n .then((res) => res.json())\n .then((res) => {\n const $ul = $('.wpstg-backup-list ul');\n $ul.empty();\n $ul.html(res);\n })\n .catch((e) => showAjaxFatalError(e, '', 'Submit an error report.'))\n ;\n });\n\n return that;\n})(jQuery);\n\njQuery(document).ready(function() {\n WPStaging.init();\n // This is necessary to make WPStaging var accessibile in WP Staging PRO js script\n window.WPStaging = WPStaging;\n});\n\n/**\n * Report Issue modal\n */\njQuery(document).ready(function($) {\n $('#wpstg-report-issue-button').on('click', function(e) {\n $('.wpstg-report-issue-form').toggleClass('wpstg-report-show');\n e.preventDefault();\n });\n\n $('body').on('click', '#wpstg-backups-report-issue-button', function(e) {\n $('.wpstg-report-issue-form').toggleClass('wpstg-report-show');\n e.preventDefault();\n });\n\n $('#wpstg-report-cancel').on('click', function(e) {\n $('.wpstg-report-issue-form').removeClass('wpstg-report-show');\n e.preventDefault();\n });\n\n /*\n * Close Success Modal\n */\n\n $('body').on('click', '#wpstg-success-button', function(e) {\n e.preventDefault();\n $('.wpstg-report-issue-form').removeClass('wpstg-report-show');\n });\n\n function sendIssueReport(button, forceSend = 'false') {\n const spinner = button.next();\n const email = $('.wpstg-report-email').val();\n const hosting_provider = $('.wpstg-report-hosting-provider').val();\n const message = $('.wpstg-report-description').val();\n const syslog = $('.wpstg-report-syslog').is(':checked');\n const terms = $('.wpstg-report-terms').is(':checked');\n\n button.attr('disabled', true);\n spinner.css('visibility', 'visible');\n\n $.ajax({\n url: ajaxurl,\n type: 'POST',\n dataType: 'json',\n async: true,\n data: {\n 'action': 'wpstg_send_report',\n 'accessToken': wpstg.accessToken,\n 'nonce': wpstg.nonce,\n 'wpstg_email': email,\n 'wpstg_provider': hosting_provider,\n 'wpstg_message': message,\n 'wpstg_syslog': +syslog,\n 'wpstg_terms': +terms,\n 'wpstg_force_send': forceSend,\n },\n }).done(function(data) {\n button.attr('disabled', false);\n spinner.css('visibility', 'hidden');\n\n if (data.errors.length > 0) {\n $('.wpstg-report-issue-form .wpstg-message').remove();\n\n let errorMessage = $('<div />').addClass('wpstg-message wpstg-error-message');\n $.each(data.errors, function(key, value) {\n if (value.status === 'already_submitted') {\n errorMessage = '';\n Swal.fire({\n title: '',\n customClass: {\n container: 'wpstg-issue-resubmit-confirmation',\n },\n icon: 'warning',\n html: value.message,\n showCloseButton: true,\n showCancelButton: true,\n focusConfirm: false,\n confirmButtonText: 'Yes',\n cancelButtonText: 'No',\n }).then((result) => {\n if (result.isConfirmed) {\n sendIssueReport(button, 'true');\n }\n });\n } else {\n errorMessage.append('<p>' + value + '</p>');\n }\n });\n\n $('.wpstg-report-issue-form').prepend(errorMessage);\n } else {\n const successMessage = $('<div />').addClass('wpstg-message wpstg-success-message');\n successMessage.append('<p>Thanks for submitting your request! You should receive an auto reply mail with your ticket ID immediately for confirmation!<br><br>If you do not get that mail please contact us directly at <strong>support@wp-staging.com</strong></p>');\n\n $('.wpstg-report-issue-form').html(successMessage);\n $('.wpstg-success-message').append('<div style=\"float:right;margin-top:10px;\"><a id=\"wpstg-success-button\" href=\"#\">Close</a></div>');\n\n // Hide message\n setTimeout(function() {\n $('.wpstg-report-issue-form').removeClass('wpstg-report-active');\n }, 2000);\n }\n });\n }\n\n $('#wpstg-report-submit').on('click', function(e) {\n const self = $(this);\n sendIssueReport(self, 'false');\n e.preventDefault();\n });\n\n // Open/close actions drop down menu\n $(document).on('click', '.wpstg-dropdown>.wpstg-dropdown-toggler', function(e) {\n e.preventDefault();\n $(e.target).next('.wpstg-dropdown-menu').toggleClass('shown');\n });\n\n // Close action drop down menu if clicked anywhere outside\n document.addEventListener('click', function(event) {\n const isClickInside = event.target.closest('.wpstg-dropdown-toggler');\n if (!isClickInside) {\n const dropDown = document.getElementsByClassName('wpstg-dropdown-menu');\n for (let i = 0; i < dropDown.length; i++) {\n dropDown[i].classList.remove('shown');\n }\n }\n });\n});\n"],"names":["qs","selector","document","querySelector","all","querySelectorAll","addEvent","parent","evt","handler","addEventListener","event","target","matches","closest","slideDown","element","duration","style","display","overflow","height","offsetHeight","transitionProperty","transitionDuration","setTimeout","window","removeProperty","slideUp","getNextSibling","sibling","nextElementSibling","getParents","result","parentElement","push","WpstgCloneStaging","pageWrapperId","wpstgObject","wpstg","pageWrapper","dom","enableButtonId","enableAction","notyf","Notyf","position","x","y","dismissible","types","type","background","icon","init","addEvents","sendRequest","action","fetch","ajaxUrl","method","credentials","body","URLSearchParams","accessToken","nonce","headers","then","response","ok","json","Promise","reject","data","success","location","reload","message","error","i18n","console","warn","WpstgDirectoryNavigation","directoryListingSelector","directoryListingContainer","dirCheckboxSelector","dirExpandSelector","unselectAllDirsSelector","selectDefaultDirsSelector","fetchChildrenAction","currentCheckboxElement","currentParentDiv","currentLoader","existingExcludes","excludedDirectories","isDefaultSelected","log","preventDefault","toggleDirExpand","unselectAll","selectDefault","parseExcludes","previousSibling","getAttribute","dirPath","value","isChecked","checked","forceDefault","setAttribute","dirContainer","createElement","classList","add","innerHTML","JSON","parse","directoryListing","appendChild","alert","getExcludedDirectories","forEach","isParentExcluded","exclude","isExcludeScanned","join","settings","directorySeparator","path","isParentAlreadyExcluded","dir","startsWith","getExtraDirectoriesRootOnly","extraDirectories","extraDirectoriesTextArea","extraCustomDirectories","split","concat","length","WpstgExcludeFilters","excludeFilterContainerSelector","excludeContainer","excludeTableBody","addFileSizeExclude","addFileExtExclude","addFileNameExclude","addDirNameExclude","clearExcludes","removeExclude","addExcludeRuleRow","templateName","excludeRowTemplate","clone","content","cloneNode","excludeRow","e","removeChild","trim","getExcludeFilters","globExcludes","sizeExcludes","sizeCompares","sizeSizes","sizeByte","Object","entries","key","sizeInput","extensionInputs","ext","cleanStringForGlob","fileNamesPos","fileNames","fileInput","fileName","dirNamesPos","dirNames","dirInput","dirName","filter","onlyUnique","index","self","indexOf","replace","WpstgModal","confirmAction","show","swalOptions","additionalParams","callback","Swal","fire","triggerConfirmAction","assign","WpstgResetModal","cloneID","workflowSelector","fetchExcludeSettingsAction","modalErrorAction","workflow","resetButtonClass","resetModalContainerClass","resetTabSelector","directoryNavigator","excludeFilters","isAllTablesChecked","resetModalContainer","toggleContent","selectDefaultTables","toggleTableSelection","toggleDirectoryNavigation","updateDirectorySelection","contentId","tabTriangle","isCollapsed","contains","transform","remove","showModal","swalPromise","loadModal","fetchCloneExcludes","title","html","getAjaxLoader","width","focusConfirm","customClass","confirmButton","container","confirmButtonText","resetClone","showCancelButton","job","errorModal","modal","renderError","getDirectoryNavigator","wpstgIcon","cbElement","subDirectories","parElem","i","children","options","multisitePattern","tblprefix","singleSitePattern","option","name","isMultisite","match","removeAttribute","WPStaging","$","that","isCancelled","isFinished","getLogs","time","executionTime","progressBar","cloneExcludeFilters","cache","elements","ajaxSpinner","get","inArray","jQuery","refresh","showError","css","text","removeClass","hide","warnIfClosingDuringProcess","returnValue","isEmpty","obj","prop","hasOwnProperty","showAjaxFatalError","prependMessage","appendMessage","removeEventListener","handleFetchErrors","status","statusText","resetErrors","slugify","url","toString","toLowerCase","normalize","$workFlow","isAllChecked","urlSpinner","ajaxurl","timer","devicePixelRatio","on","each","attr","$this","siblings","slideToggle","$directory","parents","find","addClass","getElementById","clearInterval","ajax","removeAttr","slug","$targetDir","$targetUri","uri","val","validateTargetHost","after","cloneActions","the_domain","reg","test","confirm","append","cancelCloning","startCloning","cancelCloningUpdate","restart","$existingClones","animate","scrollTop","offset","top","deleteClone","jsonResponse","tryParseJson","showErrorModal","checkDiskSpace","switchStep","resetModal","promise","dirNavigator","exclFilters","includedTables","getIncludedTables","excludeSizeRules","encodeURIComponent","sizes","excludeGlobRules","globs","dataType","showErrors","tryCount","incrementRatio","retryLimit","retryTimeout","parseInt","isNaN","Date","now","xhr","textStatus","errorThrown","errorCode","statusCode","stepButtons","focus","onlyUpdateMessage","is","verifyExternalDatabase","proceedCloning","loadOverview","getExcludedTables","excludedTables","databaseUser","databasePassword","databaseServer","databaseDatabase","error_type","render","checks","production","staging","getCloningData","getTime","rules","databasePrefix","cloneDir","cloneHostname","emailsAllowed","uploadsSymlinked","cleanPluginsThemes","cleanUploadsDir","sendCloningAjax","object","excludeOptions","tabs","$section","toggleClass","hasClass","deleteDir","logscroll","$div","scrollHeight","constructor","Array","date","usedspace","mainTabs","$wrapper","$menuItems","$contents","not","backups","dispatchEvent","Event","isLoading","convertSeconds","setInterval","seconds","setSeconds","toISOString","substr","start","processing","delayReq","last_msg","job_done","finish","$link1","$link","msg","cloneResetComplete","cloneUpdateComplete","percentage","toFixed","step","processInfo","interval","create","confirmBtnTxt","process","cancelBtnTxt","download","btnTxtNext","btnTxtConfirm","btnTxtCancel","searchReplaceForm","file","containerUpload","containerFilesystem","setFile","upload","toUnit","bytes","Math","floor","pow","size","baseDirectory","search","messages","WARNING","ERROR","INFO","DEBUG","CRITICAL","info","critical","warning","debug","shouldWarn","countByType","addMessage","isArray","item","reset","totalSeconds","prettify","stop","reader","iop","uploadInfo","isShow","$containerUpload","$containerUploader","FileReader","sendChunk","startsAt","isReset","endsAt","blob","slice","onloadend","readyState","DONE","FormData","res","writtenBytes","percent","switchModalToConfigure","readAsDataURL","hasResponse","reTryAfter","edit","fetchListing","href","downloadModal","titleExport","id","importModal","off","$parent","$container","getContainer","total","trigger","$containerFilesystem","random","$ul","empty","noImportFileFound","selectFileToImport","fullPath","backupName","dateCreatedFormatted","isExportingDatabase","isExportingPlugins","isExportingMuPlugins","isExportingThemes","isExportingUploads","isExportingOtherWpContentFiles","files","stopPropagation","originalEvent","dataTransfer","filepath","databaseChecked","mediaLibraryChecked","isResetErrors","md5","prepareBackup","wpstgExportData","createBackup","statusStop","currentStatusTitle","processResponse","logsModal","close","backupMd5","$el","timesWaited","intervalWaitForBackupInDom","backupSize","$logsContainer","msgClass","$body","$target","toggle","isExportingAnyDir","isExportingOtherFilesInWpContent","$newBackupModal","btnTxt","preConfirm","formValues","execute","containerConfigure","notes","cancel","onResponse","$modal","$logs","childNodes","isShowCancelButton","mixin","cancelButton","buttonsStyling","cancelButtonText","showConfirmButton","allowOutsideClick","allowEscapeKey","onRender","_btnCancel","getElementsByClassName","btnCancel","parentNode","replaceChild","onAfterClose","onClose","useTitle","Error","statusTitle","logs","stoppingTypes","includes","$btnShowLogs","requestData","notation","keys","lastIndex","reduce","accumulated","current","$errorContainer","$translations","before","warnings","onOpen","exportModal","a","click","actions","isConfirm","importSiteBackup","logEntries","issueFound","$form","queue","showLoaderOnConfirm","insertQueueStep","wpstgImportData","ready","sendIssueReport","button","forceSend","spinner","next","email","hosting_provider","syslog","terms","async","done","errors","errorMessage","showCloseButton","isConfirmed","prepend","successMessage","isClickInside","dropDown"],"mappings":"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