Version Description
- Feat: Compatible up to WordPress 5.7.2
- Enh: Preserve directories/tables selection and excludes rules for RESET and UPDATE process #809
- Enh: If any wpstg process is running allow to stop that process within RESET modal #942
- Fix: Fix multisite subsite capabilities on the staging site #852
- Fix: Properly resets the properties between Cloning tasks #896
- Fix: Avoid PHP warning when building version of missing asset file #929
- Fix: Make RESET modal show error message within modal on failed response instead of browser logs #942
- Fix: Replace wpstgGetCloneSettings() in mail-settings.php with CloneOption::get() #956
- Fix: Little typo changed effect to affect #963
- Fix: Made node_modules dir to be only excluded from WP Staging's Plugins #963
- Fix: Fix UPDATE and RESET for old wpstg clones which are without appended underscore db prefix #958
Download this release
Release Info
Developer | ReneHermi |
Plugin | WP Staging – DB & File Duplicator & Migration |
Version | 2.8.4 |
Comparing to | |
See all releases |
Code changes from version 2.8.3 to 2.8.4
- Backend/Administrator.php +115 -21
- Backend/Modules/Jobs/Cleaners/WpContentCleaner.php +4 -11
- Backend/Modules/Jobs/Cloning.php +40 -25
- Backend/Modules/Jobs/Data.php +0 -5
- Backend/Modules/Jobs/Database.php +42 -8
- Backend/Modules/Jobs/Delete.php +1 -1
- Backend/Modules/Jobs/Directories.php +96 -40
- Backend/Modules/Jobs/Files.php +10 -8
- Backend/Modules/Jobs/Job.php +5 -5
- Backend/Modules/Jobs/PreserveDataFirstStep.php +39 -5
- Backend/Modules/Jobs/PreserveDataSecondStep.php +70 -9
- Backend/Modules/Jobs/ProcessLock.php +26 -1
- Backend/Modules/Jobs/Scan.php +198 -123
- Backend/Modules/Jobs/SearchReplace.php +7 -15
- Backend/Modules/Jobs/Updating.php +92 -62
- Backend/Modules/Views/Forms/Settings.php +12 -0
- Backend/views/clone/ajax/exclude-settings.php +37 -0
- Backend/views/clone/ajax/scan.php +3 -63
- Backend/views/selections/database-tables.php +43 -0
- Backend/views/selections/files.php +104 -0
- Backend/views/settings/tabs/general.php +19 -0
- Backend/views/settings/tabs/mail-settings.php +1 -4
- Backend/views/templates/exclude-filters/dir-name-exclude-filter.php +29 -0
- Backend/views/templates/exclude-filters/file-ext-exclude-filter.php +18 -0
- Backend/views/templates/exclude-filters/file-name-exclude-filter.php +29 -0
- Backend/views/templates/exclude-filters/file-size-exclude-filter.php +34 -0
- Core/CoreServiceProvider.php +51 -0
- Core/DTO/Settings.php +31 -2
- Core/Forms/Elements/Color.php +29 -0
- Core/WPStaging.php +12 -9
- Core/thirdParty/thirdPartyCompatibility.php +0 -35
- Framework/Adapter/Database/InterfaceDatabaseClient.php +21 -0
- Framework/Adapter/Database/MysqlAdapter.php +18 -0
- Framework/Adapter/Database/MysqliAdapter.php +16 -0
- Framework/Adapter/Maintenance.php +1 -1
- Framework/Assets/Assets.php +81 -18
- Framework/BackgroundProcessing/Action.php +309 -0
- Framework/BackgroundProcessing/BackgroundProcessingServiceProvider.php +181 -0
- Framework/BackgroundProcessing/Demo.php +38 -0
- Framework/BackgroundProcessing/Exceptions/QueueException.php +21 -0
- Framework/BackgroundProcessing/FeatureDetection.php +183 -0
- Framework/BackgroundProcessing/Queue.php +1075 -0
- Framework/BackgroundProcessing/QueueProcessor.php +222 -0
- Framework/BackgroundProcessing/WithQueueAwareness.php +123 -0
- Framework/CloningProcess/Data/DBCloningService.php +10 -0
- Framework/CloningProcess/Data/MultisiteUpdateTablePrefix.php +0 -32
- Framework/CloningProcess/Data/UpdateStagingOptionsTable.php +10 -3
- Framework/CloningProcess/Data/UpdateTablePrefix.php +0 -10
- Framework/CloningProcess/ExcludedPlugins.php +20 -12
- Framework/Database/ExcludedTables.php +85 -0
- Framework/Database/TableService.php +2 -1
- Framework/Exceptions/IOException.php +8 -0
- Framework/Filesystem/Filesystem.php +52 -232
- Framework/Filesystem/FilterableDirectoryIterator.php +73 -4
- Framework/Filesystem/Filters/ExcludeFilter.php +143 -0
- Framework/Filesystem/Filters/FileSizeFilter.php +71 -0
- Framework/Filesystem/Filters/PathExcludeFilter.php +44 -7
- Framework/Filesystem/Filters/PathFilterHelper.php +262 -0
- Framework/Filesystem/Filters/RecursiveFileSizeFilter.php +75 -0
- Framework/Filesystem/Filters/RecursivePathExcludeFilter.php +56 -7
- Framework/Filesystem/Scanning/ScanConst.php +12 -0
- Framework/Filesystem/WpUploadsFolderSymlinker.php +53 -8
- Framework/Traits/DbRowsGeneratorTrait.php +2 -2
- Framework/Traits/ExcludeFilterTrait.php +0 -141
- Framework/Traits/FileScanToCacheTrait.php +8 -39
- Framework/Traits/PropertyConstructor.php +33 -0
- Framework/Utils/Cache/AbstractCache.php +1 -1
- Framework/Utils/Cache/BufferedCache.php +1 -1
- Framework/Utils/SlashMode.php +35 -0
- {vendor_wpstg/symfony/finder → Framework/Utils/ThirdParty}/Glob.php +4 -8
- Framework/Utils/WpDefaultDirectories.php +68 -100
- README.md +6 -0
- assets/css/{src → dist}/wpstg-admin-feedback.css +2 -1
- assets/css/dist/wpstg-admin-feedback.css.map +1 -0
- assets/css/dist/wpstg-admin-feedback.min.css +2 -0
- assets/css/dist/wpstg-admin-feedback.min.css.map +1 -0
- assets/css/{src → dist}/wpstg-admin.css +410 -55
- assets/css/dist/wpstg-admin.css.map +1 -0
- assets/css/dist/wpstg-admin.min.css +2 -0
- assets/css/dist/wpstg-admin.min.css.map +1 -0
- assets/css/src/frontend/wpstg-admin-bar.css +0 -3
- assets/css/src/wpstg-admin-bar.css +0 -3
- assets/img/spinner.gif +0 -0
- assets/img/wpstaging-icon.png +0 -0
- assets/js/dist/wpstg-admin-beta.js +18 -12
- assets/js/dist/wpstg-admin-beta.js.map +1 -0
- assets/js/dist/wpstg-admin-beta.min.js +2 -0
- assets/js/dist/wpstg-admin-beta.min.js.map +1 -0
- assets/js/dist/wpstg-admin-plugins.js +70 -65
- assets/js/dist/wpstg-admin-plugins.js.map +1 -0
- assets/js/dist/wpstg-admin-plugins.min.js +2 -0
- assets/js/dist/wpstg-admin-plugins.min.js.map +1 -0
- assets/js/dist/wpstg-admin-poll.js +19 -13
- assets/js/dist/wpstg-admin-poll.js.map +1 -0
- assets/js/dist/wpstg-admin-poll.min.js +2 -0
- assets/js/dist/wpstg-admin-poll.min.js.map +1 -0
- assets/js/dist/wpstg-admin-rating.js +118 -133
- assets/js/dist/wpstg-admin-rating.js.map +1 -0
- assets/js/dist/wpstg-admin-rating.min.js +2 -0
- assets/js/dist/wpstg-admin-rating.min.js.map +1 -0
- assets/js/dist/wpstg-admin.js +3505 -2429
- assets/js/dist/wpstg-admin.js.map +1 -0
Backend/Administrator.php
CHANGED
@@ -2,13 +2,7 @@
|
|
2 |
|
3 |
namespace WPStaging\Backend;
|
4 |
|
5 |
-
// No Direct Access
|
6 |
-
if (!defined("WPINC")) {
|
7 |
-
die;
|
8 |
-
}
|
9 |
-
|
10 |
use WPStaging\Core\WPStaging;
|
11 |
-
use WPStaging\Core\Utils\Cache;
|
12 |
use WPStaging\Framework\Assets\Assets;
|
13 |
use WPStaging\Framework\Database\DbInfo;
|
14 |
use WPStaging\Framework\SiteInfo;
|
@@ -35,6 +29,8 @@ use WPStaging\Backend\Feedback;
|
|
35 |
use WPStaging\Backend\Pro\Modules\Jobs\Processing;
|
36 |
use WPStaging\Backend\Pluginmeta\Pluginmeta;
|
37 |
use WPStaging\Core\DTO\Settings;
|
|
|
|
|
38 |
use WPStaging\Pro\Database\CompareExternalDatabase;
|
39 |
|
40 |
/**
|
@@ -162,6 +158,9 @@ class Administrator
|
|
162 |
add_action("wp_ajax_wpstg_send_feedback", [$this, "sendFeedback"]);
|
163 |
add_action("wp_ajax_wpstg_hide_disabled_items_notice", [$this, "ajaxHideDisabledItemsNotice"]);
|
164 |
add_action("wp_ajax_wpstg_enable_staging_cloning", [$this, "ajaxEnableStagingCloning"]);
|
|
|
|
|
|
|
165 |
|
166 |
|
167 |
// Ajax hooks pro Version
|
@@ -224,7 +223,7 @@ class Administrator
|
|
224 |
$error = false;
|
225 |
// is_array() is required otherwise new clone will fail.
|
226 |
if ($this->siteInfo->isStaging() && is_array($data)) {
|
227 |
-
$isStagingCloneable = $data['isStagingSiteCloneable'];
|
228 |
unset($data['isStagingSiteCloneable']);
|
229 |
$error = !$this->toggleStagingSiteCloning($isStagingCloneable === 'true');
|
230 |
}
|
@@ -582,23 +581,51 @@ class Administrator
|
|
582 |
}
|
583 |
|
584 |
// Check first if there is already a process running
|
585 |
-
$
|
586 |
-
$
|
|
|
|
|
|
|
|
|
|
|
587 |
|
588 |
$db = WPStaging::getInstance()->get('wpdb');
|
589 |
|
590 |
// Scan
|
591 |
$scan = new Scan();
|
|
|
592 |
$scan->start();
|
593 |
|
594 |
// Get Options
|
595 |
$options = $scan->getOptions();
|
596 |
-
|
597 |
require_once "{$this->path}views/clone/ajax/scan.php";
|
598 |
|
599 |
wp_die();
|
600 |
}
|
601 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
602 |
/**
|
603 |
* Ajax Check Clone Name
|
604 |
*/
|
@@ -664,11 +691,6 @@ class Administrator
|
|
664 |
return;
|
665 |
}
|
666 |
|
667 |
-
// TODO: inject this using DI
|
668 |
-
// remove clone options cache before initializing reset clone process
|
669 |
-
$cache = new Cache(-1, WPStaging::getContentDir());
|
670 |
-
$cache->delete("clone_options");
|
671 |
-
|
672 |
$cloning = new Updating();
|
673 |
$cloning->setMainJob(Updating::RESET_UPDATE);
|
674 |
if (!$cloning->save()) {
|
@@ -914,8 +936,11 @@ class Administrator
|
|
914 |
return false;
|
915 |
}
|
916 |
|
|
|
|
|
|
|
917 |
$scan = new Scan();
|
918 |
-
return $scan->hasFreeDiskSpace();
|
919 |
}
|
920 |
|
921 |
/**
|
@@ -1107,6 +1132,13 @@ class Administrator
|
|
1107 |
$database = !empty($args['databaseDatabase']) ? $args['databaseDatabase'] : '';
|
1108 |
$server = !empty($args['databaseServer']) ? $args['databaseServer'] : 'localhost';
|
1109 |
$prefix = !empty($args['databasePrefix']) ? $args['databasePrefix'] : 'wp_';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1110 |
// ensure tables with the given prefix exist, default false
|
1111 |
$ensurePrefixTableExist = !empty($args['databaseEnsurePrefixTableExist']) ? filter_var($args['databaseEnsurePrefixTableExist'], FILTER_VALIDATE_BOOLEAN) : false;
|
1112 |
|
@@ -1128,6 +1160,12 @@ class Administrator
|
|
1128 |
exit;
|
1129 |
}
|
1130 |
|
|
|
|
|
|
|
|
|
|
|
|
|
1131 |
// used in edit and update of clone
|
1132 |
if ($existingTables === null && $ensurePrefixTableExist) {
|
1133 |
echo json_encode(['success' => 'true', 'errors' => __('Tables with prefix "' . $prefix . '" not exist in database. Make sure it exists.', 'wp-staging')]);
|
@@ -1137,18 +1175,18 @@ class Administrator
|
|
1137 |
// get production db
|
1138 |
$productionDb = WPStaging::getInstance()->get('wpdb');
|
1139 |
|
1140 |
-
$
|
1141 |
$queryToFindPort = "SHOW VARIABLES WHERE Variable_name = 'port';";
|
1142 |
|
1143 |
-
$stagingSiteAddress = $wpdb->get_var($wpdb->prepare($
|
1144 |
-
$productionSiteAddress = $productionDb->get_var($productionDb->prepare($
|
1145 |
if ($stagingSiteAddress === null || $productionSiteAddress === null) {
|
1146 |
echo json_encode(['success' => 'false', 'errors' => __('Unable to find database server hostname of the staging or the production site.', 'wp-staging')]);
|
1147 |
exit;
|
1148 |
}
|
1149 |
|
1150 |
$isSameAddress = $productionSiteAddress === $stagingSiteAddress;
|
1151 |
-
$isSamePort = $wpdb->get_var($wpdb->prepare($queryToFindPort)) === $productionDb->get_var($productionDb->prepare($queryToFindPort));
|
1152 |
|
1153 |
$isSameServer = ($isSameAddress && $isSamePort) || $server === DB_HOST;
|
1154 |
|
@@ -1162,7 +1200,63 @@ class Administrator
|
|
1162 |
}
|
1163 |
|
1164 |
/**
|
1165 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1166 |
*/
|
1167 |
public function ajaxDatabaseVerification()
|
1168 |
{
|
2 |
|
3 |
namespace WPStaging\Backend;
|
4 |
|
|
|
|
|
|
|
|
|
|
|
5 |
use WPStaging\Core\WPStaging;
|
|
|
6 |
use WPStaging\Framework\Assets\Assets;
|
7 |
use WPStaging\Framework\Database\DbInfo;
|
8 |
use WPStaging\Framework\SiteInfo;
|
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 |
/**
|
158 |
add_action("wp_ajax_wpstg_send_feedback", [$this, "sendFeedback"]);
|
159 |
add_action("wp_ajax_wpstg_hide_disabled_items_notice", [$this, "ajaxHideDisabledItemsNotice"]);
|
160 |
add_action("wp_ajax_wpstg_enable_staging_cloning", [$this, "ajaxEnableStagingCloning"]);
|
161 |
+
add_action("wp_ajax_wpstg_clone_excludes_settings", [$this, "ajaxCloneExcludesSettings"]);
|
162 |
+
add_action("wp_ajax_wpstg_fetch_dir_childrens", [$this, "ajaxFetchDirChildrens"]);
|
163 |
+
add_action("wp_ajax_wpstg_modal_error", [$this, "ajaxModalError"]);
|
164 |
|
165 |
|
166 |
// Ajax hooks pro Version
|
223 |
$error = false;
|
224 |
// is_array() is required otherwise new clone will fail.
|
225 |
if ($this->siteInfo->isStaging() && is_array($data)) {
|
226 |
+
$isStagingCloneable = isset($data['isStagingSiteCloneable']) ? $data['isStagingSiteCloneable'] : 'false';
|
227 |
unset($data['isStagingSiteCloneable']);
|
228 |
$error = !$this->toggleStagingSiteCloning($isStagingCloneable === 'true');
|
229 |
}
|
581 |
}
|
582 |
|
583 |
// Check first if there is already a process running
|
584 |
+
$response = (new ProcessLock())->ajaxIsRunning();
|
585 |
+
if ($response !== false)
|
586 |
+
{
|
587 |
+
echo $response;
|
588 |
+
|
589 |
+
exit();
|
590 |
+
}
|
591 |
|
592 |
$db = WPStaging::getInstance()->get('wpdb');
|
593 |
|
594 |
// Scan
|
595 |
$scan = new Scan();
|
596 |
+
$scan->setGifLoaderPath($this->assets->getAssetsUrl('img/spinner.gif'));
|
597 |
$scan->start();
|
598 |
|
599 |
// Get Options
|
600 |
$options = $scan->getOptions();
|
601 |
+
$excludeUtils = new ExcludeFilter();
|
602 |
require_once "{$this->path}views/clone/ajax/scan.php";
|
603 |
|
604 |
wp_die();
|
605 |
}
|
606 |
|
607 |
+
/**
|
608 |
+
* Fetch children of the given directory
|
609 |
+
*/
|
610 |
+
public function ajaxFetchDirChildrens()
|
611 |
+
{
|
612 |
+
if (!$this->isAuthenticated()) {
|
613 |
+
wp_send_json(['success' => false]);
|
614 |
+
return;
|
615 |
+
}
|
616 |
+
|
617 |
+
$isChecked = isset($_POST['isChecked']) ? $_POST['isChecked'] === 'true' : false;
|
618 |
+
$forceDefault = isset($_POST['forceDefault']) ? $_POST['forceDefault'] === 'true' : false;
|
619 |
+
$path = isset($_POST['dirPath']) ? $_POST['dirPath'] : "";
|
620 |
+
$path = ABSPATH . $path;
|
621 |
+
$scan = new Scan($path);
|
622 |
+
$scan->setGifLoaderPath($this->assets->getAssetsUrl('img/spinner.gif'));
|
623 |
+
wp_send_json([
|
624 |
+
"success" => true,
|
625 |
+
"directoryListing" => json_encode($scan->directoryListing($isChecked, $forceDefault)),
|
626 |
+
]);
|
627 |
+
}
|
628 |
+
|
629 |
/**
|
630 |
* Ajax Check Clone Name
|
631 |
*/
|
691 |
return;
|
692 |
}
|
693 |
|
|
|
|
|
|
|
|
|
|
|
694 |
$cloning = new Updating();
|
695 |
$cloning->setMainJob(Updating::RESET_UPDATE);
|
696 |
if (!$cloning->save()) {
|
936 |
return false;
|
937 |
}
|
938 |
|
939 |
+
$excludedDirectories = isset($_POST["excludedDirectories"]) ? $_POST["excludedDirectories"] : '';
|
940 |
+
$extraDirectories = isset($_POST["extraDirectories"]) ? $_POST["extraDirectories"] : '';
|
941 |
+
|
942 |
$scan = new Scan();
|
943 |
+
return $scan->hasFreeDiskSpace($excludedDirectories, $extraDirectories);
|
944 |
}
|
945 |
|
946 |
/**
|
1132 |
$database = !empty($args['databaseDatabase']) ? $args['databaseDatabase'] : '';
|
1133 |
$server = !empty($args['databaseServer']) ? $args['databaseServer'] : 'localhost';
|
1134 |
$prefix = !empty($args['databasePrefix']) ? $args['databasePrefix'] : 'wp_';
|
1135 |
+
// make sure prefix doesn't contains any invalid character
|
1136 |
+
// same condition as in WordPress wpdb::set_prefix() method
|
1137 |
+
if (preg_match('|[^a-z0-9_]|i', $prefix)) {
|
1138 |
+
echo json_encode(['success' => 'false', 'errors' => __('Table prefix contains an invalid character.', 'wp-staging')]);
|
1139 |
+
exit;
|
1140 |
+
}
|
1141 |
+
|
1142 |
// ensure tables with the given prefix exist, default false
|
1143 |
$ensurePrefixTableExist = !empty($args['databaseEnsurePrefixTableExist']) ? filter_var($args['databaseEnsurePrefixTableExist'], FILTER_VALIDATE_BOOLEAN) : false;
|
1144 |
|
1160 |
exit;
|
1161 |
}
|
1162 |
|
1163 |
+
// no need to check further for new clone
|
1164 |
+
if ($existingTables === null && !$ensurePrefixTableExist) {
|
1165 |
+
echo json_encode(['success' => 'true']);
|
1166 |
+
exit;
|
1167 |
+
}
|
1168 |
+
|
1169 |
// used in edit and update of clone
|
1170 |
if ($existingTables === null && $ensurePrefixTableExist) {
|
1171 |
echo json_encode(['success' => 'true', 'errors' => __('Tables with prefix "' . $prefix . '" not exist in database. Make sure it exists.', 'wp-staging')]);
|
1175 |
// get production db
|
1176 |
$productionDb = WPStaging::getInstance()->get('wpdb');
|
1177 |
|
1178 |
+
$queryToFindHost = "SHOW VARIABLES WHERE Variable_name = 'hostname';";
|
1179 |
$queryToFindPort = "SHOW VARIABLES WHERE Variable_name = 'port';";
|
1180 |
|
1181 |
+
$stagingSiteAddress = gethostbyname($wpdb->get_var($wpdb->prepare($queryToFindHost), 1));
|
1182 |
+
$productionSiteAddress = gethostbyname($productionDb->get_var($productionDb->prepare($queryToFindHost), 1));
|
1183 |
if ($stagingSiteAddress === null || $productionSiteAddress === null) {
|
1184 |
echo json_encode(['success' => 'false', 'errors' => __('Unable to find database server hostname of the staging or the production site.', 'wp-staging')]);
|
1185 |
exit;
|
1186 |
}
|
1187 |
|
1188 |
$isSameAddress = $productionSiteAddress === $stagingSiteAddress;
|
1189 |
+
$isSamePort = $wpdb->get_var($wpdb->prepare($queryToFindPort), 1) === $productionDb->get_var($productionDb->prepare($queryToFindPort), 1);
|
1190 |
|
1191 |
$isSameServer = ($isSameAddress && $isSamePort) || $server === DB_HOST;
|
1192 |
|
1200 |
}
|
1201 |
|
1202 |
/**
|
1203 |
+
* Action to perform when error modal confirm button is clicked
|
1204 |
+
*
|
1205 |
+
* @todo use constants instead of hardcoded strings for error types
|
1206 |
+
*/
|
1207 |
+
public function ajaxModalError()
|
1208 |
+
{
|
1209 |
+
if (!$this->isAuthenticated()) {
|
1210 |
+
return;
|
1211 |
+
}
|
1212 |
+
|
1213 |
+
$type = isset($_POST['type']) ? $_POST['type'] : null;
|
1214 |
+
if ($type === 'processLock') {
|
1215 |
+
$process = new ProcessLock();
|
1216 |
+
$process->restart();
|
1217 |
+
|
1218 |
+
exit();
|
1219 |
+
}
|
1220 |
+
}
|
1221 |
+
|
1222 |
+
/**
|
1223 |
+
* Render tables and files selection for RESET function
|
1224 |
+
*/
|
1225 |
+
public function ajaxCloneExcludesSettings()
|
1226 |
+
{
|
1227 |
+
if (!$this->isAuthenticated()) {
|
1228 |
+
return;
|
1229 |
+
}
|
1230 |
+
|
1231 |
+
$response = (new ProcessLock())->ajaxIsRunning();
|
1232 |
+
if ($response !== false)
|
1233 |
+
{
|
1234 |
+
echo $response;
|
1235 |
+
|
1236 |
+
exit();
|
1237 |
+
}
|
1238 |
+
|
1239 |
+
$templateEngine = new TemplateEngine();
|
1240 |
+
|
1241 |
+
// Scan
|
1242 |
+
$scan = new Scan();
|
1243 |
+
$scan->setGifLoaderPath($this->assets->getAssetsUrl('img/spinner.gif'));
|
1244 |
+
$scan->start();
|
1245 |
+
|
1246 |
+
echo json_encode([
|
1247 |
+
'success' => true,
|
1248 |
+
"html" => $templateEngine->render("/Backend/views/clone/ajax/exclude-settings.php", [
|
1249 |
+
'scan' => $scan,
|
1250 |
+
'options' => $scan->getOptions(),
|
1251 |
+
'excludeUtils' => new ExcludeFilter(),
|
1252 |
+
])
|
1253 |
+
]);
|
1254 |
+
|
1255 |
+
exit();
|
1256 |
+
}
|
1257 |
+
|
1258 |
+
/**
|
1259 |
+
* Compare database and table properties of separate db with local db
|
1260 |
*/
|
1261 |
public function ajaxDatabaseVerification()
|
1262 |
{
|
Backend/Modules/Jobs/Cleaners/WpContentCleaner.php
CHANGED
@@ -4,6 +4,7 @@ namespace WPStaging\Backend\Modules\Jobs\Cleaners;
|
|
4 |
|
5 |
use WPStaging\Backend\Modules\Jobs\Files;
|
6 |
use WPStaging\Framework\Utils\WpDefaultDirectories;
|
|
|
7 |
use WPStaging\Framework\Filesystem\Filesystem;
|
8 |
use WPStaging\Core\Utils\Logger;
|
9 |
|
@@ -90,21 +91,13 @@ class WpContentCleaner
|
|
90 |
}
|
91 |
|
92 |
$excludePaths = [
|
93 |
-
|
94 |
-
|
95 |
-
trailingslashit($directory . $wpDirectories->getRelativePluginPath()) . "wp-staging_2",
|
96 |
-
trailingslashit($directory . $wpDirectories->getRelativePluginPath()) . "wp-staging-pro",
|
97 |
-
trailingslashit($directory . $wpDirectories->getRelativePluginPath()) . "wp-staging-pro_1",
|
98 |
-
trailingslashit($directory . $wpDirectories->getRelativePluginPath()) . "wp-staging-pro_2",
|
99 |
-
trailingslashit($directory . $wpDirectories->getRelativePluginPath()) . "wp-staging-dev",
|
100 |
-
trailingslashit($directory . $wpDirectories->getRelativePluginPath()) . 'wp-staging-hooks',
|
101 |
-
trailingslashit($directory . $wpDirectories->getRelativePluginPath()) . 'wp-staging-hooks_1',
|
102 |
-
trailingslashit($directory . $wpDirectories->getRelativePluginPath()) . 'wp-staging-hooks_2',
|
103 |
-
trailingslashit($directory . $wpDirectories->getRelativeUploadPath()) . 'wp-staging', // exclude wp-staging from uploads dir too.
|
104 |
];
|
105 |
$fs = (new Filesystem())
|
106 |
->setShouldStop([$this->job, 'isOverThreshold'])
|
107 |
->setExcludePaths($excludePaths)
|
|
|
108 |
->setRecursive();
|
109 |
try {
|
110 |
if (!$fs->deletePaths($paths)) {
|
4 |
|
5 |
use WPStaging\Backend\Modules\Jobs\Files;
|
6 |
use WPStaging\Framework\Utils\WpDefaultDirectories;
|
7 |
+
use WPStaging\Framework\Utils\SlashMode;
|
8 |
use WPStaging\Framework\Filesystem\Filesystem;
|
9 |
use WPStaging\Core\Utils\Logger;
|
10 |
|
91 |
}
|
92 |
|
93 |
$excludePaths = [
|
94 |
+
$wpDirectories->getRelativePluginPath(SlashMode::BOTH_SLASHES) . "wp-staging*",
|
95 |
+
$wpDirectories->getRelativeUploadPath(SlashMode::BOTH_SLASHES) . 'wp-staging', // exclude wp-staging from uploads dir too.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
];
|
97 |
$fs = (new Filesystem())
|
98 |
->setShouldStop([$this->job, 'isOverThreshold'])
|
99 |
->setExcludePaths($excludePaths)
|
100 |
+
->setWpRootPath($directory)
|
101 |
->setRecursive();
|
102 |
try {
|
103 |
if (!$fs->deletePaths($paths)) {
|
Backend/Modules/Jobs/Cloning.php
CHANGED
@@ -5,7 +5,9 @@ namespace WPStaging\Backend\Modules\Jobs;
|
|
5 |
use WPStaging\Backend\Modules\Jobs\Exceptions\JobNotFoundException;
|
6 |
use WPStaging\Core\Utils\Helper;
|
7 |
use WPStaging\Core\WPStaging;
|
|
|
8 |
use WPStaging\Framework\Security\AccessToken;
|
|
|
9 |
use WPStaging\Framework\Utils\WpDefaultDirectories;
|
10 |
|
11 |
/**
|
@@ -20,12 +22,18 @@ class Cloning extends Job
|
|
20 |
*/
|
21 |
private $db;
|
22 |
|
|
|
|
|
|
|
|
|
|
|
23 |
/**
|
24 |
* Initialize is called in \Job
|
25 |
*/
|
26 |
public function initialize()
|
27 |
{
|
28 |
$this->db = WPStaging::getInstance()->get("wpdb");
|
|
|
29 |
}
|
30 |
|
31 |
|
@@ -64,10 +72,11 @@ class Cloning extends Job
|
|
64 |
'.wp-staging', // Determines if a site is a staging site
|
65 |
'.wp-staging-cloneable', // File which make staging site to be cloneable
|
66 |
];
|
|
|
67 |
$this->options->excludedFilesFullPath = [
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
];
|
72 |
$this->options->currentStep = 0;
|
73 |
|
@@ -95,41 +104,41 @@ class Cloning extends Job
|
|
95 |
$this->options->tables = [];
|
96 |
}
|
97 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
$this->options->uploadsSymlinked = isset($_POST['uploadsSymlinked']) && $_POST['uploadsSymlinked'] === 'true';
|
99 |
|
100 |
-
|
101 |
-
|
|
|
|
|
102 |
$excludedDirectories = [
|
103 |
-
|
104 |
-
WPStaging::getWPpath() . 'wp-content' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'wps-hide-login',
|
105 |
-
WPStaging::getWPpath() . 'wp-content' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'wp-super-cache',
|
106 |
-
WPStaging::getWPpath() . 'wp-content' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'peters-login-redirect',
|
107 |
-
WPStaging::getWPpath() . 'wp-content' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'wp-spamshield',
|
108 |
];
|
109 |
|
110 |
// Add upload folder to list of excluded directories for push if symlink option is enabled
|
111 |
if ($this->options->uploadsSymlinked) {
|
112 |
-
$
|
113 |
-
$excludedDirectories[] = rtrim($wpUploadsFolder, '/\\');
|
114 |
}
|
115 |
|
116 |
-
$
|
117 |
-
|
118 |
-
$this->options->areDirectoriesIncluded = isset($_POST['areDirectoriesIncluded']) && $_POST['areDirectoriesIncluded'] === 'true';
|
119 |
|
120 |
-
$
|
121 |
-
// Included Directories
|
122 |
-
if ($this->options->areDirectoriesIncluded) {
|
123 |
-
$directories = isset($_POST["includedDirectories"]) ? $_POST["includedDirectories"] : '';
|
124 |
-
} else { // Get Included Directories from Excluded Directories
|
125 |
-
$directories = isset($_POST["excludedDirectories"]) ? $_POST["excludedDirectories"] : '';
|
126 |
-
}
|
127 |
-
|
128 |
-
$this->options->includedDirectories = (new WpDefaultDirectories())->getSelectedDirectories($directories, $this->options->areDirectoriesIncluded);
|
129 |
|
130 |
// Extra Directories
|
131 |
if (isset($_POST["extraDirectories"])) {
|
132 |
-
$this->options->extraDirectories =
|
133 |
}
|
134 |
|
135 |
$this->options->databaseServer = 'localhost';
|
@@ -222,6 +231,11 @@ class Cloning extends Job
|
|
222 |
"emailsAllowed" => (bool)$this->options->emailsAllowed,
|
223 |
"uploadsSymlinked" => (bool)$this->options->uploadsSymlinked,
|
224 |
"ownerId" => $this->options->ownerId,
|
|
|
|
|
|
|
|
|
|
|
225 |
];
|
226 |
|
227 |
if (update_option("wpstg_existing_clones_beta", $this->options->existingClones) === false) {
|
@@ -366,6 +380,7 @@ class Cloning extends Job
|
|
366 |
return $response;
|
367 |
}
|
368 |
|
|
|
369 |
$this->options->currentJob = $nextJob;
|
370 |
$this->options->currentStep = 0;
|
371 |
$this->options->totalSteps = 0;
|
5 |
use WPStaging\Backend\Modules\Jobs\Exceptions\JobNotFoundException;
|
6 |
use WPStaging\Core\Utils\Helper;
|
7 |
use WPStaging\Core\WPStaging;
|
8 |
+
use WPStaging\Framework\Filesystem\Scanning\ScanConst;
|
9 |
use WPStaging\Framework\Security\AccessToken;
|
10 |
+
use WPStaging\Framework\Utils\SlashMode;
|
11 |
use WPStaging\Framework\Utils\WpDefaultDirectories;
|
12 |
|
13 |
/**
|
22 |
*/
|
23 |
private $db;
|
24 |
|
25 |
+
/**
|
26 |
+
* @var WpDefaultDirectories
|
27 |
+
*/
|
28 |
+
private $dirUtils;
|
29 |
+
|
30 |
/**
|
31 |
* Initialize is called in \Job
|
32 |
*/
|
33 |
public function initialize()
|
34 |
{
|
35 |
$this->db = WPStaging::getInstance()->get("wpdb");
|
36 |
+
$this->dirUtils = new WpDefaultDirectories();
|
37 |
}
|
38 |
|
39 |
|
72 |
'.wp-staging', // Determines if a site is a staging site
|
73 |
'.wp-staging-cloneable', // File which make staging site to be cloneable
|
74 |
];
|
75 |
+
|
76 |
$this->options->excludedFilesFullPath = [
|
77 |
+
$this->dirUtils->getRelativeWpContentPath(SlashMode::TRAILING_SLASH) . 'db.php',
|
78 |
+
$this->dirUtils->getRelativeWpContentPath(SlashMode::TRAILING_SLASH) . 'object-cache.php',
|
79 |
+
$this->dirUtils->getRelativeWpContentPath(SlashMode::TRAILING_SLASH) . 'advanced-cache.php'
|
80 |
];
|
81 |
$this->options->currentStep = 0;
|
82 |
|
104 |
$this->options->tables = [];
|
105 |
}
|
106 |
|
107 |
+
// Exclude File Size Rules
|
108 |
+
$this->options->excludeSizeRules = [];
|
109 |
+
if (isset($_POST["excludeSizeRules"]) && !empty($_POST["excludeSizeRules"])) {
|
110 |
+
$this->options->excludeSizeRules = explode(',', wpstg_urldecode($_POST["excludeSizeRules"]));
|
111 |
+
}
|
112 |
+
|
113 |
+
// Exclude Glob Rules
|
114 |
+
$this->options->excludeGlobRules = [];
|
115 |
+
if (isset($_POST["excludeGlobRules"]) && !empty($_POST["excludeGlobRules"])) {
|
116 |
+
$this->options->excludeGlobRules = explode(',', wpstg_urldecode($_POST["excludeGlobRules"]));
|
117 |
+
}
|
118 |
+
|
119 |
$this->options->uploadsSymlinked = isset($_POST['uploadsSymlinked']) && $_POST['uploadsSymlinked'] === 'true';
|
120 |
|
121 |
+
/**
|
122 |
+
* @see /WPStaging/Framework/CloningProcess/ExcludedPlugins.php to exclude plugins
|
123 |
+
* Only add other directories here
|
124 |
+
*/
|
125 |
$excludedDirectories = [
|
126 |
+
$this->dirUtils->getRelativeWpContentPath(SlashMode::BOTH_SLASHES) . 'cache',
|
|
|
|
|
|
|
|
|
127 |
];
|
128 |
|
129 |
// Add upload folder to list of excluded directories for push if symlink option is enabled
|
130 |
if ($this->options->uploadsSymlinked) {
|
131 |
+
$excludedDirectories[] = $this->dirUtils->getRelativeUploadPath(SlashMode::LEADING_SLASH);
|
|
|
132 |
}
|
133 |
|
134 |
+
$excludedDirectoriesRequest = isset($_POST["excludedDirectories"]) ? $_POST["excludedDirectories"] : '';
|
135 |
+
$excludedDirectoriesRequest = $this->dirUtils->getExcludedDirectories($excludedDirectoriesRequest);
|
|
|
136 |
|
137 |
+
$this->options->excludedDirectories = array_merge($excludedDirectories, $excludedDirectoriesRequest);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
138 |
|
139 |
// Extra Directories
|
140 |
if (isset($_POST["extraDirectories"])) {
|
141 |
+
$this->options->extraDirectories = explode(ScanConst::DIRECTORIES_SEPARATOR, wpstg_urldecode($_POST["extraDirectories"]));
|
142 |
}
|
143 |
|
144 |
$this->options->databaseServer = 'localhost';
|
231 |
"emailsAllowed" => (bool)$this->options->emailsAllowed,
|
232 |
"uploadsSymlinked" => (bool)$this->options->uploadsSymlinked,
|
233 |
"ownerId" => $this->options->ownerId,
|
234 |
+
"includedTables" => $this->options->tables,
|
235 |
+
"excludeSizeRules" => $this->options->excludeSizeRules,
|
236 |
+
"excludeGlobRules" => $this->options->excludeGlobRules,
|
237 |
+
"excludedDirectories" => $this->options->excludedDirectories,
|
238 |
+
"extraDirectories" => $this->options->extraDirectories,
|
239 |
];
|
240 |
|
241 |
if (update_option("wpstg_existing_clones_beta", $this->options->existingClones) === false) {
|
380 |
return $response;
|
381 |
}
|
382 |
|
383 |
+
$this->options->job = new \stdClass();
|
384 |
$this->options->currentJob = $nextJob;
|
385 |
$this->options->currentStep = 0;
|
386 |
$this->options->totalSteps = 0;
|
Backend/Modules/Jobs/Data.php
CHANGED
@@ -6,7 +6,6 @@ use WPStaging\Framework\CloningProcess\Data\DataCloningDto;
|
|
6 |
use WPStaging\Framework\CloningProcess\Data\CopyWpConfig;
|
7 |
use WPStaging\Framework\CloningProcess\Data\MultisiteAddNetworkAdministrators;
|
8 |
use WPStaging\Framework\CloningProcess\Data\MultisiteUpdateActivePlugins;
|
9 |
-
use WPStaging\Framework\CloningProcess\Data\MultisiteUpdateTablePrefix;
|
10 |
use WPStaging\Framework\CloningProcess\Data\ResetIndexPhp;
|
11 |
use WPStaging\Framework\CloningProcess\Data\UpdateSiteUrlAndHome;
|
12 |
use WPStaging\Framework\CloningProcess\Data\UpdateTablePrefix;
|
@@ -225,10 +224,6 @@ class Data extends CloningProcess
|
|
225 |
*/
|
226 |
protected function step3()
|
227 |
{
|
228 |
-
if ($this->isMultisiteAndPro()) {
|
229 |
-
return (new MultisiteUpdateTablePrefix($this->getCloningDto(3)))->execute();
|
230 |
-
}
|
231 |
-
|
232 |
return (new UpdateTablePrefix($this->getCloningDto(3)))->execute();
|
233 |
}
|
234 |
|
6 |
use WPStaging\Framework\CloningProcess\Data\CopyWpConfig;
|
7 |
use WPStaging\Framework\CloningProcess\Data\MultisiteAddNetworkAdministrators;
|
8 |
use WPStaging\Framework\CloningProcess\Data\MultisiteUpdateActivePlugins;
|
|
|
9 |
use WPStaging\Framework\CloningProcess\Data\ResetIndexPhp;
|
10 |
use WPStaging\Framework\CloningProcess\Data\UpdateSiteUrlAndHome;
|
11 |
use WPStaging\Framework\CloningProcess\Data\UpdateTablePrefix;
|
224 |
*/
|
225 |
protected function step3()
|
226 |
{
|
|
|
|
|
|
|
|
|
227 |
return (new UpdateTablePrefix($this->getCloningDto(3)))->execute();
|
228 |
}
|
229 |
|
Backend/Modules/Jobs/Database.php
CHANGED
@@ -33,6 +33,7 @@ class Database extends CloningProcess
|
|
33 |
{
|
34 |
$this->initializeDbObjects();
|
35 |
$this->abortIfDirectoryNotEmpty();
|
|
|
36 |
if (!$this->isExternalDatabase()) {
|
37 |
$this->abortIfStagingPrefixEqualsProdPrefix();
|
38 |
} else {
|
@@ -170,6 +171,7 @@ class Database extends CloningProcess
|
|
170 |
private function isTableExist($name)
|
171 |
{
|
172 |
$old = $this->stagingDb->get_var($this->stagingDb->prepare("SHOW TABLES LIKE %s", $name));
|
|
|
173 |
return (
|
174 |
$old === $name &&
|
175 |
(
|
@@ -216,7 +218,9 @@ class Database extends CloningProcess
|
|
216 |
if (defined('WPSTGPRO_VERSION')) {
|
217 |
return false;
|
218 |
}
|
|
|
219 |
$this->returnException(__("This staging site is located in another database and needs to be edited with <a href='https://wp-staging.com' target='_blank'>WP STAGING Pro</a>", "wp-staging"));
|
|
|
220 |
return true;
|
221 |
}
|
222 |
|
@@ -266,8 +270,8 @@ class Database extends CloningProcess
|
|
266 |
}
|
267 |
}
|
268 |
|
269 |
-
if ($this->shouldAbortIfTableExist($newTableName)) {
|
270 |
-
$this->returnException(sprintf(__("Can not proceed. Tables beginning with the prefix '%s' already exist in the database. Choose another table prefix and try again.", "wp-staging"), $this->getStagingPrefix()));
|
271 |
return true;
|
272 |
}
|
273 |
|
@@ -287,16 +291,12 @@ class Database extends CloningProcess
|
|
287 |
}
|
288 |
|
289 |
/**
|
290 |
-
* Is table excluded from
|
291 |
* @param string $table
|
292 |
* @return boolean
|
293 |
*/
|
294 |
private function isExcludedTable($table)
|
295 |
{
|
296 |
-
$excludedCustomTables = apply_filters('wpstg_clone_database_tables_exclude', []);
|
297 |
-
$excludedCoreTables = ['blogs', 'blog_versions'];
|
298 |
-
|
299 |
-
$excludedtables = array_merge($excludedCustomTables, $excludedCoreTables);
|
300 |
|
301 |
if (
|
302 |
in_array(
|
@@ -305,12 +305,13 @@ class Database extends CloningProcess
|
|
305 |
function ($tableName) {
|
306 |
return $this->options->prefix . $tableName;
|
307 |
},
|
308 |
-
$
|
309 |
)
|
310 |
)
|
311 |
) {
|
312 |
return true;
|
313 |
}
|
|
|
314 |
return false;
|
315 |
}
|
316 |
|
@@ -325,6 +326,7 @@ class Database extends CloningProcess
|
|
325 |
if ($this->isExcludedTable($new)) {
|
326 |
return false;
|
327 |
}
|
|
|
328 |
if ($this->options->job->start != 0) {
|
329 |
return true;
|
330 |
}
|
@@ -332,6 +334,7 @@ class Database extends CloningProcess
|
|
332 |
if ($this->databaseCloningService->tableIsMissing($old)) {
|
333 |
return true;
|
334 |
}
|
|
|
335 |
try {
|
336 |
$this->options->job->total = 0;
|
337 |
$this->options->job->total = $this->databaseCloningService->createTable($new, $old);
|
@@ -339,10 +342,14 @@ class Database extends CloningProcess
|
|
339 |
$this->returnException($e->getMessage());
|
340 |
return true;
|
341 |
}
|
|
|
342 |
if ($this->options->job->total == 0) {
|
343 |
$this->finishStep();
|
344 |
return false;
|
345 |
}
|
|
|
|
|
|
|
346 |
return true;
|
347 |
}
|
348 |
|
@@ -358,6 +365,7 @@ class Database extends CloningProcess
|
|
358 |
$this->options->tables[] = $this->productionDb->prefix . 'users';
|
359 |
$this->saveOptions();
|
360 |
}
|
|
|
361 |
if (!in_array($this->productionDb->prefix . 'usermeta', $this->options->tables)) {
|
362 |
$this->options->tables[] = $this->productionDb->prefix . 'usermeta';
|
363 |
$this->saveOptions();
|
@@ -404,6 +412,32 @@ class Database extends CloningProcess
|
|
404 |
$this->returnException(" Can not continue for security purposes. Directory {$path} is not empty! Use FTP or a file manager plugin and make sure it does not contain any files. ");
|
405 |
return true;
|
406 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
407 |
return false;
|
408 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
409 |
}
|
33 |
{
|
34 |
$this->initializeDbObjects();
|
35 |
$this->abortIfDirectoryNotEmpty();
|
36 |
+
$this->abortIfPrefixContainsInvalidCharacter();
|
37 |
if (!$this->isExternalDatabase()) {
|
38 |
$this->abortIfStagingPrefixEqualsProdPrefix();
|
39 |
} else {
|
171 |
private function isTableExist($name)
|
172 |
{
|
173 |
$old = $this->stagingDb->get_var($this->stagingDb->prepare("SHOW TABLES LIKE %s", $name));
|
174 |
+
|
175 |
return (
|
176 |
$old === $name &&
|
177 |
(
|
218 |
if (defined('WPSTGPRO_VERSION')) {
|
219 |
return false;
|
220 |
}
|
221 |
+
|
222 |
$this->returnException(__("This staging site is located in another database and needs to be edited with <a href='https://wp-staging.com' target='_blank'>WP STAGING Pro</a>", "wp-staging"));
|
223 |
+
|
224 |
return true;
|
225 |
}
|
226 |
|
270 |
}
|
271 |
}
|
272 |
|
273 |
+
if (!$this->isCopyProcessStarted() && $this->shouldAbortIfTableExist($newTableName)) {
|
274 |
+
$this->returnException(sprintf(__("Can not proceed. Tables beginning with the prefix '%s' already exist in the database i.e. %s. Choose another table prefix and try again.", "wp-staging"), $this->getStagingPrefix(), $newTableName));
|
275 |
return true;
|
276 |
}
|
277 |
|
291 |
}
|
292 |
|
293 |
/**
|
294 |
+
* Is table excluded from database copying processing?
|
295 |
* @param string $table
|
296 |
* @return boolean
|
297 |
*/
|
298 |
private function isExcludedTable($table)
|
299 |
{
|
|
|
|
|
|
|
|
|
300 |
|
301 |
if (
|
302 |
in_array(
|
305 |
function ($tableName) {
|
306 |
return $this->options->prefix . $tableName;
|
307 |
},
|
308 |
+
$this->excludedTableService->getExcludedTables()
|
309 |
)
|
310 |
)
|
311 |
) {
|
312 |
return true;
|
313 |
}
|
314 |
+
|
315 |
return false;
|
316 |
}
|
317 |
|
326 |
if ($this->isExcludedTable($new)) {
|
327 |
return false;
|
328 |
}
|
329 |
+
|
330 |
if ($this->options->job->start != 0) {
|
331 |
return true;
|
332 |
}
|
334 |
if ($this->databaseCloningService->tableIsMissing($old)) {
|
335 |
return true;
|
336 |
}
|
337 |
+
|
338 |
try {
|
339 |
$this->options->job->total = 0;
|
340 |
$this->options->job->total = $this->databaseCloningService->createTable($new, $old);
|
342 |
$this->returnException($e->getMessage());
|
343 |
return true;
|
344 |
}
|
345 |
+
|
346 |
if ($this->options->job->total == 0) {
|
347 |
$this->finishStep();
|
348 |
return false;
|
349 |
}
|
350 |
+
|
351 |
+
$this->options->job->copyProcessStarted = true;
|
352 |
+
$this->saveOptions();
|
353 |
return true;
|
354 |
}
|
355 |
|
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();
|
412 |
$this->returnException(" Can not continue for security purposes. Directory {$path} is not empty! Use FTP or a file manager plugin and make sure it does not contain any files. ");
|
413 |
return true;
|
414 |
}
|
415 |
+
|
416 |
+
return false;
|
417 |
+
}
|
418 |
+
|
419 |
+
/**
|
420 |
+
* Stop cloning if database prefix contains hypen
|
421 |
+
* @return boolean
|
422 |
+
*/
|
423 |
+
private function abortIfPrefixContainsInvalidCharacter()
|
424 |
+
{
|
425 |
+
// make sure prefix doesn't contains any invalid character
|
426 |
+
// same condition as in WordPress wpdb::set_prefix() method
|
427 |
+
if (preg_match('|[^a-z0-9_]|i', $this->options->databasePrefix)) {
|
428 |
+
$this->returnException(__("Table prefix contains invalid character(s). Use different prefix with valid characters.", 'wp-staging'));
|
429 |
+
return true;
|
430 |
+
}
|
431 |
+
|
432 |
return false;
|
433 |
}
|
434 |
+
|
435 |
+
/**
|
436 |
+
* Check if the copy process started or not.
|
437 |
+
* @return boolean
|
438 |
+
*/
|
439 |
+
private function isCopyProcessStarted()
|
440 |
+
{
|
441 |
+
return isset($this->options->job) && isset($this->options->job->copyProcessStarted) && $this->options->job->copyProcessStarted === true;
|
442 |
+
}
|
443 |
}
|
Backend/Modules/Jobs/Delete.php
CHANGED
@@ -404,7 +404,7 @@ class Delete extends Job
|
|
404 |
->setShouldStop([$this, 'isOverThreshold'])
|
405 |
->setRecursive();
|
406 |
try {
|
407 |
-
if (!$fs->
|
408 |
return;
|
409 |
}
|
410 |
} catch (\RuntimeException $ex) {
|
404 |
->setShouldStop([$this, 'isOverThreshold'])
|
405 |
->setRecursive();
|
406 |
try {
|
407 |
+
if (!$fs->delete($this->deleteDir)) {
|
408 |
return;
|
409 |
}
|
410 |
} catch (\RuntimeException $ex) {
|
Backend/Modules/Jobs/Directories.php
CHANGED
@@ -5,7 +5,9 @@ namespace WPStaging\Backend\Modules\Jobs;
|
|
5 |
use Exception;
|
6 |
use WPStaging\Core\WPStaging;
|
7 |
use WPStaging\Framework\CloningProcess\ExcludedPlugins;
|
|
|
8 |
use WPStaging\Framework\Traits\FileScanToCacheTrait;
|
|
|
9 |
use WPStaging\Framework\Utils\Strings;
|
10 |
use WPStaging\Framework\Utils\WpDefaultDirectories;
|
11 |
|
@@ -34,12 +36,24 @@ class Directories extends JobExecutable
|
|
34 |
*/
|
35 |
private $filename;
|
36 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
/**
|
38 |
* Initialize
|
39 |
*/
|
40 |
public function initialize()
|
41 |
{
|
42 |
$this->filename = $this->cache->getCacheDir() . "files_to_copy." . $this->cache->getCacheExtension();
|
|
|
|
|
43 |
}
|
44 |
|
45 |
/**
|
@@ -112,27 +126,25 @@ class Directories extends JobExecutable
|
|
112 |
$relativeDirectory = str_replace(ABSPATH, '', $directory);
|
113 |
$this->log("Scanning " . $relativeDirectory . " for its sub-directories and files");
|
114 |
|
115 |
-
$paths = $this->filteredSelectedDirectories($directory, $this->options->includedDirectories);
|
116 |
-
|
117 |
$excludePaths = [
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
'**/node_modules',
|
122 |
];
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
if ($this->isMultisiteAndPro()) {
|
127 |
-
$excludePaths = apply_filters('wpstg_clone_mu_excl_folders', $excludePaths);
|
128 |
} else {
|
129 |
-
$excludePaths =
|
130 |
}
|
131 |
|
|
|
|
|
|
|
|
|
|
|
132 |
try {
|
133 |
-
|
134 |
-
$this->options->totalFiles += $this->scanToCacheFile($files, $path->path, $path->flag === Scan::IS_RECURSIVE, $excludePaths);
|
135 |
-
}
|
136 |
} catch (Exception $e) {
|
137 |
$this->returnException('Error: ' . $e->getMessage());
|
138 |
}
|
@@ -161,11 +173,8 @@ class Directories extends JobExecutable
|
|
161 |
$relativeDirectory = str_replace(ABSPATH, '', $directory);
|
162 |
$this->log("Scanning " . $relativeDirectory . " for its sub-directories and files");
|
163 |
|
164 |
-
$paths = $this->filteredSelectedDirectories($directory, $this->options->includedDirectories);
|
165 |
try {
|
166 |
-
|
167 |
-
$this->options->totalFiles += $this->scanToCacheFile($files, $path->path, $path->flag === Scan::IS_RECURSIVE);
|
168 |
-
}
|
169 |
} catch (Exception $e) {
|
170 |
$this->returnException('Error: ' . $e->getMessage());
|
171 |
}
|
@@ -194,11 +203,8 @@ class Directories extends JobExecutable
|
|
194 |
$relativeDirectory = str_replace(ABSPATH, '', $directory);
|
195 |
$this->log("Scanning " . $relativeDirectory . " for its sub-directories and files");
|
196 |
|
197 |
-
$paths = $this->filteredSelectedDirectories($directory, $this->options->includedDirectories);
|
198 |
try {
|
199 |
-
|
200 |
-
$this->options->totalFiles += $this->scanToCacheFile($files, $path->path, $path->flag === Scan::IS_RECURSIVE);
|
201 |
-
}
|
202 |
} catch (Exception $e) {
|
203 |
$this->returnException('Error: ' . $e->getMessage());
|
204 |
}
|
@@ -225,7 +231,7 @@ class Directories extends JobExecutable
|
|
225 |
}
|
226 |
|
227 |
// Absolute path to uploads folder
|
228 |
-
$directory =
|
229 |
|
230 |
// Skip it
|
231 |
if (!is_dir($directory)) {
|
@@ -244,12 +250,14 @@ class Directories extends JobExecutable
|
|
244 |
$files = $this->open($this->filename, 'a');
|
245 |
|
246 |
$excludePaths = [
|
|
|
247 |
'**/node_modules',
|
248 |
];
|
249 |
-
|
|
|
250 |
|
251 |
try {
|
252 |
-
$this->options->totalFiles += $this->scanToCacheFile($files, $directory, true, $excludePaths);
|
253 |
} catch (Exception $e) {
|
254 |
$this->returnException('Error: ' . $e->getMessage());
|
255 |
}
|
@@ -269,18 +277,21 @@ class Directories extends JobExecutable
|
|
269 |
*/
|
270 |
private function getExtraFiles($folder)
|
271 |
{
|
|
|
|
|
|
|
272 |
|
273 |
-
|
|
|
274 |
return true;
|
275 |
}
|
276 |
|
277 |
// open file handle and attach data to end of file
|
278 |
$files = $this->open($this->filename, 'a');
|
279 |
-
$
|
280 |
-
$this->log("Scanning {$strUtil->getLastElemAfterString( '/', $folder )} for its sub-directories and files");
|
281 |
|
282 |
try {
|
283 |
-
$this->options->totalFiles += $this->scanToCacheFile($files, $
|
284 |
} catch (Exception $e) {
|
285 |
$this->returnException('Error: ' . $e->getMessage());
|
286 |
}
|
@@ -445,18 +456,63 @@ class Directories extends JobExecutable
|
|
445 |
*/
|
446 |
protected function isDirectoryExcluded($directory)
|
447 |
{
|
448 |
-
$directory =
|
449 |
-
|
450 |
-
|
451 |
-
|
452 |
-
$
|
453 |
-
|
454 |
-
|
455 |
-
|
456 |
-
|
|
|
|
|
457 |
}
|
458 |
}
|
459 |
|
460 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
461 |
}
|
462 |
}
|
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;
|
11 |
use WPStaging\Framework\Utils\Strings;
|
12 |
use WPStaging\Framework\Utils\WpDefaultDirectories;
|
13 |
|
36 |
*/
|
37 |
private $filename;
|
38 |
|
39 |
+
/**
|
40 |
+
* @var WpDefaultDirectories
|
41 |
+
*/
|
42 |
+
private $wpDirectories;
|
43 |
+
|
44 |
+
/**
|
45 |
+
* @var Strings
|
46 |
+
*/
|
47 |
+
private $strUtils;
|
48 |
+
|
49 |
/**
|
50 |
* Initialize
|
51 |
*/
|
52 |
public function initialize()
|
53 |
{
|
54 |
$this->filename = $this->cache->getCacheDir() . "files_to_copy." . $this->cache->getCacheExtension();
|
55 |
+
$this->wpDirectories = new WpDefaultDirectories();
|
56 |
+
$this->strUtils = new Strings();
|
57 |
}
|
58 |
|
59 |
/**
|
126 |
$relativeDirectory = str_replace(ABSPATH, '', $directory);
|
127 |
$this->log("Scanning " . $relativeDirectory . " for its sub-directories and files");
|
128 |
|
|
|
|
|
129 |
$excludePaths = [
|
130 |
+
$this->wpDirectories->getRelativeWpContentPath(SlashMode::BOTH_SLASHES) . 'cache',
|
131 |
+
'/' . str_replace(ABSPATH, '', rtrim(WPStaging::getContentDir(), '/')),
|
132 |
+
'**/wp-staging*/**/node_modules', // only exclude node modules in WP Staging's plugins
|
|
|
133 |
];
|
134 |
+
|
135 |
+
if (is_multisite() && !is_main_site()) {
|
136 |
+
$excludePaths[] = $this->wpDirectories->getRelativeUploadPath(SlashMode::LEADING_SLASH);
|
|
|
|
|
137 |
} else {
|
138 |
+
$excludePaths[] = $this->wpDirectories->getRelativeUploadPath(SlashMode::BOTH_SLASHES) . 'sites';
|
139 |
}
|
140 |
|
141 |
+
// add excluded plugins defined by WP Staging
|
142 |
+
$excludePaths = array_merge((new ExcludedPlugins())->getPluginsToExcludeWithRelativePath(), $excludePaths);
|
143 |
+
|
144 |
+
$excludePaths = array_merge($this->getFilteredExcludedPaths(), $excludePaths);
|
145 |
+
|
146 |
try {
|
147 |
+
$this->options->totalFiles += $this->scanToCacheFile($files, $directory, true, $excludePaths, $this->getFilteredExcludedFileSizes());
|
|
|
|
|
148 |
} catch (Exception $e) {
|
149 |
$this->returnException('Error: ' . $e->getMessage());
|
150 |
}
|
173 |
$relativeDirectory = str_replace(ABSPATH, '', $directory);
|
174 |
$this->log("Scanning " . $relativeDirectory . " for its sub-directories and files");
|
175 |
|
|
|
176 |
try {
|
177 |
+
$this->options->totalFiles += $this->scanToCacheFile($files, $directory, true);
|
|
|
|
|
178 |
} catch (Exception $e) {
|
179 |
$this->returnException('Error: ' . $e->getMessage());
|
180 |
}
|
203 |
$relativeDirectory = str_replace(ABSPATH, '', $directory);
|
204 |
$this->log("Scanning " . $relativeDirectory . " for its sub-directories and files");
|
205 |
|
|
|
206 |
try {
|
207 |
+
$this->options->totalFiles += $this->scanToCacheFile($files, $directory, true);
|
|
|
|
|
208 |
} catch (Exception $e) {
|
209 |
$this->returnException('Error: ' . $e->getMessage());
|
210 |
}
|
231 |
}
|
232 |
|
233 |
// Absolute path to uploads folder
|
234 |
+
$directory = $this->wpDirectories->getUploadsPath();
|
235 |
|
236 |
// Skip it
|
237 |
if (!is_dir($directory)) {
|
250 |
$files = $this->open($this->filename, 'a');
|
251 |
|
252 |
$excludePaths = [
|
253 |
+
'/' . str_replace(ABSPATH, ' ', rtrim(WPStaging::getContentDir(), '/')),
|
254 |
'**/node_modules',
|
255 |
];
|
256 |
+
|
257 |
+
$excludePaths = array_merge($this->getFilteredExcludedPaths(), $excludePaths);
|
258 |
|
259 |
try {
|
260 |
+
$this->options->totalFiles += $this->scanToCacheFile($files, $directory, true, $excludePaths, $this->getFilteredExcludedFileSizes());
|
261 |
} catch (Exception $e) {
|
262 |
$this->returnException('Error: ' . $e->getMessage());
|
263 |
}
|
277 |
*/
|
278 |
private function getExtraFiles($folder)
|
279 |
{
|
280 |
+
if (empty($folder)) {
|
281 |
+
return true;
|
282 |
+
}
|
283 |
|
284 |
+
$absoluteExtraPath = ABSPATH . $folder;
|
285 |
+
if (!is_dir($absoluteExtraPath)) {
|
286 |
return true;
|
287 |
}
|
288 |
|
289 |
// open file handle and attach data to end of file
|
290 |
$files = $this->open($this->filename, 'a');
|
291 |
+
$this->log("Scanning {$folder} for its sub-directories and files");
|
|
|
292 |
|
293 |
try {
|
294 |
+
$this->options->totalFiles += $this->scanToCacheFile($files, $absoluteExtraPath, true, $this->getFilteredExcludedPaths(), $this->getFilteredExcludedFileSizes());
|
295 |
} catch (Exception $e) {
|
296 |
$this->returnException('Error: ' . $e->getMessage());
|
297 |
}
|
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 |
+
/**
|
477 |
+
* Return List of all user defined file size excludes from hooks and through UI
|
478 |
+
* @return array
|
479 |
+
*/
|
480 |
+
private function getFilteredExcludedFileSizes()
|
481 |
+
{
|
482 |
+
return apply_filters('wpstg_clone_file_size_exclude', $this->options->excludeSizeRules);
|
483 |
+
}
|
484 |
+
|
485 |
+
/**
|
486 |
+
* Return list of all exclude rules and exclude paths,
|
487 |
+
* Defined by user in hooks or through UI
|
488 |
+
* Defined by WP Staging i.e. cache or some plugins.
|
489 |
+
* @return array
|
490 |
+
*/
|
491 |
+
private function getFilteredExcludedPaths()
|
492 |
+
{
|
493 |
+
$excludePaths = [];
|
494 |
+
$abspath = $this->strUtils->sanitizeDirectorySeparator(ABSPATH);
|
495 |
+
foreach ($this->options->excludedDirectories as $excludedDirectory) {
|
496 |
+
$directory = $this->strUtils->sanitizeDirectorySeparator($excludedDirectory);
|
497 |
+
if ($this->strUtils->startsWith($directory, $abspath)) {
|
498 |
+
$excludePaths[] = '/' . str_replace($abspath, '', $directory);
|
499 |
+
continue;
|
500 |
+
}
|
501 |
+
|
502 |
+
$excludePaths[] = $excludedDirectory;
|
503 |
+
}
|
504 |
+
|
505 |
+
if ($this->isMultisiteAndPro()) {
|
506 |
+
$excludePaths = apply_filters('wpstg_clone_mu_excl_folders', $excludePaths);
|
507 |
+
} else {
|
508 |
+
$excludePaths = apply_filters('wpstg_clone_excl_folders', $excludePaths);
|
509 |
+
}
|
510 |
+
|
511 |
+
$excludeFilters = new ExcludeFilter();
|
512 |
+
$excludeGlobRules = array_map(function ($rule) use ($excludeFilters) {
|
513 |
+
return $excludeFilters->mapExclude($rule);
|
514 |
+
}, $this->options->excludeGlobRules);
|
515 |
+
|
516 |
+
return array_merge($excludePaths, $excludeGlobRules);
|
517 |
}
|
518 |
}
|
Backend/Modules/Jobs/Files.php
CHANGED
@@ -148,10 +148,6 @@ class Files extends JobExecutable
|
|
148 |
throw new \Exception('Can not delete directory: ' . $this->destination . ' This seems to be the root directory. Exclude this directory from deleting and try again.');
|
149 |
}
|
150 |
|
151 |
-
// Make sure destination is inside WordPress
|
152 |
-
$wpRoot = (new Strings())->sanitizeDirectorySeparator(ABSPATH);
|
153 |
-
$this->destination = $wpRoot . str_replace($wpRoot, '', $this->destination);
|
154 |
-
|
155 |
// Finished or path does not exist
|
156 |
if (empty($this->destination) || !is_dir($this->destination)) {
|
157 |
if (defined('WPSTG_DEBUG') && WPSTG_DEBUG) {
|
@@ -180,7 +176,7 @@ class Files extends JobExecutable
|
|
180 |
->setShouldStop([$this, 'isOverThreshold'])
|
181 |
->setRecursive(true);
|
182 |
try {
|
183 |
-
if (!$fs->
|
184 |
return false;
|
185 |
}
|
186 |
} catch (\RuntimeException $ex) {
|
@@ -292,17 +288,17 @@ class Files extends JobExecutable
|
|
292 |
}
|
293 |
|
294 |
if (!$this->options->uploadsSymlinked) {
|
295 |
-
$this->log("Skipped symlinking Wp Uploads Folder");
|
296 |
return true;
|
297 |
}
|
298 |
|
299 |
$symlinker = new WpUploadsFolderSymlinker($this->options->destinationDir);
|
300 |
if ($symlinker->trySymlink()) {
|
301 |
-
$this->log("Uploads Folder symlinked with the production site");
|
302 |
return true;
|
303 |
}
|
304 |
|
305 |
-
$this->returnException(
|
306 |
return false;
|
307 |
}
|
308 |
|
@@ -624,6 +620,12 @@ class Files extends JobExecutable
|
|
624 |
$directory = $this->sanitizeDirectorySeparator($directory);
|
625 |
|
626 |
foreach ($this->options->extraDirectories as $extraDirectory) {
|
|
|
|
|
|
|
|
|
|
|
|
|
627 |
if (strpos($directory, $this->sanitizeDirectorySeparator($extraDirectory)) === 0) {
|
628 |
return true;
|
629 |
}
|
148 |
throw new \Exception('Can not delete directory: ' . $this->destination . ' This seems to be the root directory. Exclude this directory from deleting and try again.');
|
149 |
}
|
150 |
|
|
|
|
|
|
|
|
|
151 |
// Finished or path does not exist
|
152 |
if (empty($this->destination) || !is_dir($this->destination)) {
|
153 |
if (defined('WPSTG_DEBUG') && WPSTG_DEBUG) {
|
176 |
->setShouldStop([$this, 'isOverThreshold'])
|
177 |
->setRecursive(true);
|
178 |
try {
|
179 |
+
if (!$fs->delete($this->destination)) {
|
180 |
return false;
|
181 |
}
|
182 |
} catch (\RuntimeException $ex) {
|
288 |
}
|
289 |
|
290 |
if (!$this->options->uploadsSymlinked) {
|
291 |
+
$this->log(__("Skipped symlinking Wp Uploads Folder", 'wp-staging'));
|
292 |
return true;
|
293 |
}
|
294 |
|
295 |
$symlinker = new WpUploadsFolderSymlinker($this->options->destinationDir);
|
296 |
if ($symlinker->trySymlink()) {
|
297 |
+
$this->log(__("Uploads Folder symlinked with the production site", 'wp-staging'));
|
298 |
return true;
|
299 |
}
|
300 |
|
301 |
+
$this->returnException($symlinker->getError());
|
302 |
return false;
|
303 |
}
|
304 |
|
620 |
$directory = $this->sanitizeDirectorySeparator($directory);
|
621 |
|
622 |
foreach ($this->options->extraDirectories as $extraDirectory) {
|
623 |
+
$extraDirectory = trim($extraDirectory);
|
624 |
+
|
625 |
+
if (empty($extraDirectory)) {
|
626 |
+
continue;
|
627 |
+
}
|
628 |
+
|
629 |
if (strpos($directory, $this->sanitizeDirectorySeparator($extraDirectory)) === 0) {
|
630 |
return true;
|
631 |
}
|
Backend/Modules/Jobs/Job.php
CHANGED
@@ -10,10 +10,10 @@ if (!defined("WPINC")) {
|
|
10 |
use DateInterval;
|
11 |
use DateTime;
|
12 |
use Exception;
|
13 |
-
use WPStaging\Core\thirdParty\thirdPartyCompatibility;
|
14 |
use WPStaging\Core\Utils\Cache;
|
15 |
use WPStaging\Core\Utils\Logger;
|
16 |
use WPStaging\Core\WPStaging;
|
|
|
17 |
use WPStaging\Framework\Interfaces\ShutdownableInterface;
|
18 |
use WPStaging\Framework\Traits\ResourceTrait;
|
19 |
|
@@ -57,10 +57,9 @@ abstract class Job implements ShutdownableInterface
|
|
57 |
protected $baseUrl;
|
58 |
|
59 |
/**
|
60 |
-
*
|
61 |
-
* @var object
|
62 |
*/
|
63 |
-
protected $
|
64 |
|
65 |
/**
|
66 |
* Job constructor.
|
@@ -68,7 +67,8 @@ abstract class Job implements ShutdownableInterface
|
|
68 |
*/
|
69 |
public function __construct()
|
70 |
{
|
71 |
-
|
|
|
72 |
|
73 |
// Services
|
74 |
$this->cache = new Cache(-1, WPStaging::getContentDir());
|
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 |
|
57 |
protected $baseUrl;
|
58 |
|
59 |
/**
|
60 |
+
* @var ExcludedTables
|
|
|
61 |
*/
|
62 |
+
protected $excludedTableService;
|
63 |
|
64 |
/**
|
65 |
* Job constructor.
|
67 |
*/
|
68 |
public function __construct()
|
69 |
{
|
70 |
+
// TODO: inject using DI
|
71 |
+
$this->excludedTableService = new ExcludedTables();
|
72 |
|
73 |
// Services
|
74 |
$this->cache = new Cache(-1, WPStaging::getContentDir());
|
Backend/Modules/Jobs/PreserveDataFirstStep.php
CHANGED
@@ -4,6 +4,7 @@ namespace WPStaging\Backend\Modules\Jobs;
|
|
4 |
|
5 |
use WPStaging\Core\WPStaging;
|
6 |
use WPStaging\Framework\Adapter\SourceDatabase;
|
|
|
7 |
|
8 |
/**
|
9 |
* Preserve staging sites in wpstg_existing_clones_beta in staging database while updating a site
|
@@ -80,24 +81,46 @@ class PreserveDataFirstStep extends JobExecutable
|
|
80 |
}
|
81 |
|
82 |
// Get wpstg_existing_clones_beta from staging database
|
83 |
-
$
|
84 |
$this->stagingDb->prepare(
|
85 |
"SELECT `option_value` FROM " . $this->stagingPrefix . "options WHERE `option_name` = %s",
|
86 |
"wpstg_existing_clones_beta"
|
87 |
)
|
88 |
);
|
89 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
90 |
// Nothing to do
|
91 |
-
if (!$
|
92 |
return true;
|
93 |
}
|
94 |
|
95 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
$insert = $this->productionDb->query(
|
97 |
$this->productionDb->prepare(
|
98 |
"INSERT INTO `" . $this->productionDb->prefix . "options` ( `option_id`, `option_name`, `option_value`, `autoload` ) VALUES ( NULL , %s, %s, %s )",
|
99 |
"wpstg_tmp_data",
|
100 |
-
$
|
101 |
"no"
|
102 |
)
|
103 |
);
|
@@ -105,12 +128,23 @@ class PreserveDataFirstStep extends JobExecutable
|
|
105 |
if ($delete === false) {
|
106 |
$this->log("Preserve Data: Failed to delete wpstg_tmp_data");
|
107 |
}
|
108 |
-
|
|
|
109 |
$this->log("Preserve Data: Failed to get wpstg_existing_clones_beta");
|
110 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
111 |
if ($insert === false) {
|
112 |
$this->log("Preserve Data: Failed to insert wpstg_existing_clones_beta to wpstg_tmp_data");
|
113 |
}
|
|
|
114 |
return true;
|
115 |
}
|
116 |
|
4 |
|
5 |
use WPStaging\Core\WPStaging;
|
6 |
use WPStaging\Framework\Adapter\SourceDatabase;
|
7 |
+
use WPStaging\Framework\Staging\CloneOptions;
|
8 |
|
9 |
/**
|
10 |
* Preserve staging sites in wpstg_existing_clones_beta in staging database while updating a site
|
81 |
}
|
82 |
|
83 |
// Get wpstg_existing_clones_beta from staging database
|
84 |
+
$stagingSites = $this->stagingDb->get_var(
|
85 |
$this->stagingDb->prepare(
|
86 |
"SELECT `option_value` FROM " . $this->stagingPrefix . "options WHERE `option_name` = %s",
|
87 |
"wpstg_existing_clones_beta"
|
88 |
)
|
89 |
);
|
90 |
|
91 |
+
// Get wpstg_settings from staging database
|
92 |
+
$settings = $this->stagingDb->get_var(
|
93 |
+
$this->stagingDb->prepare(
|
94 |
+
"SELECT `option_value` FROM " . $this->stagingPrefix . "options WHERE `option_name` = %s",
|
95 |
+
"wpstg_settings"
|
96 |
+
)
|
97 |
+
);
|
98 |
+
|
99 |
+
// Get wpstg_clone_options from staging database
|
100 |
+
$cloneOptions = $this->stagingDb->get_var(
|
101 |
+
$this->stagingDb->prepare(
|
102 |
+
"SELECT `option_value` FROM " . $this->stagingPrefix . "options WHERE `option_name` = %s",
|
103 |
+
CloneOptions::WPSTG_CLONE_SETTINGS_KEY
|
104 |
+
)
|
105 |
+
);
|
106 |
+
|
107 |
// Nothing to do
|
108 |
+
if (!$stagingSites && !$settings && !$cloneOptions) {
|
109 |
return true;
|
110 |
}
|
111 |
|
112 |
+
$tmpData = serialize((object) [
|
113 |
+
'stagingSites' => $stagingSites,
|
114 |
+
'settings' => $settings,
|
115 |
+
'cloneOptions' => $cloneOptions,
|
116 |
+
]);
|
117 |
+
|
118 |
+
// Insert staging site preserved data into wpstg_tmp_data in production database
|
119 |
$insert = $this->productionDb->query(
|
120 |
$this->productionDb->prepare(
|
121 |
"INSERT INTO `" . $this->productionDb->prefix . "options` ( `option_id`, `option_name`, `option_value`, `autoload` ) VALUES ( NULL , %s, %s, %s )",
|
122 |
"wpstg_tmp_data",
|
123 |
+
$tmpData,
|
124 |
"no"
|
125 |
)
|
126 |
);
|
128 |
if ($delete === false) {
|
129 |
$this->log("Preserve Data: Failed to delete wpstg_tmp_data");
|
130 |
}
|
131 |
+
|
132 |
+
if ($stagingSites === false) {
|
133 |
$this->log("Preserve Data: Failed to get wpstg_existing_clones_beta");
|
134 |
}
|
135 |
+
|
136 |
+
if ($settings === false) {
|
137 |
+
$this->log("Preserve Data: Failed to get wpstg_settings");
|
138 |
+
}
|
139 |
+
|
140 |
+
if ($cloneOptions === false) {
|
141 |
+
$this->log("Preserve Data: Failed to get wpstg_clone_options");
|
142 |
+
}
|
143 |
+
|
144 |
if ($insert === false) {
|
145 |
$this->log("Preserve Data: Failed to insert wpstg_existing_clones_beta to wpstg_tmp_data");
|
146 |
}
|
147 |
+
|
148 |
return true;
|
149 |
}
|
150 |
|
Backend/Modules/Jobs/PreserveDataSecondStep.php
CHANGED
@@ -4,6 +4,7 @@ namespace WPStaging\Backend\Modules\Jobs;
|
|
4 |
|
5 |
use WPStaging\Core\WPStaging;
|
6 |
use WPStaging\Framework\Adapter\SourceDatabase;
|
|
|
7 |
|
8 |
/**
|
9 |
* Copy wpstg_tmp_data back to wpstg_existing_clones_beta after cloning with class::PreserveDataSecondStep
|
@@ -80,30 +81,90 @@ class PreserveDataSecondStep extends JobExecutable
|
|
80 |
return true;
|
81 |
}
|
82 |
|
83 |
-
// Delete wpstg_tmp_data
|
84 |
-
$
|
|
|
|
|
|
|
|
|
|
|
85 |
$this->stagingDb->prepare("DELETE FROM " . $this->stagingPrefix . "options WHERE `option_name` = %s", "wpstg_existing_clones_beta")
|
86 |
);
|
87 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
88 |
// Insert wpstg_existing_clones_beta in staging database
|
89 |
-
$
|
90 |
$this->stagingDb->prepare(
|
91 |
"INSERT INTO `" . $this->stagingPrefix . "options` ( `option_id`, `option_name`, `option_value`, `autoload` ) VALUES ( NULL , %s, %s, %s )",
|
92 |
"wpstg_existing_clones_beta",
|
93 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
94 |
"no"
|
95 |
)
|
96 |
);
|
97 |
|
98 |
-
if ($
|
99 |
-
$this->log("Preserve Data Second Step: Failed to delete wpstg_tmp_data");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
}
|
|
|
101 |
if ($result === false) {
|
102 |
-
$this->log("Preserve Data Second Step: Failed to get
|
|
|
|
|
|
|
|
|
103 |
}
|
104 |
-
|
105 |
-
|
|
|
|
|
|
|
|
|
|
|
106 |
}
|
|
|
107 |
return true;
|
108 |
}
|
109 |
}
|
4 |
|
5 |
use WPStaging\Core\WPStaging;
|
6 |
use WPStaging\Framework\Adapter\SourceDatabase;
|
7 |
+
use WPStaging\Framework\Staging\CloneOptions;
|
8 |
|
9 |
/**
|
10 |
* Copy wpstg_tmp_data back to wpstg_existing_clones_beta after cloning with class::PreserveDataSecondStep
|
81 |
return true;
|
82 |
}
|
83 |
|
84 |
+
// Delete wpstg_tmp_data from the production site
|
85 |
+
$deleteTmpData = $this->productionDb->query(
|
86 |
+
$this->productionDb->prepare("DELETE FROM " . $this->productionDb->prefix . "options WHERE `option_name` = %s", "wpstg_tmp_data")
|
87 |
+
);
|
88 |
+
|
89 |
+
// Delete wpstg_existing_clones_beta from the staging site
|
90 |
+
$deleteStagingSites = $this->stagingDb->query(
|
91 |
$this->stagingDb->prepare("DELETE FROM " . $this->stagingPrefix . "options WHERE `option_name` = %s", "wpstg_existing_clones_beta")
|
92 |
);
|
93 |
|
94 |
+
// Delete wpstg_settings from the staging site
|
95 |
+
$deleteSettings = $this->stagingDb->query(
|
96 |
+
$this->stagingDb->prepare("DELETE FROM " . $this->stagingPrefix . "options WHERE `option_name` = %s", "wpstg_settings")
|
97 |
+
);
|
98 |
+
|
99 |
+
// Delete wpstg_clone_options from the staging site
|
100 |
+
$deleteCloneOptions = $this->stagingDb->query(
|
101 |
+
$this->stagingDb->prepare("DELETE FROM " . $this->stagingPrefix . "options WHERE `option_name` = %s", CloneOptions::WPSTG_CLONE_SETTINGS_KEY)
|
102 |
+
);
|
103 |
+
|
104 |
+
$tempData = maybe_unserialize($result);
|
105 |
+
|
106 |
// Insert wpstg_existing_clones_beta in staging database
|
107 |
+
$insertStagingSites = $this->stagingDb->query(
|
108 |
$this->stagingDb->prepare(
|
109 |
"INSERT INTO `" . $this->stagingPrefix . "options` ( `option_id`, `option_name`, `option_value`, `autoload` ) VALUES ( NULL , %s, %s, %s )",
|
110 |
"wpstg_existing_clones_beta",
|
111 |
+
$tempData->stagingSites,
|
112 |
+
"no"
|
113 |
+
)
|
114 |
+
);
|
115 |
+
|
116 |
+
// Insert wpstg_settings in staging database
|
117 |
+
$insertSettings = $this->stagingDb->query(
|
118 |
+
$this->stagingDb->prepare(
|
119 |
+
"INSERT INTO `" . $this->stagingPrefix . "options` ( `option_id`, `option_name`, `option_value`, `autoload` ) VALUES ( NULL , %s, %s, %s )",
|
120 |
+
"wpstg_settings",
|
121 |
+
$tempData->settings,
|
122 |
+
"no"
|
123 |
+
)
|
124 |
+
);
|
125 |
+
|
126 |
+
// Insert wpstg_clone_options in staging database
|
127 |
+
$insertCloneOptions = $this->stagingDb->query(
|
128 |
+
$this->stagingDb->prepare(
|
129 |
+
"INSERT INTO `" . $this->stagingPrefix . "options` ( `option_id`, `option_name`, `option_value`, `autoload` ) VALUES ( NULL , %s, %s, %s )",
|
130 |
+
CloneOptions::WPSTG_CLONE_SETTINGS_KEY,
|
131 |
+
$tempData->cloneOptions,
|
132 |
"no"
|
133 |
)
|
134 |
);
|
135 |
|
136 |
+
if ($deleteTmpData === false) {
|
137 |
+
$this->log("Preserve Data Second Step: Failed to delete wpstg_tmp_data from the production site");
|
138 |
+
}
|
139 |
+
|
140 |
+
if ($deleteStagingSites === false) {
|
141 |
+
$this->log("Preserve Data Second Step: Failed to delete wpstg_existing_clones_beta from the staging site");
|
142 |
+
}
|
143 |
+
|
144 |
+
if ($deleteSettings === false) {
|
145 |
+
$this->log("Preserve Data Second Step: Failed to delete wpstg_settings from the staging site");
|
146 |
+
}
|
147 |
+
|
148 |
+
if ($deleteCloneOptions === false) {
|
149 |
+
$this->log("Preserve Data Second Step: Failed to delete wpstg_clone_options from the staging site");
|
150 |
}
|
151 |
+
|
152 |
if ($result === false) {
|
153 |
+
$this->log("Preserve Data Second Step: Failed to get wpstg_tmp_data from the production site");
|
154 |
+
}
|
155 |
+
|
156 |
+
if ($insertStagingSites === false) {
|
157 |
+
$this->log("Preserve Data Second Step: Failed to insert preserved existing clones into wpstg_existing_clones_beta of the staging site");
|
158 |
}
|
159 |
+
|
160 |
+
if ($insertSettings === false) {
|
161 |
+
$this->log("Preserve Data Second Step: Failed to insert preserved settings into wpstg_settings of the staging site");
|
162 |
+
}
|
163 |
+
|
164 |
+
if ($insertCloneOptions === false) {
|
165 |
+
$this->log("Preserve Data Second Step: Failed to insert preserved clone options into wpstg_settings of the staging site");
|
166 |
}
|
167 |
+
|
168 |
return true;
|
169 |
}
|
170 |
}
|
Backend/Modules/Jobs/ProcessLock.php
CHANGED
@@ -23,7 +23,7 @@ class ProcessLock extends JobExecutable
|
|
23 |
if (parent::isRunning()) {
|
24 |
$this->log("Another process is running");
|
25 |
|
26 |
-
$message = __('Hold on, another WP
|
27 |
|
28 |
require_once WPSTG_PLUGIN_DIR . "Backend/views/clone/ajax/process-lock.php";
|
29 |
|
@@ -34,6 +34,31 @@ class ProcessLock extends JobExecutable
|
|
34 |
return false;
|
35 |
}
|
36 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
37 |
/**
|
38 |
* remove process lock value
|
39 |
*/
|
23 |
if (parent::isRunning()) {
|
24 |
$this->log("Another process is running");
|
25 |
|
26 |
+
$message = __('Hold on, another WP STAGING process is already running...', 'wp-staging');
|
27 |
|
28 |
require_once WPSTG_PLUGIN_DIR . "Backend/views/clone/ajax/process-lock.php";
|
29 |
|
34 |
return false;
|
35 |
}
|
36 |
|
37 |
+
/**
|
38 |
+
* Check if any process is already running, if running return a json encoded response for Swal Modal,
|
39 |
+
* Otherwise return false
|
40 |
+
*
|
41 |
+
* @return boolean|string
|
42 |
+
*/
|
43 |
+
public function ajaxIsRunning()
|
44 |
+
{
|
45 |
+
if (parent::isRunning()) {
|
46 |
+
return json_encode([
|
47 |
+
'success' => false,
|
48 |
+
'type' => 'processLock',
|
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 |
+
],
|
56 |
+
]);
|
57 |
+
}
|
58 |
+
|
59 |
+
return false;
|
60 |
+
}
|
61 |
+
|
62 |
/**
|
63 |
* remove process lock value
|
64 |
*/
|
Backend/Modules/Jobs/Scan.php
CHANGED
@@ -11,12 +11,12 @@ use Countable;
|
|
11 |
use DirectoryIterator;
|
12 |
use Exception;
|
13 |
use WPStaging\Backend\Optimizer\Optimizer;
|
14 |
-
use WPStaging\Core\Iterators;
|
15 |
use WPStaging\Core\Utils\Directories as DirectoriesUtil;
|
16 |
use WPStaging\Core\WPStaging;
|
17 |
use WPStaging\Framework\Database\LegacyDatabaseInfo;
|
18 |
-
use WPStaging\Framework\
|
19 |
use WPStaging\Framework\Utils\Strings;
|
|
|
20 |
|
21 |
/**
|
22 |
* Class Scan
|
@@ -26,35 +26,58 @@ use WPStaging\Framework\Utils\Strings;
|
|
26 |
*/
|
27 |
class Scan extends Job
|
28 |
{
|
|
|
29 |
/**
|
30 |
-
*
|
|
|
|
|
31 |
* @var string
|
32 |
*/
|
33 |
-
const
|
34 |
|
35 |
/**
|
36 |
-
*
|
|
|
|
|
37 |
* @var string
|
38 |
*/
|
39 |
-
const
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
|
41 |
/**
|
42 |
-
*
|
43 |
-
* @var int
|
44 |
*/
|
45 |
-
|
46 |
|
47 |
/**
|
48 |
-
*
|
49 |
-
* @var int
|
50 |
*/
|
51 |
-
|
52 |
|
53 |
-
|
54 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
55 |
|
56 |
-
|
57 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
|
59 |
/**
|
60 |
* Upon class initialization
|
@@ -63,6 +86,11 @@ class Scan extends Job
|
|
63 |
{
|
64 |
$this->objDirectories = new DirectoriesUtil();
|
65 |
|
|
|
|
|
|
|
|
|
|
|
66 |
$this->getTables();
|
67 |
|
68 |
$this->getDirectories();
|
@@ -84,6 +112,7 @@ class Scan extends Job
|
|
84 |
|
85 |
if (isset($_POST["clone"]) && array_key_exists($_POST["clone"], $this->options->existingClones)) {
|
86 |
$this->options->current = $_POST["clone"];
|
|
|
87 |
}
|
88 |
|
89 |
// Tables
|
@@ -109,8 +138,14 @@ class Scan extends Job
|
|
109 |
|
110 |
// Define mainJob to differentiate between cloning, updating and pushing
|
111 |
$this->options->mainJob = 'cloning';
|
|
|
|
|
|
|
|
|
112 |
|
113 |
-
if ($this->options->current !== null) {
|
|
|
|
|
114 |
$this->options->mainJob = 'updating';
|
115 |
}
|
116 |
|
@@ -154,19 +189,30 @@ class Scan extends Job
|
|
154 |
}
|
155 |
|
156 |
/**
|
157 |
-
* @param null|
|
158 |
-
* @param bool $
|
|
|
|
|
|
|
159 |
* @return string
|
|
|
|
|
160 |
*/
|
161 |
-
public function directoryListing($
|
162 |
{
|
163 |
-
|
164 |
-
$directories = $this->directories;
|
165 |
-
}
|
166 |
-
|
167 |
// Sort results
|
168 |
uksort($directories, 'strcasecmp');
|
169 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
170 |
$output = '';
|
171 |
foreach ($directories as $name => $directory) {
|
172 |
// Not a directory, possibly a symlink, therefore we will skip it
|
@@ -178,17 +224,13 @@ class Scan extends Job
|
|
178 |
$data = reset($directory);
|
179 |
unset($directory[key($directory)]);
|
180 |
|
181 |
-
|
182 |
-
$isChecked = (
|
183 |
-
empty($this->options->includedDirectories) ||
|
184 |
-
in_array($data["path"], $this->options->includedDirectories)
|
185 |
-
);
|
186 |
-
|
187 |
$dataPath = isset($data["path"]) ? $data["path"] : '';
|
188 |
$dataSize = isset($data["size"]) ? $data["size"] : '';
|
189 |
$strUtils = new Strings();
|
190 |
-
$path
|
191 |
-
$wpRoot
|
|
|
|
|
192 |
|
193 |
// Select all wp core folders and their sub dirs.
|
194 |
// Unselect all other folders (default setting)
|
@@ -200,41 +242,47 @@ class Scan extends Job
|
|
200 |
strpos(strrev($path), strrev($wpRoot . "wp-includes")) === false &&
|
201 |
strpos(strrev($path), strrev($wpRoot . "wp-content")) === false;
|
202 |
|
203 |
-
//
|
204 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
205 |
|
206 |
$output .= "<div class='wpstg-dir'>";
|
207 |
$output .= "<input type='checkbox' class='wpstg-check-dir " . $class . "'";
|
208 |
|
209 |
-
|
210 |
-
|
|
|
|
|
|
|
211 |
}
|
212 |
|
213 |
-
|
214 |
-
|
215 |
-
$dirPath = $dataPath;
|
216 |
-
if ($class === 'wpstg-root') {
|
217 |
-
$dirPath = $this->appendRecursiveFlag($dirPath, $isScanned);
|
218 |
}
|
219 |
|
220 |
-
$
|
|
|
|
|
|
|
|
|
221 |
|
222 |
$output .= "<a href='#' class='wpstg-expand-dirs ";
|
223 |
-
if (
|
224 |
$output .= " disabled";
|
225 |
}
|
226 |
|
227 |
$output .= "'>{$name}";
|
228 |
$output .= "</a>";
|
|
|
229 |
$output .= "<span class='wpstg-size-info'>{$this->formatSize( $dataSize )}</span>";
|
230 |
$output .= isset($this->settings->debugMode) ? "<span class='wpstg-size-info'> {$dataPath}</span>" : "";
|
231 |
-
|
232 |
-
if ($isScanned) {
|
233 |
-
$output .= "<div class='wpstg-dir wpstg-subdir'>";
|
234 |
-
$output .= $this->directoryListing($directory, $isDisabled);
|
235 |
-
$output .= "</div>";
|
236 |
-
}
|
237 |
-
|
238 |
$output .= "</div>";
|
239 |
}
|
240 |
|
@@ -242,19 +290,44 @@ class Scan extends Job
|
|
242 |
}
|
243 |
|
244 |
/**
|
245 |
-
* Checks if there is enough free disk space to create staging site
|
246 |
* Returns null when can't run disk_free_space function one way or another
|
|
|
|
|
|
|
247 |
* @return bool|null
|
248 |
*/
|
249 |
-
public function hasFreeDiskSpace()
|
250 |
{
|
251 |
if (!function_exists("disk_free_space")) {
|
252 |
return null;
|
253 |
}
|
254 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
255 |
|
256 |
$data = [
|
257 |
-
'usedspace' => $this->formatSize($
|
258 |
];
|
259 |
|
260 |
echo json_encode($data);
|
@@ -299,12 +372,16 @@ class Scan extends Job
|
|
299 |
}
|
300 |
|
301 |
/**
|
302 |
-
* Get directories and main meta data about
|
|
|
303 |
*/
|
304 |
-
protected function getDirectories()
|
305 |
{
|
|
|
|
|
|
|
306 |
|
307 |
-
$directories = new
|
308 |
|
309 |
foreach ($directories as $directory) {
|
310 |
// Not a valid directory
|
@@ -312,54 +389,18 @@ class Scan extends Job
|
|
312 |
continue;
|
313 |
}
|
314 |
|
315 |
-
$
|
316 |
-
|
317 |
-
// Get Sub-directories
|
318 |
-
$this->getSubDirectories($directory->getRealPath());
|
319 |
-
}
|
320 |
-
|
321 |
-
// Gather Plugins
|
322 |
-
$this->getSubDirectories(WP_PLUGIN_DIR);
|
323 |
-
|
324 |
-
// Gather Themes
|
325 |
-
$this->getSubDirectories(WP_CONTENT_DIR . DIRECTORY_SEPARATOR . "themes");
|
326 |
-
|
327 |
-
// Gather Custom Uploads Folder if there is one
|
328 |
-
$this->getSubDirectories((new WpDefaultDirectories())->getSiteUploadsPath());
|
329 |
-
}
|
330 |
-
|
331 |
-
/**
|
332 |
-
* @param string $path
|
333 |
-
* @return bool
|
334 |
-
*/
|
335 |
-
protected function getSubDirectories($path)
|
336 |
-
{
|
337 |
-
|
338 |
-
if (!is_readable($path)) {
|
339 |
-
return false;
|
340 |
-
}
|
341 |
-
|
342 |
-
if (!is_dir($path)) {
|
343 |
-
return false;
|
344 |
-
}
|
345 |
-
|
346 |
-
// IMPORTANT: This is necessary if directory does not belongs to current php user
|
347 |
-
// DirectoryIterator() will throw a fatal error which can not be catched with is_readable()
|
348 |
-
if (!opendir($path)) {
|
349 |
-
return false;
|
350 |
-
}
|
351 |
-
|
352 |
-
$directories = new DirectoryIterator($path);
|
353 |
-
|
354 |
-
foreach ($directories as $directory) {
|
355 |
-
// Not a valid directory
|
356 |
-
if (($path = $this->getPath($directory)) === false) {
|
357 |
continue;
|
358 |
}
|
359 |
|
360 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
361 |
}
|
362 |
-
return false;
|
363 |
}
|
364 |
|
365 |
/**
|
@@ -369,16 +410,15 @@ class Scan extends Job
|
|
369 |
*/
|
370 |
protected function getPath($directory)
|
371 |
{
|
372 |
-
|
373 |
/*
|
374 |
* Do not follow root path like src/web/..
|
375 |
* This must be done before \SplFileInfo->isDir() is used!
|
376 |
* Prevents open base dir restriction fatal errors
|
377 |
*/
|
378 |
-
|
379 |
if (strpos($directory->getRealPath(), WPStaging::getWPpath()) !== 0) {
|
380 |
return false;
|
381 |
}
|
|
|
382 |
$path = str_replace(WPStaging::getWPpath(), null, $directory->getRealPath());
|
383 |
// Using strpos() for symbolic links as they could create nasty stuff in nix stuff for directory structures
|
384 |
if (!$directory->isDir() || strlen($path) < 1) {
|
@@ -443,40 +483,75 @@ class Scan extends Job
|
|
443 |
/**
|
444 |
* Get total size of a directory including all its subdirectories
|
445 |
* @param string $dir
|
|
|
446 |
* @return int
|
447 |
*/
|
448 |
-
protected function getDirectorySizeInclSubdirs($dir)
|
449 |
{
|
450 |
$size = 0;
|
451 |
foreach (glob(rtrim($dir, '/') . '/*', GLOB_NOSORT) as $each) {
|
452 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
453 |
}
|
|
|
454 |
return $size;
|
455 |
}
|
456 |
|
457 |
/**
|
458 |
-
*
|
459 |
-
*
|
460 |
-
*
|
461 |
-
* so append IS_NON_RECURSIVE flag i.e. 0 to it.
|
462 |
-
* And we only need IS_RECURSIVE flag i.e. 1 for non scanned directories
|
463 |
-
* to custom recursive iterator over all it sub directories.
|
464 |
-
* Also remove wp root path from the directory path.
|
465 |
-
* @param string $directoryPath
|
466 |
-
* @param bool $isScanned
|
467 |
-
* @return string
|
468 |
*/
|
469 |
-
protected function
|
470 |
{
|
471 |
-
|
472 |
-
|
473 |
-
|
474 |
-
// no need to recursively iterate in directory job if already scanned
|
475 |
-
if ($isScanned) {
|
476 |
-
$filteredPath["isRecursive"] = self::IS_NON_RECURSIVE;
|
477 |
}
|
478 |
|
479 |
-
|
480 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
481 |
}
|
482 |
}
|
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
|
26 |
*/
|
27 |
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
|
35 |
*/
|
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
|
43 |
*/
|
44 |
+
const WP_NON_CORE_DIR = "wpstg-wp-non-core-dir";
|
45 |
+
|
46 |
+
/** @var array */
|
47 |
+
private $directories = [];
|
48 |
+
|
49 |
+
/** @var DirectoriesUtil */
|
50 |
+
private $objDirectories;
|
51 |
|
52 |
/**
|
53 |
+
* @var string
|
|
|
54 |
*/
|
55 |
+
private $directoryToScanOnly;
|
56 |
|
57 |
/**
|
58 |
+
* @var string Path to gif loader for directory loading
|
|
|
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
|
65 |
+
// Santized the path to make comparing works for windows platform too.
|
66 |
+
$this->directoryToScanOnly = null;
|
67 |
+
if ($directoryToScanOnly !== null) {
|
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
|
86 |
{
|
87 |
$this->objDirectories = new DirectoriesUtil();
|
88 |
|
89 |
+
if ($this->directoryToScanOnly !== null) {
|
90 |
+
$this->getDirectories($this->directoryToScanOnly);
|
91 |
+
return;
|
92 |
+
}
|
93 |
+
|
94 |
$this->getTables();
|
95 |
|
96 |
$this->getDirectories();
|
112 |
|
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
|
138 |
|
139 |
// Define mainJob to differentiate between cloning, updating and pushing
|
140 |
$this->options->mainJob = 'cloning';
|
141 |
+
$job = '';
|
142 |
+
if (isset($_POST["job"])) {
|
143 |
+
$job = $_POST['job'];
|
144 |
+
}
|
145 |
|
146 |
+
if ($this->options->current !== null && $job === 'resetting') {
|
147 |
+
$this->options->mainJob = 'resetting';
|
148 |
+
} elseif ($this->options->current !== null) {
|
149 |
$this->options->mainJob = 'updating';
|
150 |
}
|
151 |
|
189 |
}
|
190 |
|
191 |
/**
|
192 |
+
* @param null|bool $parentChecked Is parent folder selected
|
193 |
+
* @param bool $forceDefault Default false. Set it to true,
|
194 |
+
* when default button on ui is clicked,
|
195 |
+
* to ignore previous selected option for UPDATE and RESET process.
|
196 |
+
*
|
197 |
* @return string
|
198 |
+
*
|
199 |
+
* @todo create a template for ui
|
200 |
*/
|
201 |
+
public function directoryListing($parentChecked = null, $forceDefault = false)
|
202 |
{
|
203 |
+
$directories = $this->directories;
|
|
|
|
|
|
|
204 |
// Sort results
|
205 |
uksort($directories, 'strcasecmp');
|
206 |
|
207 |
+
$excludedDirectories = [];
|
208 |
+
$extraDirectories = [];
|
209 |
+
|
210 |
+
if ($this->isUpdateOrResetJob()) {
|
211 |
+
$currentClone = json_decode(json_encode($this->options->currentClone));
|
212 |
+
$excludedDirectories = isset($currentClone->excludedDirectories) ? $currentClone->excludedDirectories : [];
|
213 |
+
$extraDirectories = isset($currentClone->extraDirectories) ? $currentClone->extraDirectories : [];
|
214 |
+
}
|
215 |
+
|
216 |
$output = '';
|
217 |
foreach ($directories as $name => $directory) {
|
218 |
// Not a directory, possibly a symlink, therefore we will skip it
|
224 |
$data = reset($directory);
|
225 |
unset($directory[key($directory)]);
|
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)
|
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()) {
|
263 |
+
$shouldBeChecked = false;
|
264 |
}
|
265 |
|
266 |
+
if (!$forceDefault && $this->isUpdateOrResetJob() && $class === self::WP_NON_CORE_DIR && !$this->isPathInDirectories($relPath, $extraDirectories)) {
|
267 |
+
$shouldBeChecked = false;
|
|
|
|
|
|
|
268 |
}
|
269 |
|
270 |
+
if ($shouldBeChecked && ($parentChecked !== false)) {
|
271 |
+
$output .= " checked";
|
272 |
+
}
|
273 |
+
|
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 |
}
|
288 |
|
290 |
}
|
291 |
|
292 |
/**
|
293 |
+
* Checks if there is enough free disk space to create staging site according to selected directories
|
294 |
* Returns null when can't run disk_free_space function one way or another
|
295 |
+
* @param string $excludedDirectories
|
296 |
+
* @param string $extraDirectories
|
297 |
+
*
|
298 |
* @return bool|null
|
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);
|
309 |
+
|
310 |
+
$size = 0;
|
311 |
+
// Scan WP Root path for size (only files)
|
312 |
+
$size += $this->getDirectorySizeExcludingSubdirs(ABSPATH);
|
313 |
+
// Scan selected directories for size (wp-core)
|
314 |
+
foreach ($selectedDirectories as $directory) {
|
315 |
+
if ($this->isPathInDirectories($directory, $excludedDirectories)) {
|
316 |
+
continue;
|
317 |
+
}
|
318 |
+
|
319 |
+
$size += $this->getDirectorySizeInclSubdirs($directory, $excludedDirectories);
|
320 |
+
}
|
321 |
+
|
322 |
+
if (!empty($extraDirectories) && $extraDirectories !== '') {
|
323 |
+
$extraDirectories = wpstg_urldecode(explode(ScanConst::DIRECTORIES_SEPARATOR, $extraDirectories));
|
324 |
+
foreach ($extraDirectories as $directory) {
|
325 |
+
$size += $this->getDirectorySizeInclSubdirs(ABSPATH . $directory, $excludedDirectories);
|
326 |
+
}
|
327 |
+
}
|
328 |
|
329 |
$data = [
|
330 |
+
'usedspace' => $this->formatSize($size)
|
331 |
];
|
332 |
|
333 |
echo json_encode($data);
|
372 |
}
|
373 |
|
374 |
/**
|
375 |
+
* Get directories and main meta data about given directory path
|
376 |
+
* @param string $dirPath - Optional - Default ABSPATH
|
377 |
*/
|
378 |
+
protected function getDirectories($dirPath = ABSPATH)
|
379 |
{
|
380 |
+
if (!is_dir($dirPath)) {
|
381 |
+
return;
|
382 |
+
}
|
383 |
|
384 |
+
$directories = new DirectoryIterator($dirPath);
|
385 |
|
386 |
foreach ($directories as $directory) {
|
387 |
// Not a valid directory
|
389 |
continue;
|
390 |
}
|
391 |
|
392 |
+
if ($directory->isDot()) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
393 |
continue;
|
394 |
}
|
395 |
|
396 |
+
$fullPath = WPStaging::getWPpath() . $path;
|
397 |
+
$size = $this->getDirectorySize($fullPath);
|
398 |
+
|
399 |
+
$this->directories[$directory->getFilename()]['metaData'] = [
|
400 |
+
"size" => $size,
|
401 |
+
"path" => $fullPath,
|
402 |
+
];
|
403 |
}
|
|
|
404 |
}
|
405 |
|
406 |
/**
|
410 |
*/
|
411 |
protected function getPath($directory)
|
412 |
{
|
|
|
413 |
/*
|
414 |
* Do not follow root path like src/web/..
|
415 |
* This must be done before \SplFileInfo->isDir() is used!
|
416 |
* Prevents open base dir restriction fatal errors
|
417 |
*/
|
|
|
418 |
if (strpos($directory->getRealPath(), WPStaging::getWPpath()) !== 0) {
|
419 |
return false;
|
420 |
}
|
421 |
+
|
422 |
$path = str_replace(WPStaging::getWPpath(), null, $directory->getRealPath());
|
423 |
// Using strpos() for symbolic links as they could create nasty stuff in nix stuff for directory structures
|
424 |
if (!$directory->isDir() || strlen($path) < 1) {
|
483 |
/**
|
484 |
* Get total size of a directory including all its subdirectories
|
485 |
* @param string $dir
|
486 |
+
* @param array $excludedDirectories
|
487 |
* @return int
|
488 |
*/
|
489 |
+
protected function getDirectorySizeInclSubdirs($dir, $excludedDirectories)
|
490 |
{
|
491 |
$size = 0;
|
492 |
foreach (glob(rtrim($dir, '/') . '/*', GLOB_NOSORT) as $each) {
|
493 |
+
if (is_file($each)) {
|
494 |
+
$size += filesize($each);
|
495 |
+
continue;
|
496 |
+
}
|
497 |
+
|
498 |
+
if ($this->isPathInDirectories($each, $excludedDirectories)) {
|
499 |
+
continue;
|
500 |
+
}
|
501 |
+
|
502 |
+
$size += $this->getDirectorySizeInclSubdirs($each, $excludedDirectories);
|
503 |
}
|
504 |
+
|
505 |
return $size;
|
506 |
}
|
507 |
|
508 |
/**
|
509 |
+
* Get total size of a directory excluding all its subdirectories
|
510 |
+
* @param string $dir
|
511 |
+
* @return int
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
512 |
*/
|
513 |
+
protected function getDirectorySizeExcludingSubdirs($dir)
|
514 |
{
|
515 |
+
$size = 0;
|
516 |
+
foreach (glob(rtrim($dir, '/') . '/*', GLOB_NOSORT) as $each) {
|
517 |
+
$size += is_file($each) ? filesize($each) : 0;
|
|
|
|
|
|
|
518 |
}
|
519 |
|
520 |
+
return $size;
|
521 |
+
}
|
522 |
+
|
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 |
+
/**
|
549 |
+
* Is the current main job UPDATE or RESET
|
550 |
+
*
|
551 |
+
* @return boolean
|
552 |
+
*/
|
553 |
+
protected function isUpdateOrResetJob()
|
554 |
+
{
|
555 |
+
return isset($this->options->mainJob) && ($this->options->mainJob === 'updating' || $this->options->mainJob === 'resetting');
|
556 |
}
|
557 |
}
|
Backend/Modules/Jobs/SearchReplace.php
CHANGED
@@ -230,8 +230,7 @@ class SearchReplace extends CloningProcess
|
|
230 |
|
231 |
/**
|
232 |
* Start search replace job
|
233 |
-
* @param string $
|
234 |
-
* @param string $old
|
235 |
*/
|
236 |
private function startReplace($table)
|
237 |
{
|
@@ -333,7 +332,7 @@ class SearchReplace extends CloningProcess
|
|
333 |
$limit = $this->settings->querySRLimit;
|
334 |
|
335 |
/// DEBUG
|
336 |
-
$this->logDebug(
|
337 |
sprintf(
|
338 |
'SearchReplace-beforeRowsGenerator: max-memory-limit=%s; script-memory-limit=%s; memory-usage=%s; execution-time-limit=%s; running-time=%s; is-threshold=%s',
|
339 |
$this->getMaxMemoryLimit(),
|
@@ -343,7 +342,7 @@ class SearchReplace extends CloningProcess
|
|
343 |
$this->getRunningTime(),
|
344 |
($this->isThreshold() ? 'yes' : 'no')
|
345 |
)
|
346 |
-
)
|
347 |
/// DEBUG
|
348 |
|
349 |
if (defined('WPSTG_DISABLE_SEARCH_REPLACE_GENERATOR') && WPSTG_DISABLE_SEARCH_REPLACE_GENERATOR) {
|
@@ -466,7 +465,7 @@ class SearchReplace extends CloningProcess
|
|
466 |
|
467 |
if (
|
468 |
!defined('WPSTG_DISABLE_SEARCH_REPLACE_GENERATOR') ||
|
469 |
-
defined('WPSTG_DISABLE_SEARCH_REPLACE_GENERATOR') && !WPSTG_DISABLE_SEARCH_REPLACE_GENERATOR
|
470 |
) {
|
471 |
$this->updateJobStart($processed, $this->stagingDb, $table);
|
472 |
}
|
@@ -535,26 +534,19 @@ class SearchReplace extends CloningProcess
|
|
535 |
*/
|
536 |
private function isExcludedTable($table)
|
537 |
{
|
538 |
-
$excludedCustomTables = apply_filters('wpstg_clone_searchreplace_tables_exclude', []);
|
539 |
|
540 |
-
$
|
541 |
-
|
542 |
-
// @todo remove isSearchReplaceExcluded() if SearchReplace() is made DRY and provide a simple list of excluded table names
|
543 |
-
if ($this->thirdParty->isSearchReplaceExcluded($table)) {
|
544 |
-
$excludedDefaultTables[] = str_replace($this->options->prefix, '', $table);
|
545 |
-
}
|
546 |
-
|
547 |
-
$tables = array_merge($excludedCustomTables, $excludedDefaultTables);
|
548 |
|
549 |
$excludedAllTables = [];
|
550 |
foreach ($tables as $key => $value) {
|
551 |
-
$excludedAllTables[] = $this->options->prefix . $value;
|
552 |
}
|
553 |
|
554 |
if (in_array($table, $excludedAllTables)) {
|
555 |
$this->log("DB Search & Replace: Table {$table} excluded by WP STAGING", Logger::TYPE_INFO);
|
556 |
return true;
|
557 |
}
|
|
|
558 |
return false;
|
559 |
}
|
560 |
|
230 |
|
231 |
/**
|
232 |
* Start search replace job
|
233 |
+
* @param string $table
|
|
|
234 |
*/
|
235 |
private function startReplace($table)
|
236 |
{
|
332 |
$limit = $this->settings->querySRLimit;
|
333 |
|
334 |
/// DEBUG
|
335 |
+
/* $this->logDebug(
|
336 |
sprintf(
|
337 |
'SearchReplace-beforeRowsGenerator: max-memory-limit=%s; script-memory-limit=%s; memory-usage=%s; execution-time-limit=%s; running-time=%s; is-threshold=%s',
|
338 |
$this->getMaxMemoryLimit(),
|
342 |
$this->getRunningTime(),
|
343 |
($this->isThreshold() ? 'yes' : 'no')
|
344 |
)
|
345 |
+
);*/
|
346 |
/// DEBUG
|
347 |
|
348 |
if (defined('WPSTG_DISABLE_SEARCH_REPLACE_GENERATOR') && WPSTG_DISABLE_SEARCH_REPLACE_GENERATOR) {
|
465 |
|
466 |
if (
|
467 |
!defined('WPSTG_DISABLE_SEARCH_REPLACE_GENERATOR') ||
|
468 |
+
(defined('WPSTG_DISABLE_SEARCH_REPLACE_GENERATOR') && !WPSTG_DISABLE_SEARCH_REPLACE_GENERATOR)
|
469 |
) {
|
470 |
$this->updateJobStart($processed, $this->stagingDb, $table);
|
471 |
}
|
534 |
*/
|
535 |
private function isExcludedTable($table)
|
536 |
{
|
|
|
537 |
|
538 |
+
$tables = $this->excludedTableService->getExcludedTablesForSearchReplace();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
539 |
|
540 |
$excludedAllTables = [];
|
541 |
foreach ($tables as $key => $value) {
|
542 |
+
$excludedAllTables[] = $this->options->prefix . ltrim($value, '_');
|
543 |
}
|
544 |
|
545 |
if (in_array($table, $excludedAllTables)) {
|
546 |
$this->log("DB Search & Replace: Table {$table} excluded by WP STAGING", Logger::TYPE_INFO);
|
547 |
return true;
|
548 |
}
|
549 |
+
|
550 |
return false;
|
551 |
}
|
552 |
|
Backend/Modules/Jobs/Updating.php
CHANGED
@@ -5,7 +5,9 @@ namespace WPStaging\Backend\Modules\Jobs;
|
|
5 |
use WPStaging\Core\WPStaging;
|
6 |
use WPStaging\Core\Utils\Helper;
|
7 |
use WPStaging\Framework\Adapter\Database as DatabaseAdapter;
|
|
|
8 |
use WPStaging\Framework\Database\TableService;
|
|
|
9 |
use WPStaging\Framework\Utils\WpDefaultDirectories;
|
10 |
|
11 |
/**
|
@@ -40,6 +42,11 @@ class Updating extends Job
|
|
40 |
*/
|
41 |
private $mainJob;
|
42 |
|
|
|
|
|
|
|
|
|
|
|
43 |
/**
|
44 |
* Initialize is called in \Job
|
45 |
*/
|
@@ -47,6 +54,7 @@ class Updating extends Job
|
|
47 |
{
|
48 |
$this->db = WPStaging::getInstance()->get("wpdb");
|
49 |
$this->mainJob = self::NORMAL_UPDATE;
|
|
|
50 |
}
|
51 |
|
52 |
/**
|
@@ -86,6 +94,8 @@ class Updating extends Job
|
|
86 |
$this->options->includedDirectories = [];
|
87 |
$this->options->excludedDirectories = [];
|
88 |
$this->options->extraDirectories = [];
|
|
|
|
|
89 |
$this->options->excludedFiles = [
|
90 |
'.htaccess',
|
91 |
'.DS_Store',
|
@@ -101,9 +111,9 @@ class Updating extends Job
|
|
101 |
];
|
102 |
|
103 |
$this->options->excludedFilesFullPath = [
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
];
|
108 |
|
109 |
// Define mainJob to differentiate between cloning, updating and pushing
|
@@ -112,11 +122,6 @@ class Updating extends Job
|
|
112 |
// Job
|
113 |
$this->options->job = new \stdClass();
|
114 |
|
115 |
-
// This is required for reset job because Jobs/Scan was not run for reset
|
116 |
-
if ($this->mainJob === self::RESET_UPDATE) {
|
117 |
-
$this->options->existingClones = get_option("wpstg_existing_clones_beta", []);
|
118 |
-
}
|
119 |
-
|
120 |
// Check if clone data already exists and use that one
|
121 |
if (isset($this->options->existingClones[$this->options->clone])) {
|
122 |
$this->options->cloneNumber = $this->options->existingClones[$this->options->clone]['number'];
|
@@ -143,51 +148,32 @@ class Updating extends Job
|
|
143 |
|
144 |
$this->isExternalDb = !(empty($this->options->databaseUser) && empty($this->options->databasePassword));
|
145 |
|
146 |
-
|
147 |
-
|
|
|
|
|
148 |
$excludedDirectories = [
|
149 |
-
|
150 |
-
WPStaging::getWPpath() . 'wp-content' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'wps-hide-login',
|
151 |
-
WPStaging::getWPpath() . 'wp-content' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'wp-super-cache',
|
152 |
-
WPStaging::getWPpath() . 'wp-content' . DIRECTORY_SEPARATOR . 'plugins' . DIRECTORY_SEPARATOR . 'peters-login-redirect',
|
153 |
];
|
154 |
|
155 |
// Add upload folder to list of excluded directories for push if symlink option is enabled
|
156 |
if ($this->options->uploadsSymlinked) {
|
157 |
-
$
|
158 |
-
$excludedDirectories[] = rtrim($wpUploadsFolder, '/\\');
|
159 |
}
|
160 |
|
161 |
$this->options->excludedDirectories = $excludedDirectories;
|
162 |
|
163 |
-
|
164 |
-
|
165 |
-
$this->options->includedDirectories = (new WpDefaultDirectories())->getWpCoreDirectories();
|
166 |
-
// Files
|
167 |
-
$this->options->totalFiles = 0;
|
168 |
-
$this->options->totalFileSize = 0;
|
169 |
-
$this->options->copiedFiles = 0;
|
170 |
-
// Job
|
171 |
-
$this->options->currentJob = "PreserveDataFirstStep";
|
172 |
-
$this->options->currentStep = 0;
|
173 |
-
$this->options->totalSteps = 0;
|
174 |
-
} else {
|
175 |
-
$this->setTablesForUpdateJob();
|
176 |
-
$this->setDirectoriesForUpdateJob();
|
177 |
-
// Make sure it is always enabled for free version
|
178 |
-
$this->options->emailsAllowed = true;
|
179 |
-
if (defined('WPSTGPRO_VERSION')) {
|
180 |
-
$this->options->emailsAllowed = isset($_POST['emailsAllowed']) && $_POST['emailsAllowed'] !== "false";
|
181 |
-
}
|
182 |
-
}
|
183 |
|
184 |
-
|
185 |
-
|
186 |
-
|
|
|
187 |
}
|
188 |
|
|
|
189 |
$this->options->destinationDir = $this->getDestinationDir();
|
190 |
-
|
191 |
$this->options->cloneHostname = $this->options->destinationHostname;
|
192 |
|
193 |
// Process lock state
|
@@ -210,22 +196,36 @@ class Updating extends Job
|
|
210 |
|
211 |
private function setDirectoriesForUpdateJob()
|
212 |
{
|
213 |
-
|
214 |
-
|
215 |
-
$
|
216 |
-
|
217 |
-
if ($this->options->areDirectoriesIncluded) {
|
218 |
-
$directories = isset($_POST["includedDirectories"]) ? $_POST["includedDirectories"] : '';
|
219 |
-
} else { // Get Included Directories from Excluded Directories
|
220 |
-
$directories = isset($_POST["excludedDirectories"]) ? $_POST["excludedDirectories"] : '';
|
221 |
}
|
222 |
|
223 |
-
|
|
|
|
|
|
|
|
|
224 |
|
|
|
|
|
|
|
|
|
225 |
// Extra Directories
|
226 |
if (isset($_POST["extraDirectories"])) {
|
227 |
-
$this->options->extraDirectories =
|
228 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
229 |
}
|
230 |
|
231 |
private function setTablesForUpdateJob()
|
@@ -236,25 +236,55 @@ class Updating extends Job
|
|
236 |
} else {
|
237 |
$this->options->tables = [];
|
238 |
}
|
|
|
239 |
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
$
|
246 |
-
|
247 |
-
|
248 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
249 |
}
|
250 |
|
251 |
-
|
|
|
|
|
|
|
252 |
{
|
253 |
$tableService = new TableService(new DatabaseAdapter());
|
254 |
$tables = $tableService->findTableStatusStartsWith();
|
255 |
$tables = $tableService->getTablesName($tables->toArray());
|
256 |
-
$
|
257 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
258 |
}
|
259 |
|
260 |
/**
|
5 |
use WPStaging\Core\WPStaging;
|
6 |
use WPStaging\Core\Utils\Helper;
|
7 |
use WPStaging\Framework\Adapter\Database as DatabaseAdapter;
|
8 |
+
use WPStaging\Framework\Filesystem\Scanning\ScanConst;
|
9 |
use WPStaging\Framework\Database\TableService;
|
10 |
+
use WPStaging\Framework\Utils\SlashMode;
|
11 |
use WPStaging\Framework\Utils\WpDefaultDirectories;
|
12 |
|
13 |
/**
|
42 |
*/
|
43 |
private $mainJob;
|
44 |
|
45 |
+
/**
|
46 |
+
* @var WpDefaultDirectories
|
47 |
+
*/
|
48 |
+
private $dirUtils;
|
49 |
+
|
50 |
/**
|
51 |
* Initialize is called in \Job
|
52 |
*/
|
54 |
{
|
55 |
$this->db = WPStaging::getInstance()->get("wpdb");
|
56 |
$this->mainJob = self::NORMAL_UPDATE;
|
57 |
+
$this->dirUtils = new WpDefaultDirectories();
|
58 |
}
|
59 |
|
60 |
/**
|
94 |
$this->options->includedDirectories = [];
|
95 |
$this->options->excludedDirectories = [];
|
96 |
$this->options->extraDirectories = [];
|
97 |
+
$this->options->excludeGlobRules = [];
|
98 |
+
$this->options->excludeSizeRules = [];
|
99 |
$this->options->excludedFiles = [
|
100 |
'.htaccess',
|
101 |
'.DS_Store',
|
111 |
];
|
112 |
|
113 |
$this->options->excludedFilesFullPath = [
|
114 |
+
$this->dirUtils->getRelativeWpContentPath(SlashMode::TRAILING_SLASH) . 'db.php',
|
115 |
+
$this->dirUtils->getRelativeWpContentPath(SlashMode::TRAILING_SLASH) . 'object-cache.php',
|
116 |
+
$this->dirUtils->getRelativeWpContentPath(SlashMode::TRAILING_SLASH) . 'advanced-cache.php'
|
117 |
];
|
118 |
|
119 |
// Define mainJob to differentiate between cloning, updating and pushing
|
122 |
// Job
|
123 |
$this->options->job = new \stdClass();
|
124 |
|
|
|
|
|
|
|
|
|
|
|
125 |
// Check if clone data already exists and use that one
|
126 |
if (isset($this->options->existingClones[$this->options->clone])) {
|
127 |
$this->options->cloneNumber = $this->options->existingClones[$this->options->clone]['number'];
|
148 |
|
149 |
$this->isExternalDb = !(empty($this->options->databaseUser) && empty($this->options->databasePassword));
|
150 |
|
151 |
+
/**
|
152 |
+
* @see /WPStaging/Framework/CloningProcess/ExcludedPlugins.php to exclude plugins
|
153 |
+
* Only add other directories here
|
154 |
+
*/
|
155 |
$excludedDirectories = [
|
156 |
+
$this->dirUtils->getRelativeWpContentPath(SlashMode::BOTH_SLASHES) . 'cache',
|
|
|
|
|
|
|
157 |
];
|
158 |
|
159 |
// Add upload folder to list of excluded directories for push if symlink option is enabled
|
160 |
if ($this->options->uploadsSymlinked) {
|
161 |
+
$excludedDirectories[] = $this->dirUtils->getRelativeUploadPath(SlashMode::LEADING_SLASH);
|
|
|
162 |
}
|
163 |
|
164 |
$this->options->excludedDirectories = $excludedDirectories;
|
165 |
|
166 |
+
$this->setTablesForUpdateJob();
|
167 |
+
$this->setDirectoriesForUpdateJob();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
168 |
|
169 |
+
// Make sure it is always enabled for free version
|
170 |
+
$this->options->emailsAllowed = true;
|
171 |
+
if (defined('WPSTGPRO_VERSION')) {
|
172 |
+
$this->options->emailsAllowed = isset($_POST['emailsAllowed']) && $_POST['emailsAllowed'] !== "false";
|
173 |
}
|
174 |
|
175 |
+
$this->options->cloneDir = $this->options->existingClones[$this->options->clone]['path'];
|
176 |
$this->options->destinationDir = $this->getDestinationDir();
|
|
|
177 |
$this->options->cloneHostname = $this->options->destinationHostname;
|
178 |
|
179 |
// Process lock state
|
196 |
|
197 |
private function setDirectoriesForUpdateJob()
|
198 |
{
|
199 |
+
// Exclude Glob Rules
|
200 |
+
$this->options->excludeGlobRules = [];
|
201 |
+
if (isset($_POST["excludeGlobRules"]) && !empty($_POST["excludeGlobRules"])) {
|
202 |
+
$this->options->excludeGlobRules = wpstg_urldecode(explode(',', $_POST["excludeGlobRules"]));
|
|
|
|
|
|
|
|
|
203 |
}
|
204 |
|
205 |
+
// Exclude File Size Rules
|
206 |
+
$this->options->excludeSizeRules = [];
|
207 |
+
if (isset($_POST["excludeSizeRules"]) && !empty($_POST["excludeSizeRules"])) {
|
208 |
+
$this->options->excludeSizeRules = wpstg_urldecode(explode(',', $_POST["excludeSizeRules"]));
|
209 |
+
}
|
210 |
|
211 |
+
// Excluded Directories
|
212 |
+
$excludedDirectoriesRequest = isset($_POST["excludedDirectories"]) ? $_POST["excludedDirectories"] : '';
|
213 |
+
$excludedDirectoriesRequest = $this->dirUtils->getExcludedDirectories($excludedDirectoriesRequest);
|
214 |
+
$this->options->excludedDirectories = array_merge($this->options->excludedDirectories, $excludedDirectoriesRequest);
|
215 |
// Extra Directories
|
216 |
if (isset($_POST["extraDirectories"])) {
|
217 |
+
$this->options->extraDirectories = explode(ScanConst::DIRECTORIES_SEPARATOR, wpstg_urldecode($_POST["extraDirectories"]));
|
218 |
}
|
219 |
+
|
220 |
+
// delete uploads folder before copying if uploads is not symlinked
|
221 |
+
$this->options->deleteUploadsFolder = !$this->options->uploadsSymlinked && isset($_POST['cleanUploadsDir']) && $_POST['cleanUploadsDir'] === 'true';
|
222 |
+
// should not backup uploads during update process
|
223 |
+
$this->options->backupUploadsFolder = false;
|
224 |
+
// clean plugins and themes dir before updating
|
225 |
+
$this->options->deletePluginsAndThemes = isset($_POST['cleanPluginsThemes']) && $_POST['cleanPluginsThemes'] === 'true';
|
226 |
+
// set default statuses for backup of uploads dir and cleaning of uploads, themes and plugins dirs
|
227 |
+
$this->options->statusBackupUploadsDir = 'skipped';
|
228 |
+
$this->options->statusContentCleaner = 'pending';
|
229 |
}
|
230 |
|
231 |
private function setTablesForUpdateJob()
|
236 |
} else {
|
237 |
$this->options->tables = [];
|
238 |
}
|
239 |
+
}
|
240 |
|
241 |
+
/**
|
242 |
+
* @param bool $preserveExcludes
|
243 |
+
*/
|
244 |
+
private function setDirectoriesForResetJob($preserveExcludes = false)
|
245 |
+
{
|
246 |
+
$wpDirectories = new WpDefaultDirectories();
|
247 |
+
$coreDirectories = $wpDirectories->getWpCoreDirectories();
|
248 |
+
|
249 |
+
if ($preserveExcludes) {
|
250 |
+
$this->options->includedDirectories = $coreDirectories;
|
251 |
+
return;
|
252 |
+
}
|
253 |
+
|
254 |
+
$existingClone = $this->options->existingClones[$this->options->clone];
|
255 |
+
$this->options->includedDirectories = [];
|
256 |
+
foreach ($coreDirectories as $coreDir) {
|
257 |
+
if (in_array($coreDir, $existingClone['includedDirectories'])) {
|
258 |
+
$this->options->includedDirectories[] = $coreDir;
|
259 |
+
}
|
260 |
+
}
|
261 |
+
|
262 |
+
$this->options->excludedDirectories = $existingClone['excludedDirectories'];
|
263 |
+
$this->options->excludeSizeRules = $existingClone['excludeSizeRules'];
|
264 |
+
// should preserve extra directories?
|
265 |
+
// $this->options->extraDirectories = $existingClone['extraDirectories'];
|
266 |
}
|
267 |
|
268 |
+
/**
|
269 |
+
* @param bool $preserveExcludes
|
270 |
+
*/
|
271 |
+
private function setTablesForResetJob($preserveExcludes = false)
|
272 |
{
|
273 |
$tableService = new TableService(new DatabaseAdapter());
|
274 |
$tables = $tableService->findTableStatusStartsWith();
|
275 |
$tables = $tableService->getTablesName($tables->toArray());
|
276 |
+
if ($preserveExcludes) {
|
277 |
+
$this->options->tables = $tables;
|
278 |
+
return;
|
279 |
+
}
|
280 |
+
|
281 |
+
$selectedTables = $this->options->existingClones[$this->options->clone]["includedTables"];
|
282 |
+
$this->options->tables = [];
|
283 |
+
foreach ($tables as $table) {
|
284 |
+
if (in_array($table, $selectedTables)) {
|
285 |
+
$this->options->tables[] = $table;
|
286 |
+
}
|
287 |
+
}
|
288 |
}
|
289 |
|
290 |
/**
|
Backend/Modules/Views/Forms/Settings.php
CHANGED
@@ -3,12 +3,14 @@
|
|
3 |
namespace WPStaging\Backend\Modules\Views\Forms;
|
4 |
|
5 |
use WPStaging\Core\Forms\Elements\Check;
|
|
|
6 |
use WPStaging\Core\Forms\Elements\Numerical;
|
7 |
use WPStaging\Core\Forms\Elements\Select;
|
8 |
use WPStaging\Core\Forms\Elements\SelectMultiple;
|
9 |
use WPStaging\Core\Forms\Elements\Text;
|
10 |
use WPStaging\Core\Forms\Form;
|
11 |
use WPStaging\Backend\Modules\Views\Tabs\Tabs;
|
|
|
12 |
|
13 |
/**
|
14 |
* Class Settings
|
@@ -252,6 +254,16 @@ class Settings
|
|
252 |
->setDefault(isset($settings->usersWithStagingAccess) ? $settings->usersWithStagingAccess : '')
|
253 |
);
|
254 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
255 |
}
|
256 |
|
257 |
/**
|
3 |
namespace WPStaging\Backend\Modules\Views\Forms;
|
4 |
|
5 |
use WPStaging\Core\Forms\Elements\Check;
|
6 |
+
use WPStaging\Core\Forms\Elements\Color;
|
7 |
use WPStaging\Core\Forms\Elements\Numerical;
|
8 |
use WPStaging\Core\Forms\Elements\Select;
|
9 |
use WPStaging\Core\Forms\Elements\SelectMultiple;
|
10 |
use WPStaging\Core\Forms\Elements\Text;
|
11 |
use WPStaging\Core\Forms\Form;
|
12 |
use WPStaging\Backend\Modules\Views\Tabs\Tabs;
|
13 |
+
use WPStaging\Framework\Assets\Assets;
|
14 |
|
15 |
/**
|
16 |
* Class Settings
|
254 |
->setDefault(isset($settings->usersWithStagingAccess) ? $settings->usersWithStagingAccess : '')
|
255 |
);
|
256 |
}
|
257 |
+
|
258 |
+
$element = new Color(
|
259 |
+
"wpstg_settings[adminBarColor]",
|
260 |
+
[]
|
261 |
+
);
|
262 |
+
|
263 |
+
$this->form["general"]->add(
|
264 |
+
$element->setLabel(__("Admin Bar Background Color", "wp-staging"))
|
265 |
+
->setDefault((isset($settings->adminBarColor)) ? $settings->adminBarColor : Assets::DEFAULT_ADMIN_BAR_BG)
|
266 |
+
);
|
267 |
}
|
268 |
|
269 |
/**
|
Backend/views/clone/ajax/exclude-settings.php
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
<?php
|
3 |
+
/**
|
4 |
+
* @see \WPStaging\Backend\Administrator::ajaxCloneExcludeSettings Context where this is included.
|
5 |
+
*
|
6 |
+
* @var stdClass $options
|
7 |
+
*
|
8 |
+
* @see \WPStaging\Backend\Modules\Jobs\Scan::start For details on $options.
|
9 |
+
*/
|
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">►</span>
|
20 |
+
<?php _e("Selected Tables", "wp-staging") ?>
|
21 |
+
</a>
|
22 |
+
|
23 |
+
<fieldset class="wpstg-tab-section" id="wpstg-reset-excluded-tables">
|
24 |
+
<?php require(WPSTG_PLUGIN_DIR . 'Backend/views/selections/database-tables.php'); ?>
|
25 |
+
</fieldset>
|
26 |
+
|
27 |
+
<a href="#" class="wpstg-tab-header wpstg-reset-exclude-tab" data-id="#wpstg-reset-excluded-files" data-collapsed="true">
|
28 |
+
<span class="wpstg-tab-triangle">►</span>
|
29 |
+
<?php _e("Selected Files", "wp-staging") ?>
|
30 |
+
</a>
|
31 |
+
|
32 |
+
<fieldset class="wpstg-tab-section" id="wpstg-reset-excluded-files">
|
33 |
+
<?php require(WPSTG_PLUGIN_DIR . 'Backend/views/selections/files.php'); ?>
|
34 |
+
</fieldset>
|
35 |
+
</div>
|
36 |
+
</div>
|
37 |
+
|
Backend/views/clone/ajax/scan.php
CHANGED
@@ -5,6 +5,7 @@
|
|
5 |
*
|
6 |
* @var \WPStaging\Backend\Modules\Jobs\Scan $scan
|
7 |
* @var stdClass $options
|
|
|
8 |
*
|
9 |
* @see \WPStaging\Backend\Modules\Jobs\Scan::start For details on $options.
|
10 |
*/
|
@@ -33,37 +34,7 @@
|
|
33 |
</a>
|
34 |
|
35 |
<fieldset class="wpstg-tab-section" id="wpstg-scanning-db">
|
36 |
-
<?php
|
37 |
-
<h4 style="margin:0">
|
38 |
-
<p><?php printf(__("Select the tables to copy. Tables beginning with the prefix '%s' have already been selected.", "wp-staging"), $db->prefix); ?></p>
|
39 |
-
<p></p>
|
40 |
-
<?php
|
41 |
-
echo __(
|
42 |
-
"Select multiple tables by pressing left mouse button and moving or by pressing STRG+Left Mouse button. (Mac ⌘+Left Mouse Button)",
|
43 |
-
"wp-staging"
|
44 |
-
);
|
45 |
-
?>
|
46 |
-
</h4>
|
47 |
-
<div style="margin-top:10px;margin-bottom:10px;">
|
48 |
-
<a href="#" class="wpstg-button-unselect button"><?php _e('Unselect All', 'wp-staging'); ?></a>
|
49 |
-
<a href="#" class="wpstg-button-select button"> <?php _e(WPStaging\Core\WPStaging::getTablePrefix(), 'wp-staging'); ?> </a>
|
50 |
-
</div>
|
51 |
-
<select multiple="multiple" id="wpstg_select_tables_cloning">
|
52 |
-
<?php
|
53 |
-
foreach ($options->tables as $table) :
|
54 |
-
$attributes = !in_array($table->name, $options->excludedTables) && (strpos($table->name, $db->prefix) === 0) ? "selected='selected'" : "";
|
55 |
-
$attributes .= in_array($table->name, $options->clonedTables) ? "disabled" : '';
|
56 |
-
?>
|
57 |
-
<option class="wpstg-db-table" value="<?php echo $table->name ?>" name="<?php echo $table->name ?>" <?php echo $attributes ?>>
|
58 |
-
<?php echo $table->name ?> - <?php echo $scan->formatSize($table->size) ?>
|
59 |
-
</option>
|
60 |
-
<?php endforeach ?>
|
61 |
-
</select>
|
62 |
-
|
63 |
-
<div style="margin-top:10px;">
|
64 |
-
<a href="#" class="wpstg-button-unselect button"> <?php _e('Unselect All', 'wp-staging'); ?> </a>
|
65 |
-
<a href="#" class="wpstg-button-select button"> <?php _e(WPStaging\Core\WPStaging::getTablePrefix(), 'wp-staging'); ?> </a>
|
66 |
-
</div>
|
67 |
</fieldset>
|
68 |
|
69 |
<a href="#" class="wpstg-tab-header" data-id="#wpstg-scanning-files">
|
@@ -72,38 +43,7 @@
|
|
72 |
</a>
|
73 |
|
74 |
<fieldset class="wpstg-tab-section" id="wpstg-scanning-files">
|
75 |
-
|
76 |
-
<?php echo __("Select folders to copy. Click on folder name to list subfolders!", "wp-staging") ?>
|
77 |
-
</h4>
|
78 |
-
|
79 |
-
<?php echo $scan->directoryListing() ?>
|
80 |
-
|
81 |
-
<h4 style="margin:10px 0 10px 0">
|
82 |
-
<?php echo __("Extra directories to copy", "wp-staging") ?>
|
83 |
-
</h4>
|
84 |
-
|
85 |
-
<textarea id="wpstg_extraDirectories" name="wpstg_extraDirectories" style="width:100%;height:100px;"></textarea>
|
86 |
-
<p>
|
87 |
-
<span>
|
88 |
-
<?php
|
89 |
-
echo __(
|
90 |
-
"Enter one folder path per line.<br>" .
|
91 |
-
"Folders must start with absolute path: " . $options->root,
|
92 |
-
"wp-staging"
|
93 |
-
)
|
94 |
-
?>
|
95 |
-
</span>
|
96 |
-
</p>
|
97 |
-
|
98 |
-
<p>
|
99 |
-
<span>
|
100 |
-
<?php
|
101 |
-
if (isset($options->clone)) {
|
102 |
-
echo __("All files will be copied to: ", "wp-staging") . $options->root . $options->clone;
|
103 |
-
}
|
104 |
-
?>
|
105 |
-
</span>
|
106 |
-
</p>
|
107 |
</fieldset>
|
108 |
|
109 |
<a href="#" class="wpstg-tab-header" data-id="#wpstg-advanced-settings">
|
5 |
*
|
6 |
* @var \WPStaging\Backend\Modules\Jobs\Scan $scan
|
7 |
* @var stdClass $options
|
8 |
+
* @var \WPStaging\Framework\Filesystem\Filters\ExcludeFilter $excludeUtils
|
9 |
*
|
10 |
* @see \WPStaging\Backend\Modules\Jobs\Scan::start For details on $options.
|
11 |
*/
|
34 |
</a>
|
35 |
|
36 |
<fieldset class="wpstg-tab-section" id="wpstg-scanning-db">
|
37 |
+
<?php require(WPSTG_PLUGIN_DIR . 'Backend/views/selections/database-tables.php'); ?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
</fieldset>
|
39 |
|
40 |
<a href="#" class="wpstg-tab-header" data-id="#wpstg-scanning-files">
|
43 |
</a>
|
44 |
|
45 |
<fieldset class="wpstg-tab-section" id="wpstg-scanning-files">
|
46 |
+
<?php require(WPSTG_PLUGIN_DIR . 'Backend/views/selections/files.php'); ?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
</fieldset>
|
48 |
|
49 |
<a href="#" class="wpstg-tab-header" data-id="#wpstg-advanced-settings">
|
Backend/views/selections/database-tables.php
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @var stdClass $options
|
4 |
+
*
|
5 |
+
* @see \WPStaging\Backend\Modules\Jobs\Scan::start For details on $options.
|
6 |
+
*/
|
7 |
+
?>
|
8 |
+
<?php
|
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>
|
20 |
+
<a href="#" class="wpstg-button-select button"> <?php echo $dbPrefix ?> </a>
|
21 |
+
</div>
|
22 |
+
<select multiple="multiple" id="wpstg_select_tables_cloning">
|
23 |
+
<?php
|
24 |
+
foreach ($options->tables as $table) :
|
25 |
+
$attributes = !in_array($table->name, $options->excludedTables) && (strpos($table->name, $dbPrefix) === 0) ? "selected='selected'" : "";
|
26 |
+
if (($options->mainJob === 'updating' || $options->mainJob === 'resetting') && isset($options->currentClone['includedTables'])) {
|
27 |
+
$attributes = !in_array($table->name, $options->excludedTables) && in_array($table->name, $options->currentClone['includedTables']) ? "selected='selected'" : "";
|
28 |
+
}
|
29 |
+
|
30 |
+
$attributes .= in_array($table->name, $options->clonedTables) ? "disabled" : '';
|
31 |
+
?>
|
32 |
+
<option class="wpstg-db-table" value="<?php echo $table->name ?>" name="<?php echo $table->name ?>" <?php echo $attributes ?>>
|
33 |
+
<?php echo $table->name ?> - <?php echo size_format($table->size, 2) ?>
|
34 |
+
</option>
|
35 |
+
<?php endforeach ?>
|
36 |
+
</select>
|
37 |
+
<div class="wpstg-mt-10px">
|
38 |
+
<a href="#" class="wpstg-button-unselect button"> <?php _e('Unselect All', 'wp-staging'); ?> </a>
|
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>
|
Backend/views/selections/files.php
ADDED
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @var stdClass $options
|
4 |
+
*
|
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>
|
14 |
+
<button type="button" class="wpstg-select-dirs-default button"> <?php _e('Select Default', 'wp-staging'); ?></button>
|
15 |
+
</div>
|
16 |
+
<?php echo $scan->directoryListing() ?>
|
17 |
+
</div>
|
18 |
+
<!-- Exclusion Rules Table -->
|
19 |
+
<div class="wpstg-excluded-filters-container" id="wpstg-exclude-filters-container">
|
20 |
+
<table>
|
21 |
+
<tbody>
|
22 |
+
<?php
|
23 |
+
$hasRules = false;
|
24 |
+
if ($options->mainJob === 'updating' || $options->mainJob === 'resetting') :
|
25 |
+
foreach ($options->currentClone['excludeSizeRules'] as $rule) :
|
26 |
+
$hasRules = true;
|
27 |
+
echo $excludeUtils->renderSizeExclude($rule);
|
28 |
+
endforeach;
|
29 |
+
foreach ($options->currentClone['excludeGlobRules'] as $rule) :
|
30 |
+
$hasRules = true;
|
31 |
+
echo $excludeUtils->renderGlobExclude($rule);
|
32 |
+
endforeach;
|
33 |
+
endif; ?>
|
34 |
+
</tbody>
|
35 |
+
</table>
|
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>
|
44 |
+
<button class="wpstg-dropdown-action wpstg-file-ext-rule"><?php _e('File Extension', 'wp-staging'); ?></button>
|
45 |
+
<button class="wpstg-dropdown-action wpstg-file-name-rule"><?php _e('File Name', 'wp-staging'); ?></button>
|
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>
|
53 |
+
</div>
|
54 |
+
<?php
|
55 |
+
if ($options->current !== null && $options->mainJob === 'updating') {
|
56 |
+
echo '<p>' . __("Applying an exclude rule will not effect existing files on the staging site if you don't clean up the wp-content folder before updating. Existing files will not be deleted afterwards automatically!", 'wp-staging') . '</p>';
|
57 |
+
}
|
58 |
+
?>
|
59 |
+
<!-- End Exclusion Rules Table -->
|
60 |
+
|
61 |
+
<!-- Templates for exclusion filters. These will never be rendered until added to exclusion rule table -->
|
62 |
+
<?php unset($rule); ?>
|
63 |
+
<template id="wpstg-file-ext-exclude-filter-template">
|
64 |
+
<?php require(WPSTG_PLUGIN_DIR . 'Backend/views/templates/exclude-filters/file-ext-exclude-filter.php') ?>
|
65 |
+
</template>
|
66 |
+
<template id="wpstg-file-size-exclude-filter-template">
|
67 |
+
<?php require(WPSTG_PLUGIN_DIR . 'Backend/views/templates/exclude-filters/file-size-exclude-filter.php') ?>
|
68 |
+
</template>
|
69 |
+
<template id="wpstg-file-name-exclude-filter-template">
|
70 |
+
<?php require(WPSTG_PLUGIN_DIR . 'Backend/views/templates/exclude-filters/file-name-exclude-filter.php') ?>
|
71 |
+
</template>
|
72 |
+
<template id="wpstg-dir-name-exclude-filter-template">
|
73 |
+
<?php require(WPSTG_PLUGIN_DIR . 'Backend/views/templates/exclude-filters/dir-name-exclude-filter.php') ?>
|
74 |
+
</template>
|
75 |
+
<!-- End - Templates for exclusion filters -->
|
76 |
+
|
77 |
+
<?php if (defined('WPSTG_ALLOW_EXTRA_DIRECTORIES') && WPSTG_ALLOW_EXTRA_DIRECTORIES) { ?>
|
78 |
+
<h4 style="margin:10px 0 10px 0">
|
79 |
+
<?php echo __("Extra directories to copy", "wp-staging") ?>
|
80 |
+
</h4>
|
81 |
+
|
82 |
+
<textarea id="wpstg_extraDirectories" name="wpstg_extraDirectories" style="width:100%;height:100px;"></textarea>
|
83 |
+
<p>
|
84 |
+
<span>
|
85 |
+
<?php
|
86 |
+
echo __(
|
87 |
+
"Enter one folder path per line.<br>" .
|
88 |
+
"Folders must be relative to the path: " . $options->root,
|
89 |
+
"wp-staging"
|
90 |
+
)
|
91 |
+
?>
|
92 |
+
</span>
|
93 |
+
</p>
|
94 |
+
<?php } ?>
|
95 |
+
|
96 |
+
<p>
|
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>
|
104 |
+
</p>
|
Backend/views/settings/tabs/general.php
CHANGED
@@ -383,6 +383,25 @@
|
|
383 |
echo $form->render("wpstg_settings[usersWithStagingAccess]") ?>
|
384 |
</td>
|
385 |
</tr>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
386 |
<?php
|
387 |
}
|
388 |
?>
|
383 |
echo $form->render("wpstg_settings[usersWithStagingAccess]") ?>
|
384 |
</td>
|
385 |
</tr>
|
386 |
+
<tr class="row">
|
387 |
+
<td class="row th">
|
388 |
+
<div class="col-title">
|
389 |
+
<?php
|
390 |
+
echo $form->label("wpstg_settings[adminBarColor]") ?>
|
391 |
+
<span class="description">
|
392 |
+
<?php
|
393 |
+
_e(
|
394 |
+
'Specify the color of staging site admin bar.</strong>',
|
395 |
+
'wp-staging'
|
396 |
+
); ?>
|
397 |
+
</span>
|
398 |
+
</div>
|
399 |
+
</td>
|
400 |
+
<td>
|
401 |
+
<?php
|
402 |
+
echo $form->render("wpstg_settings[adminBarColor]") ?>
|
403 |
+
</td>
|
404 |
+
</tr>
|
405 |
<?php
|
406 |
}
|
407 |
?>
|
Backend/views/settings/tabs/mail-settings.php
CHANGED
@@ -1,20 +1,17 @@
|
|
1 |
<form class="wpstg-mail-settings-form" method="post">
|
2 |
-
<?php $emailsAllowed = !((bool)
|
3 |
<p>
|
4 |
<strong class="wpstg-fs-14"> <?php _e('Mail Delivery Setting', 'wp-staging'); ?></strong>
|
5 |
<br/>
|
6 |
<?php _e('Toggle mails sending for this staging site', 'wp-staging'); ?>
|
7 |
</p>
|
8 |
-
|
9 |
<div class="wpstg-form-group">
|
10 |
<label class="wpstg-checkbox" for="wpstg_allow_emails">
|
11 |
<?php _e('Allow Mails Sending:', 'wp-staging'); ?> <input type="checkbox" name="wpstg_allow_emails" id="wpstg_allow_emails" <?php echo $emailsAllowed === true ? 'checked' : '' ?>>
|
12 |
</label>
|
13 |
</div>
|
14 |
-
|
15 |
<p>
|
16 |
<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>'); ?>
|
17 |
</p>
|
18 |
-
|
19 |
<button type="button" id="wpstg-update-mail-settings" class="wpstg-link-btn wpstg-blue-primary"><?php _e("Update Settings", "wp-staging") ?></button>
|
20 |
</form>
|
1 |
<form class="wpstg-mail-settings-form" method="post">
|
2 |
+
<?php $emailsAllowed = !((bool)(new \WPStaging\Framework\Staging\CloneOptions())->get((\WPStaging\Framework\Staging\FirstRun::MAILS_DISABLED_KEY))); ?>
|
3 |
<p>
|
4 |
<strong class="wpstg-fs-14"> <?php _e('Mail Delivery Setting', 'wp-staging'); ?></strong>
|
5 |
<br/>
|
6 |
<?php _e('Toggle mails sending for this staging site', 'wp-staging'); ?>
|
7 |
</p>
|
|
|
8 |
<div class="wpstg-form-group">
|
9 |
<label class="wpstg-checkbox" for="wpstg_allow_emails">
|
10 |
<?php _e('Allow Mails Sending:', 'wp-staging'); ?> <input type="checkbox" name="wpstg_allow_emails" id="wpstg_allow_emails" <?php echo $emailsAllowed === true ? 'checked' : '' ?>>
|
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>
|
Backend/views/templates/exclude-filters/dir-name-exclude-filter.php
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
use WPStaging\Framework\Filesystem\Filters\ExcludeFilter;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* @var string $rule
|
7 |
+
* @var string $name
|
8 |
+
*
|
9 |
+
* @see \WPStaging\Framework\Filesystem\Filters\ExcludeFilter::renderExclude For details on $rule and $name.
|
10 |
+
*/
|
11 |
+
?>
|
12 |
+
<tr>
|
13 |
+
<td class="wpstg-exclude-filter-name-column"><?php _e('Folder Name', 'wp-staging') ?></td>
|
14 |
+
<td class="wpstg-exclude-filter-exclusion-column">
|
15 |
+
<select class="wpstg-exclude-rule-input wpstg-path-exclude-select" name="wpstgDirNameExcludeRulePos[]">
|
16 |
+
<option value="<?php echo ExcludeFilter::NAME_BEGINS_WITH ?>" <?php echo isset($rule) && $rule === ExcludeFilter::NAME_BEGINS_WITH ? 'selected' : '' ?>><?php _e('BEGINS WITH', 'wp-staging') ?></option>
|
17 |
+
<option value="<?php echo ExcludeFilter::NAME_ENDS_WITH ?>" <?php echo isset($rule) && $rule === ExcludeFilter::NAME_ENDS_WITH ? 'selected' : '' ?>><?php _e('ENDS WITH', 'wp-staging') ?></option>
|
18 |
+
<option value="<?php echo ExcludeFilter::NAME_EXACT_MATCHES ?>" <?php echo isset($rule) && $rule === ExcludeFilter::NAME_EXACT_MATCHES ? 'selected' : '' ?>><?php _e('EXACT MATCHES', 'wp-staging') ?></option>
|
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>
|
28 |
+
<td class="wpstg-exclude-filter-action-column"><button class="wpstg-remove-exclude-rule">×</button></td>
|
29 |
+
</tr>
|
Backend/views/templates/exclude-filters/file-ext-exclude-filter.php
ADDED
@@ -0,0 +1,18 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @var string $extension
|
4 |
+
*
|
5 |
+
* @see \WPStaging\Framework\Filesystem\Filters\ExcludeFilter::renderExclude For details on $extension.
|
6 |
+
*/
|
7 |
+
?>
|
8 |
+
<tr>
|
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>
|
18 |
+
</tr>
|
Backend/views/templates/exclude-filters/file-name-exclude-filter.php
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
use WPStaging\Framework\Filesystem\Filters\ExcludeFilter;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* @var string $rule
|
7 |
+
* @var string $name
|
8 |
+
*
|
9 |
+
* @see \WPStaging\Framework\Filesystem\Filters\ExcludeFilter::renderExclude For details on $rule and $name.
|
10 |
+
*/
|
11 |
+
?>
|
12 |
+
<tr>
|
13 |
+
<td class="wpstg-exclude-filter-name-column"><?php _e('File Name', 'wp-staging') ?></td>
|
14 |
+
<td class="wpstg-exclude-filter-exclusion-column">
|
15 |
+
<select class="wpstg-exclude-rule-input wpstg-path-exclude-select" name="wpstgFileNameExcludeRulePos[]">
|
16 |
+
<option value="<?php echo ExcludeFilter::NAME_BEGINS_WITH ?>" <?php echo isset($rule) && $rule === ExcludeFilter::NAME_BEGINS_WITH ? 'selected' : '' ?>><?php _e('BEGINS WITH', 'wp-staging') ?></option>
|
17 |
+
<option value="<?php echo ExcludeFilter::NAME_ENDS_WITH ?>" <?php echo isset($rule) && $rule === ExcludeFilter::NAME_ENDS_WITH ? 'selected' : '' ?>><?php _e('ENDS WITH', 'wp-staging') ?></option>
|
18 |
+
<option value="<?php echo ExcludeFilter::NAME_EXACT_MATCHES ?>" <?php echo isset($rule) && $rule === ExcludeFilter::NAME_EXACT_MATCHES ? 'selected' : '' ?>><?php _e('EXACT MATCHES', 'wp-staging') ?></option>
|
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>
|
28 |
+
<td class="wpstg-exclude-filter-action-column"><button class="wpstg-remove-exclude-rule">×</button></td>
|
29 |
+
</tr>
|
Backend/views/templates/exclude-filters/file-size-exclude-filter.php
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
use WPStaging\Framework\Filesystem\Filters\ExcludeFilter;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* @var string $comparison
|
7 |
+
* @var int $bytes
|
8 |
+
* @var string $size
|
9 |
+
*
|
10 |
+
* @see \WPStaging\Framework\Filesystem\Filters\ExcludeFilter::renderSizeExclude For details on $comparison, $size and $bytes.
|
11 |
+
*/
|
12 |
+
?>
|
13 |
+
<tr>
|
14 |
+
<td class="wpstg-exclude-filter-name-column"><?php _e('File Size', 'wp-staging') ?></td>
|
15 |
+
<td class="wpstg-exclude-filter-exclusion-column">
|
16 |
+
<select class="wpstg-exclude-rule-input wpstg-file-size-exclude-select" name="wpstgFileSizeExcludeRuleCompare[]">
|
17 |
+
<option value="<?php echo ExcludeFilter::SIZE_LESS_THAN ?>" <?php echo isset($comparison) && $comparison === ExcludeFilter::SIZE_LESS_THAN ? "selected" : '' ?>><?php _e('LESS THAN', 'wp-staging') ?></option>
|
18 |
+
<option value="<?php echo ExcludeFilter::SIZE_GREATER_THAN ?>" <?php echo isset($comparison) && $comparison === ExcludeFilter::SIZE_GREATER_THAN ? "selected" : '' ?>><?php _e('GREATER THAN', 'wp-staging') ?></option>
|
19 |
+
<option value="<?php echo ExcludeFilter::SIZE_EQUAL_TO ?>" <?php echo isset($comparison) && $comparison === ExcludeFilter::SIZE_EQUAL_TO ? "selected" : '' ?>><?php _e('EXACT', 'wp-staging') ?></option>
|
20 |
+
</select>
|
21 |
+
<input type="number" class="wpstg-exclude-rule-input wpstg-file-size-exclude-input" name="wpstgFileSizeExcludeRuleSize[]" <?php echo isset($bytes) ? "value='$bytes'" : '' ?> />
|
22 |
+
<select class="wpstg-exclude-rule-input wpstg-file-size-exclude-select-small" name="wpstgFileSizeExcludeRuleByte[]">
|
23 |
+
<option value="<?php echo ExcludeFilter::SIZE_KB ?>" <?php echo isset($size) && strpos($size, ExcludeFilter::SIZE_KB) !== false ? "selected" : '' ?>>KB</option>
|
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>
|
33 |
+
<td class="wpstg-exclude-filter-action-column"><button class="wpstg-remove-exclude-rule">×</button></td>
|
34 |
+
</tr>
|
Core/CoreServiceProvider.php
ADDED
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Handles the registration of the plugin Core services.
|
5 |
+
*
|
6 |
+
* @package WPStaging\Core
|
7 |
+
*/
|
8 |
+
|
9 |
+
namespace WPStaging\Core;
|
10 |
+
|
11 |
+
use WPStaging\Vendor\Psr\Log\LoggerInterface;
|
12 |
+
use WPStaging\Core\Utils\Logger;
|
13 |
+
use WPStaging\Framework\BackgroundProcessing\BackgroundProcessingServiceProvider;
|
14 |
+
use WPStaging\Framework\DI\ServiceProvider;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Class CoreServiceProvider
|
18 |
+
*
|
19 |
+
* @package WPStaging\Core
|
20 |
+
*/
|
21 |
+
class CoreServiceProvider extends ServiceProvider
|
22 |
+
{
|
23 |
+
/**
|
24 |
+
* Register the plugin core Services.
|
25 |
+
*
|
26 |
+
* @since TBD
|
27 |
+
*
|
28 |
+
*/
|
29 |
+
public function register()
|
30 |
+
{
|
31 |
+
$this->registerEarlyBindings();
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Registers a set of bindings and service providers that could be required before
|
36 |
+
* booting the service provider.
|
37 |
+
*/
|
38 |
+
private function registerEarlyBindings()
|
39 |
+
{
|
40 |
+
$this->container->bind(LoggerInterface::class, Logger::class);
|
41 |
+
}
|
42 |
+
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Binds and sets up implementations at boot time.
|
46 |
+
*/
|
47 |
+
public function boot()
|
48 |
+
{
|
49 |
+
$this->container->register(BackgroundProcessingServiceProvider::class);
|
50 |
+
}
|
51 |
+
}
|
Core/DTO/Settings.php
CHANGED
@@ -83,6 +83,12 @@ class Settings
|
|
83 |
*/
|
84 |
protected $usersWithStagingAccess = "";
|
85 |
|
|
|
|
|
|
|
|
|
|
|
|
|
86 |
/**
|
87 |
* Settings constructor.
|
88 |
*/
|
@@ -177,7 +183,9 @@ class Settings
|
|
177 |
return $this->cpuLoad;
|
178 |
}
|
179 |
|
180 |
-
|
|
|
|
|
181 |
public function getDelayRequests()
|
182 |
{
|
183 |
return $this->delayRequests;
|
@@ -272,14 +280,35 @@ class Settings
|
|
272 |
$this->debugMode = $debugMode;
|
273 |
}
|
274 |
|
275 |
-
|
|
|
|
|
276 |
public function setUserRoles($userRoles)
|
277 |
{
|
278 |
$this->userRoles = $userRoles;
|
279 |
}
|
280 |
|
|
|
|
|
|
|
281 |
public function setUsersWithStagingAccess($usersWithStagingAccess)
|
282 |
{
|
283 |
$this->usersWithStagingAccess = $usersWithStagingAccess;
|
284 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
285 |
}
|
83 |
*/
|
84 |
protected $usersWithStagingAccess = "";
|
85 |
|
86 |
+
/**
|
87 |
+
* Color of the admin bar in hexadecimal format
|
88 |
+
* @var string
|
89 |
+
*/
|
90 |
+
protected $adminBarColor = "";
|
91 |
+
|
92 |
/**
|
93 |
* Settings constructor.
|
94 |
*/
|
183 |
return $this->cpuLoad;
|
184 |
}
|
185 |
|
186 |
+
/**
|
187 |
+
* @return int
|
188 |
+
*/
|
189 |
public function getDelayRequests()
|
190 |
{
|
191 |
return $this->delayRequests;
|
280 |
$this->debugMode = $debugMode;
|
281 |
}
|
282 |
|
283 |
+
/**
|
284 |
+
* @param array $userRoles
|
285 |
+
*/
|
286 |
public function setUserRoles($userRoles)
|
287 |
{
|
288 |
$this->userRoles = $userRoles;
|
289 |
}
|
290 |
|
291 |
+
/**
|
292 |
+
* @param string $usersWithStagingAccess
|
293 |
+
*/
|
294 |
public function setUsersWithStagingAccess($usersWithStagingAccess)
|
295 |
{
|
296 |
$this->usersWithStagingAccess = $usersWithStagingAccess;
|
297 |
}
|
298 |
+
|
299 |
+
/**
|
300 |
+
* @param string $adminBarColor
|
301 |
+
*/
|
302 |
+
public function setAdminBarColor($adminBarColor)
|
303 |
+
{
|
304 |
+
$this->adminBarColor = $adminBarColor;
|
305 |
+
}
|
306 |
+
|
307 |
+
/**
|
308 |
+
* @return string
|
309 |
+
*/
|
310 |
+
public function getAdminBarColor()
|
311 |
+
{
|
312 |
+
return $this->adminBarColor;
|
313 |
+
}
|
314 |
}
|
Core/Forms/Elements/Color.php
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WPStaging\Core\Forms\Elements;
|
4 |
+
|
5 |
+
use WPStaging\Core\Forms\Elements;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Class Color
|
9 |
+
* @package WPStaging\Core\Forms\Elements
|
10 |
+
*/
|
11 |
+
class Color extends Elements
|
12 |
+
{
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @return string
|
16 |
+
*/
|
17 |
+
protected function prepareOutput()
|
18 |
+
{
|
19 |
+
return "<input id='{$this->getId()}' name='{$this->getName()}' type='color' {$this->prepareAttributes()} value='{$this->default}' />";
|
20 |
+
}
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @return string
|
24 |
+
*/
|
25 |
+
public function render()
|
26 |
+
{
|
27 |
+
return ($this->renderFile) ? @file_get_contents($this->renderFile) : $this->prepareOutput();
|
28 |
+
}
|
29 |
+
}
|
Core/WPStaging.php
CHANGED
@@ -2,18 +2,18 @@
|
|
2 |
|
3 |
namespace WPStaging\Core;
|
4 |
|
5 |
-
use WPStaging\Framework\AssetServiceProvider;
|
6 |
-
use WPStaging\Framework\Filesystem\DirectoryListing;
|
7 |
-
use WPStaging\Framework\Filesystem\Filesystem;
|
8 |
-
use WPStaging\Vendor\Psr\Log\LoggerInterface;
|
9 |
-
use WPStaging\Framework\DI\Container;
|
10 |
use WPStaging\Backend\Administrator;
|
11 |
-
use WPStaging\
|
12 |
use WPStaging\Core\Utils\Cache;
|
13 |
use WPStaging\Core\Utils\Logger;
|
|
|
|
|
|
|
|
|
14 |
use WPStaging\Framework\Permalinks\PermalinksPurge;
|
15 |
-
use WPStaging\Core\Cron\Cron;
|
16 |
use WPStaging\Framework\Staging\FirstRun;
|
|
|
|
|
17 |
|
18 |
/**
|
19 |
* Class WPStaging
|
@@ -56,10 +56,13 @@ final class WPStaging
|
|
56 |
|
57 |
$this->startTime = microtime(true);
|
58 |
|
59 |
-
|
60 |
-
$this->container->bind(LoggerInterface::class, Logger::class);
|
61 |
|
62 |
$this->loadDependencies();
|
|
|
|
|
|
|
|
|
63 |
$this->container->register(AssetServiceProvider::class);
|
64 |
$this->initCron();
|
65 |
$this->cloneSiteFirstRun();
|
2 |
|
3 |
namespace WPStaging\Core;
|
4 |
|
|
|
|
|
|
|
|
|
|
|
5 |
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
|
56 |
|
57 |
$this->startTime = microtime(true);
|
58 |
|
59 |
+
$this->container->register(CoreServiceProvider::class);
|
|
|
60 |
|
61 |
$this->loadDependencies();
|
62 |
+
|
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();
|
Core/thirdParty/thirdPartyCompatibility.php
DELETED
@@ -1,35 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace WPStaging\Core\thirdParty;
|
4 |
-
|
5 |
-
/**
|
6 |
-
* Methods to use for third party plugin compatibility
|
7 |
-
*
|
8 |
-
* @todo remove this method when src/Backend/Modules/Jobs/SearchReplace.php and
|
9 |
-
* src/Backend/Pro/Modules/Jobs/SearchReplace.php are made DRY
|
10 |
-
*
|
11 |
-
*/
|
12 |
-
class thirdPartyCompatibility {
|
13 |
-
|
14 |
-
/**
|
15 |
-
* Define a list of tables which should not run through search & replace method
|
16 |
-
* @param string table name e.g. wpsptg1_cerber_files or wpstgtmp_4_cerber_files
|
17 |
-
* @return boolean
|
18 |
-
*/
|
19 |
-
public function isSearchReplaceExcluded( $table ) {
|
20 |
-
$excludedTables = [
|
21 |
-
'_cerber_files', // Cerber Security Plugin
|
22 |
-
'_cerber_sets', // Cerber Security Plugin
|
23 |
-
];
|
24 |
-
|
25 |
-
$excludedTables = apply_filters( 'wpstg_searchreplace_excl_tables', $excludedTables );
|
26 |
-
|
27 |
-
foreach ( $excludedTables as $excludedTable ) {
|
28 |
-
if( strpos( $table, $excludedTable ) !== false ) {
|
29 |
-
return true;
|
30 |
-
}
|
31 |
-
}
|
32 |
-
return false;
|
33 |
-
}
|
34 |
-
|
35 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Framework/Adapter/Database/InterfaceDatabaseClient.php
CHANGED
@@ -68,4 +68,25 @@ interface InterfaceDatabaseClient
|
|
68 |
* @return void
|
69 |
*/
|
70 |
public function freeResult($result);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
71 |
}
|
68 |
* @return void
|
69 |
*/
|
70 |
public function freeResult($result);
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Returns the AUTO-INCREMENT value of the last insterted row.
|
74 |
+
*
|
75 |
+
* @return int The value of the auto-increment column of the last
|
76 |
+
* inserted row.
|
77 |
+
*/
|
78 |
+
public function insertId();
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Returns the number of rows found in the last query before a
|
82 |
+
* limit is applied to it.
|
83 |
+
*
|
84 |
+
* Note: this method uses the `FOUND_ROWS()` MySQL function to retrieve
|
85 |
+
* this information: read the MySQL function documentation to understand
|
86 |
+
* the result and the conditions applying to it.
|
87 |
+
*
|
88 |
+
* @return int The number of rows found in the last query before any limit
|
89 |
+
* is applied to it.
|
90 |
+
*/
|
91 |
+
public function foundRows();
|
92 |
}
|
Framework/Adapter/Database/MysqlAdapter.php
CHANGED
@@ -112,4 +112,22 @@ class MysqlAdapter implements InterfaceDatabaseClient
|
|
112 |
|
113 |
return null;
|
114 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
}
|
112 |
|
113 |
return null;
|
114 |
}
|
115 |
+
|
116 |
+
/**
|
117 |
+
* {@inheritdoc}
|
118 |
+
*/
|
119 |
+
public function insertId()
|
120 |
+
{
|
121 |
+
// phpcs:ignore PHPCompatibility.Extensions.RemovedExtensions.mysql_DeprecatedRemoved
|
122 |
+
return mysql_insert_id($this->link);
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* {@inheritdoc}
|
127 |
+
*/
|
128 |
+
public function foundRows()
|
129 |
+
{
|
130 |
+
// phpcs:ignore PHPCompatibility.Extensions.RemovedExtensions.mysql_DeprecatedRemoved
|
131 |
+
return mysql_affected_rows($this->link);
|
132 |
+
}
|
133 |
}
|
Framework/Adapter/Database/MysqliAdapter.php
CHANGED
@@ -110,4 +110,20 @@ class MysqliAdapter implements InterfaceDatabaseClient
|
|
110 |
|
111 |
return null;
|
112 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
113 |
}
|
110 |
|
111 |
return null;
|
112 |
}
|
113 |
+
|
114 |
+
/**
|
115 |
+
* {@inheritdoc}
|
116 |
+
*/
|
117 |
+
public function insertId()
|
118 |
+
{
|
119 |
+
return mysqli_insert_id($this->link);
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* {@inheritdoc}
|
124 |
+
*/
|
125 |
+
public function foundRows()
|
126 |
+
{
|
127 |
+
return mysqli_affected_rows($this->link);
|
128 |
+
}
|
129 |
}
|
Framework/Adapter/Maintenance.php
CHANGED
@@ -11,7 +11,7 @@ class Maintenance
|
|
11 |
|
12 |
public function isMaintenance()
|
13 |
{
|
14 |
-
return (
|
15 |
}
|
16 |
|
17 |
public function enableMaintenance($isMaintenance)
|
11 |
|
12 |
public function isMaintenance()
|
13 |
{
|
14 |
+
return file_exists($this->findMaintenanceFilePath());
|
15 |
}
|
16 |
|
17 |
public function enableMaintenance($isMaintenance)
|
Framework/Assets/Assets.php
CHANGED
@@ -2,14 +2,21 @@
|
|
2 |
|
3 |
namespace WPStaging\Framework\Assets;
|
4 |
|
5 |
-
use WPStaging\Backend\Modules\Jobs\Scan;
|
6 |
use WPStaging\Core\DTO\Settings;
|
7 |
use WPStaging\Core\WPStaging;
|
|
|
|
|
8 |
use WPStaging\Framework\Security\AccessToken;
|
9 |
use WPStaging\Framework\Security\Nonce;
|
10 |
|
11 |
class Assets
|
12 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
private $accessToken;
|
14 |
|
15 |
private $settings;
|
@@ -65,7 +72,8 @@ class Assets
|
|
65 |
*/
|
66 |
public function getAssetsVersion($assetsFile, $assetsVersion = '')
|
67 |
{
|
68 |
-
$
|
|
|
69 |
|
70 |
if ($filemtime !== false) {
|
71 |
return $filemtime;
|
@@ -80,20 +88,21 @@ class Assets
|
|
80 |
*/
|
81 |
public function enqueueElements($hook)
|
82 |
{
|
|
|
83 |
// Load this css file on frontend and backend on all pages if current site is a staging site
|
84 |
if (wpstg_is_stagingsite()) {
|
85 |
-
|
86 |
-
wp_enqueue_style(
|
87 |
-
|
88 |
-
$this->getAssetsUrl($asset),
|
89 |
-
[],
|
90 |
-
$this->getAssetsVersion($asset)
|
91 |
-
);
|
92 |
}
|
93 |
|
94 |
// Load js file on page plugins.php in free version only
|
95 |
if (!defined('WPSTGPRO_VERSION') && $this->isPluginsPage()) {
|
96 |
-
$asset = 'js/dist/wpstg-admin-plugins.js';
|
|
|
|
|
|
|
|
|
97 |
wp_enqueue_script(
|
98 |
"wpstg-admin-script",
|
99 |
$this->getAssetsUrl($asset),
|
@@ -102,7 +111,11 @@ class Assets
|
|
102 |
false
|
103 |
);
|
104 |
|
105 |
-
$asset = 'css/
|
|
|
|
|
|
|
|
|
106 |
wp_enqueue_style(
|
107 |
"wpstg-admin-feedback",
|
108 |
$this->getAssetsUrl($asset),
|
@@ -116,7 +129,11 @@ class Assets
|
|
116 |
}
|
117 |
|
118 |
// Load admin js files
|
119 |
-
$asset = 'js/dist/wpstg-admin.js';
|
|
|
|
|
|
|
|
|
120 |
wp_enqueue_script(
|
121 |
"wpstg-admin-script",
|
122 |
$this->getAssetsUrl($asset),
|
@@ -126,7 +143,11 @@ class Assets
|
|
126 |
);
|
127 |
|
128 |
// Load admin js files
|
129 |
-
$asset = 'js/dist/wpstg-legacy-database.js';
|
|
|
|
|
|
|
|
|
130 |
wp_enqueue_script(
|
131 |
"wpstg-legacy-database",
|
132 |
$this->getAssetsUrl($asset),
|
@@ -172,7 +193,11 @@ class Assets
|
|
172 |
|
173 |
// Load admin js pro files
|
174 |
if (defined('WPSTGPRO_VERSION')) {
|
175 |
-
$asset = 'js/dist/pro/wpstg-admin-pro.js';
|
|
|
|
|
|
|
|
|
176 |
wp_enqueue_script(
|
177 |
"wpstg-admin-pro-script",
|
178 |
$this->getAssetsUrl($asset),
|
@@ -183,7 +208,11 @@ class Assets
|
|
183 |
}
|
184 |
|
185 |
// Load admin css files
|
186 |
-
$asset = 'css/
|
|
|
|
|
|
|
|
|
187 |
wp_enqueue_style(
|
188 |
"wpstg-admin",
|
189 |
$this->getAssetsUrl($asset),
|
@@ -196,21 +225,27 @@ class Assets
|
|
196 |
|
197 |
wp_localize_script("wpstg-admin-script", "wpstg", [
|
198 |
"delayReq" => $this->getDelay(),
|
|
|
199 |
"settings" => (object)[
|
200 |
-
"directorySeparator"
|
201 |
],
|
202 |
"tblprefix" => WPStaging::getTablePrefix(),
|
203 |
"isMultisite" => is_multisite(),
|
204 |
AccessToken::REQUEST_KEY => (string)$this->accessToken->getToken() ?: (string)$this->accessToken->generateNewToken(),
|
205 |
'nonce' => wp_create_nonce(Nonce::WPSTG_NONCE),
|
206 |
'ajaxUrl' => admin_url('admin-ajax.php'),
|
|
|
207 |
// TODO: handle i18n translations through Class/Service Provider?
|
208 |
'i18n' => [
|
209 |
'dbConnectionSuccess' => esc_html__('Database Connection - Success', 'wp-staging'),
|
210 |
'dbConnectionFailed' => esc_html__('Database Connection - Failed', 'wp-staging'),
|
211 |
'somethingWentWrong' => esc_html__('Something went wrong.', 'wp-staging'),
|
212 |
-
'noImportFileFound'
|
213 |
-
'selectFileToImport'
|
|
|
|
|
|
|
|
|
214 |
],
|
215 |
]);
|
216 |
}
|
@@ -310,6 +345,11 @@ class Assets
|
|
310 |
return $delay;
|
311 |
}
|
312 |
|
|
|
|
|
|
|
|
|
|
|
313 |
public function makeScriptsES6($tag, $handle, $source)
|
314 |
{
|
315 |
if ($handle === 'wpstg-admin-pro-script' || $handle === 'wpstg-admin-script') {
|
@@ -318,4 +358,27 @@ class Assets
|
|
318 |
|
319 |
return $tag;
|
320 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
321 |
}
|
2 |
|
3 |
namespace WPStaging\Framework\Assets;
|
4 |
|
|
|
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
|
17 |
+
*/
|
18 |
+
const DEFAULT_ADMIN_BAR_BG = "#ff8d00";
|
19 |
+
|
20 |
private $accessToken;
|
21 |
|
22 |
private $settings;
|
72 |
*/
|
73 |
public function getAssetsVersion($assetsFile, $assetsVersion = '')
|
74 |
{
|
75 |
+
$filename = $this->getAssetsPath($assetsFile);
|
76 |
+
$filemtime = file_exists($filename) ? @filemtime($filename) : false;
|
77 |
|
78 |
if ($filemtime !== false) {
|
79 |
return $filemtime;
|
88 |
*/
|
89 |
public function enqueueElements($hook)
|
90 |
{
|
91 |
+
|
92 |
// Load this css file on frontend and backend on all pages if current site is a staging site
|
93 |
if (wpstg_is_stagingsite()) {
|
94 |
+
wp_register_style('wpstg-admin-bar', false);
|
95 |
+
wp_enqueue_style('wpstg-admin-bar');
|
96 |
+
wp_add_inline_style('wpstg-admin-bar', $this->getStagingAdminBarColor());
|
|
|
|
|
|
|
|
|
97 |
}
|
98 |
|
99 |
// Load js file on page plugins.php in free version only
|
100 |
if (!defined('WPSTGPRO_VERSION') && $this->isPluginsPage()) {
|
101 |
+
$asset = 'js/dist/wpstg-admin-plugins.min.js';
|
102 |
+
if ($this->isDebugOrDevMode()) {
|
103 |
+
$asset = 'js/dist/wpstg-admin-plugins.js';
|
104 |
+
}
|
105 |
+
|
106 |
wp_enqueue_script(
|
107 |
"wpstg-admin-script",
|
108 |
$this->getAssetsUrl($asset),
|
111 |
false
|
112 |
);
|
113 |
|
114 |
+
$asset = 'css/dist/wpstg-admin-feedback.min.css';
|
115 |
+
if ($this->isDebugOrDevMode()) {
|
116 |
+
$asset = 'css/dist/wpstg-admin-feedback.css';
|
117 |
+
}
|
118 |
+
|
119 |
wp_enqueue_style(
|
120 |
"wpstg-admin-feedback",
|
121 |
$this->getAssetsUrl($asset),
|
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),
|
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),
|
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';
|
199 |
+
}
|
200 |
+
|
201 |
wp_enqueue_script(
|
202 |
"wpstg-admin-pro-script",
|
203 |
$this->getAssetsUrl($asset),
|
208 |
}
|
209 |
|
210 |
// Load admin css files
|
211 |
+
$asset = 'css/dist/wpstg-admin.min.css';
|
212 |
+
if ($this->isDebugOrDevMode()) {
|
213 |
+
$asset = 'css/dist/wpstg-admin.css';
|
214 |
+
}
|
215 |
+
|
216 |
wp_enqueue_style(
|
217 |
"wpstg-admin",
|
218 |
$this->getAssetsUrl($asset),
|
225 |
|
226 |
wp_localize_script("wpstg-admin-script", "wpstg", [
|
227 |
"delayReq" => $this->getDelay(),
|
228 |
+
// TODO: move directorySeparator to consts?
|
229 |
"settings" => (object)[
|
230 |
+
"directorySeparator" => ScanConst::DIRECTORIES_SEPARATOR
|
231 |
],
|
232 |
"tblprefix" => WPStaging::getTablePrefix(),
|
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'),
|
241 |
'dbConnectionFailed' => esc_html__('Database Connection - Failed', 'wp-staging'),
|
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 |
}
|
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') {
|
358 |
|
359 |
return $tag;
|
360 |
}
|
361 |
+
|
362 |
+
/**
|
363 |
+
* @return string
|
364 |
+
*/
|
365 |
+
public function getStagingAdminBarColor()
|
366 |
+
{
|
367 |
+
$barColor = $this->settings->getAdminBarColor();
|
368 |
+
if (!preg_match("/#([a-f0-9]{3}){1,2}\b/i", $barColor)) {
|
369 |
+
$barColor = self::DEFAULT_ADMIN_BAR_BG;
|
370 |
+
}
|
371 |
+
|
372 |
+
return "#wpadminbar { background-color: {$barColor} !important; }";
|
373 |
+
}
|
374 |
+
|
375 |
+
/**
|
376 |
+
* Check whether app is in debug mode or in dev mode
|
377 |
+
*
|
378 |
+
* @return boolean
|
379 |
+
*/
|
380 |
+
private function isDebugOrDevMode()
|
381 |
+
{
|
382 |
+
return ($this->settings->isDebugMode() || (defined('WPSTG_DEV') && WPSTG_DEV === true));
|
383 |
+
}
|
384 |
}
|
Framework/BackgroundProcessing/Action.php
ADDED
@@ -0,0 +1,309 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Models the information about an Action stored in the Queue.
|
5 |
+
*
|
6 |
+
* @package WPStaging\Framework\BackgroundProcessing
|
7 |
+
*/
|
8 |
+
|
9 |
+
namespace WPStaging\Framework\BackgroundProcessing;
|
10 |
+
|
11 |
+
use BadMethodCallException;
|
12 |
+
use WPStaging\Framework\BackgroundProcessing\Exceptions\QueueException;
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Class Action
|
16 |
+
*
|
17 |
+
* @package WPStaging\Framework\BackgroundProcessing
|
18 |
+
*
|
19 |
+
* @property int $id The Action id, the unique, auto-increment value identifying its row.
|
20 |
+
* @property string $action The action name.
|
21 |
+
* @property string $jobId The Job the action belongs to.
|
22 |
+
* @property int $priority The Action priority, lower is executed first (like WP Filters API).
|
23 |
+
* @property array $args A set of arguments for the action.
|
24 |
+
* @property string $status The current Action status in the context of the Queue.
|
25 |
+
* @property string $claimedAt The date and time, in the site timezone, the Action was last claimed for processing.
|
26 |
+
* @property string $updatedAt The date and time, in the site timezone, the Action was last updated.
|
27 |
+
*/
|
28 |
+
class Action
|
29 |
+
{
|
30 |
+
use WithQueueAwareness;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* The Action id, the unique, auto-increment value identifying its row.
|
34 |
+
*
|
35 |
+
* @var int
|
36 |
+
*/
|
37 |
+
private $id;
|
38 |
+
|
39 |
+
/**
|
40 |
+
* The action name, it can be a string that will be processed as a WordPress action or
|
41 |
+
* another type of callable that will be called directly.
|
42 |
+
*
|
43 |
+
* @var string
|
44 |
+
*/
|
45 |
+
private $action;
|
46 |
+
|
47 |
+
/**
|
48 |
+
* The name of teh Job, or Group, the Action belongs to.
|
49 |
+
*
|
50 |
+
* @var string
|
51 |
+
*/
|
52 |
+
private $jobId;
|
53 |
+
|
54 |
+
/**
|
55 |
+
* The Action priority, works like the WordPress Filter API priority where
|
56 |
+
* lower values are processed first.
|
57 |
+
*
|
58 |
+
* @var int
|
59 |
+
*/
|
60 |
+
private $priority;
|
61 |
+
|
62 |
+
/**
|
63 |
+
* An optional array of arguments that will be passed to either the WordPress
|
64 |
+
* action fired by the Queue or as parameters for the invoked callable.
|
65 |
+
*
|
66 |
+
* @var array<mixed>
|
67 |
+
*/
|
68 |
+
private $args;
|
69 |
+
|
70 |
+
/**
|
71 |
+
* A string representing the Action status in the context of the Queue, e.g. ready
|
72 |
+
* or processing.
|
73 |
+
*
|
74 |
+
* @var string|null
|
75 |
+
*/
|
76 |
+
private $status;
|
77 |
+
|
78 |
+
/**
|
79 |
+
* The string representing the date and time, in the site timezone, the Action was
|
80 |
+
* last claimed for processing.
|
81 |
+
*
|
82 |
+
* @var string|null
|
83 |
+
*/
|
84 |
+
private $claimedAt;
|
85 |
+
|
86 |
+
/**
|
87 |
+
* The string representing the date and time, in the site timezone, the Action was
|
88 |
+
* last updated in any way.
|
89 |
+
*
|
90 |
+
* @var string|null
|
91 |
+
*/
|
92 |
+
private $updatedAt;
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Action constructor.
|
96 |
+
*
|
97 |
+
* @param int $id The Action id, its unique identifier in the Queue; `0` is a valid id
|
98 |
+
* for provisional Actions.
|
99 |
+
* @param string $action The Action name, it could be a string that will be used to fire a WP
|
100 |
+
* action, or a string in the format `<class>::<static-method>` that will
|
101 |
+
* cause that static method to be invoked directly with the Action arguments.
|
102 |
+
* @param array<mixed> $args An optional set of arguments for the Action that will either be passed to the
|
103 |
+
* invoked WP action, or to the specified static method as parameters.
|
104 |
+
* @param string $jobId The Job, or Group, the Action belongs to.
|
105 |
+
* @param int $priority The Action priority in the context of the Queue, it works like the priority of
|
106 |
+
* filters in the WordPress Filter API: lower values are processed first.
|
107 |
+
* @param string|null $status The Action status in the context of the Queue, e.g. ready or processing.
|
108 |
+
* @param string|null $claimedAt The string representing the date and time, in the site timezone, the Action was last claimed
|
109 |
+
* for processing.
|
110 |
+
* @param string|null $updatedAt The string representing the date and time, in the site timezone, the Action was last updated.
|
111 |
+
*
|
112 |
+
* @throws QueueException If any value used to build the Action is not valid.
|
113 |
+
*/
|
114 |
+
public function __construct(
|
115 |
+
$id,
|
116 |
+
$action,
|
117 |
+
array $args = [],
|
118 |
+
$jobId = 'default',
|
119 |
+
$priority = 0,
|
120 |
+
$status = null,
|
121 |
+
$claimedAt = null,
|
122 |
+
$updatedAt = null
|
123 |
+
) {
|
124 |
+
if (!is_numeric($id) && absint($id) == $id) {
|
125 |
+
throw new QueueException('Id MUST be a positive integer.');
|
126 |
+
}
|
127 |
+
|
128 |
+
if ((string)$action === '') {
|
129 |
+
throw new QueueException('Action MUST be a non-empty string.');
|
130 |
+
}
|
131 |
+
|
132 |
+
if ((string)$jobId === '') {
|
133 |
+
throw new QueueException('Job ID MUST be a non-empty string.');
|
134 |
+
}
|
135 |
+
|
136 |
+
$priority = is_numeric($priority) && (int)$priority == $priority ?
|
137 |
+
(int)$priority
|
138 |
+
: $this->getDefaultPriority();
|
139 |
+
|
140 |
+
$this->id = $id;
|
141 |
+
$this->action = $action;
|
142 |
+
$this->args = $args;
|
143 |
+
$this->jobId = $jobId;
|
144 |
+
$this->priority = $priority;
|
145 |
+
$this->status = $status;
|
146 |
+
$this->claimedAt = $claimedAt;
|
147 |
+
$this->updatedAt = $updatedAt;
|
148 |
+
}
|
149 |
+
|
150 |
+
/**
|
151 |
+
* Builds, and returns, an Action instance from the raw data found in a database row.
|
152 |
+
*
|
153 |
+
* @param array<string,mixed> $dbRow The database row, as an associative array.
|
154 |
+
*
|
155 |
+
* @return Action A reference to an Action instance built on the row data.
|
156 |
+
*
|
157 |
+
* @throws QueueException If there's any issue validating any one of the row fields.
|
158 |
+
*/
|
159 |
+
public static function fromDbRow(array $dbRow)
|
160 |
+
{
|
161 |
+
$id = (int)$dbRow['id'];
|
162 |
+
$action = (string)$dbRow['action'];
|
163 |
+
$jobId = isset($dbRow['jobId']) ? (string)($dbRow['jobId']) : null;
|
164 |
+
$priority = isset($dbRow['priority']) ? (int)$dbRow['priority'] : self::getDefaultPriority();
|
165 |
+
$args = isset($dbRow['args']) ? (array)maybe_unserialize($dbRow['args']) : [];
|
166 |
+
$status = isset($dbRow['status']) ? (string)$dbRow['status'] : Queue::STATUS_READY;
|
167 |
+
$claimedAt = isset($dbRow['claimed_at']) ? (string)$dbRow['claimed_at'] : null;
|
168 |
+
$updatedAt = isset($dbRow['updated_at']) ? (string)$dbRow['updated_at'] : null;
|
169 |
+
|
170 |
+
return new self($id, $action, $args, $jobId, $priority, $status, $claimedAt, $updatedAt);
|
171 |
+
}
|
172 |
+
|
173 |
+
/**
|
174 |
+
* Overrides the magic method to get private properties with a read-only API.
|
175 |
+
*
|
176 |
+
* @param string $name The name of the property to get.
|
177 |
+
*
|
178 |
+
* @return mixed The property value.
|
179 |
+
*
|
180 |
+
* @throws BadMethodCallException If the Action does not define the property.
|
181 |
+
*/
|
182 |
+
public function __get($name)
|
183 |
+
{
|
184 |
+
if (!property_exists($this, $name)) {
|
185 |
+
throw new BadMethodCallException("The Action object does not have an accessible property '{$name}'.");
|
186 |
+
}
|
187 |
+
|
188 |
+
return isset($this->{$name}) ? $this->{$name} : null;
|
189 |
+
}
|
190 |
+
|
191 |
+
/**
|
192 |
+
* Overrides the magic method to clearly signal the immutable nature of the Action object.
|
193 |
+
*
|
194 |
+
* @param string $name The name of the property to set.
|
195 |
+
* @param mixed $value The value that should be assigned to the property.
|
196 |
+
*
|
197 |
+
* @throws BadMethodCallException As Actions are immutable.
|
198 |
+
*/
|
199 |
+
public function __set($name, $value)
|
200 |
+
{
|
201 |
+
throw new BadMethodCallException("The Action object is immutable: its properties can be set only when building it.");
|
202 |
+
}
|
203 |
+
|
204 |
+
/**
|
205 |
+
* Returns whether two Actions are the same in regards to relevant properties.
|
206 |
+
*
|
207 |
+
* @param Action $toCompare A reference to the Action instance this one should
|
208 |
+
* be compared to.
|
209 |
+
* @param array<string> $compareFieldsExclude A list of Action fields that should not be used in the
|
210 |
+
* comparison; by default all the Action properties will
|
211 |
+
* be used
|
212 |
+
*
|
213 |
+
* @return bool Whether this Action and the one it's being compared to are equals
|
214 |
+
* or not.
|
215 |
+
*/
|
216 |
+
public function equals(Action $toCompare, array $compareFieldsExclude = [])
|
217 |
+
{
|
218 |
+
$compareFields = array_diff(
|
219 |
+
['id', 'action', 'jobId', 'priority', 'args','status'],
|
220 |
+
$compareFieldsExclude
|
221 |
+
);
|
222 |
+
|
223 |
+
foreach ($compareFields as $prop) {
|
224 |
+
if (!$this->{$prop} == $toCompare->{$prop}) {
|
225 |
+
return false;
|
226 |
+
}
|
227 |
+
}
|
228 |
+
|
229 |
+
return true;
|
230 |
+
}
|
231 |
+
|
232 |
+
/**
|
233 |
+
* Returns the associative array representation of the Action.
|
234 |
+
*
|
235 |
+
* @return array<string,string|int|array> A map from the Action current properties
|
236 |
+
* to their current values.
|
237 |
+
*/
|
238 |
+
public function toArray()
|
239 |
+
{
|
240 |
+
return [
|
241 |
+
'id' => $this->id,
|
242 |
+
'action' => $this->action,
|
243 |
+
'jobId' => $this->jobId,
|
244 |
+
'priority' => $this->priority,
|
245 |
+
'args' => $this->args,
|
246 |
+
'status' => $this->status,
|
247 |
+
'claimedAt' => $this->claimedAt,
|
248 |
+
'updatedAt' => $this->updatedAt,
|
249 |
+
];
|
250 |
+
}
|
251 |
+
|
252 |
+
/**
|
253 |
+
* Alters the Action instance with a set of alterations. Since the Action is immutable
|
254 |
+
* alteration will produce, in fact, a clone of it that will be returned.
|
255 |
+
*
|
256 |
+
* @param array<string,mixed> $alterations An map from the alteration keys to their
|
257 |
+
* values.
|
258 |
+
*
|
259 |
+
* @return Action A reference to a modified clone of the current Action.
|
260 |
+
*/
|
261 |
+
public function alter(array $alterations)
|
262 |
+
{
|
263 |
+
$clone = clone $this;
|
264 |
+
|
265 |
+
foreach ($alterations as $key => $value) {
|
266 |
+
$clone->{$key} = $value;
|
267 |
+
}
|
268 |
+
|
269 |
+
return $clone;
|
270 |
+
}
|
271 |
+
|
272 |
+
/**
|
273 |
+
* Utility method to sort Action in functions or methods accepting
|
274 |
+
* sorting callbacks like `usort`.
|
275 |
+
*
|
276 |
+
* The method will sort Actions by priority, action and jobId, in
|
277 |
+
* ascending order.
|
278 |
+
*
|
279 |
+
* @param array<string,mixed>|Action $actionOne Either an Action instance
|
280 |
+
* or the array representation of an
|
281 |
+
* Action.
|
282 |
+
* @param array<string,mixed>|Action $actionTwo Either an Action instance
|
283 |
+
* or the array representation of an
|
284 |
+
* Action.
|
285 |
+
*
|
286 |
+
* @return int An integer sticking with `usort` expected value that will return `-1`
|
287 |
+
* if the first Action comes before the second, `0` if they are equal
|
288 |
+
* in all regards and `1` if the second Action comes before the first.
|
289 |
+
*/
|
290 |
+
public static function sort($actionOne, $actionTwo)
|
291 |
+
{
|
292 |
+
$objectOne = (object)$actionOne;
|
293 |
+
$objectTwo = (object)$actionTwo;
|
294 |
+
|
295 |
+
if ($objectOne->priority !== $objectTwo->priority) {
|
296 |
+
return (int)($objectOne->priority > $objectTwo->priority);
|
297 |
+
}
|
298 |
+
|
299 |
+
if ($objectOne->action !== $objectTwo->action) {
|
300 |
+
return (int)($objectOne->action > $objectTwo->action);
|
301 |
+
}
|
302 |
+
|
303 |
+
if ($objectOne->jobId !== $objectTwo->jobId) {
|
304 |
+
return (int)($objectOne->jobId > $objectTwo->jobId);
|
305 |
+
}
|
306 |
+
|
307 |
+
return 0;
|
308 |
+
}
|
309 |
+
}
|
Framework/BackgroundProcessing/BackgroundProcessingServiceProvider.php
ADDED
@@ -0,0 +1,181 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Manages the registration and hooking of the Background Processing support feature.
|
5 |
+
*
|
6 |
+
* @package WPStaging\Framework\BackgroundProcessing
|
7 |
+
*/
|
8 |
+
|
9 |
+
namespace WPStaging\Framework\BackgroundProcessing;
|
10 |
+
|
11 |
+
use WPStaging\Framework\DI\FeatureServiceProvider;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Class BackgroundProcessingServiceProvider
|
15 |
+
*
|
16 |
+
* @property \tad_DI52_Container container
|
17 |
+
* @package WPStaging\Framework\BackgroundProcessing
|
18 |
+
*/
|
19 |
+
class BackgroundProcessingServiceProvider extends FeatureServiceProvider
|
20 |
+
{
|
21 |
+
/**
|
22 |
+
* {@inheritdoc}
|
23 |
+
*/
|
24 |
+
public static function getFeatureTrigger()
|
25 |
+
{
|
26 |
+
return 'WPSTG_FEATURE_ENABLE_BACKGROUND_PROCESSING';
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Registers the required Cron actions and the classes used by the feature provider.
|
31 |
+
*
|
32 |
+
* @return bool Whether the feature registration was actually done or not.
|
33 |
+
*/
|
34 |
+
public function register()
|
35 |
+
{
|
36 |
+
if (!static::isEnabled()) {
|
37 |
+
return false;
|
38 |
+
}
|
39 |
+
|
40 |
+
// For caching purposes, have one single instance of the Queue around.
|
41 |
+
$this->container->singleton(Queue::class, Queue::class);
|
42 |
+
// For concurrency purposes, have one single instance of the Queue processor around.
|
43 |
+
$this->container->singleton(QueueProcessor::class, QueueProcessor::class);
|
44 |
+
|
45 |
+
$this->registerFeatureDetection();
|
46 |
+
$this->scheduleQueueMaintenance();
|
47 |
+
$this->setupQueueProcessingEntrypoints();
|
48 |
+
|
49 |
+
/// Demo -- will be removed on release.
|
50 |
+
if (isset($_REQUEST['wpstg_q_demo'])) {
|
51 |
+
$count = (max(100, (int)filter_var($_REQUEST['wpstg_q_demo'], FILTER_SANITIZE_NUMBER_INT)));
|
52 |
+
(new Demo())->run($count);
|
53 |
+
}
|
54 |
+
/// End Demo
|
55 |
+
|
56 |
+
return true;
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Runs the Queue maintenance routines.
|
61 |
+
*
|
62 |
+
* @return void The method will not return any value.
|
63 |
+
*/
|
64 |
+
public function runQueueMaintenance()
|
65 |
+
{
|
66 |
+
/** @var Queue $queue */
|
67 |
+
$queue = $this->container->make(Queue::class);
|
68 |
+
|
69 |
+
// Mark all dangling Actions as Failed.
|
70 |
+
$queue->markDanglingAs(Queue::STATUS_FAILED);
|
71 |
+
// Remove old Actions.
|
72 |
+
$queue->cleanup();
|
73 |
+
}
|
74 |
+
|
75 |
+
/**
|
76 |
+
* Schedules the Queue mainteance by means of the Cron. The Cron is not
|
77 |
+
* a really reliable method to execute timely tasks in WordPress, especially
|
78 |
+
* if not powered by a real cron, but it's fine for addressin the maintenance
|
79 |
+
* operations of the Queue that do not require to be timely and are fine happening
|
80 |
+
* when possible.
|
81 |
+
*
|
82 |
+
* @since TBD
|
83 |
+
*
|
84 |
+
*/
|
85 |
+
private function scheduleQueueMaintenance()
|
86 |
+
{
|
87 |
+
// Once a day fire an action to run the Queue maintenance routines.
|
88 |
+
if (!wp_next_scheduled('wpstg_queue_maintain')) {
|
89 |
+
wp_schedule_event(time(), 'daily', 'wpstg_queue_maintain');
|
90 |
+
}
|
91 |
+
|
92 |
+
// When the action fires, run the maintenance routines.
|
93 |
+
add_action('wpstg_queue_maintain', [$this, 'runQueueMaintenance']);
|
94 |
+
}
|
95 |
+
|
96 |
+
/**
|
97 |
+
* Sets up the Queue processing entry points.
|
98 |
+
*
|
99 |
+
* The Queue, when loaded with Actions, has the potential to soak resources.
|
100 |
+
* The Queue Processor will have safeguards in place to avoid this, but we should
|
101 |
+
* be careful about the entrypoints of the queue processing to make sure it will
|
102 |
+
* process Actions only when doing that will not compromise the user experience.
|
103 |
+
* This is why we rely on side-processes that we can trigger while the main PHP process
|
104 |
+
* that is handling the user interaction with the site stays fast and snappy.
|
105 |
+
*
|
106 |
+
* @return void The method does not return any value.
|
107 |
+
*/
|
108 |
+
private function setupQueueProcessingEntrypoints()
|
109 |
+
{
|
110 |
+
/**
|
111 |
+
* This is the core of how the Queue works: when the `wpstg_queue_process`, or the AJAX version of it, fires, we'll process some
|
112 |
+
* Actions.
|
113 |
+
* Setting up how we make these WordPress actions fire is what we take care of next.
|
114 |
+
*/
|
115 |
+
$wpActions = [
|
116 |
+
QueueProcessor::QUEUE_PROCESS_ACTION,
|
117 |
+
'wp_ajax_nopriv_' . QueueProcessor::QUEUE_PROCESS_ACTION,
|
118 |
+
'wp_ajax_' . QueueProcessor::QUEUE_PROCESS_ACTION,
|
119 |
+
];
|
120 |
+
$queueProcessorProcess = $this->container->callback(QueueProcessor::class, 'process');
|
121 |
+
|
122 |
+
foreach ($wpActions as $wpAction) {
|
123 |
+
if (!has_action($wpAction, $queueProcessorProcess)) {
|
124 |
+
add_action($wpAction, $queueProcessorProcess);
|
125 |
+
}
|
126 |
+
}
|
127 |
+
|
128 |
+
/*
|
129 |
+
* The first way we trigger the action that will make the Queue Processor process Actions is a Cron schedule.
|
130 |
+
* With full-knowledge of the fact that it will not be reliable, we still try to get some work done
|
131 |
+
* on Cron calls.
|
132 |
+
* Once every hour (kinda, it's Cron), fire the `wpstg_queue_process` action.
|
133 |
+
*/
|
134 |
+
if (!wp_next_scheduled('wpstg_queue_process')) {
|
135 |
+
wp_schedule_event(time(), 'hourly', QueueProcessor::QUEUE_PROCESS_ACTION);
|
136 |
+
}
|
137 |
+
|
138 |
+
/*
|
139 |
+
* This is currently deactivated while we decide if supporting this is something we would like to do at all.
|
140 |
+
if (is_admin() && !wp_doing_ajax()) {
|
141 |
+
$ajaxAvailable = $this->container->make(FeatureDetection::class)->isAjaxAvailable(false);
|
142 |
+
|
143 |
+
if (!$ajaxAvailable) {
|
144 |
+
// add_action('shutdown', $queueProcessorProcess, -10000);
|
145 |
+
}
|
146 |
+
}
|
147 |
+
*/
|
148 |
+
}
|
149 |
+
|
150 |
+
/**
|
151 |
+
* Registers the two actions that will be called by the AJAX support
|
152 |
+
* feature detection.
|
153 |
+
*
|
154 |
+
* @since TBD
|
155 |
+
*/
|
156 |
+
private function registerFeatureDetection()
|
157 |
+
{
|
158 |
+
// Register the method that will handle the AJAX check.
|
159 |
+
$updateOption = $this->container->callback(FeatureDetection::class, 'updateAjaxTestOption');
|
160 |
+
// Hook on authenticated AJAX endpoint to handle the check.
|
161 |
+
add_action('wp_ajax_' . FeatureDetection::AJAX_TEST_ACTION, $updateOption);
|
162 |
+
|
163 |
+
// Once a week re-run the check.
|
164 |
+
if (!wp_next_scheduled('wpstg_q_ajax_support_feature_detection')) {
|
165 |
+
wp_schedule_event(time(), 'weekly', 'wpstg_q_ajax_support_feature_detection');
|
166 |
+
}
|
167 |
+
|
168 |
+
$runAjaxFeatureTest = $this->container->callback(FeatureDetection::class, 'runAjaxFeatureTest');
|
169 |
+
add_action('wpstg_ajax_support_feature_detection', $runAjaxFeatureTest);
|
170 |
+
|
171 |
+
// Run the test again if requested by link, e.g. from the notice.
|
172 |
+
if (
|
173 |
+
is_admin()
|
174 |
+
&& filter_input(INPUT_GET, FeatureDetection::AJAX_REQUEST_QUERY_VAR, FILTER_SANITIZE_NUMBER_INT)
|
175 |
+
) {
|
176 |
+
$runAjaxFeatureTest();
|
177 |
+
wp_redirect(remove_query_arg(FeatureDetection::AJAX_REQUEST_QUERY_VAR));
|
178 |
+
die();
|
179 |
+
}
|
180 |
+
}
|
181 |
+
}
|
Framework/BackgroundProcessing/Demo.php
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Runs a Queue Background Processing Demo from the browser.
|
5 |
+
*
|
6 |
+
* Go to https:<site>/?wpstg_q_demo to run the demo queueing 100 actions and close all browser windows on the site.
|
7 |
+
*
|
8 |
+
* Go to https:<site>/?wpstg_q_demo=<n> to run the demo queueing <n> actions and close all browser windows on the site.
|
9 |
+
*
|
10 |
+
* @since TBD
|
11 |
+
*
|
12 |
+
* @package WPStaging\Framework\BackgroundProcessing
|
13 |
+
*/
|
14 |
+
|
15 |
+
namespace WPStaging\Framework\BackgroundProcessing;
|
16 |
+
|
17 |
+
use WPStaging\Core\WPStaging;
|
18 |
+
|
19 |
+
class Demo
|
20 |
+
{
|
21 |
+
public function run($count)
|
22 |
+
{
|
23 |
+
$queue = WPStaging::getInstance()->getContainer()->make(Queue::class);
|
24 |
+
|
25 |
+
foreach (range(1, $count) as $k) {
|
26 |
+
$queue->enqueueAction(self::class . '::' . 'writeToLog', [$k]);
|
27 |
+
error_log("Enqueued Action {$k}");
|
28 |
+
}
|
29 |
+
}
|
30 |
+
|
31 |
+
public function writeToLog($k)
|
32 |
+
{
|
33 |
+
$interval = mt_rand(0, 2);
|
34 |
+
sleep($interval);
|
35 |
+
$pid = getmypid();
|
36 |
+
error_log("Action {$k} done [PID {$pid}]!");
|
37 |
+
}
|
38 |
+
}
|
Framework/BackgroundProcessing/Exceptions/QueueException.php
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Models an exception thrown in the context of a Queue scheduling or processing.
|
5 |
+
*
|
6 |
+
* @package WPStaging\Framework\BackgroundProcessing\Exceptions
|
7 |
+
*/
|
8 |
+
|
9 |
+
namespace WPStaging\Framework\BackgroundProcessing\Exceptions;
|
10 |
+
|
11 |
+
use Exception;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Class QueueException
|
15 |
+
*
|
16 |
+
* @package WPStaging\Framework\BackgroundProcessing\Exceptions
|
17 |
+
*/
|
18 |
+
class QueueException extends Exception
|
19 |
+
{
|
20 |
+
|
21 |
+
}
|
Framework/BackgroundProcessing/FeatureDetection.php
ADDED
@@ -0,0 +1,183 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Provides feature detection for the Queue system.
|
5 |
+
*
|
6 |
+
* @package WPStaging\Framework\BackgroundProcessing
|
7 |
+
*/
|
8 |
+
|
9 |
+
namespace WPStaging\Framework\BackgroundProcessing;
|
10 |
+
|
11 |
+
use WP_Error;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Class FeatureDetection
|
15 |
+
*
|
16 |
+
* @package WPStaging\Framework\BackgroundProcessing
|
17 |
+
*/
|
18 |
+
class FeatureDetection
|
19 |
+
{
|
20 |
+
const AJAX_TEST_ACTION = 'wpstg_ajax_test_action';
|
21 |
+
const AJAX_OPTION_NAME = 'wpstg_q_feature_detection_ajax_available';
|
22 |
+
const AJAX_REQUEST_QUERY_VAR = 'wpstg_q_ajax_check';
|
23 |
+
|
24 |
+
/**
|
25 |
+
* A cache property to store the result of the AJAX support check.
|
26 |
+
*
|
27 |
+
* @var bool
|
28 |
+
*/
|
29 |
+
protected $isAjaxAvailableCache;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Returns whether the AJAX based queue processing system is available or not.
|
33 |
+
*
|
34 |
+
* @param bool $showAdminNotice Whether to show an admin notice on missing support or not.
|
35 |
+
*
|
36 |
+
* @return bool Whether the AJAX based queue processing system is available or not.
|
37 |
+
*/
|
38 |
+
public function isAjaxAvailable($showAdminNotice = true)
|
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) {
|
46 |
+
// Default to say that it's supported if we cannot exclude it.
|
47 |
+
return true;
|
48 |
+
}
|
49 |
+
|
50 |
+
$availableOptionValue = get_option(self::AJAX_OPTION_NAME, null);
|
51 |
+
|
52 |
+
if (!in_array($availableOptionValue, ['y', 'n'], true)) {
|
53 |
+
$available = $this->runAjaxFeatureTest();
|
54 |
+
$availableOptionValue = $available ? 'y' : 'n';
|
55 |
+
update_option(self::AJAX_OPTION_NAME, $availableOptionValue);
|
56 |
+
}
|
57 |
+
|
58 |
+
$this->isAjaxAvailableCache = $availableOptionValue === 'y';
|
59 |
+
}
|
60 |
+
|
61 |
+
if (!$this->isAjaxAvailableCache && $showAdminNotice) {
|
62 |
+
add_action('admin_notices', [$this, 'ajaxSupportMissingAdminNotice']);
|
63 |
+
}
|
64 |
+
|
65 |
+
return $this->isAjaxAvailableCache;
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Runs the AJAX support feature detection test.
|
70 |
+
*
|
71 |
+
* This method will fire a non-blocking POST request
|
72 |
+
* to the `admin-ajax` endpoint.
|
73 |
+
* In response, the `updateAjaxTestOption` will udpate
|
74 |
+
* the flag option value and set it to `y` or not set it at all.
|
75 |
+
* This method will wait for some time for its counter-part, the
|
76 |
+
* `updateAjaxTestOption` running in the other request, to update
|
77 |
+
* the option. If the time runs out and the option is not there,
|
78 |
+
* the we know AJAX is either not working or not reliable enough.
|
79 |
+
* The method uses an option, and not a transient, as flag value to
|
80 |
+
* be able to force re-fetch it from the database.
|
81 |
+
*
|
82 |
+
* @return bool Whether the AJAX-based system is supported or not.
|
83 |
+
*
|
84 |
+
* @see FeatureDetection::updateAjaxTestOption()
|
85 |
+
*/
|
86 |
+
public function runAjaxFeatureTest()
|
87 |
+
{
|
88 |
+
$ajaxUrl = add_query_arg([
|
89 |
+
'action' => self::AJAX_TEST_ACTION,
|
90 |
+
'_ajax_nonce' => wp_create_nonce(self::AJAX_TEST_ACTION)
|
91 |
+
], admin_url('admin-ajax.php'));
|
92 |
+
|
93 |
+
$hash = md5(uniqid(__CLASS__, true));
|
94 |
+
|
95 |
+
$response = wp_remote_post(esc_url_raw($ajaxUrl), [
|
96 |
+
'headers' => [
|
97 |
+
'X-WPSTG-Request' => self::AJAX_TEST_ACTION
|
98 |
+
],
|
99 |
+
'blocking' => false,
|
100 |
+
'timeout' => 0.01,
|
101 |
+
'cookies' => isset($_COOKIE) ? $_COOKIE : [],
|
102 |
+
'sslverify' => apply_filters('https_local_ssl_verify', false),
|
103 |
+
'body' => [self::AJAX_OPTION_NAME => $hash],
|
104 |
+
]);
|
105 |
+
|
106 |
+
if ($response instanceof WP_Error) {
|
107 |
+
return false;
|
108 |
+
}
|
109 |
+
|
110 |
+
$test = static function () use ($hash) {
|
111 |
+
// Run a direct query to force the re-fetch and not hit the cache.
|
112 |
+
global $wpdb;
|
113 |
+
$fetched = $wpdb->get_var(
|
114 |
+
$wpdb->prepare(
|
115 |
+
"SELECT option_value from {$wpdb->options} WHERE option_name = %s AND option_value = 'y'",
|
116 |
+
self::AJAX_OPTION_NAME
|
117 |
+
)
|
118 |
+
);
|
119 |
+
|
120 |
+
return $fetched === 'y';
|
121 |
+
};
|
122 |
+
|
123 |
+
$waited = 0;
|
124 |
+
$waitStep = .5;
|
125 |
+
$timeout = 10;
|
126 |
+
|
127 |
+
do {
|
128 |
+
$waited += $waitStep;
|
129 |
+
sleep($waitStep);
|
130 |
+
|
131 |
+
if ($test()) {
|
132 |
+
// Look no further, it worked.
|
133 |
+
return true;
|
134 |
+
}
|
135 |
+
} while ($waited <= $timeout);
|
136 |
+
|
137 |
+
// We waited enough: either the AJAX system is not available or is not reliable.
|
138 |
+
return false;
|
139 |
+
}
|
140 |
+
|
141 |
+
/**
|
142 |
+
* Writes `y` to the feature detection option.
|
143 |
+
*
|
144 |
+
* This method will be called in response to the AJAX request
|
145 |
+
* fired by the `runAjaxFeatureTest` method.
|
146 |
+
* That method will wait, in its PHP process, for this method to
|
147 |
+
* udpate the option value and deem the AJAX support as "working".
|
148 |
+
*
|
149 |
+
* @return void The method does not return any value and will have the
|
150 |
+
* side effect of updating the option.
|
151 |
+
*
|
152 |
+
* @see FeatureDetection::runAjaxFeatureTest()
|
153 |
+
*/
|
154 |
+
public function updateAjaxTestOption()
|
155 |
+
{
|
156 |
+
update_option(self::AJAX_OPTION_NAME, 'y');
|
157 |
+
}
|
158 |
+
|
159 |
+
/**
|
160 |
+
* Displays a dismissible admin notice to let the user know the BG Processing system will not
|
161 |
+
* perform at its best due to lack of AJAX support.
|
162 |
+
*
|
163 |
+
* @return void The method will have the side effect of echoing HTML to the page.
|
164 |
+
*/
|
165 |
+
public function ajaxSupportMissingAdminNotice()
|
166 |
+
{
|
167 |
+
$message = __(
|
168 |
+
'WP STAGING Background Processing system cannot use AJAX: this will prevent it from performing at its best.',
|
169 |
+
'wp-staging'
|
170 |
+
);
|
171 |
+
$checkLink = sprintf(
|
172 |
+
'<a href="%s">%s</a>',
|
173 |
+
esc_url(admin_url('/?' . self::AJAX_REQUEST_QUERY_VAR . '=1')),
|
174 |
+
__('Click here to check again now.', 'wp-staging')
|
175 |
+
);
|
176 |
+
?>
|
177 |
+
<div class="notice notice-warning is-dismissible wpstg__notice wpstg__notice--warning">
|
178 |
+
<p><?php echo wp_kses_post($message); ?></p>
|
179 |
+
<p><?php echo wp_kses_post($checkLink); ?></p>
|
180 |
+
</div>
|
181 |
+
<?php
|
182 |
+
}
|
183 |
+
}
|
Framework/BackgroundProcessing/Queue.php
ADDED
@@ -0,0 +1,1075 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/** @noinspection ForgottenDebugOutputInspection */
|
4 |
+
|
5 |
+
/**
|
6 |
+
* Models the Queue of Steps to execute in background.
|
7 |
+
*
|
8 |
+
* @package WPStaging\Framework\BackgroundProcessing
|
9 |
+
*/
|
10 |
+
|
11 |
+
namespace WPStaging\Framework\BackgroundProcessing;
|
12 |
+
|
13 |
+
use DateTimeImmutable;
|
14 |
+
use Exception;
|
15 |
+
use WPStaging\Core\Utils\Logger;
|
16 |
+
use WPStaging\Core\WPStaging;
|
17 |
+
use WPStaging\Framework\Adapter\Database as DatabaseAdapter;
|
18 |
+
use WPStaging\Framework\Adapter\Database\InterfaceDatabaseClient as Database;
|
19 |
+
use WPStaging\Framework\BackgroundProcessing\Exceptions\QueueException;
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Class Queue
|
23 |
+
*
|
24 |
+
* @package WPStaging\Framework\BackgroundProcessing
|
25 |
+
*/
|
26 |
+
class Queue
|
27 |
+
{
|
28 |
+
use WithQueueAwareness;
|
29 |
+
|
30 |
+
/**
|
31 |
+
* A set of constants that are used internally to detect the
|
32 |
+
* state of the custom table used by the class to persist and
|
33 |
+
* manage its information.
|
34 |
+
*/
|
35 |
+
const TABLE_NOT_EXIST = -1;
|
36 |
+
const TABLE_EXISTS = 0;
|
37 |
+
const TABLE_CREATED = 1;
|
38 |
+
|
39 |
+
/**
|
40 |
+
* A set of constants that are used to normalize the possible status
|
41 |
+
* of an action in the context of the queue.
|
42 |
+
*/
|
43 |
+
const STATUS_READY = 'ready';
|
44 |
+
const STATUS_PROCESSING = 'processing';
|
45 |
+
const STATUS_COMPLETED = 'completed';
|
46 |
+
const STATUS_FAILED = 'failed';
|
47 |
+
const STATUS_ANY = 'any';
|
48 |
+
const STATUS_CANCELED = 'canceled';
|
49 |
+
/**
|
50 |
+
* A reference to te current Background Processing Feature detection service.
|
51 |
+
*
|
52 |
+
* @var FeatureDetection
|
53 |
+
*/
|
54 |
+
protected $featureDetection;
|
55 |
+
|
56 |
+
/**
|
57 |
+
* The current table state, or `null` if the current table state has never been
|
58 |
+
* assessed before.
|
59 |
+
*
|
60 |
+
* @var string|null
|
61 |
+
*/
|
62 |
+
private $tableState;
|
63 |
+
|
64 |
+
/**
|
65 |
+
* A reference to the current Logger instance.
|
66 |
+
*
|
67 |
+
* @var Logger
|
68 |
+
*/
|
69 |
+
private $logger;
|
70 |
+
|
71 |
+
/**
|
72 |
+
* A set of action stati that will be autoloaded in cache by the queue by default.
|
73 |
+
*
|
74 |
+
* @var array<string>
|
75 |
+
*/
|
76 |
+
private $defaultHydrateStati = [self::STATUS_READY];
|
77 |
+
|
78 |
+
/**
|
79 |
+
* A map from cached actions IDs to their action fields.
|
80 |
+
*
|
81 |
+
* @var array<int,array<string,mixed>>
|
82 |
+
*/
|
83 |
+
private $actionCaches = [];
|
84 |
+
|
85 |
+
/**
|
86 |
+
* A reference to the database adapter instance the class should use to interact
|
87 |
+
* with the database.
|
88 |
+
*
|
89 |
+
* @var Database
|
90 |
+
*/
|
91 |
+
private $database;
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Queue constructor.
|
95 |
+
*
|
96 |
+
* @param Database|null $database A reference to the database adapter instance the class
|
97 |
+
* should use to interact wit the database, or `null` to use
|
98 |
+
* the one globally provided by the Service Locator.
|
99 |
+
*/
|
100 |
+
public function __construct(Database $database = null)
|
101 |
+
{
|
102 |
+
$services = WPStaging::getInstance()->getContainer();
|
103 |
+
$this->database = $database ?: $services->make(DatabaseAdapter::class)->getClient();
|
104 |
+
$this->logger = $services->make('logger');
|
105 |
+
$this->featureDetection = $services->make(FeatureDetection::class);
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* Enqueue an action to run one time, as soon as possible
|
110 |
+
*
|
111 |
+
* This is like saying, in plain English, "do_action later".
|
112 |
+
*
|
113 |
+
* @param string $action The hook to trigger, this will be the name of the
|
114 |
+
* action triggered, in the following request, by the
|
115 |
+
* WordPress `do_action` function.
|
116 |
+
* @param array<string|int,mixed>|null $args Optional arguments to pass when the hook triggers.
|
117 |
+
* @param string $jobId The ID of the Job that is enqueueing the step.
|
118 |
+
* @param int $priority The priority to enqueue the action at; this works
|
119 |
+
* exactly like WordPres filter priority: lower values, negative
|
120 |
+
* values are supported, will be executed first.
|
121 |
+
*
|
122 |
+
* @return int|false The action ID, or `false` if the action could not be queued in the
|
123 |
+
* table.
|
124 |
+
*
|
125 |
+
* @throws QueueException If there's any issue scheduling the action in the queue.
|
126 |
+
*/
|
127 |
+
public function enqueueAction($action, array $args = [], $jobId = 'default', $priority = 0)
|
128 |
+
{
|
129 |
+
// We're enqueuing an Action and this is a good moment to let the user know whether AJAX works or not.
|
130 |
+
$this->featureDetection->isAjaxAvailable(true);
|
131 |
+
|
132 |
+
// Create the Action with an id of 0 until it's actually persisted.
|
133 |
+
$actionObject = new Action(0, $action, $args, $jobId, $priority);
|
134 |
+
|
135 |
+
if ($this->checkTable() === static::TABLE_NOT_EXIST) {
|
136 |
+
// The table does not exist and cannot be created, bail.
|
137 |
+
return false;
|
138 |
+
}
|
139 |
+
|
140 |
+
$assignments = [
|
141 |
+
'action' => $actionObject->action,
|
142 |
+
'jobId' => (string)$actionObject->jobId,
|
143 |
+
'status' => self::STATUS_READY,
|
144 |
+
'priority' => (int)$actionObject->priority,
|
145 |
+
'args' => $actionObject->args,
|
146 |
+
];
|
147 |
+
|
148 |
+
$assignmentsList = $this->buildAssignmentsList($assignments);
|
149 |
+
|
150 |
+
$tableName = self::getTableName();
|
151 |
+
$query = "INSERT INTO {$tableName} SET {$assignmentsList}";
|
152 |
+
|
153 |
+
$result = $this->database->query($query, true);
|
154 |
+
|
155 |
+
if (empty($result)) {
|
156 |
+
error_log(json_encode([
|
157 |
+
'root' => 'Error while trying insert Action information.',
|
158 |
+
'class' => get_class($this),
|
159 |
+
'query' => $query,
|
160 |
+
'error' => $this->database->error(),
|
161 |
+
]));
|
162 |
+
|
163 |
+
return false;
|
164 |
+
}
|
165 |
+
|
166 |
+
$id = $this->database->insertId();
|
167 |
+
|
168 |
+
if (empty($id)) {
|
169 |
+
error_log(json_encode([
|
170 |
+
'root' => 'Error while trying to fetch last inserted Action ID.',
|
171 |
+
'class' => get_class($this),
|
172 |
+
'query' => $query,
|
173 |
+
'error' => $this->database->error(),
|
174 |
+
]));
|
175 |
+
|
176 |
+
return false;
|
177 |
+
}
|
178 |
+
|
179 |
+
$actionObject = $actionObject->alter(['id' => $id, 'status' => self::STATUS_READY]);
|
180 |
+
$this->actionCaches[$id] = $actionObject->toArray();
|
181 |
+
|
182 |
+
if (!has_action('shutdown', [$this, 'maybeFireAjaxAction'])) {
|
183 |
+
add_action('shutdown', [$this, 'maybeFireAjaxAction']);
|
184 |
+
}
|
185 |
+
|
186 |
+
return (int)$id;
|
187 |
+
}
|
188 |
+
|
189 |
+
/**
|
190 |
+
* Checks and reports the state of the table.
|
191 |
+
*
|
192 |
+
* If the table does not exist, then the method will try to create or update it.
|
193 |
+
*
|
194 |
+
* @param false $force Whether to force the check on the table or trust the state
|
195 |
+
* cached from a previous check.
|
196 |
+
*
|
197 |
+
* @return int The value of one of the `TABLE` class constants to indicate the
|
198 |
+
* table status.
|
199 |
+
*/
|
200 |
+
private function checkTable($force = false)
|
201 |
+
{
|
202 |
+
if (!$force && $this->tableState !== null) {
|
203 |
+
return $this->tableState;
|
204 |
+
}
|
205 |
+
|
206 |
+
$this->tableState = self::TABLE_NOT_EXIST;
|
207 |
+
|
208 |
+
$options = get_option('wpstg_settings', []);
|
209 |
+
$currentTableVersion = isset($options['queue-table-version']) ? $options['queue-table-version'] : '0.0.0';
|
210 |
+
|
211 |
+
// Trigger an update or creation if either the table should be update, or it does not exist.
|
212 |
+
if (version_compare($currentTableVersion, $this->getLatestTableVersion(), '<') || !$this->tableExists()) {
|
213 |
+
$tableState = $this->updateTable();
|
214 |
+
|
215 |
+
if ($tableState === self::TABLE_EXISTS) {
|
216 |
+
// The table now exists.
|
217 |
+
$this->tableState = self::TABLE_EXISTS;
|
218 |
+
// Just created.
|
219 |
+
return self::TABLE_CREATED;
|
220 |
+
}
|
221 |
+
}
|
222 |
+
|
223 |
+
$this->tableState = $this->tableExists() ? self::TABLE_EXISTS : self::TABLE_NOT_EXIST;
|
224 |
+
|
225 |
+
return $this->tableState;
|
226 |
+
}
|
227 |
+
|
228 |
+
/**
|
229 |
+
* Returns the latest table version.
|
230 |
+
*
|
231 |
+
* @return string The latest table version, in semantic format.
|
232 |
+
*/
|
233 |
+
private function getLatestTableVersion()
|
234 |
+
{
|
235 |
+
if (defined('WPSTGPRO_VERSION')) {
|
236 |
+
return WPSTGPRO_VERSION;
|
237 |
+
}
|
238 |
+
|
239 |
+
return '1.0.0';
|
240 |
+
}
|
241 |
+
|
242 |
+
/**
|
243 |
+
* Updates the Queue table schema to the latest version, non destructively.
|
244 |
+
*
|
245 |
+
* The use of the `dbDelta` method will ensure the table is updated non-destructively
|
246 |
+
* and only if required.
|
247 |
+
*
|
248 |
+
* @return int The value of one of the `TABLE` constants to indicate the result of the
|
249 |
+
* update.
|
250 |
+
*/
|
251 |
+
private function updateTable()
|
252 |
+
{
|
253 |
+
global $wpdb;
|
254 |
+
$tableSql = $this->getCreateTableSql();
|
255 |
+
|
256 |
+
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
|
257 |
+
|
258 |
+
$lastError = $wpdb->last_error;
|
259 |
+
|
260 |
+
// If the table creation fails, then a db error will be thrown by WordPress.
|
261 |
+
dbDelta($tableSql);
|
262 |
+
|
263 |
+
if ($lastError !== $wpdb->last_error) {
|
264 |
+
return self::TABLE_NOT_EXIST;
|
265 |
+
}
|
266 |
+
|
267 |
+
$this->updateTableVersionOption($this->getLatestTableVersion());
|
268 |
+
|
269 |
+
return self::TABLE_EXISTS;
|
270 |
+
}
|
271 |
+
|
272 |
+
/**
|
273 |
+
* Returns the name of the table used by the Queue to store the actions and their state.
|
274 |
+
*
|
275 |
+
* @return string The prefixed name of the table used by the Queue to store the actions
|
276 |
+
* and their state.
|
277 |
+
*/
|
278 |
+
public static function getTableName()
|
279 |
+
{
|
280 |
+
global $wpdb;
|
281 |
+
|
282 |
+
return $wpdb->prefix . 'wpstg_queue';
|
283 |
+
}
|
284 |
+
|
285 |
+
/**
|
286 |
+
* Updates the version of the table in the plugin options to make sure
|
287 |
+
* it will not be updated on next check.
|
288 |
+
*
|
289 |
+
* @param string $tableVersion A semantic version format representing the
|
290 |
+
* table version to write to the plugin options.
|
291 |
+
*
|
292 |
+
* @return void The method does not return any value and will have the
|
293 |
+
* side-effect of updating the plugin options.
|
294 |
+
*/
|
295 |
+
private function updateTableVersionOption($tableVersion)
|
296 |
+
{
|
297 |
+
$options = get_option('wpstg_settings', []);
|
298 |
+
$options['queue-table-version'] = $tableVersion;
|
299 |
+
update_option('wpstg_settings', $options);
|
300 |
+
}
|
301 |
+
|
302 |
+
/**
|
303 |
+
* Checks whether the table exists or not.
|
304 |
+
*
|
305 |
+
* @return bool Whether the table exists or not.
|
306 |
+
*/
|
307 |
+
private function tableExists()
|
308 |
+
{
|
309 |
+
$tableName = self::getTableName();
|
310 |
+
$this->database->query("SELECT 1 from {$tableName} LIMIT 1");
|
311 |
+
|
312 |
+
return $this->database->foundRows() === 1;
|
313 |
+
}
|
314 |
+
|
315 |
+
/**
|
316 |
+
* Returns a specific field of an action data.
|
317 |
+
*
|
318 |
+
* @param int $actionId The action ID.
|
319 |
+
* @param string $field The action field to return.
|
320 |
+
*
|
321 |
+
* @return mixed Either the action field from the specified action, or `null` if the
|
322 |
+
* action or the field cannot be found.
|
323 |
+
*/
|
324 |
+
public function getActionField($actionId, $field)
|
325 |
+
{
|
326 |
+
if (empty($this->actionCaches[$actionId])) {
|
327 |
+
// Maybe this is an action that is not autoloaded due to its status.
|
328 |
+
$this->hydrateActionCaches([$actionId]);
|
329 |
+
}
|
330 |
+
|
331 |
+
return isset($this->actionCaches[$actionId][$field]) ?
|
332 |
+
$this->actionCaches[$actionId][$field]
|
333 |
+
: null;
|
334 |
+
}
|
335 |
+
|
336 |
+
/**
|
337 |
+
* Hydrates the action cache using a set of action IDs as models for the status of the
|
338 |
+
* actions to load into cache.
|
339 |
+
*
|
340 |
+
* By default, the class will hydrate the caches for actions that are running or to-run,
|
341 |
+
* skipping actions that have failed or completed.
|
342 |
+
* If a request comes in to fetch an action with a non-default status, then the cache
|
343 |
+
* for all actions with that status will be hydrated.
|
344 |
+
*
|
345 |
+
* @param array<int> $actionIds An optional set of actions to use as "mode" to
|
346 |
+
* hydrate the actions cache for all actions with that
|
347 |
+
* same type.
|
348 |
+
*
|
349 |
+
* @return void The method does not return any value and will just hydrate the class caches.
|
350 |
+
*/
|
351 |
+
private function hydrateActionCaches(array $actionIds = [])
|
352 |
+
{
|
353 |
+
$tableState = $this->checkTable();
|
354 |
+
|
355 |
+
if ($tableState === self::TABLE_CREATED || $tableState === false) {
|
356 |
+
// No point in trying to fetch anything.
|
357 |
+
return;
|
358 |
+
}
|
359 |
+
|
360 |
+
$queueTable = self::getTableName();
|
361 |
+
|
362 |
+
/**
|
363 |
+
* Action arguments have the potential to be pretty huge in size.
|
364 |
+
* To avoid over-loading the database, we fetch actions from it in
|
365 |
+
* batches until we find either all the actions we're looking for, or
|
366 |
+
* all the actions of a specific type.
|
367 |
+
*/
|
368 |
+
|
369 |
+
$offset = 0;
|
370 |
+
$limit = 100;
|
371 |
+
$inputActionIdsCount = count($actionIds);
|
372 |
+
$totalResultsCount = 0;
|
373 |
+
|
374 |
+
do {
|
375 |
+
$offsetAndLimit = sprintf('%d, %d', $offset, $limit);
|
376 |
+
|
377 |
+
if ($inputActionIdsCount > 0) {
|
378 |
+
$ids = implode(',', array_filter(array_map('absint', $actionIds)));
|
379 |
+
$query = "SELECT * FROM {$queueTable} q JOIN {$queueTable} q1 ON q.status = q1.status WHERE q1.id IN ({$ids}) LIMIT {$offsetAndLimit}";
|
380 |
+
} else {
|
381 |
+
$stati = implode(',', array_map(function ($status) {
|
382 |
+
return "'{$this->database->escape($status)}'";
|
383 |
+
}, $this->defaultHydrateStati));
|
384 |
+
$query = "SELECT * FROM {$queueTable} WHERE status IN ({$stati}) LIMIT {$offsetAndLimit}";
|
385 |
+
}
|
386 |
+
|
387 |
+
$result = $this->database->query($query);
|
388 |
+
|
389 |
+
if (false === $result) {
|
390 |
+
error_log(json_encode([
|
391 |
+
'root' => 'Error while trying to fetch Actions information.',
|
392 |
+
'class' => get_class($this),
|
393 |
+
'query' => $query,
|
394 |
+
'error' => $this->database->error(),
|
395 |
+
]));
|
396 |
+
|
397 |
+
// There has been an error fetching the results, bail.
|
398 |
+
return;
|
399 |
+
}
|
400 |
+
|
401 |
+
$preparedActions = [];
|
402 |
+
while ($actionRow = $this->database->fetchAssoc($result)) {
|
403 |
+
$totalResultsCount++;
|
404 |
+
$preparedActions[$actionRow['id']] = $this->convertDbRowToData($actionRow);
|
405 |
+
}
|
406 |
+
|
407 |
+
$found = count(array_diff_key($preparedActions, array_flip($actionIds))) === $inputActionIdsCount;
|
408 |
+
|
409 |
+
if (!isset($foundRows)) {
|
410 |
+
$foundRows = max(0, (int)$this->database->foundRows());
|
411 |
+
}
|
412 |
+
|
413 |
+
$offset += $limit;
|
414 |
+
} while (!$found && $totalResultsCount < $foundRows);
|
415 |
+
|
416 |
+
$this->actionCaches = array_replace($this->actionCaches, $preparedActions);
|
417 |
+
}
|
418 |
+
|
419 |
+
/**
|
420 |
+
* Converts the data from the format it's stored with in the database to
|
421 |
+
* the typed format used to retrieve the action data.
|
422 |
+
*
|
423 |
+
* @param array<string,mixed> $actionRow The data, as fetched from the database.
|
424 |
+
*
|
425 |
+
* @return array<string,mixed> The typed and prepared action data.
|
426 |
+
*/
|
427 |
+
private function convertDbRowToData(array $actionRow)
|
428 |
+
{
|
429 |
+
return Action::fromDbRow($actionRow)->toArray();
|
430 |
+
}
|
431 |
+
|
432 |
+
/**
|
433 |
+
* Tries to lock and get the next available action in the queue, in ascending
|
434 |
+
* priority order.
|
435 |
+
*
|
436 |
+
* @return Action|null Either a reference to an object representing the locked
|
437 |
+
* action, or `null` if there are no actions to process or
|
438 |
+
* no lock could be acquired on the available ones.
|
439 |
+
*/
|
440 |
+
public function getNextAvailable()
|
441 |
+
{
|
442 |
+
if ($this->checkTable() !== self::TABLE_EXISTS) {
|
443 |
+
// No actions if the table either does nto exist or has just been created.
|
444 |
+
return null;
|
445 |
+
}
|
446 |
+
|
447 |
+
$processing = self::STATUS_PROCESSING;
|
448 |
+
$ready = self::STATUS_READY;
|
449 |
+
$tableName = self::getTableName();
|
450 |
+
$now = date('Y-m-d H:i:s');
|
451 |
+
|
452 |
+
/*
|
453 |
+
* Find the first available row that is ready, update its status to processing.
|
454 |
+
* Do this with an "atomic" query that will either fully accomplish its goal
|
455 |
+
* or will completely fail.
|
456 |
+
*/
|
457 |
+
$claimQuery = "UPDATE {$tableName}
|
458 |
+
SET status='{$processing}', claimed_at='{$now}'
|
459 |
+
WHERE id=(
|
460 |
+
SELECT id FROM {$tableName}
|
461 |
+
WHERE status='{$ready}'
|
462 |
+
ORDER BY priority, action, jobId ASC
|
463 |
+
LIMIT 1
|
464 |
+
)
|
465 |
+
AND LAST_INSERT_ID(id);";
|
466 |
+
$claimed = $this->database->query($claimQuery, true);
|
467 |
+
|
468 |
+
if (!$claimed) {
|
469 |
+
// This is NOT a failure: it just means the process could not lock the row.
|
470 |
+
return null;
|
471 |
+
}
|
472 |
+
|
473 |
+
/*
|
474 |
+
* This we get from the `LAST_INSERT_ID(id)` statement in the atomic query.
|
475 |
+
* LAST_INSERT_ID will NOT only apply to INSERTions, but to UPDATEs too.
|
476 |
+
*/
|
477 |
+
$claimedActionId = $this->database->insertId();
|
478 |
+
|
479 |
+
if (empty($claimedActionId)) {
|
480 |
+
/*
|
481 |
+
* The previous query might succeed while NOT acquiring the lock, depending
|
482 |
+
* on the db. If we have not acquired a lock, let's bail.
|
483 |
+
*/
|
484 |
+
return null;
|
485 |
+
}
|
486 |
+
|
487 |
+
// Invalidate this Action cache and re-fetch the information.
|
488 |
+
unset($this->actionCaches[$claimedActionId]);
|
489 |
+
$actionObject = $this->getAction($claimedActionId);
|
490 |
+
|
491 |
+
if ($actionObject instanceof Action) {
|
492 |
+
$this->actionCaches[$claimedActionId] = $actionObject->toArray();
|
493 |
+
}
|
494 |
+
|
495 |
+
return $actionObject;
|
496 |
+
}
|
497 |
+
|
498 |
+
/**
|
499 |
+
* Counts, with a query, and returns the number of Actions currently in the Queue.
|
500 |
+
*
|
501 |
+
* @param string|array<string>|null $status An optional status, or list of stati,
|
502 |
+
* to count Actions by. If not specified, then
|
503 |
+
* the returned value will be that of all Actions
|
504 |
+
* in any status.
|
505 |
+
* @param string|array<string> $jobId An optional Job Identifier, or a list of job identifiers,
|
506 |
+
* to narrow the count by; if not provided, then
|
507 |
+
* Actions from all Jobs will be counted.
|
508 |
+
*
|
509 |
+
* @return int The number of Actions currently in the Queue, or the number of Actions
|
510 |
+
* in the Queue with a specified status.
|
511 |
+
*/
|
512 |
+
public function count($status = null, $jobId = null)
|
513 |
+
{
|
514 |
+
$tableName = self::getTableName();
|
515 |
+
|
516 |
+
$jobClause = '';
|
517 |
+
if (isset($jobId)) {
|
518 |
+
$jobIdsInterval = $this->escapeInterval((array)$jobId);
|
519 |
+
$jobClause = "AND jobId IN ({$jobIdsInterval})";
|
520 |
+
}
|
521 |
+
|
522 |
+
if (empty($status) || $status === Queue::STATUS_ANY) {
|
523 |
+
$countQuery = "SELECT COUNT(id) FROM {$tableName} WHERE 1=1 {$jobClause}";
|
524 |
+
} else {
|
525 |
+
$stati = $this->escapeInterval((array)$status);
|
526 |
+
$countQuery = "SELECT COUNT(id) FROM {$tableName} WHERE status IN ({$stati}) {$jobClause}";
|
527 |
+
}
|
528 |
+
|
529 |
+
$countResult = $this->database->query($countQuery);
|
530 |
+
|
531 |
+
if ($countResult === false) {
|
532 |
+
$error = $this->database->error();
|
533 |
+
|
534 |
+
if (!empty($error)) {
|
535 |
+
error_log(json_encode([
|
536 |
+
'root' => 'Error while trying to count Actions.',
|
537 |
+
'class' => get_class($this),
|
538 |
+
'query' => $countQuery,
|
539 |
+
'error' => $error,
|
540 |
+
]));
|
541 |
+
}
|
542 |
+
|
543 |
+
// For all intent and purposes, the Queue cannot be counted now.
|
544 |
+
return 0;
|
545 |
+
}
|
546 |
+
|
547 |
+
$count = $this->database->fetchRow($countResult);
|
548 |
+
|
549 |
+
return (array_sum((array)$count));
|
550 |
+
}
|
551 |
+
|
552 |
+
/**
|
553 |
+
* Updates an Action status in the Queue table.
|
554 |
+
*
|
555 |
+
* Updating the Action status to Processing will mark the Action as claimed the very
|
556 |
+
* moment the operation is performed.
|
557 |
+
*
|
558 |
+
* @param int|Action $action Either an action id, or a reference to an Action object.
|
559 |
+
* @param string $newStatus The status to update the Action status to.
|
560 |
+
* @param bool $unsafely If the status update is to the Processing one, then we require
|
561 |
+
* the developer to do it with full understanding that it's NOT
|
562 |
+
* the correct way to do it.
|
563 |
+
*
|
564 |
+
* @return false|int Either the updated action id, or `false` to indicate the status
|
565 |
+
* update failed.
|
566 |
+
*
|
567 |
+
* @throws QueueException If the status to update the Action to is the Processing one and
|
568 |
+
* the client code is not owning the unsafety of it.
|
569 |
+
*/
|
570 |
+
public function updateActionStatus($action, $newStatus, $unsafely = false)
|
571 |
+
{
|
572 |
+
$actionId = absint($action instanceof Action ? $action->id : (int)$action);
|
573 |
+
$tableName = self::getTableName();
|
574 |
+
$status = $this->database->escape($newStatus);
|
575 |
+
$now = date('Y-m-d H:m:s');
|
576 |
+
|
577 |
+
if ($status !== self::STATUS_PROCESSING) {
|
578 |
+
// Any status update that is not to the processing status, will clean the `claimed_at` column.
|
579 |
+
$statusUpdateQuery = "UPDATE {$tableName} SET status='{$status}', claimed_at=NULL, updated_at='{$now}' WHERE id={$actionId}";
|
580 |
+
} else {
|
581 |
+
if (!$unsafely) {
|
582 |
+
// This is a developer mistake: it should be immediately signaled as such.
|
583 |
+
throw new QueueException('Marking actions as Processing should only be done using the getNextAvailable method!');
|
584 |
+
}
|
585 |
+
|
586 |
+
// If the status update is to the Processing status, then the Action should be marked as claimed.
|
587 |
+
$statusUpdateQuery = "UPDATE {$tableName} SET status='{$status}', claimed_at='{$now}', updated_at='{$now}' WHERE id={$actionId} ";
|
588 |
+
}
|
589 |
+
|
590 |
+
$updated = $this->database->query($statusUpdateQuery, true);
|
591 |
+
|
592 |
+
if (!$updated) {
|
593 |
+
error_log(json_encode([
|
594 |
+
'root' => 'Error while trying to update Action status.',
|
595 |
+
'class' => get_class($this),
|
596 |
+
'query' => $statusUpdateQuery,
|
597 |
+
'error' => $this->database->error(),
|
598 |
+
]));
|
599 |
+
|
600 |
+
return false;
|
601 |
+
}
|
602 |
+
|
603 |
+
// Force a refresh on next action fetch.
|
604 |
+
unset($this->actionCaches[$actionId]);
|
605 |
+
|
606 |
+
return $actionId;
|
607 |
+
}
|
608 |
+
|
609 |
+
/**
|
610 |
+
* Return the Queue table creation SQL code.
|
611 |
+
*
|
612 |
+
* @return string The Queue table creation SQL code.
|
613 |
+
*/
|
614 |
+
private function getCreateTableSql()
|
615 |
+
{
|
616 |
+
global $wpdb;
|
617 |
+
$collate = $wpdb->collate;
|
618 |
+
$queueTable = self::getTableName();
|
619 |
+
$tableSql = "CREATE TABLE {$queueTable} (
|
620 |
+
id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
|
621 |
+
action VARCHAR(1000) NOT NULL,
|
622 |
+
jobId VARCHAR(1000) DEFAULT NULL,
|
623 |
+
status CHAR(20) NOT NULL DEFAULT 'ready',
|
624 |
+
priority BIGINT(20) NOT NULL DEFAULT 0,
|
625 |
+
args LONGTEXT DEFAULT NULL,
|
626 |
+
claimed_at DATETIME DEFAULT NULL,
|
627 |
+
updated_at DATETIME DEFAULT NULL,
|
628 |
+
PRIMARY KEY (id)
|
629 |
+
) COLLATE {$collate}";
|
630 |
+
return $tableSql;
|
631 |
+
}
|
632 |
+
|
633 |
+
/**
|
634 |
+
* Drops the custom table used by the Queue to store actions.
|
635 |
+
*
|
636 |
+
* Dropping the table means, implicitly, also losing all the Actions
|
637 |
+
* stored there.
|
638 |
+
*
|
639 |
+
* @return bool Whether the table dropping was successful or not.
|
640 |
+
*/
|
641 |
+
public function dropTable()
|
642 |
+
{
|
643 |
+
$tableName = self::getTableName();
|
644 |
+
$query = "DROP TABLE {$tableName}";
|
645 |
+
$this->database->query($query, true);
|
646 |
+
|
647 |
+
return !$this->tableExists();
|
648 |
+
}
|
649 |
+
|
650 |
+
/**
|
651 |
+
* Returns the last logged error provided by the underlying database adapter.
|
652 |
+
*
|
653 |
+
* @return string The last error as logged by the database adapter, or an empty
|
654 |
+
* string if there are no errors.
|
655 |
+
*/
|
656 |
+
public function lastError()
|
657 |
+
{
|
658 |
+
if ($this->database === null) {
|
659 |
+
return '';
|
660 |
+
}
|
661 |
+
return (string)$this->database->error();
|
662 |
+
}
|
663 |
+
|
664 |
+
/**
|
665 |
+
* Fetches an Action row from the database.
|
666 |
+
*
|
667 |
+
* @param int $actionId The id of the Action to fetch.
|
668 |
+
*
|
669 |
+
* @return array<string,mixed>|null Either a map from the action columns to
|
670 |
+
* their respective values, or `null` to indicate
|
671 |
+
* the Action row could not be fetched.
|
672 |
+
*/
|
673 |
+
private function fetchActionRow($actionId)
|
674 |
+
{
|
675 |
+
$actionId = absint($actionId);
|
676 |
+
|
677 |
+
if (empty($actionId)) {
|
678 |
+
return null;
|
679 |
+
}
|
680 |
+
|
681 |
+
$tableName = self::getTableName();
|
682 |
+
$fetchQuery = "SELECT * FROM {$tableName} WHERE id={$actionId}";
|
683 |
+
$fetchResult = $this->database->query($fetchQuery);
|
684 |
+
|
685 |
+
if ($fetchResult === false) {
|
686 |
+
// This is NOT an error, the query might be for a no-more existing Action.
|
687 |
+
return null;
|
688 |
+
}
|
689 |
+
|
690 |
+
$row = $this->database->fetchAssoc($fetchResult);
|
691 |
+
|
692 |
+
return is_array($row) ? $row : null;
|
693 |
+
}
|
694 |
+
|
695 |
+
/**
|
696 |
+
* Fetches an action information from the database and returns a reference to
|
697 |
+
* its object representation.
|
698 |
+
*
|
699 |
+
* @param int $actionId The id of the Action to fetch.
|
700 |
+
* @param bool $force Whether to force the refetch of the Action data from the database
|
701 |
+
* or not.
|
702 |
+
*
|
703 |
+
* @return Action|null A reference to the Action object built from the input action id,
|
704 |
+
* or `null` to indicate the Action data could not be fetched or does
|
705 |
+
* not exist.
|
706 |
+
*
|
707 |
+
* @throws QueueException If there's any issue while building and validating the Action.
|
708 |
+
*/
|
709 |
+
public function getAction($actionId, $force = false)
|
710 |
+
{
|
711 |
+
if ($force || empty($this->actionCaches[$actionId])) {
|
712 |
+
$row = $this->fetchActionRow($actionId);
|
713 |
+
|
714 |
+
if ($row !== null) {
|
715 |
+
$this->actionCaches[$actionId] = $row;
|
716 |
+
}
|
717 |
+
}
|
718 |
+
|
719 |
+
return isset($this->actionCaches[$actionId]) ?
|
720 |
+
Action::fromDbRow($this->actionCaches[$actionId])
|
721 |
+
: null;
|
722 |
+
}
|
723 |
+
|
724 |
+
/**
|
725 |
+
* Returns a list of stati in which an Action could be.
|
726 |
+
*
|
727 |
+
* While nothing is preventing other code from assigning different
|
728 |
+
* stati to the Actions, these are the ones the Queue is actually
|
729 |
+
* equipped to handle.
|
730 |
+
*
|
731 |
+
* @return array<string> A list of the possible stati an Action could
|
732 |
+
* be in.
|
733 |
+
*/
|
734 |
+
public function getSupportedActionStati()
|
735 |
+
{
|
736 |
+
return [
|
737 |
+
self::STATUS_PROCESSING,
|
738 |
+
self::STATUS_READY,
|
739 |
+
self::STATUS_COMPLETED,
|
740 |
+
];
|
741 |
+
}
|
742 |
+
|
743 |
+
/**
|
744 |
+
* Returns an immutable Date Object representing the breakpoint date and time
|
745 |
+
* that should be used to mark an Action that has been claimed before that point
|
746 |
+
* in date and time as dangling if still processing.
|
747 |
+
*
|
748 |
+
* @return DateTimeImmutable A reference to an immutable date time object representing
|
749 |
+
* the dangling breakpoint.
|
750 |
+
*/
|
751 |
+
public function getDanglingBreakpointDate()
|
752 |
+
{
|
753 |
+
return $this->getBreakpointDate(HOUR_IN_SECONDS);
|
754 |
+
}
|
755 |
+
|
756 |
+
/**
|
757 |
+
* Assigns a new status to any dangling Action.
|
758 |
+
*
|
759 |
+
* A dangling Action is one that was claimed for processing too long ago.
|
760 |
+
* Where "too long ago" is defined by the Dangling Action breakpoint date.
|
761 |
+
* Actions updated using this method will have their `claimed_at` column entry
|
762 |
+
* cleared.
|
763 |
+
*
|
764 |
+
* @param string $newStatus The new status that should be assigned to the Actions.
|
765 |
+
* The method will NOT check the status to make sure it's
|
766 |
+
* one of the supported ones, this is by design to allow
|
767 |
+
* the queue to be used in a more flexible way.
|
768 |
+
*
|
769 |
+
* @return int The number of updated Actions.
|
770 |
+
*/
|
771 |
+
public function markDanglingAs($newStatus)
|
772 |
+
{
|
773 |
+
if ($this->checkTable() === static::TABLE_NOT_EXIST) {
|
774 |
+
// The table does not exist so there is nothing to update.
|
775 |
+
return 0;
|
776 |
+
}
|
777 |
+
|
778 |
+
$tableName = self::getTableName();
|
779 |
+
$newStatus = $this->database->escape($newStatus);
|
780 |
+
$danglingBreakpoint = $this->getDanglingBreakpointDate()->format('Y-m-d H:i:s');
|
781 |
+
$markQuery = "UPDATE {$tableName}
|
782 |
+
SET status='{$newStatus}', claimed_at=NULL
|
783 |
+
WHERE claimed_at IS NOT NULL
|
784 |
+
AND claimed_at < '{$danglingBreakpoint}'";
|
785 |
+
$markResult = $this->database->query($markQuery, true);
|
786 |
+
|
787 |
+
if ($markResult === false) {
|
788 |
+
error_log(json_encode([
|
789 |
+
'root' => 'Error while trying to mark dangling Actions.',
|
790 |
+
'class' => get_class($this),
|
791 |
+
'query' => $markQuery,
|
792 |
+
'error' => $this->database->error(),
|
793 |
+
]));
|
794 |
+
|
795 |
+
return 0;
|
796 |
+
}
|
797 |
+
|
798 |
+
if (isset($this->database->link->affected_rows)) {
|
799 |
+
$marked = $this->database->link->affected_rows;
|
800 |
+
} else {
|
801 |
+
$marked = 0;
|
802 |
+
}
|
803 |
+
|
804 |
+
return (int)$marked;
|
805 |
+
}
|
806 |
+
|
807 |
+
/**
|
808 |
+
* Hooked on the `shutdown` action, this method will make sure the Queue
|
809 |
+
* will keep processing if there are ready Actions.
|
810 |
+
*
|
811 |
+
* @return bool Whether the AJAX action was correctly fired or not. Note that
|
812 |
+
* a `false` return value might indicate both that there was no
|
813 |
+
* need to fire the AJAX action or that the firing failed.
|
814 |
+
*/
|
815 |
+
public function maybeFireAjaxAction()
|
816 |
+
{
|
817 |
+
if (!$this->count(self::STATUS_READY)) {
|
818 |
+
return false;
|
819 |
+
}
|
820 |
+
|
821 |
+
return $this->fireAjaxAction();
|
822 |
+
}
|
823 |
+
|
824 |
+
/**
|
825 |
+
* Escapes a set of values to be used in a IN clause.
|
826 |
+
*
|
827 |
+
* @param array<string> $values The set of values to escape.
|
828 |
+
*
|
829 |
+
* @return string The values escaped and concatenated in a string suitable
|
830 |
+
* to be used in a IN clause.
|
831 |
+
*/
|
832 |
+
private function escapeInterval(array $values)
|
833 |
+
{
|
834 |
+
return implode(',', array_map(function ($value) {
|
835 |
+
return "'" . $this->database->escape($value) . "'";
|
836 |
+
}, (array)$values));
|
837 |
+
}
|
838 |
+
|
839 |
+
/**
|
840 |
+
* Cancels all the Actions for a Job or a list of Jobs.
|
841 |
+
*
|
842 |
+
* @param string|array<string> $jobId A Job ID, or a list of Job IDs to cancel
|
843 |
+
* all Actions for.
|
844 |
+
*
|
845 |
+
* @return int
|
846 |
+
* @since TBD
|
847 |
+
*
|
848 |
+
*/
|
849 |
+
public function cancelJob($jobId)
|
850 |
+
{
|
851 |
+
if ($this->checkTable() === static::TABLE_NOT_EXIST) {
|
852 |
+
// The table does not exist so there is nothing to cancel.
|
853 |
+
return 0;
|
854 |
+
}
|
855 |
+
|
856 |
+
$tableName = self::getTableName();
|
857 |
+
$newStatus = self::STATUS_CANCELED;
|
858 |
+
$jobIds = (array)$jobId;
|
859 |
+
$jobIdsInterval = $this->escapeInterval($jobIds);
|
860 |
+
$now = date('Y-m-d H:m:s');
|
861 |
+
$cancelQuery = "UPDATE {$tableName}
|
862 |
+
SET status='{$newStatus}', claimed_at=NULL, updated_at='{$now}'
|
863 |
+
WHERE jobId in (${jobIdsInterval})";
|
864 |
+
$cancelResult = $this->database->query($cancelQuery, true);
|
865 |
+
|
866 |
+
if ($cancelResult === false) {
|
867 |
+
error_log(json_encode([
|
868 |
+
'root' => 'Error while trying to cancel Actions.',
|
869 |
+
'class' => get_class($this),
|
870 |
+
'query' => $cancelQuery,
|
871 |
+
'error' => $this->database->error(),
|
872 |
+
]));
|
873 |
+
|
874 |
+
return 0;
|
875 |
+
}
|
876 |
+
|
877 |
+
if (isset($this->database->link->affected_rows)) {
|
878 |
+
$canceled = $this->database->link->affected_rows;
|
879 |
+
} else {
|
880 |
+
$canceled = 0;
|
881 |
+
}
|
882 |
+
|
883 |
+
$this->invalidateActionCachesByJobId($jobIds);
|
884 |
+
|
885 |
+
return (int)$canceled;
|
886 |
+
}
|
887 |
+
|
888 |
+
/**
|
889 |
+
* Invalidates cached Action values by Job Id.
|
890 |
+
*
|
891 |
+
* @param array<string> $jobIds A list of Job IDs to invalidate the Actions by.
|
892 |
+
*
|
893 |
+
* @return void The method does not return any value and will invalidate the Actions
|
894 |
+
* caches by Job ID as a side effect.
|
895 |
+
*/
|
896 |
+
private function invalidateActionCachesByJobId(array $jobIds)
|
897 |
+
{
|
898 |
+
array_walk($this->actionCaches, static function (&$cachedAction) use ($jobIds) {
|
899 |
+
if (!empty($cachedAction['jobId']) && in_array($cachedAction['jobId'], $jobIds, true)) {
|
900 |
+
$cachedAction = null;
|
901 |
+
}
|
902 |
+
});
|
903 |
+
}
|
904 |
+
|
905 |
+
/**
|
906 |
+
* Allows updating an Action field directly.
|
907 |
+
*
|
908 |
+
* This method has the potential of disrupting the Queue functions: with great power comes great
|
909 |
+
* responsibility.
|
910 |
+
*
|
911 |
+
* @param Action|int $action The Action ID or a reference to the Action instance.
|
912 |
+
* @param array<string,mixed> $updates A map from the updates keys to the updates value.
|
913 |
+
* @param bool $unsafely We require the developer to do it with full understanding that it's
|
914 |
+
* NOT the correct way to do it.
|
915 |
+
*
|
916 |
+
* @return false|int Either the ID of the updated action, or `false` to indicate the update failed.
|
917 |
+
*
|
918 |
+
* @throws QueueException If the `$unsafely` parameter is not set to `true` or the field
|
919 |
+
* to be updated is the Action ID one.
|
920 |
+
*
|
921 |
+
* @internal This method has the potential of disrupting the Queue system and should not
|
922 |
+
* be used without full knowledge of what is being done.
|
923 |
+
*/
|
924 |
+
public function updateActionFields($action, array $updates, $unsafely = false)
|
925 |
+
{
|
926 |
+
if (!$unsafely) {
|
927 |
+
// This is a developer mistake: it should be immediately signaled as such.
|
928 |
+
throw new QueueException(
|
929 |
+
'Updating Action fields has the potential of disrupting the Queue functions.'
|
930 |
+
);
|
931 |
+
}
|
932 |
+
|
933 |
+
if (isset($updates['id'])) {
|
934 |
+
// This is a developer mistake: it should be immediately signaled as such.
|
935 |
+
throw new QueueException(
|
936 |
+
'Updating an Action ID is never allowed.'
|
937 |
+
);
|
938 |
+
}
|
939 |
+
|
940 |
+
$actionId = absint($action instanceof Action ? $action->id : (int)$action);
|
941 |
+
$tableName = self::getTableName();
|
942 |
+
|
943 |
+
$assignmentsList = $this->buildAssignmentsList($updates);
|
944 |
+
$statusUpdateQuery = "UPDATE {$tableName} SET {$assignmentsList} WHERE id={$actionId}";
|
945 |
+
|
946 |
+
$updated = $this->database->query($statusUpdateQuery, true);
|
947 |
+
|
948 |
+
if (!$updated) {
|
949 |
+
error_log(json_encode([
|
950 |
+
'root' => 'Error while trying to update Action field.',
|
951 |
+
'class' => get_class($this),
|
952 |
+
'query' => $statusUpdateQuery,
|
953 |
+
'error' => $this->database->error(),
|
954 |
+
]));
|
955 |
+
|
956 |
+
return false;
|
957 |
+
}
|
958 |
+
|
959 |
+
// Force a refresh on next action fetch.
|
960 |
+
unset($this->actionCaches[$actionId]);
|
961 |
+
|
962 |
+
return $actionId;
|
963 |
+
}
|
964 |
+
|
965 |
+
/**
|
966 |
+
* Compiles a map of values to a SET assignment list suitable to use in INSERT and UPDATE
|
967 |
+
* statements.
|
968 |
+
*
|
969 |
+
* @param array<string,mixed> $assignments A map from the assignments keys to the values.
|
970 |
+
*
|
971 |
+
* @return string The compiled assignments list.
|
972 |
+
*/
|
973 |
+
private function buildAssignmentsList(array $assignments)
|
974 |
+
{
|
975 |
+
$assignmentList = [];
|
976 |
+
|
977 |
+
array_walk($assignments, function ($value, $key) use (&$assignmentList) {
|
978 |
+
if ($value === '') {
|
979 |
+
// Empty string values should be skipped to let the database default value kick in.
|
980 |
+
return;
|
981 |
+
}
|
982 |
+
|
983 |
+
$escapedKey = $this->database->escape($key);
|
984 |
+
|
985 |
+
if ($key === 'priority') {
|
986 |
+
// Keep the numeric value.
|
987 |
+
$escapedValue = (int)$value;
|
988 |
+
$assignmentList[] = "{$escapedKey}={$escapedValue}";
|
989 |
+
} elseif ($key === 'args') {
|
990 |
+
$escapedValue = serialize($value);
|
991 |
+
$assignmentList[] = "{$escapedKey}='{$escapedValue}'";
|
992 |
+
} else {
|
993 |
+
$escapedValue = $this->database->escape($value);
|
994 |
+
$assignmentList[] = "{$escapedKey}='{$escapedValue}'";
|
995 |
+
}
|
996 |
+
});
|
997 |
+
|
998 |
+
return implode(', ', $assignmentList);
|
999 |
+
}
|
1000 |
+
|
1001 |
+
/**
|
1002 |
+
* Returns an immutable Date Object representing the breakpoint date and time
|
1003 |
+
* that should be used to cleanup Actions.
|
1004 |
+
*
|
1005 |
+
* @return DateTimeImmutable A reference to an immutable date time object representing
|
1006 |
+
* the dangling breakpoint.
|
1007 |
+
*/
|
1008 |
+
public function getCleanupBreakpointDate()
|
1009 |
+
{
|
1010 |
+
return $this->getBreakpointDate(WEEK_IN_SECONDS);
|
1011 |
+
}
|
1012 |
+
|
1013 |
+
/**
|
1014 |
+
* Builds and returns a breakpoint date.
|
1015 |
+
*
|
1016 |
+
* @param int $interval The amount, in seconds, to apply to the current date
|
1017 |
+
* and time to build the breakpoint date.
|
1018 |
+
*
|
1019 |
+
* @return DateTimeImmutable A reference to the breakpoint date immutable instance.
|
1020 |
+
*/
|
1021 |
+
private function getBreakpointDate($interval)
|
1022 |
+
{
|
1023 |
+
try {
|
1024 |
+
$breakpointDate = new DateTimeImmutable(date('Y-m-d H:i:s'));
|
1025 |
+
$breakpointDate = $breakpointDate->setTimestamp($breakpointDate->getTimestamp() - $interval);
|
1026 |
+
} catch (Exception $e) {
|
1027 |
+
/*
|
1028 |
+
* On failure, return a date very far in the past, before this is written, to make sure no
|
1029 |
+
* Action will be modified.
|
1030 |
+
*/
|
1031 |
+
$breakpointDate = new DateTimeImmutable('2020-01-01 00:00:00');
|
1032 |
+
}
|
1033 |
+
|
1034 |
+
return $breakpointDate;
|
1035 |
+
}
|
1036 |
+
|
1037 |
+
public function cleanup()
|
1038 |
+
{
|
1039 |
+
if ($this->checkTable() === static::TABLE_NOT_EXIST) {
|
1040 |
+
// The table does not exist so there is nothing to update.
|
1041 |
+
return 0;
|
1042 |
+
}
|
1043 |
+
|
1044 |
+
$tableName = self::getTableName();
|
1045 |
+
$cleanupBreakpoint = $this->getCleanupBreakpointDate()->format('Y-m-d H:i:s');
|
1046 |
+
$cleanableStati = $this->escapeInterval([
|
1047 |
+
self::STATUS_READY,
|
1048 |
+
self::STATUS_COMPLETED,
|
1049 |
+
self::STATUS_FAILED,
|
1050 |
+
self::STATUS_CANCELED
|
1051 |
+
]);
|
1052 |
+
$clenupQuery = "DELETE FROM {$tableName}
|
1053 |
+
WHERE updated_at < '{$cleanupBreakpoint}'
|
1054 |
+
AND status in ({$cleanableStati})";
|
1055 |
+
$cleanupResult = $this->database->query($clenupQuery, true);
|
1056 |
+
|
1057 |
+
if ($cleanupResult === false) {
|
1058 |
+
error_log(json_encode([
|
1059 |
+
'root' => 'Error while trying to cleanup Actions.',
|
1060 |
+
'class' => get_class($this),
|
1061 |
+
'query' => $clenupQuery,
|
1062 |
+
'error' => $this->database->error(),
|
1063 |
+
]));
|
1064 |
+
|
1065 |
+
return 0;
|
1066 |
+
}
|
1067 |
+
if (isset($this->database->link->affected_rows)) {
|
1068 |
+
$removed = $this->database->link->affected_rows;
|
1069 |
+
} else {
|
1070 |
+
$removed = 0;
|
1071 |
+
}
|
1072 |
+
|
1073 |
+
return $removed;
|
1074 |
+
}
|
1075 |
+
}
|
Framework/BackgroundProcessing/QueueProcessor.php
ADDED
@@ -0,0 +1,222 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Processes Actions from the Queue, dispatching the correct Actions and methods with
|
5 |
+
* awareness of the available resources.
|
6 |
+
*
|
7 |
+
* @package WPStaging\Framework\BackgroundProcessing
|
8 |
+
*/
|
9 |
+
|
10 |
+
namespace WPStaging\Framework\BackgroundProcessing;
|
11 |
+
|
12 |
+
use ReflectionMethod;
|
13 |
+
use WPStaging\Core\Utils\Logger;
|
14 |
+
use WPStaging\Core\WPStaging;
|
15 |
+
use WPStaging\Framework\Traits\ResourceTrait;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Class QueueProcessor
|
19 |
+
*
|
20 |
+
* @package WPStaging\Framework\BackgroundProcessing
|
21 |
+
*/
|
22 |
+
class QueueProcessor
|
23 |
+
{
|
24 |
+
use ResourceTrait;
|
25 |
+
use WithQueueAwareness;
|
26 |
+
|
27 |
+
const QUEUE_PROCESS_ACTION = 'wpstg_queue_process';
|
28 |
+
|
29 |
+
/**
|
30 |
+
* A flag property indicating whether the Queue Processor
|
31 |
+
* should actually process Actions or not.
|
32 |
+
*
|
33 |
+
* @var bool
|
34 |
+
*/
|
35 |
+
private $doProcess = true;
|
36 |
+
|
37 |
+
/**
|
38 |
+
* A reference to the Queue instance the Processor should use to access and run low-level
|
39 |
+
* operations on the Queue.
|
40 |
+
*
|
41 |
+
* @var Queue
|
42 |
+
*/
|
43 |
+
private $queue;
|
44 |
+
|
45 |
+
/**
|
46 |
+
* QueueProcessor constructor.
|
47 |
+
*
|
48 |
+
* @param Queue $queue A reference to the Queue instance the Processor should use to access
|
49 |
+
* and run low-level operations on the Queue.
|
50 |
+
*/
|
51 |
+
public function __construct(Queue $queue)
|
52 |
+
{
|
53 |
+
$this->queue = $queue;
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Runs the next available Actions until either they are finished or the resources available
|
58 |
+
* are depleted.
|
59 |
+
*
|
60 |
+
* @return int The number of processed Actions. Processed does NOT mean Completed, it just means
|
61 |
+
* the Processor took hold of the Actions and dispatched them where required.
|
62 |
+
*/
|
63 |
+
public function process()
|
64 |
+
{
|
65 |
+
if (!$this->doProcess) {
|
66 |
+
return 0;
|
67 |
+
}
|
68 |
+
|
69 |
+
$processed = 0;
|
70 |
+
|
71 |
+
while (!$this->isThreshold()) {
|
72 |
+
$action = $this->queue->getNextAvailable();
|
73 |
+
|
74 |
+
if (!$action instanceof Action) {
|
75 |
+
// No Actions to process or failed to acquire lock, bail.
|
76 |
+
break;
|
77 |
+
}
|
78 |
+
|
79 |
+
$processed++;
|
80 |
+
|
81 |
+
$this->dispatch($action);
|
82 |
+
}
|
83 |
+
|
84 |
+
if ($this->queue->count(Queue::STATUS_READY)) {
|
85 |
+
// If there are more Actions to process, then keep processing.
|
86 |
+
$this->fireAjaxAction();
|
87 |
+
}
|
88 |
+
|
89 |
+
return $processed;
|
90 |
+
}
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Depending on the Action nature, dispatch the Action correctly.
|
94 |
+
*
|
95 |
+
* Note that a successful dispatch means that the execution
|
96 |
+
* of the WordPress action, function or method did not raise
|
97 |
+
* Exceptions, and not that it did what was required correctly.
|
98 |
+
* The task of assessing success, and acting on that information
|
99 |
+
* to, maybe, queue the Action again (retry) is a task better performed
|
100 |
+
* by the code that is fired, NOT the Queue Processor.
|
101 |
+
*
|
102 |
+
* @param Action $action A reference to the Action to dispatch.
|
103 |
+
*
|
104 |
+
* @return bool A value that will indicate whether the Action was
|
105 |
+
* dispatched without raising Exceptions or not.
|
106 |
+
*
|
107 |
+
* @throws Exceptions\QueueException
|
108 |
+
*/
|
109 |
+
public function dispatch(Action $action)
|
110 |
+
{
|
111 |
+
/*
|
112 |
+
* What is this?
|
113 |
+
* It's a Closure that will mark this Action as failed.
|
114 |
+
* We hook this Closure on the `shutdown` hook.
|
115 |
+
* When the Closure is called, either in the context of the `shutdown` hook,
|
116 |
+
* it will unhook itself from the `shutdown` hook to have a call-at-most-once
|
117 |
+
* Closure.
|
118 |
+
*/
|
119 |
+
$markFailed = function () use ($action, &$markFailed) {
|
120 |
+
remove_action('shutdown', $markFailed);
|
121 |
+
$this->queue->updateActionStatus($action, Queue::STATUS_FAILED);
|
122 |
+
};
|
123 |
+
|
124 |
+
// If the request dies in the next lines, the Action failed.
|
125 |
+
add_action('shutdown', $markFailed);
|
126 |
+
|
127 |
+
$originalUpdateTime = $action->updatedAt;
|
128 |
+
|
129 |
+
try {
|
130 |
+
$actionCallback = $action->action;
|
131 |
+
|
132 |
+
if (is_callable($actionCallback)) {
|
133 |
+
// Function, static or instance method.
|
134 |
+
if (function_exists($actionCallback)) {
|
135 |
+
// Function, just call it.
|
136 |
+
call_user_func_array($actionCallback, $action->args);
|
137 |
+
} else {
|
138 |
+
/*
|
139 |
+
* Static or instance methods: different versions of PHP will mark `Class::method` as
|
140 |
+
* callable even when it's an instance method, so we have to check if it's static or
|
141 |
+
* not.
|
142 |
+
*/
|
143 |
+
list($class, $method) = explode('::', $actionCallback, 2);
|
144 |
+
$methodReflection = new ReflectionMethod($class, $method);
|
145 |
+
if ($methodReflection->isStatic()) {
|
146 |
+
// Static method, just call it.
|
147 |
+
call_user_func_array($actionCallback, $action->args);
|
148 |
+
} else {
|
149 |
+
// Instance method: build the instance using the Service Locator, then call the method on it.
|
150 |
+
$instance = WPStaging::getInstance()->getContainer()->make($class);
|
151 |
+
call_user_func_array([$instance, $method], $action->args);
|
152 |
+
}
|
153 |
+
}
|
154 |
+
} else {
|
155 |
+
// If nothing of the above, then treat it as a WP action.
|
156 |
+
do_action_ref_array($actionCallback, $action->args);
|
157 |
+
}
|
158 |
+
} catch (\Throwable $e) {
|
159 |
+
/*
|
160 |
+
* This is a PHP 7.0+ interface. But since PHP will NOT check this for existence,
|
161 |
+
* the same way it will not check `instanceof`, this allows us to catch fatals
|
162 |
+
* and keep going if we're on PHP 7.0+.
|
163 |
+
*/
|
164 |
+
$markFailed();
|
165 |
+
|
166 |
+
return false;
|
167 |
+
} catch (\Exception $e) {
|
168 |
+
/*
|
169 |
+
* If we're not on PHP 7.0+, then this is the next best option: there
|
170 |
+
* was an error we could catch, and we did. If the request dies due to
|
171 |
+
* a fatal, then we'll handle that in the `shutdown` hook.
|
172 |
+
*/
|
173 |
+
$markFailed();
|
174 |
+
|
175 |
+
return false;
|
176 |
+
}
|
177 |
+
|
178 |
+
// All fine, we survived.
|
179 |
+
remove_action('shutdown', $markFailed);
|
180 |
+
|
181 |
+
// Re-fetch the Action to check if it was updated during dispatch.
|
182 |
+
$updatedAt = $this->queue->getAction($action->id, true)->updatedAt;
|
183 |
+
$updatedDuringDispatch = $originalUpdateTime === $updatedAt;
|
184 |
+
|
185 |
+
if (!$updatedDuringDispatch) {
|
186 |
+
// If an Action was updated during dispatch, we'll avoid re-setting its status to another value.
|
187 |
+
return true;
|
188 |
+
}
|
189 |
+
|
190 |
+
$this->queue->updateActionStatus($action, Queue::STATUS_COMPLETED);
|
191 |
+
|
192 |
+
return true;
|
193 |
+
}
|
194 |
+
|
195 |
+
/**
|
196 |
+
* Suspends the Queue Processer operations. Any call to the
|
197 |
+
* `process` method will be a no-op that will not process and
|
198 |
+
* dispatch any action.
|
199 |
+
*
|
200 |
+
* @since TBD
|
201 |
+
*
|
202 |
+
* @return bool Whether the Queue Processor was correctly suspended or not.
|
203 |
+
*/
|
204 |
+
public function stopProcessing()
|
205 |
+
{
|
206 |
+
$this->doProcess = false;
|
207 |
+
return true;
|
208 |
+
}
|
209 |
+
|
210 |
+
/**
|
211 |
+
* Resumes the Queue Processor processing of Actions, if stopped.
|
212 |
+
*
|
213 |
+
* @since TBD
|
214 |
+
*
|
215 |
+
* @return bool Whether the Queue Processor did correctly resume or not.
|
216 |
+
*/
|
217 |
+
public function resumeProcessing()
|
218 |
+
{
|
219 |
+
$this->doProcess = true;
|
220 |
+
return true;
|
221 |
+
}
|
222 |
+
}
|
Framework/BackgroundProcessing/WithQueueAwareness.php
ADDED
@@ -0,0 +1,123 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Provides methods to be aware of the queue system and its inner workings.
|
5 |
+
*
|
6 |
+
* @package WPStaging\Framework\BackgroundProcessing
|
7 |
+
*/
|
8 |
+
|
9 |
+
namespace WPStaging\Framework\BackgroundProcessing;
|
10 |
+
|
11 |
+
use WP_Error;
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Trait WithQueueAwareness
|
15 |
+
*
|
16 |
+
* @package WPStaging\Framework\BackgroundProcessing
|
17 |
+
*/
|
18 |
+
trait WithQueueAwareness
|
19 |
+
{
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Whether this Queue instance did fire the AJAX action request or not.
|
23 |
+
*
|
24 |
+
* @var bool
|
25 |
+
*/
|
26 |
+
private $didFireAjaxAction = false;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Returns the Queue default priority that will be used to schedule actions when the
|
30 |
+
* priority is not specified or is specified as an invalid value.
|
31 |
+
*
|
32 |
+
* @return int The Queue default priority.
|
33 |
+
*/
|
34 |
+
public static function getDefaultPriority()
|
35 |
+
{
|
36 |
+
return 0;
|
37 |
+
}
|
38 |
+
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Fires a non-blocking request to the WordPress admin AJAX endpoint that will,
|
42 |
+
* in turn, trigger the procesing of more Actions.
|
43 |
+
*
|
44 |
+
* @param mixed|null $bodyData An optional set of data to customize the processing request
|
45 |
+
* for. If not provided, then the request will be fired for the
|
46 |
+
* next available Actions (normal operations).
|
47 |
+
*
|
48 |
+
* @return bool A value that will indicate whether the request was correctly dispathed
|
49 |
+
* or not.
|
50 |
+
*/
|
51 |
+
public function fireAjaxAction($bodyData = null)
|
52 |
+
{
|
53 |
+
if ($this->didFireAjaxAction) {
|
54 |
+
// Let's not fire the AJAX request more than once per HTTP request, per Queue.
|
55 |
+
return false;
|
56 |
+
}
|
57 |
+
|
58 |
+
$ajaxUrl = add_query_arg([
|
59 |
+
'action' => QueueProcessor::QUEUE_PROCESS_ACTION,
|
60 |
+
'_ajax_nonce' => wp_create_nonce(QueueProcessor::QUEUE_PROCESS_ACTION)
|
61 |
+
], admin_url('admin-ajax.php'));
|
62 |
+
|
63 |
+
$response = wp_remote_post(esc_url_raw($ajaxUrl), [
|
64 |
+
'headers' => [
|
65 |
+
'X-WPSTG-Request' => QueueProcessor::QUEUE_PROCESS_ACTION,
|
66 |
+
],
|
67 |
+
'blocking' => false,
|
68 |
+
'timeout' => 0.01,
|
69 |
+
'cookies' => isset($_COOKIE) ? $_COOKIE : [],
|
70 |
+
'sslverify' => apply_filters('https_local_ssl_verify', false),
|
71 |
+
'body' => $this->normalizeAjaxRequestBody($bodyData),
|
72 |
+
]);
|
73 |
+
|
74 |
+
/*
|
75 |
+
* A non-blocking request will either return a WP_Error instance, or
|
76 |
+
* a mock response. The response is a mock as we cannot really build
|
77 |
+
* a good response without waiting for it to be processed from the server.
|
78 |
+
*/
|
79 |
+
if ($response instanceof WP_Error) {
|
80 |
+
error_log(json_encode([
|
81 |
+
'root' => 'Queue processing admin-ajax request failed.',
|
82 |
+
'class' => get_class($this),
|
83 |
+
'code' => $response->get_error_code(),
|
84 |
+
'message' => $response->get_error_message(),
|
85 |
+
'data' => $response->get_error_data()
|
86 |
+
], JSON_PRETTY_PRINT));
|
87 |
+
|
88 |
+
return false;
|
89 |
+
}
|
90 |
+
|
91 |
+
$this->didFireAjaxAction = true;
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Fires an Action to indicate the Queue did fire the AJAX request that will
|
95 |
+
* trigger side-processing in another PHP process.
|
96 |
+
*
|
97 |
+
* @param Queue $this A reference to the instance of the Queue that actually fired
|
98 |
+
* the AJAX request.
|
99 |
+
*/
|
100 |
+
do_action('wpstg_queue_fire_ajax_request', $this);
|
101 |
+
|
102 |
+
return true;
|
103 |
+
}
|
104 |
+
|
105 |
+
/**
|
106 |
+
* Normalizes the data to be sent along the non-blocking AJAX request
|
107 |
+
* that will trigger the Queue processing of an Action.
|
108 |
+
*
|
109 |
+
* @param mixed|null $bodyData The data to normlize to a format suitable for
|
110 |
+
* the remote request.
|
111 |
+
*
|
112 |
+
* @return array The normalized body data to be sent along the non-blocking
|
113 |
+
* AJAX request.
|
114 |
+
*/
|
115 |
+
private function normalizeAjaxRequestBody($bodyData)
|
116 |
+
{
|
117 |
+
$normalized = (array)$bodyData;
|
118 |
+
|
119 |
+
$normalized['_referer'] = __CLASS__;
|
120 |
+
|
121 |
+
return $normalized;
|
122 |
+
}
|
123 |
+
}
|
Framework/CloningProcess/Data/DBCloningService.php
CHANGED
@@ -41,6 +41,16 @@ abstract class DBCloningService extends CloningService
|
|
41 |
// @see WPStaging/Backend/Modules/Jobs/Cloning.php#L293
|
42 |
// code below solves this issue https://github.com/WP-Staging/wp-staging-pro/issues/385
|
43 |
$prefix = rtrim($this->dto->getPrefix(), '_') . '_';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
// Skip - Table does not exist
|
45 |
if (!$this->tableExists($prefix . $table)) {
|
46 |
$this->log("Table " . $prefix . $table . ' not found. Skipping');
|
41 |
// @see WPStaging/Backend/Modules/Jobs/Cloning.php#L293
|
42 |
// code below solves this issue https://github.com/WP-Staging/wp-staging-pro/issues/385
|
43 |
$prefix = rtrim($this->dto->getPrefix(), '_') . '_';
|
44 |
+
|
45 |
+
// But if the the clone was created with old WP STAGING version where we were not forcing underscore in prefix,
|
46 |
+
// this could to let to unwanted results. As we are force copying users and usermeta table into the staging site,
|
47 |
+
// It will be good to check against users that without forced appending underscore
|
48 |
+
// Code below solves this issue https://github.com/WP-Staging/wp-staging-pro/issues/925
|
49 |
+
// If the main job is UPDATE or RESET and users table without post underscore exists then use prefix without post underscore
|
50 |
+
if ($this->dto->getMainJob() !== 'cloning' && $this->tableExists($this->dto->getPrefix() . 'users')) {
|
51 |
+
$prefix = $this->dto->getPrefix();
|
52 |
+
}
|
53 |
+
|
54 |
// Skip - Table does not exist
|
55 |
if (!$this->tableExists($prefix . $table)) {
|
56 |
$this->log("Table " . $prefix . $table . ' not found. Skipping');
|
Framework/CloningProcess/Data/MultisiteUpdateTablePrefix.php
DELETED
@@ -1,32 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace WPStaging\Framework\CloningProcess\Data;
|
4 |
-
|
5 |
-
class MultisiteUpdateTablePrefix extends UpdateTablePrefix
|
6 |
-
{
|
7 |
-
/**
|
8 |
-
* Changes the base table prefix of the main network site
|
9 |
-
*/
|
10 |
-
protected function updateBaseTablePrefix()
|
11 |
-
{
|
12 |
-
$prefix = $this->dto->getPrefix();
|
13 |
-
$db = $this->dto->getStagingDb();
|
14 |
-
$productionDb = $this->dto->getProductionDb();
|
15 |
-
|
16 |
-
$this->debugLog("SQL: UPDATE {$prefix}usermeta SET meta_key = replace(meta_key, {$productionDb->base_prefix}, {$prefix}) WHERE meta_key LIKE {$productionDb->base_prefix}_%");
|
17 |
-
$update = $db->query(
|
18 |
-
$db->prepare(
|
19 |
-
"UPDATE {$prefix}usermeta SET meta_key = replace(meta_key, %s, %s) WHERE meta_key LIKE %s",
|
20 |
-
$productionDb->base_prefix,
|
21 |
-
$prefix,
|
22 |
-
$productionDb->base_prefix . "_%"
|
23 |
-
)
|
24 |
-
);
|
25 |
-
|
26 |
-
if ($update === false) {
|
27 |
-
$this->log("Failed updating {$prefix}usermeta meta_key database base_prefix {$db->last_error}");
|
28 |
-
} else {
|
29 |
-
//$this->log("Done");
|
30 |
-
}
|
31 |
-
}
|
32 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Framework/CloningProcess/Data/UpdateStagingOptionsTable.php
CHANGED
@@ -24,15 +24,21 @@ class UpdateStagingOptionsTable extends DBCloningService
|
|
24 |
'wpstg_rmpermalinks_executed' => ' ',
|
25 |
'blog_public' => 0,
|
26 |
FirstRun::FIRST_RUN_KEY => 'true',
|
27 |
-
|
|
|
|
|
|
|
|
|
28 |
FirstRun::MAILS_DISABLED_KEY => !((bool) $this->dto->getJob()->getOptions()->emailsAllowed),
|
29 |
ExcludedPlugins::EXCLUDED_PLUGINS_KEY => (new ExcludedPlugins())->getFilteredPluginsToExclude(),
|
30 |
-
])
|
31 |
-
|
|
|
32 |
if (!$this->keepPermalinks()) {
|
33 |
$updateOrInsert['rewrite_rules'] = null;
|
34 |
$updateOrInsert['permalink_structure'] = ' ';
|
35 |
}
|
|
|
36 |
$this->updateOrInsertOptions($updateOrInsert);
|
37 |
|
38 |
$update = [
|
@@ -42,6 +48,7 @@ class UpdateStagingOptionsTable extends DBCloningService
|
|
42 |
if ($this->dto->getMainJob() !== 'updating') {
|
43 |
$update['wpstg_existing_clones_beta'] = serialize([]);
|
44 |
}
|
|
|
45 |
$this->updateOptions($update);
|
46 |
|
47 |
return true;
|
24 |
'wpstg_rmpermalinks_executed' => ' ',
|
25 |
'blog_public' => 0,
|
26 |
FirstRun::FIRST_RUN_KEY => 'true',
|
27 |
+
];
|
28 |
+
// only insert or update clone option if job is not updating
|
29 |
+
// during update this data will be preserved
|
30 |
+
if ($this->dto->getMainJob() !== 'updating') {
|
31 |
+
$update[CloneOptions::WPSTG_CLONE_SETTINGS_KEY] = serialize((object) [
|
32 |
FirstRun::MAILS_DISABLED_KEY => !((bool) $this->dto->getJob()->getOptions()->emailsAllowed),
|
33 |
ExcludedPlugins::EXCLUDED_PLUGINS_KEY => (new ExcludedPlugins())->getFilteredPluginsToExclude(),
|
34 |
+
]);
|
35 |
+
}
|
36 |
+
|
37 |
if (!$this->keepPermalinks()) {
|
38 |
$updateOrInsert['rewrite_rules'] = null;
|
39 |
$updateOrInsert['permalink_structure'] = ' ';
|
40 |
}
|
41 |
+
|
42 |
$this->updateOrInsertOptions($updateOrInsert);
|
43 |
|
44 |
$update = [
|
48 |
if ($this->dto->getMainJob() !== 'updating') {
|
49 |
$update['wpstg_existing_clones_beta'] = serialize([]);
|
50 |
}
|
51 |
+
|
52 |
$this->updateOptions($update);
|
53 |
|
54 |
return true;
|
Framework/CloningProcess/Data/UpdateTablePrefix.php
CHANGED
@@ -22,8 +22,6 @@ class UpdateTablePrefix extends DBCloningService
|
|
22 |
return true;
|
23 |
}
|
24 |
|
25 |
-
$this->updateBaseTablePrefix();
|
26 |
-
|
27 |
$this->debugLog("SQL: UPDATE {$prefix}usermeta SET meta_key = replace(meta_key, {$productionDb->prefix}, {$prefix}) WHERE meta_key LIKE {$productionDb->prefix}%");
|
28 |
|
29 |
$update = $db->query(
|
@@ -41,12 +39,4 @@ class UpdateTablePrefix extends DBCloningService
|
|
41 |
|
42 |
return true;
|
43 |
}
|
44 |
-
|
45 |
-
/**
|
46 |
-
* This function is overwritten for the multisite service
|
47 |
-
*/
|
48 |
-
protected function updateBaseTablePrefix()
|
49 |
-
{
|
50 |
-
//Do nothing since this is the single-site class
|
51 |
-
}
|
52 |
}
|
22 |
return true;
|
23 |
}
|
24 |
|
|
|
|
|
25 |
$this->debugLog("SQL: UPDATE {$prefix}usermeta SET meta_key = replace(meta_key, {$productionDb->prefix}, {$prefix}) WHERE meta_key LIKE {$productionDb->prefix}%");
|
26 |
|
27 |
$update = $db->query(
|
39 |
|
40 |
return true;
|
41 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
42 |
}
|
Framework/CloningProcess/ExcludedPlugins.php
CHANGED
@@ -3,6 +3,7 @@
|
|
3 |
namespace WPStaging\Framework\CloningProcess;
|
4 |
|
5 |
use WPStaging\Framework\Staging\CloneOptions;
|
|
|
6 |
|
7 |
/**
|
8 |
* Add here the list of excluded plugins to make sure code remain DRY
|
@@ -19,11 +20,18 @@ class ExcludedPlugins
|
|
19 |
*/
|
20 |
private $excludedPlugins;
|
21 |
|
|
|
|
|
|
|
|
|
|
|
22 |
public function __construct()
|
23 |
{
|
24 |
-
// list of excluded plugins defined by WP Staging
|
25 |
$this->excludedPlugins = [
|
26 |
-
'wps-hide-login'
|
|
|
|
|
|
|
27 |
];
|
28 |
}
|
29 |
|
@@ -45,14 +53,14 @@ class ExcludedPlugins
|
|
45 |
}
|
46 |
|
47 |
/**
|
48 |
-
* Get list of excluded plugins with
|
49 |
*
|
50 |
* @return array
|
51 |
*/
|
52 |
-
public function
|
53 |
{
|
54 |
return array_map(function ($plugin) {
|
55 |
-
return trailingslashit(
|
56 |
}, $this->excludedPlugins);
|
57 |
}
|
58 |
|
@@ -67,9 +75,9 @@ class ExcludedPlugins
|
|
67 |
{
|
68 |
// Apply filter
|
69 |
if (is_multisite()) {
|
70 |
-
$filteredExcludedPlugins = apply_filters('wpstg_clone_mu_excl_folders', $this->
|
71 |
} else {
|
72 |
-
$filteredExcludedPlugins = apply_filters('wpstg_clone_excl_folders', $this->
|
73 |
}
|
74 |
|
75 |
if ($installedPlugins === []) {
|
@@ -80,7 +88,7 @@ class ExcludedPlugins
|
|
80 |
// Remove all paths other than plugins not in installed plugins
|
81 |
$filteredExcludedPlugins = array_filter($filteredExcludedPlugins, function ($path) use ($installedPlugins) {
|
82 |
foreach ($installedPlugins as $plugin) {
|
83 |
-
$plugin = trailingslashit(
|
84 |
if (strpos($path, $plugin) !== false) {
|
85 |
return true;
|
86 |
}
|
@@ -94,12 +102,12 @@ class ExcludedPlugins
|
|
94 |
/*
|
95 |
* Remove plugins dir from the paths and
|
96 |
* only return plugin dir if inside directory otherwise return file
|
97 |
-
*
|
98 |
-
*
|
99 |
-
*
|
100 |
*/
|
101 |
return array_map(function ($path) {
|
102 |
-
$plugin = str_replace(trailingslashit(
|
103 |
return explode('/', $plugin)[0];
|
104 |
}, $filteredExcludedPlugins);
|
105 |
}
|
3 |
namespace WPStaging\Framework\CloningProcess;
|
4 |
|
5 |
use WPStaging\Framework\Staging\CloneOptions;
|
6 |
+
use WPStaging\Framework\Utils\WpDefaultDirectories;
|
7 |
|
8 |
/**
|
9 |
* Add here the list of excluded plugins to make sure code remain DRY
|
20 |
*/
|
21 |
private $excludedPlugins;
|
22 |
|
23 |
+
/**
|
24 |
+
* Place below the list of plugins to exclude
|
25 |
+
* If any of these below plugins are installed in user site they will be skipped during cloning
|
26 |
+
* And a message will be shown to them about their exclusion
|
27 |
+
*/
|
28 |
public function __construct()
|
29 |
{
|
|
|
30 |
$this->excludedPlugins = [
|
31 |
+
'wps-hide-login',
|
32 |
+
'wp-super-cache',
|
33 |
+
'peters-login-redirect',
|
34 |
+
'wp-spamshield',
|
35 |
];
|
36 |
}
|
37 |
|
53 |
}
|
54 |
|
55 |
/**
|
56 |
+
* Get list of excluded plugins with relative path to wp root
|
57 |
*
|
58 |
* @return array
|
59 |
*/
|
60 |
+
public function getPluginsToExcludeWithRelativePath()
|
61 |
{
|
62 |
return array_map(function ($plugin) {
|
63 |
+
return '/' . trailingslashit((new WpDefaultDirectories())->getRelativePluginPath()) . $plugin;
|
64 |
}, $this->excludedPlugins);
|
65 |
}
|
66 |
|
75 |
{
|
76 |
// Apply filter
|
77 |
if (is_multisite()) {
|
78 |
+
$filteredExcludedPlugins = apply_filters('wpstg_clone_mu_excl_folders', $this->getPluginsToExcludeWithRelativePath());
|
79 |
} else {
|
80 |
+
$filteredExcludedPlugins = apply_filters('wpstg_clone_excl_folders', $this->getPluginsToExcludeWithRelativePath());
|
81 |
}
|
82 |
|
83 |
if ($installedPlugins === []) {
|
88 |
// Remove all paths other than plugins not in installed plugins
|
89 |
$filteredExcludedPlugins = array_filter($filteredExcludedPlugins, function ($path) use ($installedPlugins) {
|
90 |
foreach ($installedPlugins as $plugin) {
|
91 |
+
$plugin = '/' . trailingslashit((new WpDefaultDirectories())->getRelativePluginPath()) . explode('/', $plugin)[0];
|
92 |
if (strpos($path, $plugin) !== false) {
|
93 |
return true;
|
94 |
}
|
102 |
/*
|
103 |
* Remove plugins dir from the paths and
|
104 |
* only return plugin dir if inside directory otherwise return file
|
105 |
+
* /wp-content/plugins/some-plugin/some-plugin.php will return some-plugin
|
106 |
+
* /wp-content/plugins/single-file-plugin.php will return single-file-plugin.php
|
107 |
+
* /wp-content/plugins/plugin-dir will return plugin-dir
|
108 |
*/
|
109 |
return array_map(function ($path) {
|
110 |
+
$plugin = str_replace('/' . trailingslashit((new WpDefaultDirectories())->getRelativePluginPath()), '', $path);
|
111 |
return explode('/', $plugin)[0];
|
112 |
}, $filteredExcludedPlugins);
|
113 |
}
|
Framework/Database/ExcludedTables.php
ADDED
@@ -0,0 +1,85 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WPStaging\Framework\Database;
|
4 |
+
|
5 |
+
use WPStaging\Framework\BackgroundProcessing\Queue;
|
6 |
+
|
7 |
+
/**
|
8 |
+
* Provide list of table excluded from Database Copy and SearchReplace Job
|
9 |
+
*/
|
10 |
+
class ExcludedTables
|
11 |
+
{
|
12 |
+
/**
|
13 |
+
* @var string
|
14 |
+
*/
|
15 |
+
const CLONE_DATABASE_TABLES_EXCLUDE_FILTER = 'wpstg_clone_database_tables_exclude';
|
16 |
+
|
17 |
+
/**
|
18 |
+
* @var string
|
19 |
+
*/
|
20 |
+
const CLONE_SEARCH_REPLACE_TABLES_EXCLUDE_FILTER = 'wpstg_clone_searchreplace_tables_exclude';
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @var string
|
24 |
+
*/
|
25 |
+
const SEARCH_REPLACE_TABLES_EXCLUDE_FILTER = 'wpstg_searchreplace_excl_tables';
|
26 |
+
|
27 |
+
/**
|
28 |
+
* @var array
|
29 |
+
*/
|
30 |
+
private $excludedTables;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* @var array
|
34 |
+
*/
|
35 |
+
private $excludedTablesSearchReplaceOnly;
|
36 |
+
|
37 |
+
public function __construct()
|
38 |
+
{
|
39 |
+
$this->excludedTables = [
|
40 |
+
'blogs',
|
41 |
+
'blog_version',
|
42 |
+
Queue::getTableName(),
|
43 |
+
];
|
44 |
+
|
45 |
+
$this->excludedTablesSearchReplaceOnly = [
|
46 |
+
'_cerber_files', // Cerber Security Plugin
|
47 |
+
'_cerber_sets', // Cerber Security Plugin
|
48 |
+
];
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Get List of excluded tables for database copy
|
53 |
+
*
|
54 |
+
* @return array
|
55 |
+
*/
|
56 |
+
public function getExcludedTables()
|
57 |
+
{
|
58 |
+
$excludedCustomTables = apply_filters(self::CLONE_DATABASE_TABLES_EXCLUDE_FILTER, []);
|
59 |
+
return array_merge($this->excludedTables, $excludedCustomTables);
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Get List of excluded tables for search replace cloning process job
|
64 |
+
* This also includes list of tables excluded through filters for cloning database copy process
|
65 |
+
*
|
66 |
+
* @return array
|
67 |
+
*/
|
68 |
+
public function getExcludedTablesForSearchReplace()
|
69 |
+
{
|
70 |
+
$excludedCustomCloneTables = apply_filters(self::CLONE_SEARCH_REPLACE_TABLES_EXCLUDE_FILTER, []);
|
71 |
+
$excludedCustomClonePushTables = apply_filters(self::SEARCH_REPLACE_TABLES_EXCLUDE_FILTER, $this->excludedTablesSearchReplaceOnly);
|
72 |
+
$searchReplaceExcludedTables = array_merge($excludedCustomCloneTables, $excludedCustomClonePushTables);
|
73 |
+
return array_merge($this->getExcludedTables(), $searchReplaceExcludedTables);
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Get List of excluded tables for search replace push process job
|
78 |
+
*
|
79 |
+
* @return array
|
80 |
+
*/
|
81 |
+
public function getExcludedTablesForSearchReplacePushOnly()
|
82 |
+
{
|
83 |
+
return apply_filters(self::SEARCH_REPLACE_TABLES_EXCLUDE_FILTER, $this->excludedTablesSearchReplaceOnly);
|
84 |
+
}
|
85 |
+
}
|
Framework/Database/TableService.php
CHANGED
@@ -63,7 +63,8 @@ class TableService
|
|
63 |
*/
|
64 |
public function findTableStatusStartsWith($prefix = null)
|
65 |
{
|
66 |
-
|
|
|
67 |
if (!$tables) {
|
68 |
return null;
|
69 |
}
|
63 |
*/
|
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 |
}
|
Framework/Exceptions/IOException.php
ADDED
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WPStaging\Framework\Exceptions;
|
4 |
+
|
5 |
+
class IOException extends \Exception
|
6 |
+
{
|
7 |
+
|
8 |
+
}
|
Framework/Filesystem/Filesystem.php
CHANGED
@@ -6,8 +6,6 @@ use WPStaging\Backend\Notices\Notices;
|
|
6 |
use WPStaging\Core\WPStaging;
|
7 |
use WPStaging\Vendor\Psr\Log\LoggerInterface;
|
8 |
use RuntimeException;
|
9 |
-
use WPStaging\Vendor\Symfony\Component\Filesystem\Filesystem as SymfonyFilesystem;
|
10 |
-
use WPStaging\Vendor\Symfony\Component\Finder\Finder;
|
11 |
|
12 |
class Filesystem extends FilterableDirectoryIterator
|
13 |
{
|
@@ -17,9 +15,6 @@ class Filesystem extends FilterableDirectoryIterator
|
|
17 |
/** @var callable|null */
|
18 |
private $shouldStop;
|
19 |
|
20 |
-
/** @var string[]|array|null */
|
21 |
-
private $notPath;
|
22 |
-
|
23 |
/** @var int|null */
|
24 |
private $depth;
|
25 |
|
@@ -29,39 +24,6 @@ class Filesystem extends FilterableDirectoryIterator
|
|
29 |
/** @var LoggerInterface|null */
|
30 |
private $logger;
|
31 |
|
32 |
-
/**
|
33 |
-
* @param string|null $directory
|
34 |
-
* @return Finder
|
35 |
-
*/
|
36 |
-
public function findFiles($directory = null)
|
37 |
-
{
|
38 |
-
$finder = (new Finder())
|
39 |
-
->ignoreUnreadableDirs()
|
40 |
-
->files()
|
41 |
-
->in($this->findPath($directory))
|
42 |
-
;
|
43 |
-
|
44 |
-
if ($this->depth !== null) {
|
45 |
-
$finder = $finder->depth((string) $this->depth);
|
46 |
-
}
|
47 |
-
|
48 |
-
foreach ($this->getNotPath() as $exclude) {
|
49 |
-
$finder->notPath(untrailingslashit($exclude));
|
50 |
-
}
|
51 |
-
|
52 |
-
foreach ($this->getFileNames() as $fileName) {
|
53 |
-
$finder->name(untrailingslashit($fileName));
|
54 |
-
}
|
55 |
-
|
56 |
-
$finder_has_results = count($finder) > 0;
|
57 |
-
|
58 |
-
if (!$finder_has_results) {
|
59 |
-
return null;
|
60 |
-
}
|
61 |
-
|
62 |
-
return $finder;
|
63 |
-
}
|
64 |
-
|
65 |
/**
|
66 |
* Safe path makes sure given path is within WP root directory
|
67 |
* @param string $fullPath
|
@@ -78,71 +40,9 @@ class Filesystem extends FilterableDirectoryIterator
|
|
78 |
return $safePath;
|
79 |
}
|
80 |
|
81 |
-
/**
|
82 |
-
* Checks given file or directory exists
|
83 |
-
* @param string $fullPath
|
84 |
-
* @return bool
|
85 |
-
*/
|
86 |
-
public function exists($fullPath)
|
87 |
-
{
|
88 |
-
return (new SymfonyFilesystem())->exists($fullPath);
|
89 |
-
}
|
90 |
-
|
91 |
-
/**
|
92 |
-
* @param string $newPath
|
93 |
-
* @return bool
|
94 |
-
*/
|
95 |
-
public function rename($newPath)
|
96 |
-
{
|
97 |
-
// Target doesn't exist, just use rename
|
98 |
-
if (!$this->exists($newPath)) {
|
99 |
-
return rename($this->getPath(), $newPath);
|
100 |
-
}
|
101 |
-
|
102 |
-
// Get all files and dirs
|
103 |
-
$finder = (new Finder())->ignoreUnreadableDirs()->in($this->getPath());
|
104 |
-
if ($this->getNotPath()) {
|
105 |
-
foreach ($this->getNotPath() as $notPath) {
|
106 |
-
$finder->notPath($notPath);
|
107 |
-
}
|
108 |
-
}
|
109 |
-
|
110 |
-
$basePath = trailingslashit($newPath);
|
111 |
-
foreach ($finder as $item) {
|
112 |
-
if (!$this->exists($item->getPathname())) {
|
113 |
-
$this->log('Failed to move directory. Directory does not exists' . $item->getPathname());
|
114 |
-
continue;
|
115 |
-
}
|
116 |
-
|
117 |
-
// RelativePathname is relative to $this->path
|
118 |
-
$destination = $basePath . $item->getRelativePathname();
|
119 |
-
|
120 |
-
// It is not a directory, use built-in rename instead
|
121 |
-
if (!$item->isDir()) {
|
122 |
-
$this->renameDirect($item->getPathname(), $destination);
|
123 |
-
continue;
|
124 |
-
}
|
125 |
-
|
126 |
-
// If it doesn't exist, use built-in rename instead
|
127 |
-
if (!$this->exists($destination)) {
|
128 |
-
$this->renameDirect($item->getPathname(), $destination);
|
129 |
-
continue;
|
130 |
-
}
|
131 |
-
|
132 |
-
if ($this->shouldStop) {
|
133 |
-
return false;
|
134 |
-
}
|
135 |
-
}
|
136 |
-
|
137 |
-
// Due to rename, all files should be deleted so just empty directories left, make sure all of them are deleted.
|
138 |
-
// Due to setting shouldStop, this might return false till everything is deleted.
|
139 |
-
// This might not be just empty dirs as we can exclude some directories using notPath()
|
140 |
-
return $this->delete(null, false);
|
141 |
-
}
|
142 |
-
|
143 |
/**
|
144 |
* Move content from one path to another
|
145 |
-
* This is better than $this->rename() method as this use custom fileiterator and $this->
|
146 |
* @param string $source
|
147 |
* @param string $target
|
148 |
*
|
@@ -207,7 +107,7 @@ class Filesystem extends FilterableDirectoryIterator
|
|
207 |
$deleteSelf = false;
|
208 |
}
|
209 |
|
210 |
-
return $this->
|
211 |
}
|
212 |
|
213 |
/**
|
@@ -219,7 +119,7 @@ class Filesystem extends FilterableDirectoryIterator
|
|
219 |
public function renameDirect($source, $target)
|
220 |
{
|
221 |
$dir = dirname($target);
|
222 |
-
if (
|
223 |
$this->mkdir($dir);
|
224 |
}
|
225 |
|
@@ -267,23 +167,6 @@ class Filesystem extends FilterableDirectoryIterator
|
|
267 |
return trailingslashit($path);
|
268 |
}
|
269 |
|
270 |
-
/**
|
271 |
-
* Copy file
|
272 |
-
*
|
273 |
-
* @param string $source
|
274 |
-
* @param string $destination
|
275 |
-
* @return boolean
|
276 |
-
*
|
277 |
-
* @todo update this to allow copying big files
|
278 |
-
*/
|
279 |
-
public function copy($source, $destination)
|
280 |
-
{
|
281 |
-
$fs = new SymfonyFilesystem();
|
282 |
-
// TODO perhaps use stream_set_chunk_size()?
|
283 |
-
$fs->copy($source, $destination);
|
284 |
-
return $fs->exists($destination);
|
285 |
-
}
|
286 |
-
|
287 |
/**
|
288 |
* The new copy method which works for files, links and directories
|
289 |
*
|
@@ -291,11 +174,12 @@ class Filesystem extends FilterableDirectoryIterator
|
|
291 |
* @param string $target
|
292 |
* @return boolean
|
293 |
*/
|
294 |
-
public function
|
295 |
{
|
296 |
// if $source is link or file, move it and stop execution
|
297 |
if (is_link($source) || is_file($source)) {
|
298 |
-
|
|
|
299 |
}
|
300 |
|
301 |
// if $source is empty dir
|
@@ -333,7 +217,8 @@ class Filesystem extends FilterableDirectoryIterator
|
|
333 |
if ($item->isDir()) {
|
334 |
$result = wp_mkdir_p($destination);
|
335 |
} else { // if file or link
|
336 |
-
$
|
|
|
337 |
}
|
338 |
|
339 |
if (!$result || !is_callable($this->shouldStop)) {
|
@@ -348,15 +233,6 @@ class Filesystem extends FilterableDirectoryIterator
|
|
348 |
return true;
|
349 |
}
|
350 |
|
351 |
-
/**
|
352 |
-
* @param string
|
353 |
-
* @return bool
|
354 |
-
*/
|
355 |
-
public function isWritableDir($fullPath)
|
356 |
-
{
|
357 |
-
return is_dir($fullPath) && is_writable($fullPath);
|
358 |
-
}
|
359 |
-
|
360 |
/**
|
361 |
* Check if directory exists and is not empty
|
362 |
* @param string $dir
|
@@ -372,83 +248,25 @@ class Filesystem extends FilterableDirectoryIterator
|
|
372 |
}
|
373 |
|
374 |
/**
|
375 |
-
*
|
376 |
-
*
|
377 |
-
* @
|
378 |
-
*
|
379 |
-
* @
|
|
|
|
|
|
|
|
|
380 |
*/
|
381 |
-
public function delete($path = null, $
|
382 |
{
|
383 |
$path = $this->findPath($path);
|
384 |
-
if (!$path) {
|
385 |
-
$this->log('You need to define path to delete');
|
386 |
-
throw new RuntimeException('You need to define path to delete');
|
387 |
-
}
|
388 |
|
389 |
if ($path === ABSPATH) {
|
390 |
$this->log('You can not delete WP Root directory');
|
391 |
throw new RuntimeException('You can not delete WP Root directory');
|
392 |
}
|
393 |
|
394 |
-
if (is_link($path) || is_file($path)) {
|
395 |
-
return unlink($path);
|
396 |
-
}
|
397 |
-
|
398 |
-
if (!is_dir($path)) {
|
399 |
-
return true;
|
400 |
-
}
|
401 |
-
|
402 |
-
$iterator = (new Finder())
|
403 |
-
->ignoreUnreadableDirs()
|
404 |
-
->ignoreDotFiles(false)
|
405 |
-
->in($this->findPath($path))
|
406 |
-
;
|
407 |
-
|
408 |
-
if ($this->getShouldStop()) {
|
409 |
-
$iterator->depth('0');
|
410 |
-
}
|
411 |
-
|
412 |
-
if ($isUseNotPath) {
|
413 |
-
foreach ($this->getNotPath() as $exclude) {
|
414 |
-
$iterator->notPath(untrailingslashit($exclude));
|
415 |
-
}
|
416 |
-
}
|
417 |
-
|
418 |
-
foreach ($this->getFileNames() as $fileName) {
|
419 |
-
$iterator->name(untrailingslashit($fileName));
|
420 |
-
}
|
421 |
-
|
422 |
-
$iteratorHasResults = count($iterator) > 0;
|
423 |
-
|
424 |
-
if (is_dir($path) && !$iteratorHasResults && $this->isEmptyDir($path)) {
|
425 |
-
return rmdir($path);
|
426 |
-
}
|
427 |
-
|
428 |
-
foreach ($iterator as $file) {
|
429 |
-
$this->delete($file->getPathname(), $isUseNotPath);
|
430 |
-
if ($this->shouldStop) {
|
431 |
-
return false;
|
432 |
-
}
|
433 |
-
}
|
434 |
-
|
435 |
-
if (is_dir($path)) {
|
436 |
-
return rmdir($path);
|
437 |
-
}
|
438 |
-
}
|
439 |
-
|
440 |
-
/**
|
441 |
-
* Delete a whole directory including all sub directories or a file.
|
442 |
-
* A new faster method than $this->delete()
|
443 |
-
* $this->delete() uses the finder method which seems to be very slow compared to native RecursiveIteratorIterator!
|
444 |
-
* @todo replace $this->>delete() with this method if this can fulfill all requirements
|
445 |
-
*
|
446 |
-
* @param string $path
|
447 |
-
* @param bool $deleteSelf making it optional to delete the parent itself, useful during file and dir exclusion
|
448 |
-
* @return bool True if folder or file is deleted or file is empty ($deleteSelf = false); Return False if folder is not empty and execution should be continued
|
449 |
-
*/
|
450 |
-
public function deleteNew($path, $deleteSelf = true, $throw = false)
|
451 |
-
{
|
452 |
// if $path is link or file, delete it and stop execution
|
453 |
if (is_link($path) || is_file($path)) {
|
454 |
if (!unlink($path)) {
|
@@ -479,17 +297,28 @@ class Filesystem extends FilterableDirectoryIterator
|
|
479 |
return true;
|
480 |
}
|
481 |
|
482 |
-
|
483 |
$this->setDirectory($path);
|
484 |
-
$
|
485 |
try {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
486 |
$iterator = $this->setIteratorMode(\RecursiveIteratorIterator::CHILD_FIRST)->get();
|
487 |
} catch (FilesystemExceptions $e) {
|
488 |
$this->log('Permission Error: Can not create recursive iterator for ' . $path);
|
489 |
if ($throw) {
|
|
|
490 |
// This allows us to know that Filesystem FAILED and should not continue;
|
491 |
throw $e;
|
492 |
} else {
|
|
|
493 |
return false;
|
494 |
}
|
495 |
}
|
@@ -501,17 +330,20 @@ class Filesystem extends FilterableDirectoryIterator
|
|
501 |
}
|
502 |
|
503 |
if (call_user_func($this->shouldStop)) {
|
|
|
504 |
return false;
|
505 |
}
|
506 |
}
|
507 |
|
508 |
// Don't delete the parent main dir itself and finish execution
|
509 |
if (!$deleteSelf) {
|
|
|
510 |
return true;
|
511 |
}
|
512 |
|
513 |
// Folder is not empty. Return false and continue execution if requested
|
514 |
if (!$this->isEmptyDir($path)) {
|
|
|
515 |
return false;
|
516 |
}
|
517 |
|
@@ -522,6 +354,7 @@ class Filesystem extends FilterableDirectoryIterator
|
|
522 |
}
|
523 |
}
|
524 |
|
|
|
525 |
return true;
|
526 |
}
|
527 |
|
@@ -616,7 +449,7 @@ class Filesystem extends FilterableDirectoryIterator
|
|
616 |
}
|
617 |
|
618 |
// force to not delete the parent path itself
|
619 |
-
if (!$this->
|
620 |
return false;
|
621 |
}
|
622 |
}
|
@@ -669,34 +502,6 @@ class Filesystem extends FilterableDirectoryIterator
|
|
669 |
return $this;
|
670 |
}
|
671 |
|
672 |
-
/**
|
673 |
-
* @return array
|
674 |
-
*/
|
675 |
-
public function getNotPath()
|
676 |
-
{
|
677 |
-
return $this->notPath ?: [];
|
678 |
-
}
|
679 |
-
|
680 |
-
/**
|
681 |
-
* @param array $notPath
|
682 |
-
* @return self
|
683 |
-
*/
|
684 |
-
public function setNotPath(array $notPath = [])
|
685 |
-
{
|
686 |
-
$this->notPath = $notPath;
|
687 |
-
return $this;
|
688 |
-
}
|
689 |
-
|
690 |
-
/**
|
691 |
-
* @param string $notPath
|
692 |
-
* @return self
|
693 |
-
*/
|
694 |
-
public function addNotPath($notPath)
|
695 |
-
{
|
696 |
-
$this->notPath[] = $notPath;
|
697 |
-
return $this;
|
698 |
-
}
|
699 |
-
|
700 |
/**
|
701 |
* @return int|null
|
702 |
*/
|
@@ -766,7 +571,7 @@ class Filesystem extends FilterableDirectoryIterator
|
|
766 |
$this->log('Permission Error: Can not delete link ' . $perms);
|
767 |
|
768 |
if ($item->isLink()) {
|
769 |
-
if (
|
770 |
$this->log('Permission Error: Can not delete link ' . $path);
|
771 |
throw new RuntimeException('Permission Error: Can not delete link ' . $path);
|
772 |
}
|
@@ -796,6 +601,21 @@ class Filesystem extends FilterableDirectoryIterator
|
|
796 |
return true;
|
797 |
}
|
798 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
799 |
/**
|
800 |
* @param $string
|
801 |
*/
|
6 |
use WPStaging\Core\WPStaging;
|
7 |
use WPStaging\Vendor\Psr\Log\LoggerInterface;
|
8 |
use RuntimeException;
|
|
|
|
|
9 |
|
10 |
class Filesystem extends FilterableDirectoryIterator
|
11 |
{
|
15 |
/** @var callable|null */
|
16 |
private $shouldStop;
|
17 |
|
|
|
|
|
|
|
18 |
/** @var int|null */
|
19 |
private $depth;
|
20 |
|
24 |
/** @var LoggerInterface|null */
|
25 |
private $logger;
|
26 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
/**
|
28 |
* Safe path makes sure given path is within WP root directory
|
29 |
* @param string $fullPath
|
40 |
return $safePath;
|
41 |
}
|
42 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
/**
|
44 |
* Move content from one path to another
|
45 |
+
* This is better than $this->rename() method as this use custom fileiterator and $this->delete()
|
46 |
* @param string $source
|
47 |
* @param string $target
|
48 |
*
|
107 |
$deleteSelf = false;
|
108 |
}
|
109 |
|
110 |
+
return $this->delete($source, $deleteSelf);
|
111 |
}
|
112 |
|
113 |
/**
|
119 |
public function renameDirect($source, $target)
|
120 |
{
|
121 |
$dir = dirname($target);
|
122 |
+
if (!file_exists($dir)) {
|
123 |
$this->mkdir($dir);
|
124 |
}
|
125 |
|
167 |
return trailingslashit($path);
|
168 |
}
|
169 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
170 |
/**
|
171 |
* The new copy method which works for files, links and directories
|
172 |
*
|
174 |
* @param string $target
|
175 |
* @return boolean
|
176 |
*/
|
177 |
+
public function copy($source, $target)
|
178 |
{
|
179 |
// if $source is link or file, move it and stop execution
|
180 |
if (is_link($source) || is_file($source)) {
|
181 |
+
$this->mkdir(dirname($target));
|
182 |
+
return copy($source, $target);
|
183 |
}
|
184 |
|
185 |
// if $source is empty dir
|
217 |
if ($item->isDir()) {
|
218 |
$result = wp_mkdir_p($destination);
|
219 |
} else { // if file or link
|
220 |
+
$this->mkdir(dirname($destination));
|
221 |
+
$result = copy($item->getPathname(), $destination);
|
222 |
}
|
223 |
|
224 |
if (!$result || !is_callable($this->shouldStop)) {
|
233 |
return true;
|
234 |
}
|
235 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
236 |
/**
|
237 |
* Check if directory exists and is not empty
|
238 |
* @param string $dir
|
248 |
}
|
249 |
|
250 |
/**
|
251 |
+
* Deletes a directory recursively or not.
|
252 |
+
*
|
253 |
+
* @see \WPStaging\Framework\Filesystem\FilterableDirectoryIterator::setRecursive To control whether this function should delete recursively.
|
254 |
+
*
|
255 |
+
* @param string $path
|
256 |
+
* @param bool $deleteSelf Whether to delete the target folder after deleting it's contents.
|
257 |
+
* @throws FilesystemExceptions Only if $throw is true.
|
258 |
+
*
|
259 |
+
* @return bool True if target was completely deleted, false if file not deleted or folder still have contents.
|
260 |
*/
|
261 |
+
public function delete($path = null, $deleteSelf = true, $throw = false)
|
262 |
{
|
263 |
$path = $this->findPath($path);
|
|
|
|
|
|
|
|
|
264 |
|
265 |
if ($path === ABSPATH) {
|
266 |
$this->log('You can not delete WP Root directory');
|
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)) {
|
297 |
return true;
|
298 |
}
|
299 |
|
|
|
300 |
$this->setDirectory($path);
|
301 |
+
$originalIsRecursive = (bool)$this->isIteratorRecursive();
|
302 |
try {
|
303 |
+
/*
|
304 |
+
* For historical reasons, this function will run as Recursive Mode by default.
|
305 |
+
* To minimize any side-effects of calling this method on an existing instance
|
306 |
+
* of Filesystem, we will store the original isRecursive, and set it to the
|
307 |
+
* original value before returning.
|
308 |
+
*/
|
309 |
+
if ($this->isIteratorRecursive() === null) {
|
310 |
+
$this->setRecursive();
|
311 |
+
}
|
312 |
+
|
313 |
$iterator = $this->setIteratorMode(\RecursiveIteratorIterator::CHILD_FIRST)->get();
|
314 |
} catch (FilesystemExceptions $e) {
|
315 |
$this->log('Permission Error: Can not create recursive iterator for ' . $path);
|
316 |
if ($throw) {
|
317 |
+
$this->setRecursive($originalIsRecursive);
|
318 |
// This allows us to know that Filesystem FAILED and should not continue;
|
319 |
throw $e;
|
320 |
} else {
|
321 |
+
$this->setRecursive($originalIsRecursive);
|
322 |
return false;
|
323 |
}
|
324 |
}
|
330 |
}
|
331 |
|
332 |
if (call_user_func($this->shouldStop)) {
|
333 |
+
$this->setRecursive($originalIsRecursive);
|
334 |
return false;
|
335 |
}
|
336 |
}
|
337 |
|
338 |
// Don't delete the parent main dir itself and finish execution
|
339 |
if (!$deleteSelf) {
|
340 |
+
$this->setRecursive($originalIsRecursive);
|
341 |
return true;
|
342 |
}
|
343 |
|
344 |
// Folder is not empty. Return false and continue execution if requested
|
345 |
if (!$this->isEmptyDir($path)) {
|
346 |
+
$this->setRecursive($originalIsRecursive);
|
347 |
return false;
|
348 |
}
|
349 |
|
354 |
}
|
355 |
}
|
356 |
|
357 |
+
$this->setRecursive($originalIsRecursive);
|
358 |
return true;
|
359 |
}
|
360 |
|
449 |
}
|
450 |
|
451 |
// force to not delete the parent path itself
|
452 |
+
if (!$this->delete($path, false)) {
|
453 |
return false;
|
454 |
}
|
455 |
}
|
502 |
return $this;
|
503 |
}
|
504 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
505 |
/**
|
506 |
* @return int|null
|
507 |
*/
|
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);
|
576 |
throw new RuntimeException('Permission Error: Can not delete link ' . $path);
|
577 |
}
|
601 |
return true;
|
602 |
}
|
603 |
|
604 |
+
/**
|
605 |
+
* Remove symlink for both windows and other OSes
|
606 |
+
* @param string $path Path to the link
|
607 |
+
* @return boolean
|
608 |
+
*/
|
609 |
+
protected function removeSymlink($path)
|
610 |
+
{
|
611 |
+
// remove symlink using rmdir if OS is windows
|
612 |
+
if (PHP_SHLIB_SUFFIX === 'dll') {
|
613 |
+
return rmdir($path);
|
614 |
+
}
|
615 |
+
|
616 |
+
return unlink($path);
|
617 |
+
}
|
618 |
+
|
619 |
/**
|
620 |
* @param $string
|
621 |
*/
|
Framework/Filesystem/FilterableDirectoryIterator.php
CHANGED
@@ -10,9 +10,17 @@ use RecursiveIteratorIterator;
|
|
10 |
use WPStaging\Framework\Filesystem\Filters\DirectoryDotFilter;
|
11 |
use WPStaging\Framework\Filesystem\Filters\PathExcludeFilter;
|
12 |
use WPStaging\Framework\Filesystem\Filters\RecursivePathExcludeFilter;
|
|
|
|
|
13 |
|
14 |
class FilterableDirectoryIterator
|
15 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
/**
|
17 |
* The directory to iterate
|
18 |
* @var string
|
@@ -25,11 +33,17 @@ class FilterableDirectoryIterator
|
|
25 |
*/
|
26 |
private $paths = [];
|
27 |
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
/**
|
29 |
* Iterator recursively including sub folders or only items located in root of $this->$directory
|
30 |
-
* @var bool
|
31 |
*/
|
32 |
-
private $isRecursive =
|
33 |
|
34 |
/**
|
35 |
* skip dot in non recursive iterator depending on value
|
@@ -51,6 +65,25 @@ class FilterableDirectoryIterator
|
|
51 |
public function __construct()
|
52 |
{
|
53 |
$this->iteratorMode = RecursiveIteratorIterator::LEAVES_ONLY;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
54 |
}
|
55 |
|
56 |
/**
|
@@ -135,6 +168,34 @@ class FilterableDirectoryIterator
|
|
135 |
return $this;
|
136 |
}
|
137 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
138 |
/**
|
139 |
* @return int
|
140 |
*/
|
@@ -182,8 +243,12 @@ class FilterableDirectoryIterator
|
|
182 |
|
183 |
$iterator = new RecursiveDirectoryIterator($this->directory, FilesystemIterator::SKIP_DOTS);
|
184 |
|
|
|
|
|
|
|
|
|
185 |
if (count($this->paths) !== 0) {
|
186 |
-
$iterator = new RecursivePathExcludeFilter($iterator, $this->paths);
|
187 |
}
|
188 |
|
189 |
$iterator = new RecursiveIteratorIterator($iterator, $this->iteratorMode);
|
@@ -203,8 +268,12 @@ class FilterableDirectoryIterator
|
|
203 |
$iterator = new DirectoryDotFilter($iterator);
|
204 |
}
|
205 |
|
|
|
|
|
|
|
|
|
206 |
if (count($this->paths) !== 0) {
|
207 |
-
$iterator = new PathExcludeFilter($iterator, $this->paths);
|
208 |
}
|
209 |
|
210 |
$iterator = new IteratorIterator($iterator);
|
10 |
use WPStaging\Framework\Filesystem\Filters\DirectoryDotFilter;
|
11 |
use WPStaging\Framework\Filesystem\Filters\PathExcludeFilter;
|
12 |
use WPStaging\Framework\Filesystem\Filters\RecursivePathExcludeFilter;
|
13 |
+
use WPStaging\Framework\Filesystem\Filters\FileSizeFilter;
|
14 |
+
use WPStaging\Framework\Filesystem\Filters\RecursiveFileSizeFilter;
|
15 |
|
16 |
class FilterableDirectoryIterator
|
17 |
{
|
18 |
+
/**
|
19 |
+
* Root path of WP
|
20 |
+
* @var string
|
21 |
+
*/
|
22 |
+
private $wpRootPath;
|
23 |
+
|
24 |
/**
|
25 |
* The directory to iterate
|
26 |
* @var string
|
33 |
*/
|
34 |
private $paths = [];
|
35 |
|
36 |
+
/**
|
37 |
+
* list of files sizes exclude rules
|
38 |
+
* @var array
|
39 |
+
*/
|
40 |
+
private $sizes = [];
|
41 |
+
|
42 |
/**
|
43 |
* Iterator recursively including sub folders or only items located in root of $this->$directory
|
44 |
+
* @var bool|null
|
45 |
*/
|
46 |
+
private $isRecursive = null;
|
47 |
|
48 |
/**
|
49 |
* skip dot in non recursive iterator depending on value
|
65 |
public function __construct()
|
66 |
{
|
67 |
$this->iteratorMode = RecursiveIteratorIterator::LEAVES_ONLY;
|
68 |
+
$this->wpRootPath = ABSPATH;
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* @return string
|
73 |
+
*/
|
74 |
+
public function getWpRootPath()
|
75 |
+
{
|
76 |
+
return $this->wpRootPath;
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* @param string $wpRootPath
|
81 |
+
* @return self
|
82 |
+
*/
|
83 |
+
public function setWpRootPath($wpRootPath)
|
84 |
+
{
|
85 |
+
$this->wpRootPath = $wpRootPath;
|
86 |
+
return $this;
|
87 |
}
|
88 |
|
89 |
/**
|
168 |
return $this;
|
169 |
}
|
170 |
|
171 |
+
/**
|
172 |
+
* @return array
|
173 |
+
*/
|
174 |
+
public function getExcludeSizeRules()
|
175 |
+
{
|
176 |
+
return $this->sizes;
|
177 |
+
}
|
178 |
+
|
179 |
+
/**
|
180 |
+
* @param array $rules
|
181 |
+
* @return self
|
182 |
+
*/
|
183 |
+
public function setExcludeSizeRules($rules)
|
184 |
+
{
|
185 |
+
$this->sizes = $rules;
|
186 |
+
return $this;
|
187 |
+
}
|
188 |
+
|
189 |
+
/**
|
190 |
+
* @param string $rule
|
191 |
+
* @return self
|
192 |
+
*/
|
193 |
+
public function addExcludeSizeRule($rule)
|
194 |
+
{
|
195 |
+
$this->sizes[] = $rule;
|
196 |
+
return $this;
|
197 |
+
}
|
198 |
+
|
199 |
/**
|
200 |
* @return int
|
201 |
*/
|
243 |
|
244 |
$iterator = new RecursiveDirectoryIterator($this->directory, FilesystemIterator::SKIP_DOTS);
|
245 |
|
246 |
+
if (count($this->sizes) !== 0) {
|
247 |
+
$iterator = new RecursiveFileSizeFilter($iterator, $this->sizes);
|
248 |
+
}
|
249 |
+
|
250 |
if (count($this->paths) !== 0) {
|
251 |
+
$iterator = new RecursivePathExcludeFilter($iterator, $this->paths, $this->wpRootPath);
|
252 |
}
|
253 |
|
254 |
$iterator = new RecursiveIteratorIterator($iterator, $this->iteratorMode);
|
268 |
$iterator = new DirectoryDotFilter($iterator);
|
269 |
}
|
270 |
|
271 |
+
if (count($this->sizes) !== 0) {
|
272 |
+
$iterator = new FileSizeFilter($iterator, $this->sizes);
|
273 |
+
}
|
274 |
+
|
275 |
if (count($this->paths) !== 0) {
|
276 |
+
$iterator = new PathExcludeFilter($iterator, $this->paths, $this->wpRootPath);
|
277 |
}
|
278 |
|
279 |
$iterator = new IteratorIterator($iterator);
|
Framework/Filesystem/Filters/ExcludeFilter.php
ADDED
@@ -0,0 +1,143 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WPStaging\Framework\Filesystem\Filters;
|
4 |
+
|
5 |
+
use WPStaging\Framework\TemplateEngine\TemplateEngine;
|
6 |
+
use WPStaging\Framework\Utils\Strings;
|
7 |
+
|
8 |
+
class ExcludeFilter
|
9 |
+
{
|
10 |
+
const NAME_BEGINS_WITH = 'name_begins_with';
|
11 |
+
const NAME_ENDS_WITH = 'name_ends_with';
|
12 |
+
const NAME_EXACT_MATCHES = 'name_exact_matches';
|
13 |
+
const NAME_CONTAINS = 'name_contains';
|
14 |
+
|
15 |
+
const SIZE_KB = 'kb';
|
16 |
+
const SIZE_MB = 'mb';
|
17 |
+
const SIZE_GB = 'gb';
|
18 |
+
|
19 |
+
const SIZE_GREATER_THAN = 'size_greater_than';
|
20 |
+
const SIZE_LESS_THAN = 'size_less_than';
|
21 |
+
const SIZE_EQUAL_TO = 'size_equal_to';
|
22 |
+
|
23 |
+
/**
|
24 |
+
* @var Strings
|
25 |
+
*/
|
26 |
+
private $strUtils;
|
27 |
+
|
28 |
+
/**
|
29 |
+
* @var TemplateEngine
|
30 |
+
*/
|
31 |
+
private $templateEngine;
|
32 |
+
|
33 |
+
public function __construct()
|
34 |
+
{
|
35 |
+
$this->strUtils = new Strings();
|
36 |
+
$this->templateEngine = new TemplateEngine();
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Convert wpstg exclude rule to glob rule
|
41 |
+
*
|
42 |
+
* @param string $rule
|
43 |
+
* @return string
|
44 |
+
*/
|
45 |
+
public function mapExclude($rule)
|
46 |
+
{
|
47 |
+
if ($this->strUtils->startsWith($rule, 'ext:')) {
|
48 |
+
return '/**/*.' . trim(substr($rule, 4));
|
49 |
+
}
|
50 |
+
|
51 |
+
$nameRule = $rule;
|
52 |
+
if ($this->strUtils->startsWith($rule, 'file:')) {
|
53 |
+
$nameRule = trim(substr($rule, 5));
|
54 |
+
} elseif ($this->strUtils->startsWith($rule, 'dir:')) {
|
55 |
+
$nameRule = trim(substr($rule, 4));
|
56 |
+
}
|
57 |
+
|
58 |
+
$globRule = $this->convertToNameGlob($nameRule);
|
59 |
+
if ($this->strUtils->startsWith($rule, 'file:')) {
|
60 |
+
return $globRule . '.*';
|
61 |
+
}
|
62 |
+
|
63 |
+
return $globRule . '/**';
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Return rendered exclude template as output for the wpstg exclude filter size rule
|
68 |
+
*
|
69 |
+
* @param string $rule
|
70 |
+
*
|
71 |
+
* @return string
|
72 |
+
*/
|
73 |
+
public function renderSizeExclude($rule)
|
74 |
+
{
|
75 |
+
list($comparison, $size) = explode(' ', $rule);
|
76 |
+
$bytes = (int)$size;
|
77 |
+
return $this->templateEngine->render("Backend/views/templates/exclude-filters/file-size-exclude-filter.php", [
|
78 |
+
"comparison" => trim($comparison),
|
79 |
+
"bytes" => trim($bytes),
|
80 |
+
"size" => trim($size)
|
81 |
+
]);
|
82 |
+
}
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Return rendered exclude template as output for the wpstg exclude filter glob rule
|
86 |
+
*
|
87 |
+
* @param string $rule
|
88 |
+
*
|
89 |
+
* @return string
|
90 |
+
*/
|
91 |
+
public function renderGlobExclude($rule)
|
92 |
+
{
|
93 |
+
if ($this->strUtils->startsWith($rule, 'ext:')) {
|
94 |
+
return $this->templateEngine->render("Backend/views/templates/exclude-filters/file-ext-exclude-filter.php", [
|
95 |
+
"extension" => trim(substr($rule, 4)),
|
96 |
+
]);
|
97 |
+
}
|
98 |
+
|
99 |
+
if ($this->strUtils->startsWith($rule, 'file:')) {
|
100 |
+
list($rule, $name) = explode(' ', trim(substr($rule, 5)));
|
101 |
+
return $this->templateEngine->render("Backend/views/templates/exclude-filters/file-name-exclude-filter.php", [
|
102 |
+
"rule" => trim($rule),
|
103 |
+
"name" => trim($name),
|
104 |
+
]);
|
105 |
+
}
|
106 |
+
|
107 |
+
if ($this->strUtils->startsWith($rule, 'dir:')) {
|
108 |
+
list($rule, $name) = explode(' ', trim(substr($rule, 4)));
|
109 |
+
return $this->templateEngine->render("Backend/views/templates/exclude-filters/dir-name-exclude-filter.php", [
|
110 |
+
"rule" => trim($rule),
|
111 |
+
"name" => trim($name),
|
112 |
+
]);
|
113 |
+
}
|
114 |
+
|
115 |
+
return '';
|
116 |
+
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* Convert wpstg name rule to glob rule
|
120 |
+
*
|
121 |
+
* @return $string
|
122 |
+
*/
|
123 |
+
private function convertToNameGlob($rule)
|
124 |
+
{
|
125 |
+
if ($this->strUtils->startsWith($rule, self::NAME_BEGINS_WITH)) {
|
126 |
+
$len = strlen(self::NAME_BEGINS_WITH);
|
127 |
+
return '/**/' . trim(substr($rule, $len)) . "*";
|
128 |
+
}
|
129 |
+
|
130 |
+
if ($this->strUtils->startsWith($rule, self::NAME_ENDS_WITH)) {
|
131 |
+
$len = strlen(self::NAME_ENDS_WITH);
|
132 |
+
return '/**/*' . trim(substr($rule, $len));
|
133 |
+
}
|
134 |
+
|
135 |
+
if ($this->strUtils->startsWith($rule, self::NAME_EXACT_MATCHES)) {
|
136 |
+
$len = strlen(self::NAME_EXACT_MATCHES);
|
137 |
+
return '/**/' . trim(substr($rule, $len));
|
138 |
+
}
|
139 |
+
|
140 |
+
$len = strlen(self::NAME_CONTAINS);
|
141 |
+
return '/**/*' . trim(substr($rule, $len)) . "*";
|
142 |
+
}
|
143 |
+
}
|
Framework/Filesystem/Filters/FileSizeFilter.php
ADDED
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WPStaging\Framework\Filesystem\Filters;
|
4 |
+
|
5 |
+
use Iterator;
|
6 |
+
use FilterIterator;
|
7 |
+
|
8 |
+
class FileSizeFilter extends FilterIterator
|
9 |
+
{
|
10 |
+
private $sizeFilters = [];
|
11 |
+
public function __construct(Iterator $iterator, $sizeFilters = [])
|
12 |
+
{
|
13 |
+
parent::__construct($iterator);
|
14 |
+
$this->sizeFilters = $sizeFilters;
|
15 |
+
}
|
16 |
+
|
17 |
+
public function accept()
|
18 |
+
{
|
19 |
+
$current = $this->current();
|
20 |
+
|
21 |
+
// return true of not file
|
22 |
+
if (!$current->isFile()) {
|
23 |
+
return true;
|
24 |
+
}
|
25 |
+
|
26 |
+
$fileSize = $current->getSize();
|
27 |
+
foreach ($this->sizeFilters as $sizeFilter) {
|
28 |
+
$sizeComparator = explode(' ', $sizeFilter);
|
29 |
+
if (count($sizeComparator) !== 2) {
|
30 |
+
continue;
|
31 |
+
}
|
32 |
+
|
33 |
+
if ($this->compareBytes($fileSize, $sizeComparator[1], $sizeComparator[0])) {
|
34 |
+
return false;
|
35 |
+
}
|
36 |
+
}
|
37 |
+
|
38 |
+
return true;
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Compare Bytes
|
43 |
+
*
|
44 |
+
* @param string|int $compare
|
45 |
+
* @param string|int $compareWith
|
46 |
+
* @param string $comparator
|
47 |
+
* @return bool
|
48 |
+
*/
|
49 |
+
public function compareBytes($compare, $compareWith, $comparator = '=')
|
50 |
+
{
|
51 |
+
$compare = wp_convert_hr_to_bytes($compare);
|
52 |
+
$compareWith = wp_convert_hr_to_bytes($compareWith);
|
53 |
+
|
54 |
+
// comparison for equal to
|
55 |
+
if (($comparator === '=' || $comparator === ExcludeFilter::SIZE_EQUAL_TO) && ($compare == $compareWith)) {
|
56 |
+
return true;
|
57 |
+
}
|
58 |
+
|
59 |
+
// comparison for greater than
|
60 |
+
if (($comparator === '>' || $comparator === ExcludeFilter::SIZE_GREATER_THAN) && ($compare > $compareWith)) {
|
61 |
+
return true;
|
62 |
+
}
|
63 |
+
|
64 |
+
// comparison for less than
|
65 |
+
if (($comparator === '<' || $comparator === ExcludeFilter::SIZE_LESS_THAN) && ($compare < $compareWith)) {
|
66 |
+
return true;
|
67 |
+
}
|
68 |
+
|
69 |
+
return false;
|
70 |
+
}
|
71 |
+
}
|
Framework/Filesystem/Filters/PathExcludeFilter.php
CHANGED
@@ -4,25 +4,62 @@ namespace WPStaging\Framework\Filesystem\Filters;
|
|
4 |
|
5 |
use FilterIterator;
|
6 |
use Iterator;
|
7 |
-
use WPStaging\Framework\
|
8 |
|
9 |
class PathExcludeFilter extends FilterIterator
|
10 |
{
|
11 |
-
|
|
|
|
|
|
|
12 |
|
13 |
-
|
|
|
|
|
|
|
14 |
|
15 |
-
public function __construct(Iterator $iterator, $exclude = [])
|
16 |
{
|
17 |
parent::__construct($iterator);
|
18 |
-
$this->
|
19 |
-
$this->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
}
|
21 |
|
22 |
public function accept()
|
23 |
{
|
24 |
// Get the current SplFileInfo object
|
25 |
$fileInfo = $this->getInnerIterator()->current();
|
26 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
}
|
28 |
}
|
4 |
|
5 |
use FilterIterator;
|
6 |
use Iterator;
|
7 |
+
use WPStaging\Framework\Filesystem\Filters\PathFilterHelper;
|
8 |
|
9 |
class PathExcludeFilter extends FilterIterator
|
10 |
{
|
11 |
+
/**
|
12 |
+
* @var PathFilterHelper
|
13 |
+
*/
|
14 |
+
protected $excludeFilter;
|
15 |
|
16 |
+
/**
|
17 |
+
* @var PathFilterHelper
|
18 |
+
*/
|
19 |
+
protected $includeFilter;
|
20 |
|
21 |
+
public function __construct(Iterator $iterator, $exclude = [], $wpRootPath = ABSPATH)
|
22 |
{
|
23 |
parent::__construct($iterator);
|
24 |
+
$this->excludeFilter = new PathFilterHelper();
|
25 |
+
$this->excludeFilter->setWpRootPath($wpRootPath);
|
26 |
+
$this->excludeFilter->categorizeRules($exclude);
|
27 |
+
$this->includeFilter = new PathFilterHelper(true);
|
28 |
+
$this->includeFilter->setWpRootPath($wpRootPath);
|
29 |
+
$this->includeFilter->categorizeRules($exclude);
|
30 |
+
}
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Set the WP Root Path
|
34 |
+
* @param string $wpRootPath
|
35 |
+
*/
|
36 |
+
public function setWpRootPath($wpRootPath)
|
37 |
+
{
|
38 |
+
$this->excludeFilter->setWpRootPath($wpRootPath);
|
39 |
+
$this->includeFilter->setWpRootPath($wpRootPath);
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Get the WP Root Path
|
44 |
+
* @return string
|
45 |
+
*/
|
46 |
+
public function getWpRootPath()
|
47 |
+
{
|
48 |
+
return $this->excludeFilter->getWpRootPath();
|
49 |
}
|
50 |
|
51 |
public function accept()
|
52 |
{
|
53 |
// Get the current SplFileInfo object
|
54 |
$fileInfo = $this->getInnerIterator()->current();
|
55 |
+
if ($this->includeFilter->isMatched($fileInfo)) {
|
56 |
+
return true;
|
57 |
+
}
|
58 |
+
|
59 |
+
if ($fileInfo->isDir() && $this->includeFilter->hasRules()) {
|
60 |
+
return true;
|
61 |
+
}
|
62 |
+
|
63 |
+
return !$this->excludeFilter->isMatched($fileInfo);
|
64 |
}
|
65 |
}
|
Framework/Filesystem/Filters/PathFilterHelper.php
ADDED
@@ -0,0 +1,262 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WPStaging\Framework\Filesystem\Filters;
|
4 |
+
|
5 |
+
use SplFileInfo;
|
6 |
+
use WPStaging\Framework\Utils\Strings;
|
7 |
+
use WPStaging\Framework\Utils\ThirdParty\Glob;
|
8 |
+
|
9 |
+
/**
|
10 |
+
* This helper is used in both RecursivePathExcludeFilter and PathExcludeFilter
|
11 |
+
* This will help in keeping the code DRY
|
12 |
+
*/
|
13 |
+
class PathFilterHelper
|
14 |
+
{
|
15 |
+
/**
|
16 |
+
* @var array
|
17 |
+
*/
|
18 |
+
private $absolutePathRules;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @var array
|
22 |
+
*/
|
23 |
+
private $globRules;
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @var string
|
27 |
+
*/
|
28 |
+
private $wpRootPath;
|
29 |
+
|
30 |
+
/**
|
31 |
+
* @var Strings
|
32 |
+
*/
|
33 |
+
private $strUtils;
|
34 |
+
|
35 |
+
/**
|
36 |
+
* @var boolean
|
37 |
+
*/
|
38 |
+
private $isInclude;
|
39 |
+
|
40 |
+
/**
|
41 |
+
* @var int
|
42 |
+
*/
|
43 |
+
private $rulesCount;
|
44 |
+
|
45 |
+
public function __construct($isInclude = false)
|
46 |
+
{
|
47 |
+
$this->isInclude = $isInclude;
|
48 |
+
$this->strUtils = new Strings();
|
49 |
+
$this->setWpRootPath(ABSPATH);
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Set the WP Root Path
|
54 |
+
* Use this method for staging site or mocking
|
55 |
+
* @param string $wpRootPath
|
56 |
+
*/
|
57 |
+
public function setWpRootPath($wpRootPath)
|
58 |
+
{
|
59 |
+
$this->wpRootPath = $this->strUtils->sanitizeDirectorySeparator($wpRootPath);
|
60 |
+
$this->wpRootPath = rtrim($this->wpRootPath, '/');
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Get the WP Root Path
|
65 |
+
* @return string
|
66 |
+
*/
|
67 |
+
public function getWpRootPath()
|
68 |
+
{
|
69 |
+
return $this->wpRootPath;
|
70 |
+
}
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Categories Rules
|
74 |
+
*
|
75 |
+
* @param array $excludes
|
76 |
+
*/
|
77 |
+
public function categorizeRules($rules)
|
78 |
+
{
|
79 |
+
$this->absolutePathRules = [];
|
80 |
+
$this->globRules = [];
|
81 |
+
$this->rulesCount = 0;
|
82 |
+
foreach ($rules as $rule) {
|
83 |
+
if (empty($rule) || $rule === '') {
|
84 |
+
continue;
|
85 |
+
}
|
86 |
+
|
87 |
+
// Skip if include rule but helper is for exclude
|
88 |
+
if (!$this->isInclude && $this->strUtils->startsWith($rule, '!')) {
|
89 |
+
continue;
|
90 |
+
}
|
91 |
+
|
92 |
+
// Skip if exclude rule but helper is for include
|
93 |
+
if ($this->isInclude && !$this->strUtils->startsWith($rule, '!')) {
|
94 |
+
continue;
|
95 |
+
}
|
96 |
+
|
97 |
+
if ($this->isInclude) {
|
98 |
+
$rule = ltrim($rule, '!');
|
99 |
+
}
|
100 |
+
|
101 |
+
// If the rule starts with / and doesn't have any glob character add it to absoluate path array and move to next rule
|
102 |
+
if ($this->strUtils->startsWith($rule, '/') && !$this->isGlobPattern($rule)) {
|
103 |
+
$this->absolutePathRules[] = $rule;
|
104 |
+
$this->rulesCount++;
|
105 |
+
continue;
|
106 |
+
}
|
107 |
+
|
108 |
+
// *. is to check whether the exclude is extension exclude or not,
|
109 |
+
// If it is extension exclude then convert to glob pattern
|
110 |
+
if ($this->strUtils->startsWith($rule, '*.')) {
|
111 |
+
$rule = '/**/' . $rule;
|
112 |
+
}
|
113 |
+
|
114 |
+
// **/ is to check whether the exclude is anywhere/wildcard exclude or not,
|
115 |
+
// If it is anywhere exclude then convert to glob pattern
|
116 |
+
if ($this->strUtils->startsWith($rule, '**/')) {
|
117 |
+
$rule = '/' . $rule;
|
118 |
+
}
|
119 |
+
|
120 |
+
// convert path to wildcard glob path if it doesn't have any glob character
|
121 |
+
if (!$this->isGlobPattern($rule)) {
|
122 |
+
$rule = '/**/' . $rule;
|
123 |
+
}
|
124 |
+
|
125 |
+
// make exclude works for its children if it is for directory
|
126 |
+
if ($this->isChildrenMatchingAllow($rule)) {
|
127 |
+
$this->globRules[] = $this->wildcardGlobToRegex(Glob::toRegex($rule . '/**'));
|
128 |
+
$this->rulesCount++;
|
129 |
+
}
|
130 |
+
|
131 |
+
// If the exclude doesn't matches extension or anywhere exclude treat it as glob exclude
|
132 |
+
$this->globRules[] = $this->wildcardGlobToRegex(Glob::toRegex($rule));
|
133 |
+
$this->rulesCount++;
|
134 |
+
}
|
135 |
+
}
|
136 |
+
|
137 |
+
/**
|
138 |
+
* Check whether the file meets any of the exclude criteria
|
139 |
+
* @param SplFileInfo $fileInfo
|
140 |
+
*
|
141 |
+
* @return boolean
|
142 |
+
*/
|
143 |
+
public function isMatched($fileInfo)
|
144 |
+
{
|
145 |
+
$path = $fileInfo->getPathname();
|
146 |
+
$path = $this->strUtils->sanitizeDirectorySeparator($path);
|
147 |
+
$relpath = str_replace($this->wpRootPath, '', $path);
|
148 |
+
|
149 |
+
// Check absolute path
|
150 |
+
if ($this->isAbsolutePathMatched($relpath)) {
|
151 |
+
return true;
|
152 |
+
}
|
153 |
+
|
154 |
+
// Check glob pattern but only check against in relative path to wordpress installation
|
155 |
+
if ($this->isGlobPatternMatched($relpath)) {
|
156 |
+
return true;
|
157 |
+
}
|
158 |
+
|
159 |
+
return false;
|
160 |
+
}
|
161 |
+
|
162 |
+
/**
|
163 |
+
* Determine whether there is any rule or not.
|
164 |
+
*
|
165 |
+
* @return boolean
|
166 |
+
*/
|
167 |
+
public function hasRules()
|
168 |
+
{
|
169 |
+
return $this->rulesCount > 0;
|
170 |
+
}
|
171 |
+
|
172 |
+
/**
|
173 |
+
* Check whether the given path satisfy any absolute path exclusion
|
174 |
+
*
|
175 |
+
* @param string $path
|
176 |
+
* @return boolean
|
177 |
+
*/
|
178 |
+
protected function isAbsolutePathMatched($path)
|
179 |
+
{
|
180 |
+
// will check if path matches
|
181 |
+
if (in_array($path, $this->absolutePathRules)) {
|
182 |
+
return true;
|
183 |
+
}
|
184 |
+
|
185 |
+
// will check if path children match
|
186 |
+
foreach ($this->absolutePathRules as $rule) {
|
187 |
+
if ($this->strUtils->startsWith($path, $rule . '/')) {
|
188 |
+
return true;
|
189 |
+
}
|
190 |
+
}
|
191 |
+
|
192 |
+
return false;
|
193 |
+
}
|
194 |
+
|
195 |
+
/**
|
196 |
+
* Check whether the given path satisfy any glob pattern
|
197 |
+
*
|
198 |
+
* @param string $path
|
199 |
+
* @return boolean
|
200 |
+
*/
|
201 |
+
protected function isGlobPatternMatched($path)
|
202 |
+
{
|
203 |
+
foreach ($this->globRules as $rule) {
|
204 |
+
if (preg_match($rule, $path)) {
|
205 |
+
return true;
|
206 |
+
}
|
207 |
+
}
|
208 |
+
|
209 |
+
return false;
|
210 |
+
}
|
211 |
+
|
212 |
+
/**
|
213 |
+
* Check whether the path is glob pattern
|
214 |
+
*
|
215 |
+
* @param string $pattern
|
216 |
+
* @return boolean
|
217 |
+
*/
|
218 |
+
protected function isGlobPattern($pattern)
|
219 |
+
{
|
220 |
+
return false !== strpos($pattern, '*') || false !== strpos($pattern, '{') || false !== strpos($pattern, '?') || false !== strpos($pattern, '[');
|
221 |
+
}
|
222 |
+
|
223 |
+
/**
|
224 |
+
* Convert symfony glob pattern converted regex to support wildcard path regex
|
225 |
+
*
|
226 |
+
* @param string $pattern
|
227 |
+
* @return string
|
228 |
+
*/
|
229 |
+
protected function wildcardGlobToRegex($pattern)
|
230 |
+
{
|
231 |
+
// Make /**/ to work as anywhere exclude for Symfony Glob
|
232 |
+
if (strpos($pattern, '/(?=[^\.])[^/]*[^/]*/(?=[^\.])') !== false) {
|
233 |
+
$pattern = str_replace('/(?=[^\.])[^/]*[^/]*/(?=[^\.])', '/([^/]+/)*', $pattern);
|
234 |
+
}
|
235 |
+
|
236 |
+
// Make /** to allow exclude/include children as well
|
237 |
+
if (strpos($pattern, '/(?=[^\.])[^/]*[^/]*') !== false) {
|
238 |
+
$pattern = str_replace('/(?=[^\.])[^/]*[^/]*', '/(.*)', $pattern);
|
239 |
+
}
|
240 |
+
|
241 |
+
return $pattern;
|
242 |
+
}
|
243 |
+
|
244 |
+
/**
|
245 |
+
* Is /** be appended to allow matching of children
|
246 |
+
*
|
247 |
+
* @param string $rule
|
248 |
+
* @return boolean
|
249 |
+
*/
|
250 |
+
protected function isChildrenMatchingAllow($rule)
|
251 |
+
{
|
252 |
+
$rule = rtrim($rule, '/');
|
253 |
+
$segments = explode('/', $rule);
|
254 |
+
$lastSegment = $segments[count($segments) - 1];
|
255 |
+
// Already allowed
|
256 |
+
if ($lastSegment === '**') {
|
257 |
+
return false;
|
258 |
+
}
|
259 |
+
|
260 |
+
return (strpos($lastSegment, '.') === false);
|
261 |
+
}
|
262 |
+
}
|
Framework/Filesystem/Filters/RecursiveFileSizeFilter.php
ADDED
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WPStaging\Framework\Filesystem\Filters;
|
4 |
+
|
5 |
+
use RecursiveFilterIterator;
|
6 |
+
use RecursiveDirectoryIterator;
|
7 |
+
|
8 |
+
class RecursiveFileSizeFilter extends RecursiveFilterIterator
|
9 |
+
{
|
10 |
+
private $sizeFilters = [];
|
11 |
+
public function __construct(RecursiveDirectoryIterator $iterator, $sizeFilters = [])
|
12 |
+
{
|
13 |
+
parent::__construct($iterator);
|
14 |
+
$this->sizeFilters = $sizeFilters;
|
15 |
+
}
|
16 |
+
|
17 |
+
public function accept()
|
18 |
+
{
|
19 |
+
$current = $this->current();
|
20 |
+
|
21 |
+
if (!$current->isFile()) {
|
22 |
+
return true;
|
23 |
+
}
|
24 |
+
|
25 |
+
$fileSize = $current->getSize();
|
26 |
+
foreach ($this->sizeFilters as $sizeFilter) {
|
27 |
+
$sizeComparator = explode(' ', $sizeFilter);
|
28 |
+
if (count($sizeComparator) !== 2) {
|
29 |
+
continue;
|
30 |
+
}
|
31 |
+
|
32 |
+
if ($this->compareBytes($fileSize, $sizeComparator[1], $sizeComparator[0])) {
|
33 |
+
return false;
|
34 |
+
}
|
35 |
+
}
|
36 |
+
|
37 |
+
return true;
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Compare Bytes
|
42 |
+
*
|
43 |
+
* @param string|int $compare
|
44 |
+
* @param string|int $compareWith
|
45 |
+
* @param string $comparator
|
46 |
+
* @return bool
|
47 |
+
*/
|
48 |
+
public function compareBytes($compare, $compareWith, $comparator = '=')
|
49 |
+
{
|
50 |
+
$compare = wp_convert_hr_to_bytes($compare);
|
51 |
+
$compareWith = wp_convert_hr_to_bytes($compareWith);
|
52 |
+
|
53 |
+
// comparison for equal to
|
54 |
+
if (($comparator === '=' || $comparator === ExcludeFilter::SIZE_EQUAL_TO) && ($compare == $compareWith)) {
|
55 |
+
return true;
|
56 |
+
}
|
57 |
+
|
58 |
+
// comparison for greater than
|
59 |
+
if (($comparator === '>' || $comparator === ExcludeFilter::SIZE_GREATER_THAN) && ($compare > $compareWith)) {
|
60 |
+
return true;
|
61 |
+
}
|
62 |
+
|
63 |
+
// comparison for less than
|
64 |
+
if (($comparator === '<' || $comparator === ExcludeFilter::SIZE_LESS_THAN) && ($compare < $compareWith)) {
|
65 |
+
return true;
|
66 |
+
}
|
67 |
+
|
68 |
+
return false;
|
69 |
+
}
|
70 |
+
|
71 |
+
public function getChildren()
|
72 |
+
{
|
73 |
+
return new self($this->getInnerIterator()->getChildren(), $this->sizeFilters);
|
74 |
+
}
|
75 |
+
}
|
Framework/Filesystem/Filters/RecursivePathExcludeFilter.php
CHANGED
@@ -4,30 +4,79 @@ namespace WPStaging\Framework\Filesystem\Filters;
|
|
4 |
|
5 |
use RecursiveFilterIterator;
|
6 |
use RecursiveDirectoryIterator;
|
7 |
-
use WPStaging\Framework\Traits\ExcludeFilterTrait;
|
8 |
|
9 |
class RecursivePathExcludeFilter extends RecursiveFilterIterator
|
10 |
{
|
11 |
-
|
12 |
-
|
|
|
13 |
protected $excludePaths = [];
|
14 |
|
15 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
{
|
17 |
parent::__construct($iterator);
|
18 |
$this->excludePaths = $excludePaths;
|
19 |
-
$this->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
}
|
21 |
|
22 |
public function accept()
|
23 |
{
|
24 |
// Get the current SplFileInfo object
|
25 |
$fileInfo = $this->getInnerIterator()->current();
|
26 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
}
|
28 |
|
29 |
public function getChildren()
|
30 |
{
|
31 |
-
return new self($this->getInnerIterator()->getChildren(), $this->excludePaths);
|
32 |
}
|
33 |
}
|
4 |
|
5 |
use RecursiveFilterIterator;
|
6 |
use RecursiveDirectoryIterator;
|
|
|
7 |
|
8 |
class RecursivePathExcludeFilter extends RecursiveFilterIterator
|
9 |
{
|
10 |
+
/**
|
11 |
+
* @var array
|
12 |
+
*/
|
13 |
protected $excludePaths = [];
|
14 |
|
15 |
+
/**
|
16 |
+
* @var PathFilterHelper
|
17 |
+
*/
|
18 |
+
protected $excludeFilter;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @var PathFilterHelper
|
22 |
+
*/
|
23 |
+
protected $includeFilter;
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @var string
|
27 |
+
*/
|
28 |
+
protected $wpRootPath = ABSPATH;
|
29 |
+
|
30 |
+
public function __construct(RecursiveDirectoryIterator $iterator, $excludePaths = [], $wpRootPath = ABSPATH)
|
31 |
{
|
32 |
parent::__construct($iterator);
|
33 |
$this->excludePaths = $excludePaths;
|
34 |
+
$this->excludeFilter = new PathFilterHelper();
|
35 |
+
$this->includeFilter = new PathFilterHelper(true);
|
36 |
+
$this->setWpRootPath($wpRootPath);
|
37 |
+
$this->excludeFilter->categorizeRules($excludePaths);
|
38 |
+
$this->includeFilter->categorizeRules($excludePaths);
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Set the WP Root Path
|
43 |
+
* @param string $wpRootPath
|
44 |
+
*/
|
45 |
+
public function setWpRootPath($wpRootPath)
|
46 |
+
{
|
47 |
+
$this->wpRootPath = $wpRootPath;
|
48 |
+
$this->excludeFilter->setWpRootPath($wpRootPath);
|
49 |
+
$this->includeFilter->setWpRootPath($wpRootPath);
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Get the WP Root Path
|
54 |
+
* @return string
|
55 |
+
*/
|
56 |
+
public function getWpRootPath()
|
57 |
+
{
|
58 |
+
return $this->wpRootPath;
|
59 |
}
|
60 |
|
61 |
public function accept()
|
62 |
{
|
63 |
// Get the current SplFileInfo object
|
64 |
$fileInfo = $this->getInnerIterator()->current();
|
65 |
+
if ($this->includeFilter->hasRules()) {
|
66 |
+
if ($this->includeFilter->isMatched($fileInfo)) {
|
67 |
+
return true;
|
68 |
+
}
|
69 |
+
|
70 |
+
if ($fileInfo->isDir()) {
|
71 |
+
return true;
|
72 |
+
}
|
73 |
+
}
|
74 |
+
|
75 |
+
return !$this->excludeFilter->isMatched($fileInfo);
|
76 |
}
|
77 |
|
78 |
public function getChildren()
|
79 |
{
|
80 |
+
return new self($this->getInnerIterator()->getChildren(), $this->excludePaths, $this->getWpRootPath());
|
81 |
}
|
82 |
}
|
Framework/Filesystem/Scanning/ScanConst.php
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
namespace WPStaging\Framework\Filesystem\Scanning;
|
4 |
+
|
5 |
+
class ScanConst
|
6 |
+
{
|
7 |
+
/**
|
8 |
+
* separator to separate directories
|
9 |
+
* @var string
|
10 |
+
*/
|
11 |
+
const DIRECTORIES_SEPARATOR = ',';
|
12 |
+
}
|
Framework/Filesystem/WpUploadsFolderSymlinker.php
CHANGED
@@ -49,26 +49,25 @@ class WpUploadsFolderSymlinker
|
|
49 |
public function trySymlink()
|
50 |
{
|
51 |
if (is_link($this->stagingUploadPath)) {
|
52 |
-
$this->error = "Link already exists";
|
53 |
return false;
|
54 |
}
|
55 |
|
56 |
if (file_exists($this->stagingUploadPath)) {
|
57 |
-
$this->error = "
|
58 |
return false;
|
59 |
}
|
60 |
|
61 |
-
$uploadPath = $this->wpDirectories->getUploadsPath();
|
62 |
|
63 |
(new Filesystem())->mkdir(dirname($this->stagingUploadPath));
|
64 |
|
65 |
-
|
66 |
-
|
67 |
-
return
|
68 |
}
|
69 |
|
70 |
-
$this->
|
71 |
-
return true;
|
72 |
}
|
73 |
|
74 |
/**
|
@@ -78,4 +77,50 @@ class WpUploadsFolderSymlinker
|
|
78 |
{
|
79 |
return $this->error;
|
80 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
81 |
}
|
49 |
public function trySymlink()
|
50 |
{
|
51 |
if (is_link($this->stagingUploadPath)) {
|
52 |
+
$this->error = __("Link already exists", 'wp-staging');
|
53 |
return false;
|
54 |
}
|
55 |
|
56 |
if (file_exists($this->stagingUploadPath)) {
|
57 |
+
$this->error = __("Path exists at link path", 'wp-staging');
|
58 |
return false;
|
59 |
}
|
60 |
|
61 |
+
$uploadPath = rtrim($this->wpDirectories->getUploadsPath(), '/\\');
|
62 |
|
63 |
(new Filesystem())->mkdir(dirname($this->stagingUploadPath));
|
64 |
|
65 |
+
// try symlink with exec(ln) if exec is enabled and user is on windows
|
66 |
+
if ((stripos(PHP_OS, 'WIN') === 0) && $this->isExecEnabled()) {
|
67 |
+
return $this->linkWithExec($uploadPath, $this->stagingUploadPath);
|
68 |
}
|
69 |
|
70 |
+
return $this->link($uploadPath, $this->stagingUploadPath);
|
|
|
71 |
}
|
72 |
|
73 |
/**
|
77 |
{
|
78 |
return $this->error;
|
79 |
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Try symlinking with exec
|
83 |
+
*
|
84 |
+
* @param string $source
|
85 |
+
* @param string $destination
|
86 |
+
* @return boolean
|
87 |
+
*/
|
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());
|
95 |
+
return false;
|
96 |
+
}
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Try symlinking with php function
|
101 |
+
*
|
102 |
+
* @param string $source
|
103 |
+
* @param string $destination
|
104 |
+
* @return boolean
|
105 |
+
*/
|
106 |
+
private function link($source, $destination)
|
107 |
+
{
|
108 |
+
try {
|
109 |
+
symlink($source, $destination);
|
110 |
+
return true;
|
111 |
+
} catch (FatalException $ex) {
|
112 |
+
$this->error = sprintf(__("Can not symlink %s. Error: ", 'wp-staging'), $destination, $ex->getMessage());
|
113 |
+
return false;
|
114 |
+
}
|
115 |
+
}
|
116 |
+
|
117 |
+
private function isExecEnabled()
|
118 |
+
{
|
119 |
+
if (!function_exists('exec')) {
|
120 |
+
return false;
|
121 |
+
}
|
122 |
+
|
123 |
+
$disabled = explode(',', ini_get('disable_functions'));
|
124 |
+
return !in_array('exec', $disabled);
|
125 |
+
}
|
126 |
}
|
Framework/Traits/DbRowsGeneratorTrait.php
CHANGED
@@ -38,7 +38,7 @@ trait DbRowsGeneratorTrait
|
|
38 |
*/
|
39 |
protected function rowsGenerator($table, $offset, $limit, \wpdb $db = null)
|
40 |
{
|
41 |
-
if (defined('WPSTG_DEBUG') && WPSTG_DEBUG) {
|
42 |
error_log(
|
43 |
sprintf(
|
44 |
'DbRowsGeneratorTrait: max-memory-limit=%s; script-memory-limit=%s; memory-usage=%s; execution-time-limit=%s; running-time=%s; is-threshold=%s',
|
@@ -50,7 +50,7 @@ trait DbRowsGeneratorTrait
|
|
50 |
($this->isThreshold() ? 'yes' : 'no')
|
51 |
)
|
52 |
);
|
53 |
-
}
|
54 |
|
55 |
|
56 |
if (null === $db) {
|
38 |
*/
|
39 |
protected function rowsGenerator($table, $offset, $limit, \wpdb $db = null)
|
40 |
{
|
41 |
+
/* if (defined('WPSTG_DEBUG') && WPSTG_DEBUG) {
|
42 |
error_log(
|
43 |
sprintf(
|
44 |
'DbRowsGeneratorTrait: max-memory-limit=%s; script-memory-limit=%s; memory-usage=%s; execution-time-limit=%s; running-time=%s; is-threshold=%s',
|
50 |
($this->isThreshold() ? 'yes' : 'no')
|
51 |
)
|
52 |
);
|
53 |
+
}*/
|
54 |
|
55 |
|
56 |
if (null === $db) {
|
Framework/Traits/ExcludeFilterTrait.php
DELETED
@@ -1,141 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
namespace WPStaging\Framework\Traits;
|
4 |
-
|
5 |
-
use WPStaging\Framework\Utils\Strings;
|
6 |
-
|
7 |
-
/**
|
8 |
-
* This trait is used in both RecursivePathExcludeFilter and PathExcludeFilter
|
9 |
-
* This will help in keeping the code DRY
|
10 |
-
*/
|
11 |
-
trait ExcludeFilterTrait
|
12 |
-
{
|
13 |
-
/**
|
14 |
-
* @var array
|
15 |
-
*/
|
16 |
-
private $extensionExcludes;
|
17 |
-
|
18 |
-
/**
|
19 |
-
* @var array
|
20 |
-
*/
|
21 |
-
private $absolutePathExcludes;
|
22 |
-
|
23 |
-
/**
|
24 |
-
* @var array
|
25 |
-
*/
|
26 |
-
private $anywherePathExcludes;
|
27 |
-
|
28 |
-
/**
|
29 |
-
* Categories Exclude in array
|
30 |
-
*
|
31 |
-
* @param array $excludes
|
32 |
-
*/
|
33 |
-
protected function categorizeExcludes($excludes)
|
34 |
-
{
|
35 |
-
$this->extensionExcludes = [];
|
36 |
-
$this->absolutePathExcludes = [];
|
37 |
-
$this->anywherePathExcludes = [];
|
38 |
-
$strUtils = new Strings();
|
39 |
-
foreach ($excludes as $exclude) {
|
40 |
-
// *. is to check whether the exclude is extension exclude or not,
|
41 |
-
// If it is extension exclude then add to extension exclude array and move to next exclude
|
42 |
-
if ($strUtils->startsWith($exclude, '*.')) {
|
43 |
-
$this->extensionExcludes[] = $exclude;
|
44 |
-
continue;
|
45 |
-
}
|
46 |
-
|
47 |
-
// **/ is to check whether the exclude is anywhere/wildcard exclude or not,
|
48 |
-
// If it is anywhere exclude then add to anywhere exclude array and move to next exclude
|
49 |
-
if ($strUtils->startsWith($exclude, '**/')) {
|
50 |
-
$this->anywherePathExcludes[] = $exclude;
|
51 |
-
continue;
|
52 |
-
}
|
53 |
-
|
54 |
-
// If the exclude doesn't matches extension or anywhere exclude treat it as absolute path exclude
|
55 |
-
$this->absolutePathExcludes[] = $exclude;
|
56 |
-
}
|
57 |
-
}
|
58 |
-
|
59 |
-
/**
|
60 |
-
* Check whether the file extension satisfy any extension exclusion
|
61 |
-
*
|
62 |
-
* @param string $fileExt
|
63 |
-
* @return boolean
|
64 |
-
*/
|
65 |
-
protected function isExcludedExtension($fileExt)
|
66 |
-
{
|
67 |
-
$fileExt = '*.' . $fileExt;
|
68 |
-
return in_array($fileExt, $this->extensionExcludes);
|
69 |
-
}
|
70 |
-
|
71 |
-
/**
|
72 |
-
* Check whether the given path satisfy any absolute path exclusion
|
73 |
-
*
|
74 |
-
* @param string $path
|
75 |
-
* @return boolean
|
76 |
-
*/
|
77 |
-
protected function isExcludedAbsolutePath($path)
|
78 |
-
{
|
79 |
-
foreach ($this->absolutePathExcludes as $exclude) {
|
80 |
-
if ((new Strings())->startsWith($path, $exclude)) {
|
81 |
-
return true;
|
82 |
-
}
|
83 |
-
}
|
84 |
-
|
85 |
-
return false;
|
86 |
-
}
|
87 |
-
|
88 |
-
/**
|
89 |
-
* Check whether the given path satisfy any anywhere path exclusion
|
90 |
-
*
|
91 |
-
* @param string $path
|
92 |
-
* @return boolean
|
93 |
-
*/
|
94 |
-
protected function isExcludedAnywherePath($path)
|
95 |
-
{
|
96 |
-
if (is_dir($path)) {
|
97 |
-
$path = trailingslashit($path);
|
98 |
-
}
|
99 |
-
|
100 |
-
foreach ($this->anywherePathExcludes as $exclude) {
|
101 |
-
$exclude = ltrim($exclude, '**');
|
102 |
-
if (is_dir($path)) {
|
103 |
-
$exclude = trailingslashit($exclude);
|
104 |
-
}
|
105 |
-
|
106 |
-
if (strpos($path, $exclude) !== false) {
|
107 |
-
return true;
|
108 |
-
}
|
109 |
-
}
|
110 |
-
|
111 |
-
return false;
|
112 |
-
}
|
113 |
-
|
114 |
-
/**
|
115 |
-
* Check whether the file meets any of the exclude criteria
|
116 |
-
* @param SplFileInfo $fileInfo
|
117 |
-
*
|
118 |
-
* @return boolean
|
119 |
-
*/
|
120 |
-
protected function isExcluded($fileInfo)
|
121 |
-
{
|
122 |
-
$path = $fileInfo->getPathname();
|
123 |
-
|
124 |
-
// Check extension
|
125 |
-
if ($this->isExcludedExtension($fileInfo->getExtension())) {
|
126 |
-
return true;
|
127 |
-
}
|
128 |
-
|
129 |
-
// Check absolute path
|
130 |
-
if ($this->isExcludedAbsolutePath($path)) {
|
131 |
-
return true;
|
132 |
-
}
|
133 |
-
|
134 |
-
// Check anywhere path
|
135 |
-
if ($this->isExcludedAnywherePath($path)) {
|
136 |
-
return true;
|
137 |
-
}
|
138 |
-
|
139 |
-
return false;
|
140 |
-
}
|
141 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Framework/Traits/FileScanToCacheTrait.php
CHANGED
@@ -4,7 +4,7 @@ namespace WPStaging\Framework\Traits;
|
|
4 |
|
5 |
use Exception;
|
6 |
use stdClass;
|
7 |
-
use WPStaging\
|
8 |
use WPStaging\Framework\Filesystem\FilterableDirectoryIterator;
|
9 |
use WPStaging\Framework\Utils\Strings;
|
10 |
|
@@ -27,11 +27,12 @@ trait FileScanToCacheTrait
|
|
27 |
* @param string $path
|
28 |
* @param bool $isRecursive
|
29 |
* @param array $excludePaths absolute path of dir/files to exclude
|
|
|
30 |
* @param string $wpRootPath
|
31 |
*
|
32 |
* @return int count of files path written to cache file
|
33 |
*/
|
34 |
-
public function scanToCacheFile($filesHandle, $path, $isRecursive = false, $excludePaths = [], $wpRootPath = ABSPATH)
|
35 |
{
|
36 |
if (is_link($path)) {
|
37 |
return 0;
|
@@ -53,7 +54,11 @@ trait FileScanToCacheTrait
|
|
53 |
->setRecursive(false)
|
54 |
->setDotSkip()
|
55 |
->setExcludePaths($excludePaths)
|
|
|
|
|
56 |
->get();
|
|
|
|
|
57 |
foreach ($iterator as $item) {
|
58 |
// Always check link first otherwise it may be treated as directory
|
59 |
if ($item->isLink()) {
|
@@ -61,7 +66,7 @@ trait FileScanToCacheTrait
|
|
61 |
}
|
62 |
|
63 |
if ($isRecursive && $item->isDir()) {
|
64 |
-
$filesWrittenToCache += $this->scanToCacheFile($filesHandle, $item->getPathname(), $isRecursive, $excludePaths, $wpRootPath);
|
65 |
}
|
66 |
|
67 |
if ($item->isFile()) {
|
@@ -74,40 +79,4 @@ trait FileScanToCacheTrait
|
|
74 |
|
75 |
return $filesWrittenToCache;
|
76 |
}
|
77 |
-
|
78 |
-
/**
|
79 |
-
* Filtered directories according to the directory given
|
80 |
-
* @param string $directoryPath
|
81 |
-
* @param array $directories list of selected directories in the form of directoryPath . separatorConst . scanFlag e.g. /var/www/wp-content/plugins/::1
|
82 |
-
*
|
83 |
-
* @return array
|
84 |
-
*/
|
85 |
-
public function filteredSelectedDirectories($directoryPath, $directories)
|
86 |
-
{
|
87 |
-
$strUtil = new Strings();
|
88 |
-
$directoryPath = $strUtil->sanitizeDirectorySeparator($directoryPath);
|
89 |
-
return array_filter($this->mapSelectedDirectories($directories), function ($directory) use ($directoryPath, $strUtil) {
|
90 |
-
if ($strUtil->startsWith($strUtil->sanitizeDirectorySeparator($directory->path), $directoryPath)) {
|
91 |
-
return true;
|
92 |
-
}
|
93 |
-
});
|
94 |
-
}
|
95 |
-
|
96 |
-
/**
|
97 |
-
* Map included directories to object
|
98 |
-
* @param array $directories list of selected directories in the form of directoryPath . separatorConst . scanFlag
|
99 |
-
*
|
100 |
-
* @return array array of objects which contains information about directory path and whether it is scanned or not
|
101 |
-
*/
|
102 |
-
protected function mapSelectedDirectories($directories)
|
103 |
-
{
|
104 |
-
return array_map(function ($directory) {
|
105 |
-
$directory = trim($directory, ' ');
|
106 |
-
list($directoryPath, $flag) = explode(Scan::DIRECTORY_PATH_FLAG_SEPARATOR, $directory);
|
107 |
-
$directoryInfo = new stdClass();
|
108 |
-
$directoryInfo->path = trim($directoryPath, ' ');
|
109 |
-
$directoryInfo->flag = trim($flag, ' ');
|
110 |
-
return $directoryInfo;
|
111 |
-
}, $directories);
|
112 |
-
}
|
113 |
}
|
4 |
|
5 |
use Exception;
|
6 |
use stdClass;
|
7 |
+
use WPStaging\Framework\Filesystem\Scanning\ScanConst;
|
8 |
use WPStaging\Framework\Filesystem\FilterableDirectoryIterator;
|
9 |
use WPStaging\Framework\Utils\Strings;
|
10 |
|
27 |
* @param string $path
|
28 |
* @param bool $isRecursive
|
29 |
* @param array $excludePaths absolute path of dir/files to exclude
|
30 |
+
* @param array $excludeSizeRules exclude files by different size comparing rules
|
31 |
* @param string $wpRootPath
|
32 |
*
|
33 |
* @return int count of files path written to cache file
|
34 |
*/
|
35 |
+
public function scanToCacheFile($filesHandle, $path, $isRecursive = false, $excludePaths = [], $excludeSizeRules = [], $wpRootPath = ABSPATH)
|
36 |
{
|
37 |
if (is_link($path)) {
|
38 |
return 0;
|
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()) {
|
66 |
}
|
67 |
|
68 |
if ($isRecursive && $item->isDir()) {
|
69 |
+
$filesWrittenToCache += $this->scanToCacheFile($filesHandle, $item->getPathname(), $isRecursive, $excludePaths, $excludeSizeRules, $wpRootPath);
|
70 |
}
|
71 |
|
72 |
if ($item->isFile()) {
|
79 |
|
80 |
return $filesWrittenToCache;
|
81 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
}
|
Framework/Traits/PropertyConstructor.php
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Provides methods to build a value object from a map of values that will be mapped
|
5 |
+
* to the object properties.
|
6 |
+
*
|
7 |
+
* @package WPStaging\Framework\Traits
|
8 |
+
*/
|
9 |
+
|
10 |
+
namespace WPStaging\Framework\Traits;
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Trait PropertyConstructor
|
14 |
+
*
|
15 |
+
* @package WPStaging\Framework\Traits
|
16 |
+
*/
|
17 |
+
trait PropertyConstructor
|
18 |
+
{
|
19 |
+
|
20 |
+
/**
|
21 |
+
* JobArguments constructor.
|
22 |
+
*
|
23 |
+
* @param array<string,mixed> $props A map from the property names to their values.
|
24 |
+
*/
|
25 |
+
public function __construct(array $props = [])
|
26 |
+
{
|
27 |
+
foreach ($props as $prop => $value) {
|
28 |
+
if (property_exists($this, $prop)) {
|
29 |
+
$this->{$prop} = $value;
|
30 |
+
}
|
31 |
+
}
|
32 |
+
}
|
33 |
+
}
|
Framework/Utils/Cache/AbstractCache.php
CHANGED
@@ -7,7 +7,7 @@
|
|
7 |
namespace WPStaging\Framework\Utils\Cache;
|
8 |
|
9 |
use WPStaging\Framework\Filesystem\Filesystem;
|
10 |
-
use WPStaging\
|
11 |
use WPStaging\Framework\Adapter\Directory;
|
12 |
|
13 |
abstract class AbstractCache
|
7 |
namespace WPStaging\Framework\Utils\Cache;
|
8 |
|
9 |
use WPStaging\Framework\Filesystem\Filesystem;
|
10 |
+
use WPStaging\Framework\Exceptions\IOException;
|
11 |
use WPStaging\Framework\Adapter\Directory;
|
12 |
|
13 |
abstract class AbstractCache
|
Framework/Utils/Cache/BufferedCache.php
CHANGED
@@ -8,7 +8,7 @@ namespace WPStaging\Framework\Utils\Cache;
|
|
8 |
|
9 |
use LimitIterator;
|
10 |
use SplFileObject;
|
11 |
-
use WPStaging\
|
12 |
use WPStaging\Framework\Filesystem\File;
|
13 |
use WPStaging\Framework\Filesystem\Filesystem;
|
14 |
|
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 |
|
Framework/Utils/SlashMode.php
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// TODO PHP7.x; declare(strict_types=1);
|
4 |
+
namespace WPStaging\Framework\Utils;
|
5 |
+
|
6 |
+
// TODO PHP7.1; constant visibility
|
7 |
+
/**
|
8 |
+
* This class is mainly used as a enum to provide SLASH MODE
|
9 |
+
*/
|
10 |
+
class SlashMode
|
11 |
+
{
|
12 |
+
/**
|
13 |
+
* Make path have no leading and trailing slashes
|
14 |
+
* @var int
|
15 |
+
*/
|
16 |
+
const NO_SLASH = 0;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Make path have only leading slash but no trailing slash
|
20 |
+
* @var int
|
21 |
+
*/
|
22 |
+
const LEADING_SLASH = -1;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Make path have only trailing slash but no leading slash
|
26 |
+
* @var int
|
27 |
+
*/
|
28 |
+
const TRAILING_SLASH = 1;
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Make path have both slashes i.e. trailing slash and leading slash
|
32 |
+
* @var int
|
33 |
+
*/
|
34 |
+
const BOTH_SLASHES = 2;
|
35 |
+
}
|
{vendor_wpstg/symfony/finder → Framework/Utils/ThirdParty}/Glob.php
RENAMED
@@ -1,14 +1,10 @@
|
|
1 |
<?php
|
2 |
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
*
|
7 |
-
*
|
8 |
-
* For the full copyright and license information, please view the LICENSE
|
9 |
-
* file that was distributed with this source code.
|
10 |
*/
|
11 |
-
namespace WPStaging\Vendor\Symfony\Component\Finder;
|
12 |
|
13 |
/**
|
14 |
* Glob matches globbing patterns against text.
|
1 |
<?php
|
2 |
|
3 |
+
namespace WPStaging\Framework\Utils\ThirdParty;
|
4 |
+
|
5 |
+
/**
|
6 |
+
* This is a port of Symfony\Component\Finder\Glob.
|
|
|
|
|
|
|
7 |
*/
|
|
|
8 |
|
9 |
/**
|
10 |
* Glob matches globbing patterns against text.
|
Framework/Utils/WpDefaultDirectories.php
CHANGED
@@ -5,7 +5,8 @@
|
|
5 |
namespace WPStaging\Framework\Utils;
|
6 |
|
7 |
use DirectoryIterator;
|
8 |
-
use WPStaging\
|
|
|
9 |
|
10 |
// TODO PHP7.1; constant visibility
|
11 |
class WpDefaultDirectories
|
@@ -64,15 +65,21 @@ class WpDefaultDirectories
|
|
64 |
* `wp-content/uploads`
|
65 |
* `wp-content/uploads/sites/2`
|
66 |
*
|
67 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
68 |
*
|
69 |
* @return string
|
70 |
*/
|
71 |
-
public function getRelativeUploadPath()
|
72 |
{
|
73 |
$relPath = str_replace($this->wpRoot, null, $this->getUploadsPath());
|
74 |
|
75 |
-
return
|
76 |
}
|
77 |
|
78 |
/*
|
@@ -126,41 +133,57 @@ class WpDefaultDirectories
|
|
126 |
|
127 |
/**
|
128 |
* Get the relative path of wp content directory
|
|
|
|
|
|
|
|
|
|
|
129 |
* @return string
|
130 |
*/
|
131 |
-
public function getRelativeWpContentPath()
|
132 |
{
|
133 |
$wpContentDir = $this->strUtils->sanitizeDirectorySeparator(WP_CONTENT_DIR);
|
134 |
$relPath = str_replace($this->wpRoot, null, $wpContentDir);
|
135 |
|
136 |
-
return
|
137 |
}
|
138 |
|
139 |
/**
|
140 |
* Get the relative path of plugins directory
|
|
|
|
|
|
|
|
|
|
|
141 |
* @return string
|
142 |
*/
|
143 |
-
public function getRelativePluginPath()
|
144 |
{
|
145 |
$wpPluginDir = $this->strUtils->sanitizeDirectorySeparator(WP_PLUGIN_DIR);
|
146 |
$relPath = str_replace($this->wpRoot, null, $wpPluginDir);
|
147 |
|
148 |
-
return
|
149 |
}
|
150 |
|
151 |
/**
|
152 |
* Get the relative path of themes directory
|
|
|
|
|
|
|
|
|
|
|
153 |
* @return string
|
154 |
*/
|
155 |
-
public function getRelativeThemePath()
|
156 |
{
|
157 |
-
$
|
158 |
-
|
|
|
159 |
}
|
160 |
|
161 |
/**
|
162 |
-
* Get array of wp core directories
|
163 |
-
* i.e. wp-content, wp-admin, wp-includes
|
164 |
*
|
165 |
* @return array
|
166 |
*/
|
@@ -190,115 +213,60 @@ class WpDefaultDirectories
|
|
190 |
continue;
|
191 |
}
|
192 |
|
193 |
-
$this->
|
|
|
194 |
}
|
195 |
|
196 |
-
// Gather Plugins
|
197 |
-
$pluginsDir = $this->wpRoot . $this->getRelativePluginPath();
|
198 |
-
$this->handleSelfAndSubDirs($pluginsDir);
|
199 |
-
|
200 |
-
// Gather Themes
|
201 |
-
$themesDir = $this->wpRoot . $this->getRelativeThemePath();
|
202 |
-
$this->handleSelfAndSubDirs($themesDir);
|
203 |
-
|
204 |
-
// Gather Uploads
|
205 |
-
$this->handleSelfAndSubDirs($this->getUploadsPath());
|
206 |
-
|
207 |
return $this->coreDirectories;
|
208 |
}
|
209 |
|
210 |
/**
|
211 |
-
*
|
212 |
*
|
213 |
-
* @param string $
|
214 |
-
|
215 |
-
protected function handleSelfAndSubDirs($path)
|
216 |
-
{
|
217 |
-
$this->addDirectoryToList($path, Scan::IS_NON_RECURSIVE);
|
218 |
-
$directories = new DirectoryIterator($path);
|
219 |
-
foreach ($directories as $directory) {
|
220 |
-
if ($directory->isDot() || $directory->isFile() || $directory->isLink()) {
|
221 |
-
continue;
|
222 |
-
}
|
223 |
-
|
224 |
-
$this->addDirectoryToList($directory->getPathname(), Scan::IS_RECURSIVE);
|
225 |
-
}
|
226 |
-
}
|
227 |
-
|
228 |
-
/**
|
229 |
-
* Add directory if not already exist
|
230 |
-
* Override the flag value with scanned only if directory already present and was scanned
|
231 |
*
|
232 |
-
* @
|
233 |
-
* @param int $flag
|
234 |
*/
|
235 |
-
|
236 |
{
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
if (in_array($dirInfo, $this->coreDirectories)) {
|
241 |
-
return;
|
242 |
-
}
|
243 |
-
|
244 |
-
if (in_array($path . Scan::DIRECTORY_PATH_FLAG_SEPARATOR . Scan::IS_NON_RECURSIVE, $this->coreDirectories)) {
|
245 |
-
return;
|
246 |
}
|
247 |
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
return;
|
253 |
-
}
|
254 |
-
}
|
255 |
-
}
|
256 |
|
257 |
-
|
258 |
}
|
259 |
|
260 |
/**
|
261 |
-
*
|
262 |
-
*
|
263 |
-
* @param
|
264 |
-
*
|
265 |
-
*
|
266 |
-
*
|
267 |
-
*
|
|
|
268 |
*/
|
269 |
-
|
270 |
{
|
271 |
-
$
|
272 |
-
if (
|
273 |
-
return $
|
274 |
}
|
275 |
|
276 |
-
if ($
|
277 |
-
$
|
278 |
-
$directories = array_map(function ($directory) {
|
279 |
-
return $this->wpRoot . $directory;
|
280 |
-
}, $directories);
|
281 |
-
|
282 |
-
return $directories;
|
283 |
}
|
284 |
|
285 |
-
$
|
286 |
-
|
287 |
-
|
288 |
-
}, $excludedDirectories);
|
289 |
-
|
290 |
-
$directories = array_filter($directories, function ($directory) use ($excludedDirectories) {
|
291 |
-
$directory = explode(Scan::DIRECTORY_PATH_FLAG_SEPARATOR, $directory)[0];
|
292 |
-
foreach ($excludedDirectories as $excludedDirectory) {
|
293 |
-
$excludedDirectory = explode(Scan::DIRECTORY_PATH_FLAG_SEPARATOR, $excludedDirectory)[0];
|
294 |
-
if ($directory === $excludedDirectory) {
|
295 |
-
return false;
|
296 |
-
}
|
297 |
-
}
|
298 |
-
|
299 |
-
return true;
|
300 |
-
});
|
301 |
|
302 |
-
return
|
303 |
}
|
304 |
}
|
5 |
namespace WPStaging\Framework\Utils;
|
6 |
|
7 |
use DirectoryIterator;
|
8 |
+
use WPStaging\Framework\Filesystem\Scanning\ScanConst;
|
9 |
+
use WPStaging\Framework\Utils\SlashMode;
|
10 |
|
11 |
// TODO PHP7.1; constant visibility
|
12 |
class WpDefaultDirectories
|
65 |
* `wp-content/uploads`
|
66 |
* `wp-content/uploads/sites/2`
|
67 |
*
|
68 |
+
* Directory separator will be forward slash always for Microsoft IIS compatibility
|
69 |
+
*
|
70 |
+
* @param int $mode Optional. Slash Mode. Default SlashMode::NO_SLASH.
|
71 |
+
* Use SlashMode::NO_SLASH, if you don't want trailing and leading slash.
|
72 |
+
* Use SlashMode::TRAILING_SLASH, if you want trailing forward slash.
|
73 |
+
* Use SlashMode::LEADING_SLASH, if you want leading forward slash.
|
74 |
+
* Use SlashMode::BOTH_SLASHES, if you want both trailing and leading forward slash.
|
75 |
*
|
76 |
* @return string
|
77 |
*/
|
78 |
+
public function getRelativeUploadPath($mode = SlashMode::NO_SLASH)
|
79 |
{
|
80 |
$relPath = str_replace($this->wpRoot, null, $this->getUploadsPath());
|
81 |
|
82 |
+
return $this->slashit($relPath, $mode);
|
83 |
}
|
84 |
|
85 |
/*
|
133 |
|
134 |
/**
|
135 |
* Get the relative path of wp content directory
|
136 |
+
* @param int $mode Optional. Slash Mode. Default SlashMode::NO_SLASH.
|
137 |
+
* Use SlashMode::NO_SLASH, if you don't want trailing and leading slash.
|
138 |
+
* Use SlashMode::TRAILING_SLASH, if you want trailing forward slash.
|
139 |
+
* Use SlashMode::LEADING_SLASH, if you want leading forward slash.
|
140 |
+
* Use SlashMode::BOTH_SLASHES, if you want both trailing and leading forward slash.
|
141 |
* @return string
|
142 |
*/
|
143 |
+
public function getRelativeWpContentPath($mode = SlashMode::NO_SLASH)
|
144 |
{
|
145 |
$wpContentDir = $this->strUtils->sanitizeDirectorySeparator(WP_CONTENT_DIR);
|
146 |
$relPath = str_replace($this->wpRoot, null, $wpContentDir);
|
147 |
|
148 |
+
return $this->slashit($relPath, $mode);
|
149 |
}
|
150 |
|
151 |
/**
|
152 |
* Get the relative path of plugins directory
|
153 |
+
* @param int $mode Optional. Slash Mode. Default SlashMode::NO_SLASH.
|
154 |
+
* Use SlashMode::NO_SLASH, if you don't want trailing and leading slash.
|
155 |
+
* Use SlashMode::TRAILING_SLASH, if you want trailing forward slash.
|
156 |
+
* Use SlashMode::LEADING_SLASH, if you want leading forward slash.
|
157 |
+
* Use SlashMode::BOTH_SLASHES, if you want both trailing and leading forward slash.
|
158 |
* @return string
|
159 |
*/
|
160 |
+
public function getRelativePluginPath($mode = SlashMode::NO_SLASH)
|
161 |
{
|
162 |
$wpPluginDir = $this->strUtils->sanitizeDirectorySeparator(WP_PLUGIN_DIR);
|
163 |
$relPath = str_replace($this->wpRoot, null, $wpPluginDir);
|
164 |
|
165 |
+
return $this->slashit($relPath, $mode);
|
166 |
}
|
167 |
|
168 |
/**
|
169 |
* Get the relative path of themes directory
|
170 |
+
* @param int $mode Optional. Slash Mode. Default SlashMode::NO_SLASH.
|
171 |
+
* Use SlashMode::NO_SLASH, if you don't want trailing and leading slash.
|
172 |
+
* Use SlashMode::TRAILING_SLASH, if you want trailing forward slash.
|
173 |
+
* Use SlashMode::LEADING_SLASH, if you want leading forward slash.
|
174 |
+
* Use SlashMode::BOTH_SLASHES, if you want both trailing and leading forward slash.
|
175 |
* @return string
|
176 |
*/
|
177 |
+
public function getRelativeThemePath($mode = SlashMode::NO_SLASH)
|
178 |
{
|
179 |
+
$relPath = $this->getRelativeWpContentPath() . '/themes';
|
180 |
+
|
181 |
+
return $this->slashit($relPath, $mode);
|
182 |
}
|
183 |
|
184 |
/**
|
185 |
+
* Get array of wp core directories with flag 0|1
|
186 |
+
* i.e. wp-content, wp-admin, wp-includes
|
187 |
*
|
188 |
* @return array
|
189 |
*/
|
213 |
continue;
|
214 |
}
|
215 |
|
216 |
+
$path = untrailingslashit($this->strUtils->sanitizeDirectorySeparator($path));
|
217 |
+
$this->coreDirectories[] = $path;
|
218 |
}
|
219 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
220 |
return $this->coreDirectories;
|
221 |
}
|
222 |
|
223 |
/**
|
224 |
+
* Get excluded directories and map it to array
|
225 |
*
|
226 |
+
* @param string $directoriesRequest
|
227 |
+
* @return array
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
228 |
*
|
229 |
+
* @todo find a better place
|
|
|
230 |
*/
|
231 |
+
public function getExcludedDirectories($directoriesRequest)
|
232 |
{
|
233 |
+
if ((empty($directoriesRequest) || $directoriesRequest === '')) {
|
234 |
+
return [];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
235 |
}
|
236 |
|
237 |
+
$excludedDirectories = explode(ScanConst::DIRECTORIES_SEPARATOR, wpstg_urldecode($directoriesRequest));
|
238 |
+
$excludedDirectories = array_map(function ($directory) {
|
239 |
+
return $this->slashit($directory, SlashMode::LEADING_SLASH);
|
240 |
+
}, $excludedDirectories);
|
|
|
|
|
|
|
|
|
241 |
|
242 |
+
return $excludedDirectories;
|
243 |
}
|
244 |
|
245 |
/**
|
246 |
+
* Different slash mode for path
|
247 |
+
* @param string $path
|
248 |
+
* @param int $mode Optional. Slash Mode. Default SlashMode::NO_SLASH.
|
249 |
+
* Use SlashMode::NO_SLASH, if you don't want trailing and leading slash.
|
250 |
+
* Use SlashMode::TRAILING_SLASH, if you want trailing forward slash.
|
251 |
+
* Use SlashMode::LEADING_SLASH, if you want leading forward slash.
|
252 |
+
* Use SlashMode::BOTH_SLASHES, if you want both trailing and leading forward slash.
|
253 |
+
* @return string
|
254 |
*/
|
255 |
+
private function slashit($path, $mode = SlashMode::NO_SLASH)
|
256 |
{
|
257 |
+
$path = trim(trim($path, '\\'), '/');
|
258 |
+
if ($mode === SlashMode::BOTH_SLASHES) {
|
259 |
+
return '/' . $path . '/';
|
260 |
}
|
261 |
|
262 |
+
if ($mode === SlashMode::TRAILING_SLASH) {
|
263 |
+
return $path . '/';
|
|
|
|
|
|
|
|
|
|
|
264 |
}
|
265 |
|
266 |
+
if ($mode === SlashMode::LEADING_SLASH) {
|
267 |
+
return '/' . $path;
|
268 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
269 |
|
270 |
+
return $path;
|
271 |
}
|
272 |
}
|
README.md
CHANGED
@@ -6,6 +6,12 @@
|
|
6 |
|
7 |
This is the latest release of WP STAGING BASIC for WordPress that you can find on [wordpress.org](https://wordpress.org/plugins/wp-staging/)
|
8 |
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
## Bugs ##
|
10 |
If you find an issue, let us know [here](https://github.com/WP-Staging/wp-staging/issues?state=open)!
|
11 |
|
6 |
|
7 |
This is the latest release of WP STAGING BASIC for WordPress that you can find on [wordpress.org](https://wordpress.org/plugins/wp-staging/)
|
8 |
|
9 |
+
## About This Repository ##
|
10 |
+
|
11 |
+
This is the repository for WPSTAGING Basic. It is **generated automatically** as part of a build process that happens in the private repository of WPSTAGING Pro, where the real development happens.
|
12 |
+
|
13 |
+
In the real repository, we run thousands of quality tests using GitHub actions during development, such as code style (PHPCS), static code analysis checks (PHPSTAN), and automated unit tests (PHPUnit) and webdriver tests (Selenium), powered by wp-browser.
|
14 |
+
|
15 |
## Bugs ##
|
16 |
If you find an issue, let us know [here](https://github.com/WP-Staging/wp-staging/issues?state=open)!
|
17 |
|
assets/css/{src → dist}/wpstg-admin-feedback.css
RENAMED
@@ -37,4 +37,5 @@
|
|
37 |
padding:0px;
|
38 |
padding-bottom:50px;
|
39 |
}
|
40 |
-
}
|
|
37 |
padding:0px;
|
38 |
padding-bottom:50px;
|
39 |
}
|
40 |
+
}
|
41 |
+
/*# sourceMappingURL=wpstg-admin-feedback.css.map */
|
assets/css/dist/wpstg-admin-feedback.css.map
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
{"version":3,"sources":["wpstg-admin-feedback.css"],"names":[],"mappings":"AAAA;;CAEC;AACD;IACI,gFAAgF;IAChF,YAAY;IACZ,WAAW;IACX,eAAe,EAAE,kBAAkB;IACnC,cAAc,EAAE,eAAe;IAC/B,OAAO;IACP,MAAM;IACN,kCAAkC,EAAE,yBAAyB;IAC7D,kCAAkC,EAAE,oBAAoB;AAC5D;AACA;IACI,kBAAkB;IAClB,QAAQ,EAAE,qBAAqB;IAC/B,YAAY;IACZ,eAAe;IACf,YAAY;IACZ,gBAAgB,EAAE,+EAA+E;IACjG,eAAe;IACf,aAAa;IACb,sBAAsB;IACtB,gBAAgB;AACpB;AACA;6CAC6C,YAAY,CAAC,UAAU,EAAE;AACtE,iCAAiC,cAAc,EAAE,iBAAiB,EAAE;;AAEpE;IACI,UAAU;AACd;;AAEA;IACI;QACI,WAAW;QACX,mBAAmB;IACvB;AACJ","file":"wpstg-admin-feedback.css","sourcesContent":["/**\n PLUGINS ADMIN PAGE\n*/\n#wpstg-feedback-overlay {\n /* Height & width depends on how you want to reveal the overlay (see JS below) */ \n height: 100%;\n width: 100%;\n position: fixed; /* Stay in place */\n z-index: 10000; /* Sit on top */\n left: 0;\n top: 0;\n background-color: rgb(120,120,120); /* Black fallback color */\n background-color: rgba(0,0,0, 0.5); /* Black w/opacity */\n}\n#wpstg-feedback-content {\n position: relative;\n top: 25%; /* 25% from the top */\n width: 500px;\n max-width: 100%;\n margin: auto;\n margin-top: 30px; /* 30px top margin to avoid conflict with the close button on smaller screens */\n max-height: 50%;\n padding: 20px;\n background-color: #fff;\n overflow-y: auto;\n}\n#wpstg-feedback-content textarea,\n#wpstg-feedback-content input[type=\"text\"] { display:none;width:100%; }\n.wpstg-feedback-not-deactivate { display: block; text-align: right; }\n\n#wpstg-feedback-content h3{\n margin:5px;\n}\n\n@media screen and (max-width:400px){\n #wpstg-feedback-content {\n padding:0px;\n padding-bottom:50px;\n }\n}"]}
|
assets/css/dist/wpstg-admin-feedback.min.css
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
1 |
+
#wpstg-feedback-overlay{background-color:#787878;background-color:rgba(0,0,0,.5);height:100%;left:0;position:fixed;top:0;width:100%;z-index:10000}#wpstg-feedback-content{background-color:#fff;margin:30px auto auto;max-height:50%;max-width:100%;overflow-y:auto;padding:20px;position:relative;top:25%;width:500px}#wpstg-feedback-content input[type=text],#wpstg-feedback-content textarea{display:none;width:100%}.wpstg-feedback-not-deactivate{display:block;text-align:right}#wpstg-feedback-content h3{margin:5px}@media screen and (max-width:400px){#wpstg-feedback-content{padding:0 0 50px}}
|
2 |
+
/*# sourceMappingURL=wpstg-admin-feedback.min.css.map */
|
assets/css/dist/wpstg-admin-feedback.min.css.map
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
{"version":3,"sources":["wpstg-admin-feedback.css"],"names":[],"mappings":"AAGA,wBAQI,wBAAkC,CAClC,+BAAkC,CAPlC,WAAY,CAIZ,MAAO,CAFP,cAAe,CAGf,KAAM,CAJN,UAAW,CAEX,aAKJ,CACA,wBASI,qBAAsB,CAHtB,qBAAgB,CAChB,cAAe,CAHf,cAAe,CAMf,eAAgB,CAFhB,YAAa,CAPb,iBAAkB,CAClB,OAAQ,CACR,WAQJ,CACA,0EAC6C,YAAY,CAAC,UAAY,CACtE,+BAAiC,aAAc,CAAE,gBAAmB,CAEpE,2BACI,UACJ,CAEA,oCACI,wBAEI,gBACJ,CACJ","file":"wpstg-admin-feedback.min.css","sourcesContent":["/**\n PLUGINS ADMIN PAGE\n*/\n#wpstg-feedback-overlay {\n /* Height & width depends on how you want to reveal the overlay (see JS below) */ \n height: 100%;\n width: 100%;\n position: fixed; /* Stay in place */\n z-index: 10000; /* Sit on top */\n left: 0;\n top: 0;\n background-color: rgb(120,120,120); /* Black fallback color */\n background-color: rgba(0,0,0, 0.5); /* Black w/opacity */\n}\n#wpstg-feedback-content {\n position: relative;\n top: 25%; /* 25% from the top */\n width: 500px;\n max-width: 100%;\n margin: auto;\n margin-top: 30px; /* 30px top margin to avoid conflict with the close button on smaller screens */\n max-height: 50%;\n padding: 20px;\n background-color: #fff;\n overflow-y: auto;\n}\n#wpstg-feedback-content textarea,\n#wpstg-feedback-content input[type=\"text\"] { display:none;width:100%; }\n.wpstg-feedback-not-deactivate { display: block; text-align: right; }\n\n#wpstg-feedback-content h3{\n margin:5px;\n}\n\n@media screen and (max-width:400px){\n #wpstg-feedback-content {\n padding:0px;\n padding-bottom:50px;\n }\n}"]}
|
assets/css/{src → dist}/wpstg-admin.css
RENAMED
@@ -3,7 +3,7 @@
|
|
3 |
*
|
4 |
* @package WPSTG
|
5 |
* @subpackage Admin CSS
|
6 |
-
* @copyright Copyright (c)
|
7 |
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
8 |
*/
|
9 |
|
@@ -156,14 +156,12 @@
|
|
156 |
|
157 |
#wpstg-clonepage-wrapper {
|
158 |
margin-bottom: 20px;
|
159 |
-
/*max-width: 690px;*/
|
160 |
}
|
161 |
|
162 |
@media screen and (min-width: 1090px) {
|
163 |
#wpstg-clonepage-wrapper {
|
164 |
float: left;
|
165 |
margin-bottom: 20px;
|
166 |
-
/*width: 690px;*/
|
167 |
}
|
168 |
.wpstg-sidebar {
|
169 |
display: none;
|
@@ -253,7 +251,7 @@
|
|
253 |
|
254 |
.wpstg-clone-actions {
|
255 |
display: flex;
|
256 |
-
align-items: right
|
257 |
}
|
258 |
|
259 |
.wpstg-dropdown {
|
@@ -279,6 +277,11 @@
|
|
279 |
position: relative;
|
280 |
}
|
281 |
|
|
|
|
|
|
|
|
|
|
|
282 |
.wpstg-dropdown>.wpstg-dropdown-menu {
|
283 |
background: #fff;
|
284 |
display: none;
|
@@ -293,11 +296,18 @@
|
|
293 |
z-index: 1000;
|
294 |
}
|
295 |
|
|
|
|
|
|
|
|
|
|
|
|
|
296 |
.wpstg-dropdown>.wpstg-dropdown-menu.shown {
|
297 |
display: flex;
|
298 |
}
|
299 |
|
300 |
-
.wpstg-clone-action
|
|
|
301 |
color: #002648;
|
302 |
padding: 5px 8px;
|
303 |
border-radius: 3px;
|
@@ -306,10 +316,19 @@
|
|
306 |
transition: color .2s ease-in-out;
|
307 |
}
|
308 |
|
309 |
-
.wpstg-clone-action:hover
|
|
|
310 |
background: rgba(0,0,0,0.05);
|
311 |
}
|
312 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
313 |
.wpstg-remove-clone:hover {
|
314 |
color: #ef6d6d;
|
315 |
}
|
@@ -412,11 +431,8 @@
|
|
412 |
content: "Finished";
|
413 |
background-color: #00c89a;
|
414 |
color: white;
|
415 |
-
padding
|
416 |
-
|
417 |
-
padding-top: 2px;
|
418 |
-
padding-bottom: 2px;
|
419 |
-
margin-top: 0px;
|
420 |
border-radius: 3px;
|
421 |
}
|
422 |
|
@@ -513,16 +529,11 @@
|
|
513 |
#wpstg-new-clone {
|
514 |
background: #25a1f0;
|
515 |
border-color: #2188c9;
|
516 |
-
/*box-shadow: inset 0 2px 0 #006799;*/
|
517 |
-
background-color: #25a1f0;
|
518 |
}
|
519 |
|
520 |
#wpstg-new-clone:hover {
|
521 |
background: #259be6;
|
522 |
border-color: #2188c9;
|
523 |
-
/*border-width: 2px;*/
|
524 |
-
/*box-shadow: inset 0 2px 0 #006799;*/
|
525 |
-
background-color: #259be6;
|
526 |
}
|
527 |
|
528 |
#wpstg-clone-path {
|
@@ -620,9 +631,9 @@
|
|
620 |
}
|
621 |
|
622 |
.wpstg-tab-triangle {
|
623 |
-
font-family: arial;
|
624 |
display: inline-block;
|
625 |
margin-right: 10px;
|
|
|
626 |
}
|
627 |
|
628 |
.wpstg-tab-header:focus {
|
@@ -752,7 +763,7 @@
|
|
752 |
}
|
753 |
|
754 |
.wpstg-share-button-container p {
|
755 |
-
margin:
|
756 |
}
|
757 |
|
758 |
.wpstg-share-button {
|
@@ -778,8 +789,6 @@
|
|
778 |
display: inline;
|
779 |
font-size: 12px;
|
780 |
padding: 4px 8px;
|
781 |
-
/* will be overided due to display: inline
|
782 |
-
width: 40px; */
|
783 |
}
|
784 |
|
785 |
.wpstg-share-button-twitter .wpstg-share {
|
@@ -858,7 +867,7 @@
|
|
858 |
}
|
859 |
|
860 |
.wpstg-h2 {
|
861 |
-
margin-top:
|
862 |
margin-bottom: 1.2rem;
|
863 |
font-size: 30px;
|
864 |
line-height: 2.5rem;
|
@@ -877,13 +886,16 @@
|
|
877 |
}
|
878 |
|
879 |
.wpstg-h1 {
|
880 |
-
font-size: 2.75em;
|
881 |
margin-bottom: 1.35rem;
|
882 |
font-size: 2.5em;
|
883 |
line-height: 3.68rem;
|
884 |
letter-spacing: normal;
|
885 |
}
|
886 |
|
|
|
|
|
|
|
|
|
887 |
#wpstg-welcome h2 {
|
888 |
margin: 0 0 15px;
|
889 |
}
|
@@ -896,9 +908,6 @@
|
|
896 |
|
897 |
#wpstg-footer {
|
898 |
clear: both;
|
899 |
-
padding-top: 20px;
|
900 |
-
clear: both;
|
901 |
-
padding-top: 20px;
|
902 |
background-color: white;
|
903 |
padding: 20px;
|
904 |
margin-top: 20px;
|
@@ -930,14 +939,14 @@
|
|
930 |
#wpstg-processing-status {
|
931 |
margin-top: 5px;
|
932 |
font-size: 13px;
|
933 |
-
font-weight:
|
934 |
float: left;
|
935 |
}
|
936 |
|
937 |
#wpstg-processing-timer {
|
938 |
margin-top: 5px;
|
939 |
font-size: 13px;
|
940 |
-
font-weight:
|
941 |
float: right;
|
942 |
}
|
943 |
|
@@ -996,9 +1005,7 @@
|
|
996 |
box-sizing: border-box;
|
997 |
background: #25a1f0;
|
998 |
border-color: #2188c9;
|
999 |
-
/*box-shadow: 0 1px 0 #006799;*/
|
1000 |
color: #fff;
|
1001 |
-
text-decoration: none;
|
1002 |
text-shadow: 0 -1px 1px #006799, 1px 0 1px #006799, 0 1px 1px #006799, -1px 0 1px #006799;
|
1003 |
}
|
1004 |
|
@@ -1011,14 +1018,12 @@
|
|
1011 |
z-index: 9999;
|
1012 |
width: 300px;
|
1013 |
background-color: #fff;
|
1014 |
-
margin: 6px 0 0;
|
1015 |
padding: 15px 15px 10px;
|
1016 |
border: 1px solid #e8e8e8;
|
1017 |
border-radius: 3px;
|
1018 |
box-shadow: 0 1px 0 0 #fff inset;
|
1019 |
display: none;
|
1020 |
-
margin
|
1021 |
-
margin-left: 123px;
|
1022 |
}
|
1023 |
|
1024 |
.wpstg-report-show {
|
@@ -1064,7 +1069,7 @@
|
|
1064 |
|
1065 |
.wpstg-buttons .spinner {
|
1066 |
float: none;
|
1067 |
-
margin:
|
1068 |
}
|
1069 |
|
1070 |
.wpstg-message {
|
@@ -1101,8 +1106,7 @@
|
|
1101 |
padding: 10px;
|
1102 |
background-color: #ffb804;
|
1103 |
color: #ffffff;
|
1104 |
-
margin: 10px;
|
1105 |
-
margin-left: 0px;
|
1106 |
}
|
1107 |
|
1108 |
.wpstg-warning a {
|
@@ -1116,8 +1120,7 @@
|
|
1116 |
padding: 10px;
|
1117 |
background-color: #fe6501;
|
1118 |
color: #ffffff;
|
1119 |
-
margin: 10px;
|
1120 |
-
margin-left: 0px;
|
1121 |
}
|
1122 |
|
1123 |
.wpstg-error a {
|
@@ -1209,7 +1212,6 @@
|
|
1209 |
cursor: pointer;
|
1210 |
display: inline-block;
|
1211 |
padding: 1em 1.25em;
|
1212 |
-
border-bottom: .5em solid transparent;
|
1213 |
border: solid 1px;
|
1214 |
}
|
1215 |
|
@@ -1253,9 +1255,9 @@
|
|
1253 |
border-radius: 3px;
|
1254 |
position: absolute;
|
1255 |
z-index: 1;
|
1256 |
-
-webkit-box-shadow: -1px 1px 5px
|
1257 |
-
-moz-box-shadow: -1px 1px 5px
|
1258 |
-
box-shadow: -1px 1px 5px
|
1259 |
}
|
1260 |
|
1261 |
.wpstg--tooltip:hover .wpstg--tooltiptext {
|
@@ -1341,7 +1343,6 @@ Tooltip top arrow
|
|
1341 |
margin-top: 1em;
|
1342 |
display: none;
|
1343 |
padding: 1em;
|
1344 |
-
overflow-x: hidden;
|
1345 |
overflow-x: auto;
|
1346 |
text-align: justify;
|
1347 |
}
|
@@ -1520,10 +1521,6 @@ span.wpstg--drag-or-upload {
|
|
1520 |
position: absolute;
|
1521 |
width: 185px;
|
1522 |
background: #25a1f0;
|
1523 |
-
border-top: .2em solid #25a1f0;
|
1524 |
-
border-bottom: .25em solid #25a1f0;
|
1525 |
-
border-left: .25em solid #25a1f0;
|
1526 |
-
border-right: .25em solid #25a1f0;
|
1527 |
box-sizing: border-box;
|
1528 |
border-radius: 0 0 3px 3px;
|
1529 |
border-width: 1px;
|
@@ -1533,7 +1530,7 @@ span.wpstg--drag-or-upload {
|
|
1533 |
|
1534 |
.wpstg--backup--import--options.wpstg--show-options ul li {
|
1535 |
border-bottom: .1em solid #25a1f0;
|
1536 |
-
margin:
|
1537 |
}
|
1538 |
|
1539 |
.wpstg--backup--import--options.wpstg--show-options ul li:hover {
|
@@ -1584,7 +1581,7 @@ span.wpstg--drag-or-upload {
|
|
1584 |
}
|
1585 |
|
1586 |
.wpstg--import--advanced-options--button {
|
1587 |
-
border:
|
1588 |
border-radius: 3px;
|
1589 |
font-size: 18px;
|
1590 |
text-shadow: 0 -1px 1px #006799, 1px 0 1px #006799, 0 1px 1px #006799, -1px 0 1px #006799;
|
@@ -1881,13 +1878,22 @@ span.wpstg--drag-or-upload {
|
|
1881 |
}
|
1882 |
|
1883 |
.wpstg-m-0 {
|
1884 |
-
margin:
|
1885 |
}
|
1886 |
|
1887 |
.wpstg-mt-16 {
|
1888 |
margin-top: 16px;
|
1889 |
}
|
1890 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1891 |
.wpstg-w-100 {
|
1892 |
width: 100%;
|
1893 |
}
|
@@ -1905,8 +1911,7 @@ span.wpstg--drag-or-upload {
|
|
1905 |
background-color: #59a7f7;
|
1906 |
color: white;
|
1907 |
padding: 10px;
|
1908 |
-
margin: 10px;
|
1909 |
-
margin-left: 0px;
|
1910 |
}
|
1911 |
|
1912 |
.wpstg-bold-text {
|
@@ -2025,10 +2030,16 @@ span.wpstg--drag-or-upload {
|
|
2025 |
background-color: #378cc9;
|
2026 |
}
|
2027 |
|
2028 |
-
.wpstg-issue-resubmit-confirmation.swal2-container
|
|
|
2029 |
z-index: 10500;
|
2030 |
}
|
2031 |
|
|
|
|
|
|
|
|
|
|
|
2032 |
body.toplevel_page_wpstg_clone .swal2-container .swal2-content {
|
2033 |
z-index:2;
|
2034 |
}
|
@@ -2157,11 +2168,355 @@ ul.wpstg-import-backup-more-info li {
|
|
2157 |
|
2158 |
.wpstg-settings-form-group > .wpstg-settings-message {
|
2159 |
width: 30%;
|
2160 |
-
padding:
|
2161 |
-
margin:
|
2162 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2163 |
}
|
2164 |
|
2165 |
.wpstg-swal-push-container.swal2-container {
|
2166 |
z-index: 9995;
|
2167 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
*
|
4 |
* @package WPSTG
|
5 |
* @subpackage Admin CSS
|
6 |
+
* @copyright Copyright (c) 2021, René Hermenau
|
7 |
* @license http://opensource.org/licenses/gpl-2.0.php GNU Public License
|
8 |
*/
|
9 |
|
156 |
|
157 |
#wpstg-clonepage-wrapper {
|
158 |
margin-bottom: 20px;
|
|
|
159 |
}
|
160 |
|
161 |
@media screen and (min-width: 1090px) {
|
162 |
#wpstg-clonepage-wrapper {
|
163 |
float: left;
|
164 |
margin-bottom: 20px;
|
|
|
165 |
}
|
166 |
.wpstg-sidebar {
|
167 |
display: none;
|
251 |
|
252 |
.wpstg-clone-actions {
|
253 |
display: flex;
|
254 |
+
/*align-items: right;*/
|
255 |
}
|
256 |
|
257 |
.wpstg-dropdown {
|
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;
|
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;
|
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;
|
329 |
+
box-shadow: none;
|
330 |
+
}
|
331 |
+
|
332 |
.wpstg-remove-clone:hover {
|
333 |
color: #ef6d6d;
|
334 |
}
|
431 |
content: "Finished";
|
432 |
background-color: #00c89a;
|
433 |
color: white;
|
434 |
+
padding: 2px 10px;
|
435 |
+
margin-top: 0;
|
|
|
|
|
|
|
436 |
border-radius: 3px;
|
437 |
}
|
438 |
|
529 |
#wpstg-new-clone {
|
530 |
background: #25a1f0;
|
531 |
border-color: #2188c9;
|
|
|
|
|
532 |
}
|
533 |
|
534 |
#wpstg-new-clone:hover {
|
535 |
background: #259be6;
|
536 |
border-color: #2188c9;
|
|
|
|
|
|
|
537 |
}
|
538 |
|
539 |
#wpstg-clone-path {
|
631 |
}
|
632 |
|
633 |
.wpstg-tab-triangle {
|
|
|
634 |
display: inline-block;
|
635 |
margin-right: 10px;
|
636 |
+
animation: transform 0.5s;
|
637 |
}
|
638 |
|
639 |
.wpstg-tab-header:focus {
|
763 |
}
|
764 |
|
765 |
.wpstg-share-button-container p {
|
766 |
+
margin: 0 0 10px 0;
|
767 |
}
|
768 |
|
769 |
.wpstg-share-button {
|
789 |
display: inline;
|
790 |
font-size: 12px;
|
791 |
padding: 4px 8px;
|
|
|
|
|
792 |
}
|
793 |
|
794 |
.wpstg-share-button-twitter .wpstg-share {
|
867 |
}
|
868 |
|
869 |
.wpstg-h2 {
|
870 |
+
margin-top: 0;
|
871 |
margin-bottom: 1.2rem;
|
872 |
font-size: 30px;
|
873 |
line-height: 2.5rem;
|
886 |
}
|
887 |
|
888 |
.wpstg-h1 {
|
|
|
889 |
margin-bottom: 1.35rem;
|
890 |
font-size: 2.5em;
|
891 |
line-height: 3.68rem;
|
892 |
letter-spacing: normal;
|
893 |
}
|
894 |
|
895 |
+
.swal2-content h1 {
|
896 |
+
color:#444;
|
897 |
+
}
|
898 |
+
|
899 |
#wpstg-welcome h2 {
|
900 |
margin: 0 0 15px;
|
901 |
}
|
908 |
|
909 |
#wpstg-footer {
|
910 |
clear: both;
|
|
|
|
|
|
|
911 |
background-color: white;
|
912 |
padding: 20px;
|
913 |
margin-top: 20px;
|
939 |
#wpstg-processing-status {
|
940 |
margin-top: 5px;
|
941 |
font-size: 13px;
|
942 |
+
font-weight: 400;
|
943 |
float: left;
|
944 |
}
|
945 |
|
946 |
#wpstg-processing-timer {
|
947 |
margin-top: 5px;
|
948 |
font-size: 13px;
|
949 |
+
font-weight: 400;
|
950 |
float: right;
|
951 |
}
|
952 |
|
1005 |
box-sizing: border-box;
|
1006 |
background: #25a1f0;
|
1007 |
border-color: #2188c9;
|
|
|
1008 |
color: #fff;
|
|
|
1009 |
text-shadow: 0 -1px 1px #006799, 1px 0 1px #006799, 0 1px 1px #006799, -1px 0 1px #006799;
|
1010 |
}
|
1011 |
|
1018 |
z-index: 9999;
|
1019 |
width: 300px;
|
1020 |
background-color: #fff;
|
|
|
1021 |
padding: 15px 15px 10px;
|
1022 |
border: 1px solid #e8e8e8;
|
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 {
|
1069 |
|
1070 |
.wpstg-buttons .spinner {
|
1071 |
float: none;
|
1072 |
+
margin: 0 0 0 5px;
|
1073 |
}
|
1074 |
|
1075 |
.wpstg-message {
|
1106 |
padding: 10px;
|
1107 |
background-color: #ffb804;
|
1108 |
color: #ffffff;
|
1109 |
+
margin: 10px 10px 10px 0;
|
|
|
1110 |
}
|
1111 |
|
1112 |
.wpstg-warning a {
|
1120 |
padding: 10px;
|
1121 |
background-color: #fe6501;
|
1122 |
color: #ffffff;
|
1123 |
+
margin: 10px 10px 10px 0;
|
|
|
1124 |
}
|
1125 |
|
1126 |
.wpstg-error a {
|
1212 |
cursor: pointer;
|
1213 |
display: inline-block;
|
1214 |
padding: 1em 1.25em;
|
|
|
1215 |
border: solid 1px;
|
1216 |
}
|
1217 |
|
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 {
|
1343 |
margin-top: 1em;
|
1344 |
display: none;
|
1345 |
padding: 1em;
|
|
|
1346 |
overflow-x: auto;
|
1347 |
text-align: justify;
|
1348 |
}
|
1521 |
position: absolute;
|
1522 |
width: 185px;
|
1523 |
background: #25a1f0;
|
|
|
|
|
|
|
|
|
1524 |
box-sizing: border-box;
|
1525 |
border-radius: 0 0 3px 3px;
|
1526 |
border-width: 1px;
|
1530 |
|
1531 |
.wpstg--backup--import--options.wpstg--show-options ul li {
|
1532 |
border-bottom: .1em solid #25a1f0;
|
1533 |
+
margin: 0;
|
1534 |
}
|
1535 |
|
1536 |
.wpstg--backup--import--options.wpstg--show-options ul li:hover {
|
1581 |
}
|
1582 |
|
1583 |
.wpstg--import--advanced-options--button {
|
1584 |
+
border: 0;
|
1585 |
border-radius: 3px;
|
1586 |
font-size: 18px;
|
1587 |
text-shadow: 0 -1px 1px #006799, 1px 0 1px #006799, 0 1px 1px #006799, -1px 0 1px #006799;
|
1878 |
}
|
1879 |
|
1880 |
.wpstg-m-0 {
|
1881 |
+
margin: 0;
|
1882 |
}
|
1883 |
|
1884 |
.wpstg-mt-16 {
|
1885 |
margin-top: 16px;
|
1886 |
}
|
1887 |
|
1888 |
+
.wpstg-mt-10px {
|
1889 |
+
margin-top: 10px;
|
1890 |
+
}
|
1891 |
+
|
1892 |
+
.wpstg-my-10px {
|
1893 |
+
margin-top: 10px;
|
1894 |
+
margin-bottom: 10px;
|
1895 |
+
}
|
1896 |
+
|
1897 |
.wpstg-w-100 {
|
1898 |
width: 100%;
|
1899 |
}
|
1911 |
background-color: #59a7f7;
|
1912 |
color: white;
|
1913 |
padding: 10px;
|
1914 |
+
margin: 10px 10px 10px 0;
|
|
|
1915 |
}
|
1916 |
|
1917 |
.wpstg-bold-text {
|
2030 |
background-color: #378cc9;
|
2031 |
}
|
2032 |
|
2033 |
+
.wpstg-issue-resubmit-confirmation.swal2-container,
|
2034 |
+
.wpstg-swal2-container.swal2-container {
|
2035 |
z-index: 10500;
|
2036 |
}
|
2037 |
|
2038 |
+
.wpstg-swal2-container.wpstg-swal2-loading .swal2-actions,
|
2039 |
+
.wpstg-swal2-container.wpstg-swal2-loading .swal2-header {
|
2040 |
+
display: none;
|
2041 |
+
}
|
2042 |
+
|
2043 |
body.toplevel_page_wpstg_clone .swal2-container .swal2-content {
|
2044 |
z-index:2;
|
2045 |
}
|
2168 |
|
2169 |
.wpstg-settings-form-group > .wpstg-settings-message {
|
2170 |
width: 30%;
|
2171 |
+
padding: 0;
|
2172 |
+
margin: 7px 0 0;
|
2173 |
+
}
|
2174 |
+
|
2175 |
+
/**
|
2176 |
+
* WP STAGING EXCLUSION RULES TABLE LAYOUT
|
2177 |
+
*/
|
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 |
+
|
2187 |
+
.wpstg-excluded-filters-container > table {
|
2188 |
+
width: 100%;
|
2189 |
+
border-collapse: collapse;
|
2190 |
+
border-color: transparent;
|
2191 |
+
}
|
2192 |
+
|
2193 |
+
.wpstg-excluded-filters-container td {
|
2194 |
+
padding-top: 4px;
|
2195 |
+
padding-bottom: 4px;
|
2196 |
+
height: 20px;
|
2197 |
+
}
|
2198 |
+
|
2199 |
+
.wpstg-excluded-filters-container h4 {
|
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;;
|
2253 |
+
border: 1px solid #135e96;;
|
2254 |
+
}
|
2255 |
+
|
2256 |
+
.wpstg-exclude-filter-dropdown > .wpstg-dropdown-menu {
|
2257 |
+
width: 128px;
|
2258 |
+
}
|
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;
|
2274 |
+
line-height: 0.7;
|
2275 |
+
margin-top: 5px;
|
2276 |
+
cursor: pointer;
|
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 {
|
2316 |
+
background: #f8f8f8 !important;
|
2317 |
+
}
|
2318 |
+
|
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 {
|
2330 |
+
color: #fff !important;
|
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;
|
2343 |
+
font-weight: 400;
|
2344 |
+
vertical-align: middle;
|
2345 |
+
}
|
2346 |
+
|
2347 |
+
.wpstg-exclusion-rule-info:hover {
|
2348 |
+
background-color: #ffba0c;
|
2349 |
+
border: 1px solid #ffba0c;
|
2350 |
+
}
|
2351 |
+
|
2352 |
+
/**
|
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;
|
2360 |
+
outline: none !important;
|
2361 |
+
display: inline-block;
|
2362 |
+
font-weight: 400;
|
2363 |
+
line-height: 1.5;
|
2364 |
+
color: #222;
|
2365 |
+
border-radius: 0 !important;
|
2366 |
+
background-color: #fff;
|
2367 |
+
border: 1px solid #bbb;
|
2368 |
+
min-height: 24px !important;
|
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 {
|
2381 |
+
border: 1px solid #999;
|
2382 |
+
}
|
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,
|
2390 |
+
.wpstg-path-exclude-select {
|
2391 |
+
width: 135px;
|
2392 |
+
}
|
2393 |
+
|
2394 |
+
.wpstg-file-size-exclude-select-small {
|
2395 |
+
width: 52px;
|
2396 |
+
}
|
2397 |
+
|
2398 |
+
.wpstg-file-size-exclude-input {
|
2399 |
+
width: 75px;
|
2400 |
+
}
|
2401 |
+
|
2402 |
+
.wpstg-staging-option-title {
|
2403 |
+
margin: 15px 0 0;
|
2404 |
}
|
2405 |
|
2406 |
.wpstg-swal-push-container.swal2-container {
|
2407 |
z-index: 9995;
|
2408 |
}
|
2409 |
+
|
2410 |
+
#wpstg-scanning-files {
|
2411 |
+
padding-bottom: 5px;
|
2412 |
+
}
|
2413 |
+
|
2414 |
+
#wpstg-scanning-files.wpstg-tab-section{
|
2415 |
+
padding-top:0;
|
2416 |
+
}
|
2417 |
+
|
2418 |
+
.wpstg-reset-excludes-container {
|
2419 |
+
margin: 10px 0;
|
2420 |
+
}
|
2421 |
+
|
2422 |
+
.wpstg-swal2-ajax-loader {
|
2423 |
+
width: 100%;
|
2424 |
+
height: 150px;
|
2425 |
+
overflow: hidden;
|
2426 |
+
display: flex;
|
2427 |
+
justify-content: center;
|
2428 |
+
align-items: center;
|
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 {
|
2441 |
+
width: 64px;
|
2442 |
+
height: 64px;
|
2443 |
+
animation: wpstg-loading-icon-anim 1s infinite linear;
|
2444 |
+
-webkit-animation: wpstg-loading-icon-anim 1s infinite linear;
|
2445 |
+
}
|
2446 |
+
|
2447 |
+
.wpstg-swal2-container .wpstg-tab-section {
|
2448 |
+
width: auto !important;
|
2449 |
+
}
|
2450 |
+
|
2451 |
+
.wpstg-is-dir-loading {
|
2452 |
+
position: absolute;
|
2453 |
+
margin-top: -2px;
|
2454 |
+
margin-left: 8px;
|
2455 |
+
display: none;
|
2456 |
+
}
|
2457 |
+
|
2458 |
+
.wpstg-ml-8px {
|
2459 |
+
margin-left: 8px;
|
2460 |
+
}
|
2461 |
+
|
2462 |
+
.wpstg-mb-8px {
|
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 {
|
2482 |
+
height: 200px;
|
2483 |
+
}
|
2484 |
+
|
2485 |
+
.wpstg-reset-confirmation.wpstg-swal2-container:not(.wpstg-swal2-loading) > .swal2-modal {
|
2486 |
+
max-width: 480px;
|
2487 |
+
}
|
2488 |
+
|
2489 |
+
.wpstg-reset-confirmation.wpstg-swal2-container .swal2-header {
|
2490 |
+
display: none;
|
2491 |
+
}
|
2492 |
+
|
2493 |
+
.wpstg-reset-confirmation.wpstg-swal2-container .swal2-content {
|
2494 |
+
height: auto;
|
2495 |
+
}
|
2496 |
+
|
2497 |
+
.wpstg-reset-confirmation.wpstg-swal2-container > .swal2-modal > .swal2-content .wpstg-tabs-wrapper {
|
2498 |
+
overflow-y: auto;
|
2499 |
+
height: auto !important;
|
2500 |
+
}
|
2501 |
+
|
2502 |
+
.wpstg-reset-confirmation.wpstg-swal2-container > .swal2-modal > .swal2-content {
|
2503 |
+
font-size: 13px;
|
2504 |
+
}
|
2505 |
+
|
2506 |
+
.wpstg-reset-confirmation.wpstg-swal2-container > .swal2-modal > .swal2-content .wpstg-dir {
|
2507 |
+
margin-bottom: 4px;
|
2508 |
+
}
|
2509 |
+
|
2510 |
+
.wpstg-reset-confirmation.wpstg-swal2-container > .swal2-modal > .swal2-content .wpstg-subdir {
|
2511 |
+
margin-top: 4px;
|
2512 |
+
}
|
2513 |
+
|
2514 |
+
.wpstg-reset-confirmation.wpstg-swal2-container.has-collapsible-open .swal2-modal {
|
2515 |
+
height: calc(100vh - 70px);
|
2516 |
+
}
|
2517 |
+
|
2518 |
+
.wpstg-reset-confirmation.wpstg-swal2-container.has-collapsible-open > .swal2-modal > .swal2-content .wpstg-tabs-wrapper {
|
2519 |
+
height: calc(100vh - 350px) !important;
|
2520 |
+
}
|
2521 |
+
|
2522 |
+
/*# sourceMappingURL=wpstg-admin.css.map */
|
assets/css/dist/wpstg-admin.css.map
ADDED
@@ -0,0 +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"]}
|
assets/css/dist/wpstg-admin.min.css
ADDED
@@ -0,0 +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 */
|
assets/css/dist/wpstg-admin.min.css.map
ADDED
@@ -0,0 +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"]}
|
assets/css/src/frontend/wpstg-admin-bar.css
DELETED
@@ -1,3 +0,0 @@
|
|
1 |
-
#wpadminbar{
|
2 |
-
background-color: #ff8d00 !important;
|
3 |
-
}
|
|
|
|
|
|
assets/css/src/wpstg-admin-bar.css
DELETED
@@ -1,3 +0,0 @@
|
|
1 |
-
#wpadminbar{
|
2 |
-
background-color: #ff8d00 !important;
|
3 |
-
}
|
|
|
|
|
|
assets/img/spinner.gif
ADDED
Binary file
|
assets/img/wpstaging-icon.png
ADDED
Binary file
|
assets/js/dist/wpstg-admin-beta.js
CHANGED
@@ -1,15 +1,21 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
e.preventDefault();
|
4 |
-
window.WPStaging.ajax({
|
5 |
-
action: 'wpstg_hide_beta'
|
6 |
-
}, function (response) {
|
7 |
-
if (true === response) {
|
8 |
-
$('.wpstg_beta_notice').slideUp('slow');
|
9 |
-
return true;
|
10 |
-
}
|
11 |
|
12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
});
|
14 |
});
|
15 |
-
|
|
|
|
1 |
+
(function () {
|
2 |
+
'use strict';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
|
4 |
+
jQuery(document).ready(function ($) {
|
5 |
+
$('.wpstg_hide_beta').on('click', function (e) {
|
6 |
+
e.preventDefault();
|
7 |
+
window.WPStaging.ajax({
|
8 |
+
action: 'wpstg_hide_beta'
|
9 |
+
}, function (response) {
|
10 |
+
if (true === response) {
|
11 |
+
$('.wpstg_beta_notice').slideUp('slow');
|
12 |
+
return true;
|
13 |
+
}
|
14 |
+
|
15 |
+
alert('Unexpected message received. This might mean the data was not saved ' + 'and you might see this message again');
|
16 |
+
});
|
17 |
});
|
18 |
});
|
19 |
+
|
20 |
+
}());
|
21 |
+
//# sourceMappingURL=wpstg-admin-beta.js.map
|
assets/js/dist/wpstg-admin-beta.js.map
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
{"version":3,"file":"wpstg-admin-beta.js","sources":["../src/wpstg-admin-beta.js"],"sourcesContent":["jQuery(document).ready(function($) {\n $('.wpstg_hide_beta').on('click', function(e) {\n e.preventDefault();\n\n window.WPStaging.ajax(\n {action: 'wpstg_hide_beta'},\n function(response) {\n if (true === response) {\n $('.wpstg_beta_notice').slideUp('slow');\n return true;\n }\n\n alert(\n 'Unexpected message received. This might mean the data was not saved ' +\n 'and you might see this message again',\n );\n },\n );\n });\n});\n"],"names":["jQuery","document","ready","$","on","e","preventDefault","window","WPStaging","ajax","action","response","slideUp","alert"],"mappings":";;;EAAAA,MAAM,CAACC,QAAD,CAAN,CAAiBC,KAAjB,CAAuB,UAASC,CAAT,EAAY;EACjCA,EAAAA,CAAC,CAAC,kBAAD,CAAD,CAAsBC,EAAtB,CAAyB,OAAzB,EAAkC,UAASC,CAAT,EAAY;EAC5CA,IAAAA,CAAC,CAACC,cAAF;EAEAC,IAAAA,MAAM,CAACC,SAAP,CAAiBC,IAAjB,CACI;EAACC,MAAAA,MAAM,EAAE;EAAT,KADJ,EAEI,UAASC,QAAT,EAAmB;EACjB,UAAI,SAASA,QAAb,EAAuB;EACrBR,QAAAA,CAAC,CAAC,oBAAD,CAAD,CAAwBS,OAAxB,CAAgC,MAAhC;EACA,eAAO,IAAP;EACD;;EAEDC,MAAAA,KAAK,CACD,yEACM,sCAFL,CAAL;EAID,KAZL;EAcD,GAjBD;EAkBD,CAnBD;;;;;;"}
|
assets/js/dist/wpstg-admin-beta.min.js
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
1 |
+
!function(){"use strict";jQuery(document).ready((function(e){e(".wpstg_hide_beta").on("click",(function(t){t.preventDefault(),window.WPStaging.ajax({action:"wpstg_hide_beta"},(function(t){if(!0===t)return e(".wpstg_beta_notice").slideUp("slow"),!0;alert("Unexpected message received. This might mean the data was not saved and you might see this message again")}))}))}))}();
|
2 |
+
//# sourceMappingURL=wpstg-admin-beta.min.js.map
|
assets/js/dist/wpstg-admin-beta.min.js.map
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
{"version":3,"file":"wpstg-admin-beta.min.js","sources":["../src/wpstg-admin-beta.js"],"sourcesContent":["jQuery(document).ready(function($) {\n $('.wpstg_hide_beta').on('click', function(e) {\n e.preventDefault();\n\n window.WPStaging.ajax(\n {action: 'wpstg_hide_beta'},\n function(response) {\n if (true === response) {\n $('.wpstg_beta_notice').slideUp('slow');\n return true;\n }\n\n alert(\n 'Unexpected message received. This might mean the data was not saved ' +\n 'and you might see this message again',\n );\n },\n );\n });\n});\n"],"names":["jQuery","document","ready","$","on","e","preventDefault","window","WPStaging","ajax","action","response","slideUp","alert"],"mappings":"yBAAAA,OAAOC,UAAUC,OAAM,SAASC,GAC9BA,EAAE,oBAAoBC,GAAG,SAAS,SAASC,GACzCA,EAAEC,iBAEFC,OAAOC,UAAUC,KACb,CAACC,OAAQ,oBACT,SAASC,OACH,IAASA,SACXR,EAAE,sBAAsBS,QAAQ,SACzB,EAGTC,MACI"}
|
assets/js/dist/wpstg-admin-plugins.js
CHANGED
@@ -1,77 +1,82 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
/**
|
4 |
-
* DEACTIVATION FEEDBACK FORM
|
5 |
-
*/
|
6 |
-
// show overlay when clicked on "deactivate"
|
7 |
-
wpstg_deactivate_link = $('.wp-admin.plugins-php tr[data-slug="wp-staging"] .row-actions .deactivate a');
|
8 |
-
wpstg_deactivate_link_url = wpstg_deactivate_link.attr('href');
|
9 |
-
wpstg_deactivate_link.on('click', function (e) {
|
10 |
-
e.preventDefault(); // only show feedback form once per 30 days
|
11 |
|
12 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
|
14 |
-
|
15 |
-
$('#wpstg-feedback-overlay').show();
|
16 |
-
} else {
|
17 |
-
// click on the link
|
18 |
-
window.location.href = wpstg_deactivate_link_url;
|
19 |
-
}
|
20 |
-
}); // show text fields
|
21 |
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
|
|
|
|
|
|
26 |
|
27 |
-
|
28 |
-
|
|
|
|
|
29 |
|
30 |
-
|
31 |
-
|
32 |
-
document.cookie = 'wpstg_hide_feedback=1; expires=' + exdate.toUTCString() + '; path=/';
|
33 |
-
$('#wpstg-feedback-overlay').hide();
|
34 |
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
url: ajaxurl,
|
40 |
-
dataType: 'json',
|
41 |
-
data: {
|
42 |
-
action: 'wpstg_send_feedback',
|
43 |
-
data: $('#wpstg-feedback-content form').serialize()
|
44 |
-
},
|
45 |
-
complete: function complete(MLHttpRequest, textStatus, errorThrown) {
|
46 |
-
// deactivate the plugin and close the popup
|
47 |
-
$('#wpstg-feedback-overlay').remove();
|
48 |
-
window.location.href = wpstg_deactivate_link_url;
|
49 |
-
}
|
50 |
-
});
|
51 |
-
} else {
|
52 |
-
$('#wpstg-feedback-overlay').remove();
|
53 |
-
window.location.href = wpstg_deactivate_link_url;
|
54 |
-
}
|
55 |
-
}); // close form without doing anything
|
56 |
|
57 |
-
|
58 |
-
|
59 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
60 |
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
|
72 |
-
|
73 |
-
|
|
|
74 |
}
|
75 |
}
|
76 |
-
}
|
77 |
-
|
|
|
|
1 |
+
(function () {
|
2 |
+
'use strict';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
|
4 |
+
jQuery(document).ready(function ($) {
|
5 |
+
/**
|
6 |
+
* DEACTIVATION FEEDBACK FORM
|
7 |
+
*/
|
8 |
+
// show overlay when clicked on "deactivate"
|
9 |
+
wpstg_deactivate_link = $('.wp-admin.plugins-php tr[data-slug="wp-staging"] .row-actions .deactivate a');
|
10 |
+
wpstg_deactivate_link_url = wpstg_deactivate_link.attr('href');
|
11 |
+
wpstg_deactivate_link.on('click', function (e) {
|
12 |
+
e.preventDefault(); // only show feedback form once per 30 days
|
13 |
|
14 |
+
var c_value = wpstg_admin_get_cookie('wpstg_hide_feedback');
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
|
16 |
+
if (c_value === undefined) {
|
17 |
+
$('#wpstg-feedback-overlay').show();
|
18 |
+
} else {
|
19 |
+
// click on the link
|
20 |
+
window.location.href = wpstg_deactivate_link_url;
|
21 |
+
}
|
22 |
+
}); // show text fields
|
23 |
|
24 |
+
$('#wpstg-feedback-content input[type="radio"]').on('click', function () {
|
25 |
+
// show text field if there is one
|
26 |
+
$(this).parents('li').next('li').children('input[type="text"], textarea').show();
|
27 |
+
}); // send form or close it
|
28 |
|
29 |
+
$('#wpstg-feedback-content .button').on('click', function (e) {
|
30 |
+
e.preventDefault(); // set cookie for 30 days
|
|
|
|
|
31 |
|
32 |
+
var exdate = new Date();
|
33 |
+
exdate.setSeconds(exdate.getSeconds() + 2592000);
|
34 |
+
document.cookie = 'wpstg_hide_feedback=1; expires=' + exdate.toUTCString() + '; path=/';
|
35 |
+
$('#wpstg-feedback-overlay').hide();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
|
37 |
+
if ('wpstg-feedback-submit' === this.id) {
|
38 |
+
// Send form data
|
39 |
+
$.ajax({
|
40 |
+
type: 'POST',
|
41 |
+
url: ajaxurl,
|
42 |
+
dataType: 'json',
|
43 |
+
data: {
|
44 |
+
action: 'wpstg_send_feedback',
|
45 |
+
data: $('#wpstg-feedback-content form').serialize()
|
46 |
+
},
|
47 |
+
complete: function complete(MLHttpRequest, textStatus, errorThrown) {
|
48 |
+
// deactivate the plugin and close the popup
|
49 |
+
$('#wpstg-feedback-overlay').remove();
|
50 |
+
window.location.href = wpstg_deactivate_link_url;
|
51 |
+
}
|
52 |
+
});
|
53 |
+
} else {
|
54 |
+
$('#wpstg-feedback-overlay').remove();
|
55 |
+
window.location.href = wpstg_deactivate_link_url;
|
56 |
+
}
|
57 |
+
}); // close form without doing anything
|
58 |
+
|
59 |
+
$('.wpstg-feedback-not-deactivate').on('click', function (e) {
|
60 |
+
$('#wpstg-feedback-overlay').hide();
|
61 |
+
});
|
62 |
|
63 |
+
function wpstg_admin_get_cookie(name) {
|
64 |
+
var i;
|
65 |
+
var x;
|
66 |
+
var y;
|
67 |
+
var wpstg_cookies = document.cookie.split(';');
|
68 |
|
69 |
+
for (i = 0; i < wpstg_cookies.length; i++) {
|
70 |
+
x = wpstg_cookies[i].substr(0, wpstg_cookies[i].indexOf('='));
|
71 |
+
y = wpstg_cookies[i].substr(wpstg_cookies[i].indexOf('=') + 1);
|
72 |
+
x = x.replace(/^\s+|\s+$/g, '');
|
73 |
|
74 |
+
if (x === name) {
|
75 |
+
return unescape(y);
|
76 |
+
}
|
77 |
}
|
78 |
}
|
79 |
+
});
|
80 |
+
|
81 |
+
}());
|
82 |
+
//# sourceMappingURL=wpstg-admin-plugins.js.map
|
assets/js/dist/wpstg-admin-plugins.js.map
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
{"version":3,"file":"wpstg-admin-plugins.js","sources":["../src/wpstg-admin-plugins.js"],"sourcesContent":["let strict;\n\njQuery(document).ready(function($) {\n /**\n * DEACTIVATION FEEDBACK FORM\n */\n // show overlay when clicked on \"deactivate\"\n wpstg_deactivate_link = $('.wp-admin.plugins-php tr[data-slug=\"wp-staging\"] .row-actions .deactivate a');\n wpstg_deactivate_link_url = wpstg_deactivate_link.attr('href');\n\n wpstg_deactivate_link.on('click', function(e) {\n e.preventDefault();\n\n // only show feedback form once per 30 days\n const c_value = wpstg_admin_get_cookie('wpstg_hide_feedback');\n\n if (c_value === undefined) {\n $('#wpstg-feedback-overlay').show();\n } else {\n // click on the link\n window.location.href = wpstg_deactivate_link_url;\n }\n });\n // show text fields\n $('#wpstg-feedback-content input[type=\"radio\"]').on('click', function() {\n // show text field if there is one\n $(this).parents('li').next('li').children('input[type=\"text\"], textarea').show();\n });\n // send form or close it\n $('#wpstg-feedback-content .button').on('click', function(e) {\n e.preventDefault();\n // set cookie for 30 days\n const exdate = new Date();\n exdate.setSeconds(exdate.getSeconds() + 2592000);\n document.cookie = 'wpstg_hide_feedback=1; expires=' + exdate.toUTCString() + '; path=/';\n\n $('#wpstg-feedback-overlay').hide();\n if ('wpstg-feedback-submit' === this.id) {\n // Send form data\n $.ajax({\n type: 'POST',\n url: ajaxurl,\n dataType: 'json',\n data: {\n action: 'wpstg_send_feedback',\n data: $('#wpstg-feedback-content form').serialize(),\n },\n complete: function(MLHttpRequest, textStatus, errorThrown) {\n // deactivate the plugin and close the popup\n $('#wpstg-feedback-overlay').remove();\n window.location.href = wpstg_deactivate_link_url;\n },\n });\n } else {\n $('#wpstg-feedback-overlay').remove();\n window.location.href = wpstg_deactivate_link_url;\n }\n });\n // close form without doing anything\n $('.wpstg-feedback-not-deactivate').on('click', function(e) {\n $('#wpstg-feedback-overlay').hide();\n });\n\n function wpstg_admin_get_cookie(name) {\n let i; let x; let y; const wpstg_cookies = document.cookie.split( ';' );\n for (i = 0; i < wpstg_cookies.length; i++) {\n x = wpstg_cookies[i].substr( 0, wpstg_cookies[i].indexOf( '=' ) );\n y = wpstg_cookies[i].substr( wpstg_cookies[i].indexOf( '=' ) + 1 );\n x = x.replace( /^\\s+|\\s+$/g, '' );\n if (x === name) {\n return unescape( y );\n }\n }\n }\n});\n"],"names":["jQuery","document","ready","$","wpstg_deactivate_link","wpstg_deactivate_link_url","attr","on","e","preventDefault","c_value","wpstg_admin_get_cookie","undefined","show","window","location","href","parents","next","children","exdate","Date","setSeconds","getSeconds","cookie","toUTCString","hide","id","ajax","type","url","ajaxurl","dataType","data","action","serialize","complete","MLHttpRequest","textStatus","errorThrown","remove","name","i","x","y","wpstg_cookies","split","length","substr","indexOf","replace","unescape"],"mappings":"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"}
|
assets/js/dist/wpstg-admin-plugins.min.js
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
1 |
+
!function(){"use strict";jQuery(document).ready((function(e){wpstg_deactivate_link=e('.wp-admin.plugins-php tr[data-slug="wp-staging"] .row-actions .deactivate a'),wpstg_deactivate_link_url=wpstg_deactivate_link.attr("href"),wpstg_deactivate_link.on("click",(function(t){t.preventDefault(),void 0===function(e){var t,a,n,i=document.cookie.split(";");for(t=0;t<i.length;t++)if(a=i[t].substr(0,i[t].indexOf("=")),n=i[t].substr(i[t].indexOf("=")+1),(a=a.replace(/^\s+|\s+$/g,""))===e)return unescape(n)}("wpstg_hide_feedback")?e("#wpstg-feedback-overlay").show():window.location.href=wpstg_deactivate_link_url})),e('#wpstg-feedback-content input[type="radio"]').on("click",(function(){e(this).parents("li").next("li").children('input[type="text"], textarea').show()})),e("#wpstg-feedback-content .button").on("click",(function(t){t.preventDefault();var a=new Date;a.setSeconds(a.getSeconds()+2592e3),document.cookie="wpstg_hide_feedback=1; expires="+a.toUTCString()+"; path=/",e("#wpstg-feedback-overlay").hide(),"wpstg-feedback-submit"===this.id?e.ajax({type:"POST",url:ajaxurl,dataType:"json",data:{action:"wpstg_send_feedback",data:e("#wpstg-feedback-content form").serialize()},complete:function(t,a,n){e("#wpstg-feedback-overlay").remove(),window.location.href=wpstg_deactivate_link_url}}):(e("#wpstg-feedback-overlay").remove(),window.location.href=wpstg_deactivate_link_url)})),e(".wpstg-feedback-not-deactivate").on("click",(function(t){e("#wpstg-feedback-overlay").hide()}))}))}();
|
2 |
+
//# sourceMappingURL=wpstg-admin-plugins.min.js.map
|
assets/js/dist/wpstg-admin-plugins.min.js.map
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
{"version":3,"file":"wpstg-admin-plugins.min.js","sources":["../src/wpstg-admin-plugins.js"],"sourcesContent":["let strict;\n\njQuery(document).ready(function($) {\n /**\n * DEACTIVATION FEEDBACK FORM\n */\n // show overlay when clicked on \"deactivate\"\n wpstg_deactivate_link = $('.wp-admin.plugins-php tr[data-slug=\"wp-staging\"] .row-actions .deactivate a');\n wpstg_deactivate_link_url = wpstg_deactivate_link.attr('href');\n\n wpstg_deactivate_link.on('click', function(e) {\n e.preventDefault();\n\n // only show feedback form once per 30 days\n const c_value = wpstg_admin_get_cookie('wpstg_hide_feedback');\n\n if (c_value === undefined) {\n $('#wpstg-feedback-overlay').show();\n } else {\n // click on the link\n window.location.href = wpstg_deactivate_link_url;\n }\n });\n // show text fields\n $('#wpstg-feedback-content input[type=\"radio\"]').on('click', function() {\n // show text field if there is one\n $(this).parents('li').next('li').children('input[type=\"text\"], textarea').show();\n });\n // send form or close it\n $('#wpstg-feedback-content .button').on('click', function(e) {\n e.preventDefault();\n // set cookie for 30 days\n const exdate = new Date();\n exdate.setSeconds(exdate.getSeconds() + 2592000);\n document.cookie = 'wpstg_hide_feedback=1; expires=' + exdate.toUTCString() + '; path=/';\n\n $('#wpstg-feedback-overlay').hide();\n if ('wpstg-feedback-submit' === this.id) {\n // Send form data\n $.ajax({\n type: 'POST',\n url: ajaxurl,\n dataType: 'json',\n data: {\n action: 'wpstg_send_feedback',\n data: $('#wpstg-feedback-content form').serialize(),\n },\n complete: function(MLHttpRequest, textStatus, errorThrown) {\n // deactivate the plugin and close the popup\n $('#wpstg-feedback-overlay').remove();\n window.location.href = wpstg_deactivate_link_url;\n },\n });\n } else {\n $('#wpstg-feedback-overlay').remove();\n window.location.href = wpstg_deactivate_link_url;\n }\n });\n // close form without doing anything\n $('.wpstg-feedback-not-deactivate').on('click', function(e) {\n $('#wpstg-feedback-overlay').hide();\n });\n\n function wpstg_admin_get_cookie(name) {\n let i; let x; let y; const wpstg_cookies = document.cookie.split( ';' );\n for (i = 0; i < wpstg_cookies.length; i++) {\n x = wpstg_cookies[i].substr( 0, wpstg_cookies[i].indexOf( '=' ) );\n y = wpstg_cookies[i].substr( wpstg_cookies[i].indexOf( '=' ) + 1 );\n x = x.replace( /^\\s+|\\s+$/g, '' );\n if (x === name) {\n return unescape( y );\n }\n }\n }\n});\n"],"names":["jQuery","document","ready","$","wpstg_deactivate_link","wpstg_deactivate_link_url","attr","on","e","preventDefault","undefined","name","i","x","y","wpstg_cookies","cookie","split","length","substr","indexOf","replace","unescape","wpstg_admin_get_cookie","show","window","location","href","this","parents","next","children","exdate","Date","setSeconds","getSeconds","toUTCString","hide","id","ajax","type","url","ajaxurl","dataType","data","action","serialize","complete","MLHttpRequest","textStatus","errorThrown","remove"],"mappings":"yBAEAA,OAAOC,UAAUC,OAAM,SAASC,GAK9BC,sBAAwBD,EAAE,+EAC1BE,0BAA4BD,sBAAsBE,KAAK,QAEvDF,sBAAsBG,GAAG,SAAS,SAASC,GACzCA,EAAEC,sBAKcC,aA+CcC,OAC1BC,EAAOC,EAAOC,EAASC,EAAgBd,SAASe,OAAOC,MAAO,SAC7DL,EAAI,EAAGA,EAAIG,EAAcG,OAAQN,OACpCC,EAAIE,EAAcH,GAAGO,OAAQ,EAAGJ,EAAcH,GAAGQ,QAAS,MAC1DN,EAAIC,EAAcH,GAAGO,OAAQJ,EAAcH,GAAGQ,QAAS,KAAQ,IAC/DP,EAAIA,EAAEQ,QAAS,aAAc,OACnBV,SACDW,SAAUR,GAxDLS,CAAuB,uBAGrCpB,EAAE,2BAA2BqB,OAG7BC,OAAOC,SAASC,KAAOtB,6BAI3BF,EAAE,+CAA+CI,GAAG,SAAS,WAE3DJ,EAAEyB,MAAMC,QAAQ,MAAMC,KAAK,MAAMC,SAAS,gCAAgCP,UAG5ErB,EAAE,mCAAmCI,GAAG,SAAS,SAASC,GACxDA,EAAEC,qBAEIuB,EAAS,IAAIC,KACnBD,EAAOE,WAAWF,EAAOG,aAAe,QACxClC,SAASe,OAAS,kCAAoCgB,EAAOI,cAAgB,WAE7EjC,EAAE,2BAA2BkC,OACzB,0BAA4BT,KAAKU,GAEnCnC,EAAEoC,KAAK,CACLC,KAAM,OACNC,IAAKC,QACLC,SAAU,OACVC,KAAM,CACJC,OAAQ,sBACRD,KAAMzC,EAAE,gCAAgC2C,aAE1CC,SAAU,SAASC,EAAeC,EAAYC,GAE5C/C,EAAE,2BAA2BgD,SAC7B1B,OAAOC,SAASC,KAAOtB,8BAI3BF,EAAE,2BAA2BgD,SAC7B1B,OAAOC,SAASC,KAAOtB,8BAI3BF,EAAE,kCAAkCI,GAAG,SAAS,SAASC,GACvDL,EAAE,2BAA2BkC"}
|
assets/js/dist/wpstg-admin-poll.js
CHANGED
@@ -1,15 +1,21 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
|
|
|
|
|
|
|
|
13 |
});
|
14 |
});
|
15 |
-
|
|
|
|
1 |
+
(function () {
|
2 |
+
'use strict';
|
3 |
+
|
4 |
+
jQuery(document).ready(function ($) {
|
5 |
+
$('.wpstg_hide_poll').on('click', function (e) {
|
6 |
+
e.preventDefault();
|
7 |
+
window.WPStaging.ajax({
|
8 |
+
action: 'wpstg_hide_poll'
|
9 |
+
}, function (response) {
|
10 |
+
if (true === response) {
|
11 |
+
$('.wpstg_poll').slideUp('fast');
|
12 |
+
return true;
|
13 |
+
} else {
|
14 |
+
alert('Unexpected message received. This might mean the data was not saved ' + 'and you might see this message again.');
|
15 |
+
}
|
16 |
+
});
|
17 |
});
|
18 |
});
|
19 |
+
|
20 |
+
}());
|
21 |
+
//# sourceMappingURL=wpstg-admin-poll.js.map
|
assets/js/dist/wpstg-admin-poll.js.map
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
{"version":3,"file":"wpstg-admin-poll.js","sources":["../src/wpstg-admin-poll.js"],"sourcesContent":["jQuery(document).ready(function($) {\n $('.wpstg_hide_poll').on('click', function(e) {\n e.preventDefault();\n\n window.WPStaging.ajax(\n {action: 'wpstg_hide_poll'},\n function(response) {\n if (true === response) {\n $('.wpstg_poll').slideUp('fast');\n return true;\n } else {\n alert(\n 'Unexpected message received. This might mean the data was not saved ' +\n 'and you might see this message again.',\n );\n }\n },\n );\n });\n});\n"],"names":["jQuery","document","ready","$","on","e","preventDefault","window","WPStaging","ajax","action","response","slideUp","alert"],"mappings":";;;EAAAA,MAAM,CAACC,QAAD,CAAN,CAAiBC,KAAjB,CAAuB,UAASC,CAAT,EAAY;EACjCA,EAAAA,CAAC,CAAC,kBAAD,CAAD,CAAsBC,EAAtB,CAAyB,OAAzB,EAAkC,UAASC,CAAT,EAAY;EAC5CA,IAAAA,CAAC,CAACC,cAAF;EAEAC,IAAAA,MAAM,CAACC,SAAP,CAAiBC,IAAjB,CACI;EAACC,MAAAA,MAAM,EAAE;EAAT,KADJ,EAEI,UAASC,QAAT,EAAmB;EACjB,UAAI,SAASA,QAAb,EAAuB;EACrBR,QAAAA,CAAC,CAAC,aAAD,CAAD,CAAiBS,OAAjB,CAAyB,MAAzB;EACA,eAAO,IAAP;EACD,OAHD,MAGO;EACLC,QAAAA,KAAK,CACD,yEACQ,uCAFP,CAAL;EAID;EACF,KAZL;EAcD,GAjBD;EAkBD,CAnBD;;;;;;"}
|
assets/js/dist/wpstg-admin-poll.min.js
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
1 |
+
!function(){"use strict";jQuery(document).ready((function(e){e(".wpstg_hide_poll").on("click",(function(t){t.preventDefault(),window.WPStaging.ajax({action:"wpstg_hide_poll"},(function(t){if(!0===t)return e(".wpstg_poll").slideUp("fast"),!0;alert("Unexpected message received. This might mean the data was not saved and you might see this message again.")}))}))}))}();
|
2 |
+
//# sourceMappingURL=wpstg-admin-poll.min.js.map
|
assets/js/dist/wpstg-admin-poll.min.js.map
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
{"version":3,"file":"wpstg-admin-poll.min.js","sources":["../src/wpstg-admin-poll.js"],"sourcesContent":["jQuery(document).ready(function($) {\n $('.wpstg_hide_poll').on('click', function(e) {\n e.preventDefault();\n\n window.WPStaging.ajax(\n {action: 'wpstg_hide_poll'},\n function(response) {\n if (true === response) {\n $('.wpstg_poll').slideUp('fast');\n return true;\n } else {\n alert(\n 'Unexpected message received. This might mean the data was not saved ' +\n 'and you might see this message again.',\n );\n }\n },\n );\n });\n});\n"],"names":["jQuery","document","ready","$","on","e","preventDefault","window","WPStaging","ajax","action","response","slideUp","alert"],"mappings":"yBAAAA,OAAOC,UAAUC,OAAM,SAASC,GAC9BA,EAAE,oBAAoBC,GAAG,SAAS,SAASC,GACzCA,EAAEC,iBAEFC,OAAOC,UAAUC,KACb,CAACC,OAAQ,oBACT,SAASC,OACH,IAASA,SACXR,EAAE,eAAeS,QAAQ,SAClB,EAEPC,MACI"}
|
assets/js/dist/wpstg-admin-rating.js
CHANGED
@@ -1,153 +1,138 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
Let's wait for jQuery to be available to show the rating.
|
4 |
-
We need it to dispatch AJAX requests.
|
5 |
-
*/
|
6 |
|
7 |
-
var
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
|
|
17 |
|
18 |
-
|
19 |
-
|
|
|
|
|
20 |
|
21 |
-
|
22 |
-
|
23 |
-
jQuery('.wpstg_fivestar').show();
|
24 |
-
/**
|
25 |
-
* Dispatch the request to hide the video after user clicks to rate the plugin.
|
26 |
-
*/
|
27 |
|
28 |
-
|
29 |
-
jQuery.
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
|
|
|
|
|
|
47 |
},
|
48 |
-
|
49 |
-
|
|
|
|
|
|
|
|
|
|
|
50 |
}
|
51 |
-
}
|
52 |
});
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
alert('Unknown error. Please get in contact with us to solve it support@wp-staging.com');
|
66 |
-
},
|
67 |
-
success: function success(data) {
|
68 |
-
jQuery('.wpstg_fivestar').slideUp('fast');
|
69 |
-
return true;
|
70 |
-
},
|
71 |
-
statusCode: {
|
72 |
-
404: function _() {
|
73 |
-
alert('Something went wrong; can\'t find ajax request URL! Please get in contact with us to solve it support@wp-staging.com');
|
74 |
},
|
75 |
-
|
76 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
77 |
}
|
78 |
-
}
|
79 |
});
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
action: 'wpstg_hide_later'
|
88 |
-
},
|
89 |
-
error: function error(xhr, textStatus, errorThrown) {
|
90 |
-
console.log(xhr.status + ' ' + xhr.statusText + '---' + textStatus);
|
91 |
-
console.log(textStatus);
|
92 |
-
alert('Unknown error. Please get in contact with us to solve it support@wp-staging.com');
|
93 |
-
},
|
94 |
-
success: function success(data) {
|
95 |
-
jQuery('.wpstg_fivestar').slideUp('fast');
|
96 |
-
return true;
|
97 |
-
},
|
98 |
-
statusCode: {
|
99 |
-
404: function _() {
|
100 |
-
alert('Something went wrong; can\'t find ajax request URL! Please get in contact with us to solve it support@wp-staging.com');
|
101 |
},
|
102 |
-
|
103 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
104 |
}
|
105 |
-
}
|
106 |
});
|
107 |
-
}
|
108 |
-
}
|
109 |
|
110 |
-
document.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}}', '');
|
111 |
-
document.addEventListener('DOMContentLoaded', function () {
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
var conf = confirm(message);
|
119 |
|
120 |
-
|
121 |
-
|
122 |
-
|
|
|
123 |
}
|
124 |
-
}
|
125 |
});
|
126 |
-
});
|
127 |
-
|
128 |
-
function wpstgFetchVideo() {
|
129 |
-
var tag = document.createElement('script');
|
130 |
-
tag.src = 'https://www.youtube.com/iframe_api';
|
131 |
-
var firstScriptTag = document.getElementsByTagName('script')[0];
|
132 |
-
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
|
133 |
-
}
|
134 |
|
135 |
-
function
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
rel: 0,
|
142 |
-
showinfo: 0,
|
143 |
-
ecver: 2
|
144 |
-
},
|
145 |
-
events: {
|
146 |
-
'onReady': onPlayerReady
|
147 |
-
}
|
148 |
-
});
|
149 |
-
}
|
150 |
|
151 |
-
|
152 |
-
|
153 |
-
}
|
1 |
+
(function () {
|
2 |
+
'use strict';
|
|
|
|
|
|
|
3 |
|
4 |
+
var wpstgTimesWaited = 0;
|
5 |
+
/*
|
6 |
+
Let's wait for jQuery to be available to show the rating.
|
7 |
+
We need it to dispatch AJAX requests.
|
8 |
+
*/
|
9 |
|
10 |
+
var wpstgWaitForJQuery = setInterval(function () {
|
11 |
+
if (wpstgTimesWaited > 100) {
|
12 |
+
// Give up waiting.
|
13 |
+
clearInterval(wpstgWaitForJQuery);
|
14 |
+
}
|
15 |
|
16 |
+
if (typeof jQuery != 'undefined') {
|
17 |
+
wpstgRegisterRatingEvents();
|
18 |
+
clearInterval(wpstgWaitForJQuery);
|
19 |
+
}
|
20 |
|
21 |
+
wpstgTimesWaited = wpstgTimesWaited + 1;
|
22 |
+
}, 100);
|
|
|
|
|
|
|
|
|
23 |
|
24 |
+
function wpstgRegisterRatingEvents() {
|
25 |
+
// Show the rating once jQuery is loaded.
|
26 |
+
jQuery('.wpstg_fivestar').show();
|
27 |
+
/**
|
28 |
+
* Dispatch the request to hide the video after user clicks to rate the plugin.
|
29 |
+
*/
|
30 |
+
|
31 |
+
jQuery(document).on('click', '#wpstg_clicked_deserved_it', function (e) {
|
32 |
+
jQuery.ajax({
|
33 |
+
url: ajaxurl,
|
34 |
+
type: 'POST',
|
35 |
+
data: {
|
36 |
+
action: 'wpstg_hide_rating'
|
37 |
+
},
|
38 |
+
error: function error(xhr, textStatus, errorThrown) {
|
39 |
+
console.log(xhr.status + ' ' + xhr.statusText + '---' + textStatus);
|
40 |
+
console.log(textStatus);
|
41 |
+
alert('Unknown error. Please get in contact with us to solve it support@wp-staging.com');
|
42 |
+
},
|
43 |
+
success: function success(data) {
|
44 |
+
jQuery('.wpstg_fivestar').slideUp('fast');
|
45 |
+
return true;
|
46 |
},
|
47 |
+
statusCode: {
|
48 |
+
404: function _() {
|
49 |
+
alert('Something went wrong; can\'t find ajax request URL! Please get in contact with us to solve it support@wp-staging.com');
|
50 |
+
},
|
51 |
+
500: function _() {
|
52 |
+
alert('Something went wrong; internal server error while processing the request! Please get in contact with us to solve it support@wp-staging.com');
|
53 |
+
}
|
54 |
}
|
55 |
+
});
|
56 |
});
|
57 |
+
jQuery('.wpstg_hide_rating').on('click', function (e) {
|
58 |
+
e.preventDefault();
|
59 |
+
jQuery.ajax({
|
60 |
+
url: ajaxurl,
|
61 |
+
type: 'POST',
|
62 |
+
data: {
|
63 |
+
action: 'wpstg_hide_rating'
|
64 |
+
},
|
65 |
+
error: function error(xhr, textStatus, errorThrown) {
|
66 |
+
console.log(xhr.status + ' ' + xhr.statusText + '---' + textStatus);
|
67 |
+
console.log(textStatus);
|
68 |
+
alert('Unknown error. Please get in contact with us to solve it support@wp-staging.com');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
},
|
70 |
+
success: function success(data) {
|
71 |
+
jQuery('.wpstg_fivestar').slideUp('fast');
|
72 |
+
return true;
|
73 |
+
},
|
74 |
+
statusCode: {
|
75 |
+
404: function _() {
|
76 |
+
alert('Something went wrong; can\'t find ajax request URL! Please get in contact with us to solve it support@wp-staging.com');
|
77 |
+
},
|
78 |
+
500: function _() {
|
79 |
+
alert('Something went wrong; internal server error while processing the request! Please get in contact with us to solve it support@wp-staging.com');
|
80 |
+
}
|
81 |
}
|
82 |
+
});
|
83 |
});
|
84 |
+
jQuery('.wpstg_rate_later').on('click', function (e) {
|
85 |
+
e.preventDefault();
|
86 |
+
jQuery.ajax({
|
87 |
+
url: ajaxurl,
|
88 |
+
type: 'POST',
|
89 |
+
data: {
|
90 |
+
action: 'wpstg_hide_later'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
91 |
},
|
92 |
+
error: function error(xhr, textStatus, errorThrown) {
|
93 |
+
console.log(xhr.status + ' ' + xhr.statusText + '---' + textStatus);
|
94 |
+
console.log(textStatus);
|
95 |
+
alert('Unknown error. Please get in contact with us to solve it support@wp-staging.com');
|
96 |
+
},
|
97 |
+
success: function success(data) {
|
98 |
+
jQuery('.wpstg_fivestar').slideUp('fast');
|
99 |
+
return true;
|
100 |
+
},
|
101 |
+
statusCode: {
|
102 |
+
404: function _() {
|
103 |
+
alert('Something went wrong; can\'t find ajax request URL! Please get in contact with us to solve it support@wp-staging.com');
|
104 |
+
},
|
105 |
+
500: function _() {
|
106 |
+
alert('Something went wrong; internal server error while processing the request! Please get in contact with us to solve it support@wp-staging.com');
|
107 |
+
}
|
108 |
}
|
109 |
+
});
|
110 |
});
|
111 |
+
}
|
|
|
112 |
|
113 |
+
document.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}}', '');
|
114 |
+
document.addEventListener('DOMContentLoaded', function () {
|
115 |
+
var accepted = wpstgYouTubeConfig.accepted;
|
116 |
+
var playerPlaceholder = document.getElementById('welcomeNoticeFree');
|
117 |
+
playerPlaceholder.addEventListener('click', function () {
|
118 |
+
if (!accepted) {
|
119 |
+
var message = wpstgYouTubeConfig.message + '\n \n' + wpstgYouTubeConfig.regards;
|
120 |
+
var conf = confirm(message);
|
|
|
121 |
|
122 |
+
if (conf) {
|
123 |
+
accepted = true;
|
124 |
+
wpstgFetchVideo();
|
125 |
+
}
|
126 |
}
|
127 |
+
});
|
128 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
129 |
|
130 |
+
function wpstgFetchVideo() {
|
131 |
+
var tag = document.createElement('script');
|
132 |
+
tag.src = 'https://www.youtube.com/iframe_api';
|
133 |
+
var firstScriptTag = document.getElementsByTagName('script')[0];
|
134 |
+
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
|
135 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
136 |
|
137 |
+
}());
|
138 |
+
//# sourceMappingURL=wpstg-admin-rating.js.map
|
|
assets/js/dist/wpstg-admin-rating.js.map
ADDED
@@ -0,0 +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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"}
|
assets/js/dist/wpstg-admin-rating.min.js
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
1 |
+
!function(){"use strict";var t=0,e=setInterval((function(){t>100&&clearInterval(e),"undefined"!=typeof jQuery&&(jQuery(".wpstg_fivestar").show(),jQuery(document).on("click","#wpstg_clicked_deserved_it",(function(t){jQuery.ajax({url:ajaxurl,type:"POST",data:{action:"wpstg_hide_rating"},error:function(t,e,n){console.log(t.status+" "+t.statusText+"---"+e),console.log(e),alert("Unknown error. Please get in contact with us to solve it support@wp-staging.com")},success:function(t){return jQuery(".wpstg_fivestar").slideUp("fast"),!0},statusCode:{404:function(){alert("Something went wrong; can't find ajax request URL! Please get in contact with us to solve it support@wp-staging.com")},500:function(){alert("Something went wrong; internal server error while processing the request! Please get in contact with us to solve it support@wp-staging.com")}}})})),jQuery(".wpstg_hide_rating").on("click",(function(t){t.preventDefault(),jQuery.ajax({url:ajaxurl,type:"POST",data:{action:"wpstg_hide_rating"},error:function(t,e,n){console.log(t.status+" "+t.statusText+"---"+e),console.log(e),alert("Unknown error. Please get in contact with us to solve it support@wp-staging.com")},success:function(t){return jQuery(".wpstg_fivestar").slideUp("fast"),!0},statusCode:{404:function(){alert("Something went wrong; can't find ajax request URL! Please get in contact with us to solve it support@wp-staging.com")},500:function(){alert("Something went wrong; internal server error while processing the request! Please get in contact with us to solve it support@wp-staging.com")}}})})),jQuery(".wpstg_rate_later").on("click",(function(t){t.preventDefault(),jQuery.ajax({url:ajaxurl,type:"POST",data:{action:"wpstg_hide_later"},error:function(t,e,n){console.log(t.status+" "+t.statusText+"---"+e),console.log(e),alert("Unknown error. Please get in contact with us to solve it support@wp-staging.com")},success:function(t){return jQuery(".wpstg_fivestar").slideUp("fast"),!0},statusCode:{404:function(){alert("Something went wrong; can't find ajax request URL! Please get in contact with us to solve it support@wp-staging.com")},500:function(){alert("Something went wrong; internal server error while processing the request! Please get in contact with us to solve it support@wp-staging.com")}}})})),clearInterval(e)),t+=1}),100);document.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}}",""),document.addEventListener("DOMContentLoaded",(function(){var t=wpstgYouTubeConfig.accepted;document.getElementById("welcomeNoticeFree").addEventListener("click",(function(){if(!t){var e=wpstgYouTubeConfig.message+"\n \n"+wpstgYouTubeConfig.regards;confirm(e)&&(t=!0,function(){var t=document.createElement("script");t.src="https://www.youtube.com/iframe_api";var e=document.getElementsByTagName("script")[0];e.parentNode.insertBefore(t,e)}())}}))}))}();
|
2 |
+
//# sourceMappingURL=wpstg-admin-rating.min.js.map
|
assets/js/dist/wpstg-admin-rating.min.js.map
ADDED
@@ -0,0 +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"}
|
assets/js/dist/wpstg-admin.js
CHANGED
@@ -1,2837 +1,3913 @@
|
|
1 |
-
|
2 |
-
|
3 |
-
|
4 |
-
|
5 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
|
7 |
-
|
|
|
|
|
|
|
|
|
|
|
8 |
|
9 |
-
function _asyncToGenerator(fn) {
|
|
|
|
|
|
|
|
|
|
|
10 |
|
11 |
-
|
|
|
|
|
12 |
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
isFinished: false,
|
17 |
-
getLogs: false,
|
18 |
-
time: 1,
|
19 |
-
executionTime: false,
|
20 |
-
progressBar: 0
|
21 |
-
};
|
22 |
-
var cache = {
|
23 |
-
elements: []
|
24 |
-
};
|
25 |
-
var timeout;
|
26 |
-
var ajaxSpinner;
|
27 |
-
/**
|
28 |
-
* Get / Set Cache for Selector
|
29 |
-
* @param {String} selector
|
30 |
-
* @return {*}
|
31 |
-
*/
|
32 |
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
} // Create cache and return
|
38 |
|
|
|
|
|
|
|
|
|
39 |
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
*/
|
47 |
|
|
|
|
|
48 |
|
49 |
-
|
50 |
-
|
51 |
-
};
|
52 |
-
/**
|
53 |
-
* Show and Log Error Message
|
54 |
-
* @param {String} message
|
55 |
-
*/
|
56 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
|
58 |
-
|
59 |
-
|
60 |
-
cache.get('#wpstg-cancel-cloning').text('Reset');
|
61 |
-
cache.get('#wpstg-resume-cloning').show();
|
62 |
-
cache.get('#wpstg-error-wrapper').show();
|
63 |
-
cache.get('#wpstg-error-details').show().html(message);
|
64 |
-
cache.get('#wpstg-removing-clone').removeClass('loading');
|
65 |
-
cache.get('.wpstg-loader').hide();
|
66 |
-
$('.wpstg--modal--process--generic-problem').show().html(message);
|
67 |
-
};
|
68 |
-
/**
|
69 |
-
* Show warning during cloning or push process when closing tab or browser, or changing page
|
70 |
-
* @param {beforeunload} event
|
71 |
-
* @return {null}
|
72 |
-
*/
|
73 |
|
|
|
74 |
|
75 |
-
|
76 |
-
|
77 |
-
event.returnValue = 'You MUST leave this window open while cloning/pushing. Please wait...';
|
78 |
-
return null;
|
79 |
-
};
|
80 |
-
/**
|
81 |
-
*
|
82 |
-
* @param obj
|
83 |
-
* @return {boolean}
|
84 |
-
*/
|
85 |
|
|
|
|
|
86 |
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
91 |
}
|
|
|
|
|
92 |
}
|
93 |
|
94 |
-
|
|
|
95 |
}
|
|
|
96 |
/**
|
97 |
-
|
98 |
-
|
99 |
-
* @param prependMessage Overwrite default error message at beginning
|
100 |
-
* @param appendMessage Overwrite default error message at end
|
101 |
-
* @returns void
|
102 |
-
*/
|
103 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
104 |
|
105 |
-
|
106 |
-
|
107 |
-
|
|
|
|
|
|
|
108 |
|
109 |
-
|
110 |
-
|
111 |
-
|
112 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
113 |
}
|
114 |
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
120 |
}
|
121 |
-
};
|
122 |
-
/**
|
123 |
-
*
|
124 |
-
* @param response
|
125 |
-
* @return {{ok}|*}
|
126 |
-
*/
|
127 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
128 |
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
|
134 |
-
|
135 |
-
|
136 |
-
|
|
|
|
|
137 |
|
|
|
|
|
|
|
|
|
|
|
138 |
|
139 |
-
|
140 |
-
|
141 |
-
};
|
142 |
|
143 |
-
var slugify = function slugify(url) {
|
144 |
-
return url.toString().toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '').replace(/\s+/g, '-').replace(/&/g, '-and-').replace(/[^a-z0-9\-]/g, '').replace(/-+/g, '-').replace(/^-*/, '').replace(/-*$/, '');
|
145 |
-
};
|
146 |
/**
|
147 |
-
|
148 |
-
|
149 |
|
|
|
|
|
|
|
|
|
|
|
150 |
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
var urlSpinner = ajaxurl.replace('/admin-ajax.php', '') + '/images/spinner';
|
155 |
-
var timer;
|
156 |
|
157 |
-
|
158 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
159 |
}
|
160 |
|
161 |
-
|
162 |
-
ajaxSpinner = '<img src=\'\'' + urlSpinner + '\' alt=\'\' class=\'ajax-spinner general-spinner\' />';
|
163 |
|
164 |
-
|
165 |
-
var
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
}
|
|
|
|
|
|
|
|
|
170 |
};
|
171 |
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
184 |
-
|
185 |
-
|
186 |
-
|
187 |
-
|
188 |
-
|
189 |
-
})
|
190 |
-
/**
|
191 |
-
* Select tables with certain tbl prefix | NEW
|
192 |
-
* @param obj e
|
193 |
-
* @returns {undefined}
|
194 |
-
*/
|
195 |
-
.on('click', '.wpstg-button-select', function (e) {
|
196 |
-
e.preventDefault();
|
197 |
-
$('#wpstg_select_tables_cloning .wpstg-db-table').each(function () {
|
198 |
-
if (wpstg.isMultisite == 1) {
|
199 |
-
if ($(this).attr('name').match('^' + wpstg.tblprefix + '([^0-9])_*')) {
|
200 |
-
$(this).prop('selected', 'selected');
|
201 |
-
} else {
|
202 |
-
$(this).prop('selected', false);
|
203 |
-
}
|
204 |
}
|
205 |
-
|
206 |
-
if (
|
207 |
-
|
208 |
-
$(this).prop('selected', 'selected');
|
209 |
-
} else {
|
210 |
-
$(this).prop('selected', false);
|
211 |
-
}
|
212 |
}
|
213 |
-
});
|
214 |
-
}) // Expand Directories
|
215 |
-
.on('click', '.wpstg-expand-dirs', function (e) {
|
216 |
-
e.preventDefault();
|
217 |
-
var $this = $(this);
|
218 |
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
|
|
225 |
|
226 |
-
if (this.checked) {
|
227 |
-
$directory.parents('.wpstg-dir').children('.wpstg-check-dir').prop('checked', true);
|
228 |
-
$directory.find('.wpstg-expand-dirs').removeClass('disabled');
|
229 |
-
$directory.find('.wpstg-subdir .wpstg-check-dir').prop('checked', true);
|
230 |
-
} else {
|
231 |
-
$directory.find('.wpstg-dir .wpstg-check-dir').prop('checked', false);
|
232 |
-
$directory.find('.wpstg-expand-dirs, .wpstg-check-subdirs').addClass('disabled');
|
233 |
-
$directory.find('.wpstg-check-subdirs').data('action', 'check').text('check');
|
234 |
-
}
|
235 |
-
}) // When a directory name is Selected
|
236 |
-
.on('change', 'href.wpstg-check-dir', function () {
|
237 |
-
var $directory = $(this).parent('.wpstg-dir');
|
238 |
-
|
239 |
-
if (this.checked) {
|
240 |
-
$directory.parents('.wpstg-dir').children('.wpstg-check-dir').prop('checked', true);
|
241 |
-
$directory.find('.wpstg-expand-dirs').removeClass('disabled');
|
242 |
-
$directory.find('.wpstg-subdir .wpstg-check-dir').prop('checked', true);
|
243 |
-
} else {
|
244 |
-
$directory.find('.wpstg-dir .wpstg-check-dir').prop('checked', false);
|
245 |
-
$directory.find('.wpstg-expand-dirs, .wpstg-check-subdirs').addClass('disabled');
|
246 |
-
$directory.find('.wpstg-check-subdirs').data('action', 'check').text('check');
|
247 |
-
}
|
248 |
-
}) // Check the max length of the clone name and if the clone name already exists
|
249 |
-
.on('keyup', '#wpstg-new-clone-id', function () {
|
250 |
-
// Hide previous errors
|
251 |
-
document.getElementById('wpstg-error-details').style.display = 'none'; // This request was already sent, clear it up!
|
252 |
|
253 |
-
|
254 |
-
|
255 |
-
}
|
256 |
|
257 |
-
|
258 |
-
|
259 |
-
ajax({
|
260 |
-
action: 'wpstg_check_clone',
|
261 |
-
accessToken: wpstg.accessToken,
|
262 |
-
nonce: wpstg.nonce,
|
263 |
-
cloneID: cloneID
|
264 |
-
}, function (response) {
|
265 |
-
if (response.status === 'success') {
|
266 |
-
cache.get('#wpstg-new-clone-id').removeClass('wpstg-error-input');
|
267 |
-
cache.get('#wpstg-start-cloning').removeAttr('disabled');
|
268 |
-
cache.get('#wpstg-clone-id-error').text('').hide();
|
269 |
-
} else {
|
270 |
-
cache.get('#wpstg-new-clone-id').addClass('wpstg-error-input');
|
271 |
-
cache.get('#wpstg-start-cloning').prop('disabled', true);
|
272 |
-
cache.get('#wpstg-clone-id-error').text(response.message).show();
|
273 |
-
}
|
274 |
-
});
|
275 |
-
}, 500);
|
276 |
-
}) // Restart cloning process
|
277 |
-
.on('click', '#wpstg-start-cloning', function () {
|
278 |
-
resetErrors();
|
279 |
-
that.isCancelled = false;
|
280 |
-
that.getLogs = false;
|
281 |
-
that.progressBar = 0;
|
282 |
-
}).on('input', '#wpstg-new-clone-id', function () {
|
283 |
-
if ($('#wpstg-clone-directory').length < 1) {
|
284 |
-
return;
|
285 |
-
}
|
286 |
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
|
293 |
-
|
294 |
-
|
295 |
-
}
|
296 |
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
$('#wpstg_clone_dir').attr('placeholder', path);
|
306 |
-
$('#wpstg_clone_hostname').attr('placeholder', uri);
|
307 |
-
}).on('input', '#wpstg_clone_hostname', function () {
|
308 |
-
if ($(this).val() === '' || validateTargetHost()) {
|
309 |
-
$('#wpstg_clone_hostname_error').remove();
|
310 |
-
return;
|
311 |
}
|
312 |
|
313 |
-
if (
|
314 |
-
|
315 |
}
|
316 |
-
});
|
317 |
-
cloneActions();
|
318 |
-
};
|
319 |
-
/* @returns {boolean} */
|
320 |
-
|
321 |
-
|
322 |
-
var validateTargetHost = function validateTargetHost() {
|
323 |
-
var the_domain = $('#wpstg_clone_hostname').val();
|
324 |
|
325 |
-
|
326 |
-
|
327 |
-
|
328 |
-
|
329 |
-
var reg = /^http(s)?:\/\/.*$/;
|
330 |
|
331 |
-
|
332 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
333 |
}
|
334 |
|
335 |
-
|
336 |
-
};
|
337 |
-
/**
|
338 |
-
* Clone actions
|
339 |
-
*/
|
340 |
|
|
|
|
|
341 |
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
.on('click', '#wpstg-cancel-cloning', function () {
|
346 |
-
if (!confirm('Are you sure you want to cancel cloning process?')) {
|
347 |
-
return false;
|
348 |
}
|
349 |
|
350 |
-
|
351 |
-
|
352 |
-
$this.prop('disabled', true);
|
353 |
-
that.isCancelled = true;
|
354 |
-
that.progressBar = 0;
|
355 |
-
$('#wpstg-processing-status').text('Please wait...this can take up a while.');
|
356 |
-
$('.wpstg-loader, #wpstg-show-log-button').hide();
|
357 |
-
$this.parent().append(ajaxSpinner);
|
358 |
-
cancelCloning();
|
359 |
-
}) // Resume cloning
|
360 |
-
.on('click', '#wpstg-resume-cloning', function () {
|
361 |
-
resetErrors();
|
362 |
-
var $this = $(this);
|
363 |
-
$('#wpstg-try-again, #wpstg-home-link').hide();
|
364 |
-
that.isCancelled = false;
|
365 |
-
$('#wpstg-processing-status').text('Try to resume cloning process...');
|
366 |
-
$('#wpstg-error-details').hide();
|
367 |
-
$('.wpstg-loader').show();
|
368 |
-
$this.parent().append(ajaxSpinner);
|
369 |
-
that.startCloning();
|
370 |
-
}) // Cancel update cloning
|
371 |
-
.on('click', '#wpstg-cancel-cloning-update', function () {
|
372 |
-
resetErrors();
|
373 |
-
var $this = $(this);
|
374 |
-
$('#wpstg-try-again, #wpstg-home-link').hide();
|
375 |
-
$this.prop('disabled', true);
|
376 |
-
that.isCancelled = true;
|
377 |
-
$('#wpstg-cloning-result').text('Please wait...this can take up a while.');
|
378 |
-
$('.wpstg-loader, #wpstg-show-log-button').hide();
|
379 |
-
$this.parent().append(ajaxSpinner);
|
380 |
-
cancelCloningUpdate();
|
381 |
-
}) // Restart cloning
|
382 |
-
.on('click', '#wpstg-restart-cloning', function () {
|
383 |
-
resetErrors();
|
384 |
-
var $this = $(this);
|
385 |
-
$('#wpstg-try-again, #wpstg-home-link').hide();
|
386 |
-
$this.prop('disabled', true);
|
387 |
-
that.isCancelled = true;
|
388 |
-
$('#wpstg-cloning-result').text('Please wait...this can take up a while.');
|
389 |
-
$('.wpstg-loader, #wpstg-show-log-button').hide();
|
390 |
-
$this.parent().append(ajaxSpinner);
|
391 |
-
restart();
|
392 |
-
}) // Delete clone - confirmation
|
393 |
-
.on('click', '.wpstg-remove-clone[data-clone]', function (e) {
|
394 |
-
resetErrors();
|
395 |
-
e.preventDefault();
|
396 |
-
var $existingClones = cache.get('#wpstg-existing-clones');
|
397 |
-
$workFlow.removeClass('active');
|
398 |
-
cache.get('.wpstg-loader').show();
|
399 |
-
ajax({
|
400 |
-
action: 'wpstg_confirm_delete_clone',
|
401 |
-
accessToken: wpstg.accessToken,
|
402 |
-
nonce: wpstg.nonce,
|
403 |
-
clone: $(this).data('clone')
|
404 |
-
}, function (response) {
|
405 |
-
cache.get('#wpstg-removing-clone').html(response);
|
406 |
-
$existingClones.children('img').remove();
|
407 |
-
cache.get('.wpstg-loader').hide();
|
408 |
-
$('html, body').animate({
|
409 |
-
// This logic is meant to be a "scrollBottom"
|
410 |
-
scrollTop: $('#wpstg-remove-clone').offset().top - $(window).height() + $('#wpstg-remove-clone').height() + 50
|
411 |
-
}, 100);
|
412 |
-
}, 'HTML');
|
413 |
-
}) // Delete clone - confirmed
|
414 |
-
.on('click', '#wpstg-remove-clone', function (e) {
|
415 |
-
resetErrors();
|
416 |
-
e.preventDefault();
|
417 |
-
cache.get('#wpstg-removing-clone').addClass('loading');
|
418 |
-
cache.get('.wpstg-loader').show();
|
419 |
-
deleteClone($(this).data('clone'));
|
420 |
-
}) // Cancel deleting clone
|
421 |
-
.on('click', '#wpstg-cancel-removing', function (e) {
|
422 |
-
e.preventDefault();
|
423 |
-
$('.wpstg-clone').removeClass('active');
|
424 |
-
cache.get('#wpstg-removing-clone').html('');
|
425 |
-
}) // Update
|
426 |
-
.on('click', '.wpstg-execute-clone', function (e) {
|
427 |
-
e.preventDefault();
|
428 |
-
var clone = $(this).data('clone');
|
429 |
-
$workFlow.addClass('loading');
|
430 |
-
ajax({
|
431 |
-
action: 'wpstg_scanning',
|
432 |
-
clone: clone,
|
433 |
-
accessToken: wpstg.accessToken,
|
434 |
-
nonce: wpstg.nonce
|
435 |
-
}, function (response) {
|
436 |
-
if (response.length < 1) {
|
437 |
-
showError('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.');
|
438 |
-
}
|
439 |
-
|
440 |
-
$workFlow.removeClass('loading').html(response); // register check disk space function for clone update process.
|
441 |
|
442 |
-
|
443 |
-
|
444 |
-
}, 'HTML');
|
445 |
-
}) // Reset Clone
|
446 |
-
.on('click', '.wpstg-reset-clone', function (e) {
|
447 |
-
e.preventDefault();
|
448 |
-
var clone = $(this).data('clone');
|
449 |
-
Swal.fire({
|
450 |
-
title: '',
|
451 |
-
icon: 'warning',
|
452 |
-
html: 'Do you really want to reset this staging site with the current state of the production site? <br> <span style="color:red;">This will delete all your modifications!</span>',
|
453 |
-
width: '650px',
|
454 |
-
focusConfirm: false,
|
455 |
-
customClass: {
|
456 |
-
confirmButton: 'wpstg-confirm-reset-clone'
|
457 |
-
},
|
458 |
-
confirmButtonText: 'Reset Clone',
|
459 |
-
showCancelButton: true
|
460 |
-
}).then(function (result) {
|
461 |
-
if (result.value) {
|
462 |
-
resetClone(clone);
|
463 |
}
|
464 |
});
|
465 |
-
|
466 |
-
|
467 |
-
|
468 |
-
|
469 |
-
|
470 |
-
|
471 |
-
|
472 |
-
* @param string dataType
|
473 |
-
* @param bool showErrors
|
474 |
-
* @param int tryCount
|
475 |
-
* @param float incrementRatio
|
476 |
-
*/
|
477 |
-
|
478 |
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
483 |
|
484 |
-
|
485 |
-
|
486 |
-
|
|
|
487 |
|
488 |
-
|
489 |
-
|
490 |
-
|
491 |
|
492 |
-
|
493 |
-
|
494 |
-
|
495 |
-
incrementRatio = parseInt(incrementRatio);
|
496 |
|
497 |
-
|
498 |
-
|
499 |
-
}
|
500 |
|
501 |
-
|
502 |
-
|
503 |
-
type: 'POST',
|
504 |
-
dataType: dataType,
|
505 |
-
cache: false,
|
506 |
-
data: data,
|
507 |
-
error: function error(xhr, textStatus, errorThrown) {
|
508 |
-
console.log(xhr.status + ' ' + xhr.statusText + '---' + textStatus); // try again after 10 seconds
|
509 |
|
510 |
-
|
|
|
|
|
511 |
|
512 |
-
|
513 |
-
|
514 |
-
|
515 |
-
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
}
|
526 |
-
}
|
527 |
-
|
528 |
-
|
529 |
-
if (tryCount >= retryLimit) {
|
530 |
-
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.');
|
531 |
-
}
|
532 |
-
},
|
533 |
-
500: function _() {
|
534 |
-
if (tryCount >= retryLimit) {
|
535 |
-
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.');
|
536 |
-
}
|
537 |
-
},
|
538 |
-
504: function _() {
|
539 |
-
if (tryCount > retryLimit) {
|
540 |
-
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\ ');
|
541 |
-
}
|
542 |
-
},
|
543 |
-
502: function _() {
|
544 |
-
if (tryCount >= retryLimit) {
|
545 |
-
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\ ');
|
546 |
-
}
|
547 |
-
},
|
548 |
-
503: function _() {
|
549 |
-
if (tryCount >= retryLimit) {
|
550 |
-
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\ ');
|
551 |
-
}
|
552 |
-
},
|
553 |
-
429: function _() {
|
554 |
-
if (tryCount >= retryLimit) {
|
555 |
-
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\ ');
|
556 |
-
}
|
557 |
-
},
|
558 |
-
403: function _() {
|
559 |
-
if (tryCount >= retryLimit) {
|
560 |
-
showError('Refresh page or login again! The process should be finished successfully. \n\ ');
|
561 |
-
}
|
562 |
}
|
563 |
-
}
|
564 |
-
});
|
565 |
-
};
|
566 |
-
/**
|
567 |
-
* Next / Previous Step Clicks to Navigate Through Staging Job
|
568 |
-
*/
|
569 |
|
|
|
|
|
|
|
|
|
570 |
|
571 |
-
|
572 |
-
|
573 |
-
|
574 |
-
|
575 |
-
e.preventDefault();
|
576 |
-
var $this = $(this);
|
577 |
-
var isScan = false;
|
578 |
|
579 |
-
|
580 |
-
$('#wpstg_clone_hostname').focus();
|
581 |
-
return false;
|
582 |
-
}
|
583 |
|
584 |
-
|
585 |
-
|
586 |
-
|
587 |
|
588 |
-
|
589 |
-
|
590 |
}
|
591 |
|
592 |
-
if (
|
593 |
-
|
|
|
|
|
594 |
}
|
595 |
-
}
|
|
|
|
|
|
|
596 |
|
|
|
|
|
597 |
|
598 |
-
|
599 |
-
|
600 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
601 |
|
602 |
-
|
603 |
-
|
604 |
-
|
605 |
-
|
606 |
-
|
607 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
608 |
}
|
609 |
|
610 |
-
|
611 |
-
|
612 |
-
|
613 |
-
e.preventDefault();
|
614 |
-
cache.get('.wpstg-loader').removeClass('wpstg-finished');
|
615 |
-
cache.get('.wpstg-loader').hide();
|
616 |
-
loadOverview();
|
617 |
-
});
|
618 |
-
};
|
619 |
-
/**
|
620 |
-
* Get Included (Checked) Database Tables
|
621 |
-
* @return {Array}
|
622 |
-
*/
|
623 |
|
|
|
|
|
|
|
|
|
|
|
624 |
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
includedTables.push(this.value);
|
629 |
-
});
|
630 |
-
return includedTables;
|
631 |
-
};
|
632 |
-
/**
|
633 |
-
* Get Excluded (Unchecked) Database Tables
|
634 |
-
* Not used anymore!
|
635 |
-
* @return {Array}
|
636 |
-
*/
|
637 |
|
|
|
|
|
|
|
638 |
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
643 |
-
|
644 |
-
|
645 |
-
|
646 |
-
/**
|
647 |
-
* Get Included Directories
|
648 |
-
* @return {string}
|
649 |
-
*/
|
650 |
|
|
|
|
|
651 |
|
652 |
-
|
653 |
-
|
654 |
-
|
655 |
-
var $this = $(this);
|
656 |
-
includedDirectories.push(encodeURIComponent($this.val()));
|
657 |
-
});
|
658 |
-
return includedDirectories.join(wpstg.settings.directorySeparator);
|
659 |
-
};
|
660 |
-
/**
|
661 |
-
* Get Excluded Directories
|
662 |
-
* @return {string}
|
663 |
-
*/
|
664 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
665 |
|
666 |
-
var getExcludedDirectories = function getExcludedDirectories() {
|
667 |
-
var excludedDirectories = [];
|
668 |
-
$('.wpstg-dir input:not(:checked).wpstg-root').each(function () {
|
669 |
-
var $this = $(this);
|
670 |
-
excludedDirectories.push(encodeURIComponent($this.val()));
|
671 |
-
});
|
672 |
-
return excludedDirectories.join(wpstg.settings.directorySeparator);
|
673 |
-
};
|
674 |
/**
|
675 |
-
*
|
676 |
-
* All directories except wp-content, wp-admin, wp-includes
|
677 |
-
* @return {string}
|
678 |
*/
|
679 |
|
|
|
|
|
|
|
|
|
|
|
680 |
|
681 |
-
|
682 |
-
|
683 |
-
|
684 |
-
$('.wpstg-dir input:checked.wpstg-extra').each(function () {
|
685 |
-
var $this = $(this);
|
686 |
-
extraDirectories.push(encodeURIComponent($this.val()));
|
687 |
-
}); // Add any other custom selected extra directories
|
688 |
|
689 |
-
|
690 |
-
|
|
|
|
|
691 |
}
|
692 |
|
693 |
-
var
|
694 |
-
return extraDirectories.concat(extraCustomDirectories).join(wpstg.settings.directorySeparator);
|
695 |
-
};
|
696 |
-
/**
|
697 |
-
* Verify External Database for Cloning
|
698 |
-
*/
|
699 |
|
|
|
|
|
700 |
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
-
|
707 |
-
|
708 |
-
|
709 |
-
|
710 |
-
|
711 |
-
|
712 |
-
|
713 |
-
|
714 |
-
|
715 |
-
|
716 |
-
|
717 |
-
|
718 |
-
|
|
|
719 |
|
720 |
-
|
721 |
-
|
722 |
-
|
723 |
return;
|
724 |
}
|
725 |
|
726 |
-
|
727 |
-
|
728 |
-
proceedCloning($this, workflow);
|
729 |
-
return;
|
730 |
-
}
|
731 |
|
732 |
-
|
733 |
-
|
734 |
-
|
735 |
-
response.checks.forEach(function (x) {
|
736 |
-
var icon = '<i style="color: #00ff00">✔</i>';
|
737 |
|
738 |
-
|
739 |
-
|
740 |
-
|
741 |
|
742 |
-
|
743 |
-
|
744 |
-
|
745 |
-
|
746 |
-
|
747 |
-
|
748 |
-
|
749 |
-
|
750 |
-
|
751 |
-
|
752 |
-
|
753 |
-
|
754 |
-
|
755 |
-
|
756 |
-
|
|
|
|
|
757 |
});
|
758 |
-
return;
|
759 |
}
|
|
|
760 |
|
761 |
-
|
762 |
-
|
763 |
-
|
764 |
-
|
765 |
-
focusConfirm: true,
|
766 |
-
confirmButtonText: 'Ok',
|
767 |
-
showCancelButton: false
|
768 |
});
|
769 |
-
|
770 |
-
}, 'json', false);
|
771 |
-
};
|
772 |
-
/**
|
773 |
-
* Get Cloning Step Data
|
774 |
-
*/
|
775 |
|
|
|
|
|
|
|
|
|
776 |
|
777 |
-
|
778 |
-
|
779 |
-
|
|
|
|
|
780 |
}
|
|
|
|
|
|
|
|
|
|
|
781 |
|
782 |
-
|
783 |
-
|
784 |
-
|
785 |
-
var includedDirectories = getIncludedDirectories();
|
786 |
-
var excludedDirectories = getExcludedDirectories(); // only send that one whose size is low
|
787 |
-
// same reason as above to keep request size small
|
788 |
-
|
789 |
-
if (includedDirectories.length <= excludedDirectories.length) {
|
790 |
-
that.data.includedDirectories = includedDirectories;
|
791 |
-
that.data.areDirectoriesIncluded = true;
|
792 |
-
} else {
|
793 |
-
that.data.excludedDirectories = excludedDirectories;
|
794 |
-
that.data.areDirectoriesIncluded = false;
|
795 |
-
}
|
796 |
|
797 |
-
|
798 |
-
|
799 |
-
|
800 |
-
|
801 |
-
|
802 |
-
that.data.databaseDatabase = $('#wpstg_db_database').val();
|
803 |
-
that.data.databasePrefix = $('#wpstg_db_prefix').val();
|
804 |
-
var cloneDir = $('#wpstg_clone_dir').val();
|
805 |
-
that.data.cloneDir = encodeURIComponent($.trim(cloneDir));
|
806 |
-
that.data.cloneHostname = $('#wpstg_clone_hostname').val();
|
807 |
-
that.data.emailsAllowed = $('#wpstg_allow_emails').is(':checked');
|
808 |
-
that.data.uploadsSymlinked = $('#wpstg_symlink_upload').is(':checked');
|
809 |
-
that.data.cleanPluginsThemes = $('#wpstg-clean-plugins-themes').is(':checked');
|
810 |
-
that.data.cleanUploadsDir = $('#wpstg-clean-uploads').is(':checked');
|
811 |
-
};
|
812 |
-
|
813 |
-
var proceedCloning = function proceedCloning($this, workflow) {
|
814 |
-
// Add loading overlay
|
815 |
-
workflow.addClass('loading'); // Prepare data
|
816 |
-
|
817 |
-
that.data = {
|
818 |
-
action: $this.data('action'),
|
819 |
-
accessToken: wpstg.accessToken,
|
820 |
-
nonce: wpstg.nonce
|
821 |
-
}; // Cloning data
|
822 |
-
|
823 |
-
getCloningData();
|
824 |
-
console.log(that.data);
|
825 |
-
sendCloningAjax(workflow);
|
826 |
-
};
|
827 |
-
|
828 |
-
var sendCloningAjax = function sendCloningAjax(workflow) {
|
829 |
-
// Send ajax request
|
830 |
-
ajax(that.data, function (response) {
|
831 |
-
// Undefined Error
|
832 |
-
if (false === response) {
|
833 |
-
showError('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 \'' + 'and try again. If that does not help, ' + '<a href=\'https://wp-staging.com/support/\' target=\'_blank\'>open a support ticket</a> ');
|
834 |
-
}
|
835 |
-
|
836 |
-
if (response.length < 1) {
|
837 |
-
showError('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 \'' + 'and try again. If that does not help, ' + '<a href=\'https://wp-staging.com/support/\' target=\'_blank\'>open a support ticket</a> ');
|
838 |
-
} // Styling of elements
|
839 |
-
|
840 |
-
|
841 |
-
workflow.removeClass('loading').html(response);
|
842 |
-
|
843 |
-
if (that.data.action === 'wpstg_scanning') {
|
844 |
-
that.switchStep(2);
|
845 |
-
} else if (that.data.action === 'wpstg_cloning' || that.data.action === 'wpstg_update' || that.data.action === 'wpstg_reset') {
|
846 |
-
that.switchStep(3);
|
847 |
-
} // Start cloning
|
848 |
-
|
849 |
-
|
850 |
-
that.startCloning();
|
851 |
-
}, 'HTML');
|
852 |
-
};
|
853 |
-
|
854 |
-
var resetClone = function resetClone(clone) {
|
855 |
-
that.data = {
|
856 |
-
action: 'wpstg_reset',
|
857 |
-
accessToken: wpstg.accessToken,
|
858 |
-
nonce: wpstg.nonce,
|
859 |
-
cloneID: clone
|
860 |
-
};
|
861 |
-
var $workFlow = cache.get('#wpstg-workflow');
|
862 |
-
sendCloningAjax($workFlow);
|
863 |
-
};
|
864 |
-
/**
|
865 |
-
* Loads Overview (first step) of Staging Job
|
866 |
-
*/
|
867 |
|
|
|
|
|
|
|
|
|
868 |
|
869 |
-
|
870 |
-
|
871 |
-
|
872 |
-
ajax({
|
873 |
-
action: 'wpstg_overview',
|
874 |
-
accessToken: wpstg.accessToken,
|
875 |
-
nonce: wpstg.nonce
|
876 |
-
}, function (response) {
|
877 |
-
if (response.length < 1) {
|
878 |
-
showError('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.');
|
879 |
}
|
880 |
|
881 |
-
var
|
882 |
-
|
883 |
-
|
884 |
-
}, 'HTML');
|
885 |
-
that.switchStep(1);
|
886 |
-
cache.get('.wpstg-step3-cloning').show();
|
887 |
-
cache.get('.wpstg-step3-pushing').hide();
|
888 |
-
};
|
889 |
-
/**
|
890 |
-
* Load Tabs
|
891 |
-
*/
|
892 |
|
|
|
|
|
|
|
|
|
|
|
|
|
893 |
|
894 |
-
|
895 |
-
|
896 |
-
|
897 |
-
|
898 |
-
|
899 |
-
$this.toggleClass('expand');
|
900 |
-
$section.slideToggle();
|
901 |
|
902 |
-
|
903 |
-
|
904 |
-
|
905 |
-
$this.find('.wpstg-tab-triangle').html('►');
|
906 |
}
|
907 |
-
});
|
908 |
-
};
|
909 |
-
/**
|
910 |
-
* Delete Clone
|
911 |
-
* @param {String} clone
|
912 |
-
*/
|
913 |
|
|
|
|
|
914 |
|
915 |
-
|
916 |
-
|
917 |
-
|
918 |
-
|
919 |
-
|
920 |
-
accessToken: wpstg.accessToken,
|
921 |
-
nonce: wpstg.nonce,
|
922 |
-
excludedTables: getExcludedTables(),
|
923 |
-
deleteDir: deleteDir
|
924 |
-
}, function (response) {
|
925 |
-
if (response) {
|
926 |
-
showAjaxFatalError(response); // Finished
|
927 |
-
|
928 |
-
if ('undefined' !== typeof response["delete"] && (response["delete"] === 'finished' || response["delete"] === 'unfinished')) {
|
929 |
-
cache.get('#wpstg-removing-clone').removeClass('loading').html('');
|
930 |
-
|
931 |
-
if (response["delete"] === 'finished') {
|
932 |
-
$('.wpstg-clone#' + clone).remove();
|
933 |
-
}
|
934 |
-
|
935 |
-
if ($('.wpstg-clone').length < 1) {
|
936 |
-
cache.get('#wpstg-existing-clones').find('h3').text('');
|
937 |
-
}
|
938 |
|
939 |
-
|
940 |
-
|
941 |
}
|
942 |
-
} // continue
|
943 |
-
|
944 |
-
|
945 |
-
if (true !== response) {
|
946 |
-
deleteClone(clone);
|
947 |
-
return;
|
948 |
}
|
949 |
-
});
|
950 |
-
};
|
951 |
-
/**
|
952 |
-
* Cancel Cloning Process
|
953 |
-
*/
|
954 |
-
|
955 |
|
956 |
-
|
957 |
-
|
|
|
|
|
|
|
|
|
958 |
|
959 |
-
|
960 |
-
return
|
961 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
962 |
|
963 |
-
|
964 |
-
|
965 |
-
|
966 |
-
|
967 |
-
nonce: wpstg.nonce
|
968 |
-
}, function (response) {
|
969 |
-
if (response && 'undefined' !== typeof response["delete"] && response["delete"] === 'finished') {
|
970 |
-
cache.get('.wpstg-loader').hide(); // Load overview
|
971 |
-
|
972 |
-
loadOverview();
|
973 |
-
return;
|
974 |
-
}
|
975 |
-
|
976 |
-
if (true !== response) {
|
977 |
-
// continue
|
978 |
-
cancelCloning();
|
979 |
-
return;
|
980 |
-
} // Load overview
|
981 |
|
|
|
|
|
982 |
|
983 |
-
loadOverview();
|
984 |
-
});
|
985 |
-
};
|
986 |
/**
|
987 |
-
*
|
988 |
*/
|
|
|
|
|
|
|
|
|
|
|
989 |
|
990 |
-
|
991 |
-
|
992 |
-
if (true === that.isFinished) {
|
993 |
-
return true;
|
994 |
}
|
995 |
|
996 |
-
|
997 |
-
action: 'wpstg_cancel_update',
|
998 |
-
clone: that.data.cloneID,
|
999 |
-
accessToken: wpstg.accessToken,
|
1000 |
-
nonce: wpstg.nonce
|
1001 |
-
}, function (response) {
|
1002 |
-
if (response && 'undefined' !== typeof response["delete"] && response["delete"] === 'finished') {
|
1003 |
-
// Load overview
|
1004 |
-
loadOverview();
|
1005 |
-
return;
|
1006 |
-
}
|
1007 |
|
1008 |
-
|
1009 |
-
|
1010 |
-
cancelCloningUpdate();
|
1011 |
-
return;
|
1012 |
-
} // Load overview
|
1013 |
|
|
|
|
|
|
|
1014 |
|
1015 |
-
|
1016 |
-
|
1017 |
-
|
1018 |
-
/**
|
1019 |
-
* Cancel Cloning Process
|
1020 |
-
*/
|
1021 |
|
|
|
|
|
|
|
|
|
|
|
|
|
1022 |
|
1023 |
-
|
1024 |
-
|
1025 |
-
return true;
|
1026 |
-
}
|
1027 |
|
1028 |
-
|
1029 |
-
|
1030 |
-
// clone: that.data.cloneID,
|
1031 |
-
accessToken: wpstg.accessToken,
|
1032 |
-
nonce: wpstg.nonce
|
1033 |
-
}, function (response) {
|
1034 |
-
if (response && 'undefined' !== typeof response["delete"] && response["delete"] === 'finished') {
|
1035 |
-
// Load overview
|
1036 |
-
loadOverview();
|
1037 |
-
return;
|
1038 |
}
|
1039 |
|
1040 |
-
if (
|
1041 |
-
|
1042 |
-
|
1043 |
-
return;
|
1044 |
-
} // Load overview
|
1045 |
-
|
1046 |
|
1047 |
-
|
1048 |
-
|
1049 |
-
|
1050 |
-
|
1051 |
-
|
1052 |
-
|
1053 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1054 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1055 |
|
1056 |
-
|
1057 |
-
|
1058 |
|
1059 |
-
if ('undefined' !== typeof $div[0]) {
|
1060 |
-
$div.scrollTop($div[0].scrollHeight);
|
1061 |
-
}
|
1062 |
-
};
|
1063 |
/**
|
1064 |
-
*
|
1065 |
-
* @param string log
|
1066 |
-
* @return void
|
1067 |
*/
|
1068 |
|
1069 |
-
|
1070 |
-
|
1071 |
-
|
1072 |
-
|
1073 |
-
$.each(log, function (index, value) {
|
1074 |
-
if (value === null) {
|
1075 |
-
return;
|
1076 |
-
}
|
1077 |
-
|
1078 |
-
if (value.type === 'ERROR') {
|
1079 |
-
cache.get('.wpstg-log-details').append('<span style="color:red;">[' + value.type + ']</span>-' + '[' + value.date + '] ' + value.message + '</br>');
|
1080 |
-
} else {
|
1081 |
-
cache.get('.wpstg-log-details').append('[' + value.type + ']-' + '[' + value.date + '] ' + value.message + '</br>');
|
1082 |
-
}
|
1083 |
-
});
|
1084 |
-
} else {
|
1085 |
-
cache.get('.wpstg-log-details').append('[' + log.type + ']-' + '[' + log.date + '] ' + log.message + '</br>');
|
1086 |
}
|
1087 |
-
}
|
1088 |
-
|
1089 |
-
logscroll();
|
1090 |
-
};
|
1091 |
-
/**
|
1092 |
-
* Check diskspace
|
1093 |
-
* @return string json
|
1094 |
-
*/
|
1095 |
-
|
1096 |
-
|
1097 |
-
var checkDiskSpace = function checkDiskSpace() {
|
1098 |
-
cache.get('#wpstg-check-space').on('click', function (e) {
|
1099 |
-
cache.get('.wpstg-loader').show();
|
1100 |
-
console.log('check disk space');
|
1101 |
-
ajax({
|
1102 |
-
action: 'wpstg_check_disk_space',
|
1103 |
-
accessToken: wpstg.accessToken,
|
1104 |
-
nonce: wpstg.nonce
|
1105 |
-
}, function (response) {
|
1106 |
-
if (false === response) {
|
1107 |
-
cache.get('#wpstg-clone-id-error').text('Can not detect required disk space').show();
|
1108 |
-
cache.get('.wpstg-loader').hide();
|
1109 |
-
return;
|
1110 |
-
} // Show required disk space
|
1111 |
-
|
1112 |
-
|
1113 |
-
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();
|
1114 |
-
cache.get('.wpstg-loader').hide();
|
1115 |
-
}, 'json', false);
|
1116 |
-
});
|
1117 |
-
};
|
1118 |
|
1119 |
-
|
1120 |
-
|
1121 |
-
var $this = $(this);
|
1122 |
-
var target = $this.attr('data-target');
|
1123 |
-
var $wrapper = $this.parents('.wpstg--tab--wrapper');
|
1124 |
-
var $menuItems = $wrapper.find('.wpstg--tab--header a[data-target]');
|
1125 |
-
var $contents = $wrapper.find('.wpstg--tab--contents > .wpstg--tab--content');
|
1126 |
-
$contents.filter('.wpstg--tab--active:not(.wpstg--tab--active' + target + ')').removeClass('wpstg--tab--active');
|
1127 |
-
$menuItems.not($this).removeClass('wpstg--tab--active');
|
1128 |
-
$this.addClass('wpstg--tab--active');
|
1129 |
-
$(target).addClass('wpstg--tab--active');
|
1130 |
-
|
1131 |
-
if ('#wpstg--tab--backup' === target) {
|
1132 |
-
that.backups.init();
|
1133 |
}
|
1134 |
|
1135 |
-
if (
|
1136 |
-
|
1137 |
}
|
1138 |
-
});
|
1139 |
-
};
|
1140 |
-
/**
|
1141 |
-
* Show or hide animated loading icon
|
1142 |
-
* @param isLoading bool
|
1143 |
-
*/
|
1144 |
|
|
|
|
|
|
|
1145 |
|
1146 |
-
|
1147 |
-
|
1148 |
-
|
1149 |
-
|
1150 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
1151 |
}
|
1152 |
-
};
|
1153 |
-
/**
|
1154 |
-
* Count up processing execution time
|
1155 |
-
* @param string status
|
1156 |
-
* @return html
|
1157 |
-
*/
|
1158 |
|
|
|
1159 |
|
1160 |
-
|
1161 |
-
|
1162 |
-
var time = that.time;
|
1163 |
-
that.time = 1;
|
1164 |
-
clearInterval(that.executionTime);
|
1165 |
-
return that.convertSeconds(time);
|
1166 |
-
}
|
1167 |
-
|
1168 |
-
that.executionTime = setInterval(function () {
|
1169 |
-
if (null !== document.getElementById('wpstg-processing-timer')) {
|
1170 |
-
document.getElementById('wpstg-processing-timer').innerHTML = 'Elapsed Time: ' + that.convertSeconds(that.time);
|
1171 |
-
}
|
1172 |
|
1173 |
-
|
1174 |
|
1175 |
-
if (
|
1176 |
-
|
1177 |
-
|
1178 |
}
|
1179 |
-
}, 1000);
|
1180 |
-
};
|
1181 |
-
/**
|
1182 |
-
* Convert seconds to hourly format
|
1183 |
-
* @param int seconds
|
1184 |
-
* @return string
|
1185 |
-
*/
|
1186 |
-
|
1187 |
-
|
1188 |
-
that.convertSeconds = function (seconds) {
|
1189 |
-
var date = new Date(null);
|
1190 |
-
date.setSeconds(seconds); // specify value for SECONDS here
|
1191 |
-
|
1192 |
-
return date.toISOString().substr(11, 8);
|
1193 |
-
};
|
1194 |
-
/**
|
1195 |
-
* Start Cloning Process
|
1196 |
-
* @type {Function}
|
1197 |
-
*/
|
1198 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1199 |
|
1200 |
-
|
1201 |
-
|
|
|
|
|
|
|
|
|
1202 |
|
1203 |
-
|
|
|
|
|
1204 |
|
1205 |
-
|
1206 |
-
|
1207 |
-
|
|
|
|
|
|
|
1208 |
|
1209 |
-
|
|
|
|
|
|
|
|
|
|
|
1210 |
|
1211 |
-
|
1212 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1213 |
|
1214 |
-
|
1215 |
-
|
1216 |
-
|
1217 |
-
|
1218 |
-
cache.get('#wpstg-resume-cloning').hide();
|
1219 |
-
cache.get('#wpstg-error-details').hide(); // Clone Database
|
1220 |
-
|
1221 |
-
setTimeout(function () {
|
1222 |
-
// cloneDatabase();
|
1223 |
-
window.addEventListener('beforeunload', warnIfClosingDuringProcess);
|
1224 |
-
processing();
|
1225 |
-
}, wpstg.delayReq);
|
1226 |
-
that.timer('start');
|
1227 |
}
|
1228 |
/**
|
1229 |
-
*
|
1230 |
-
* @return
|
1231 |
*/
|
|
|
1232 |
|
|
|
|
|
|
|
|
|
|
|
|
|
1233 |
|
1234 |
-
|
1235 |
-
|
1236 |
-
|
1237 |
-
|
1238 |
-
|
1239 |
-
|
1240 |
-
|
1241 |
-
|
1242 |
-
|
1243 |
-
|
1244 |
-
|
1245 |
-
|
1246 |
-
|
1247 |
-
|
1248 |
-
|
1249 |
-
excludedDirectories: getExcludedDirectories(),
|
1250 |
-
extraDirectories: getIncludedExtraDirectories()
|
1251 |
-
}, function (response) {
|
1252 |
-
showAjaxFatalError(response); // Add Log messages
|
1253 |
-
|
1254 |
-
if ('undefined' !== typeof response.last_msg && response.last_msg) {
|
1255 |
-
getLogs(response.last_msg);
|
1256 |
-
} // Continue processing
|
1257 |
-
|
1258 |
|
1259 |
-
|
1260 |
-
|
1261 |
-
|
1262 |
-
|
1263 |
-
|
1264 |
-
|
1265 |
-
|
1266 |
-
|
1267 |
-
|
1268 |
-
|
1269 |
-
|
1270 |
-
|
1271 |
-
|
1272 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1273 |
}
|
1274 |
|
1275 |
-
;
|
1276 |
-
}
|
1277 |
-
|
1278 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1279 |
|
1280 |
-
|
1281 |
-
|
1282 |
-
|
1283 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1284 |
|
1285 |
-
|
|
|
|
|
1286 |
|
1287 |
-
|
1288 |
-
|
1289 |
-
|
1290 |
|
1291 |
-
|
1292 |
-
|
1293 |
-
|
1294 |
-
$('#wpstg-processing-status').text('Succesfully finished');
|
1295 |
-
cache.get('#wpstg_staging_name').html(that.data.cloneID);
|
1296 |
-
cache.get('#wpstg-finished-result').show();
|
1297 |
-
cache.get('#wpstg-cancel-cloning').hide();
|
1298 |
-
cache.get('#wpstg-resume-cloning').hide();
|
1299 |
-
cache.get('#wpstg-cancel-cloning-update').prop('disabled', true);
|
1300 |
-
var $link1 = cache.get('#wpstg-clone-url-1');
|
1301 |
-
var $link = cache.get('#wpstg-clone-url');
|
1302 |
-
$link1.attr('href', response.url);
|
1303 |
-
$link1.html(response.url);
|
1304 |
-
$link.attr('href', response.url);
|
1305 |
-
cache.get('#wpstg-remove-clone').data('clone', that.data.cloneID); // Finished
|
1306 |
-
|
1307 |
-
that.isFinished = true;
|
1308 |
-
that.timer('stop');
|
1309 |
-
cache.get('.wpstg-loader').hide();
|
1310 |
-
cache.get('#wpstg-processing-header').html('Processing Complete');
|
1311 |
-
return false;
|
1312 |
-
}
|
1313 |
-
/**
|
1314 |
-
* Add percentage progress bar
|
1315 |
-
* @param object response
|
1316 |
-
* @return {Boolean}
|
1317 |
-
*/
|
1318 |
|
|
|
|
|
1319 |
|
1320 |
-
|
1321 |
-
|
1322 |
-
return false;
|
1323 |
}
|
1324 |
|
1325 |
-
if (
|
1326 |
-
|
1327 |
-
cache.get('#wpstg-processing-status').html(response.percentage.toFixed(0) + '%' + ' - Step 1 of 4 Cloning Database Tables...');
|
1328 |
}
|
1329 |
|
1330 |
-
|
1331 |
-
cache.get('#wpstg-progress-db').css('background-color', '#3bc36b');
|
1332 |
-
cache.get('#wpstg-progress-db').html('1. Database'); // Assumption: All previous steps are done.
|
1333 |
-
// This avoids bugs where some steps are skipped and the progress bar is incomplete as a result
|
1334 |
|
1335 |
-
|
1336 |
-
|
1337 |
-
|
1338 |
-
|
1339 |
-
|
1340 |
-
if (response.job === 'directories') {
|
1341 |
-
cache.get('#wpstg-progress-sr').css('background-color', '#3bc36b');
|
1342 |
-
cache.get('#wpstg-progress-sr').html('2. Data');
|
1343 |
-
cache.get('#wpstg-progress-sr').width('10%');
|
1344 |
-
cache.get('#wpstg-progress-dirs').width(response.percentage * 0.1 + '%').html(response.percentage + '%');
|
1345 |
-
cache.get('#wpstg-processing-status').html(response.percentage.toFixed(0) + '%' + ' - Step 3 of 4 Getting files...');
|
1346 |
}
|
|
|
1347 |
|
1348 |
-
|
1349 |
-
|
1350 |
-
cache.get('#wpstg-progress-dirs').html('3. Files');
|
1351 |
-
cache.get('#wpstg-progress-dirs').width('10%');
|
1352 |
-
cache.get('#wpstg-progress-files').width(response.percentage * 0.6 + '%').html(response.percentage + '%');
|
1353 |
-
cache.get('#wpstg-processing-status').html(response.percentage.toFixed(0) + '%' + ' - Step 4 of 4 Copy files...');
|
1354 |
-
}
|
1355 |
|
1356 |
-
if (
|
1357 |
-
|
1358 |
-
|
1359 |
-
|
1360 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1361 |
}
|
1362 |
};
|
1363 |
-
};
|
1364 |
|
1365 |
-
|
1366 |
-
|
1367 |
-
cache.get('.wpstg-step' + step).addClass('wpstg-current-step');
|
1368 |
-
};
|
1369 |
-
/**
|
1370 |
-
* Initiation
|
1371 |
-
* @type {Function}
|
1372 |
-
*/
|
1373 |
|
|
|
|
|
|
|
|
|
|
|
|
|
1374 |
|
1375 |
-
|
1376 |
-
|
1377 |
-
|
1378 |
-
|
1379 |
-
|
1380 |
-
|
1381 |
-
|
1382 |
-
|
1383 |
-
|
1384 |
-
|
1385 |
-
|
1386 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1387 |
|
|
|
1388 |
|
1389 |
-
|
1390 |
-
|
1391 |
-
|
1392 |
-
|
1393 |
-
|
1394 |
-
|
1395 |
-
|
1396 |
-
|
1397 |
-
|
1398 |
-
|
1399 |
-
|
1400 |
-
|
1401 |
-
|
1402 |
-
|
1403 |
-
|
1404 |
-
|
1405 |
-
|
1406 |
-
|
1407 |
-
|
1408 |
-
|
1409 |
-
|
1410 |
-
|
1411 |
-
|
1412 |
-
|
1413 |
-
}
|
1414 |
-
|
1415 |
-
|
1416 |
-
|
1417 |
-
|
1418 |
-
|
1419 |
-
|
1420 |
-
|
1421 |
-
|
1422 |
-
|
1423 |
-
|
1424 |
-
|
1425 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1426 |
}
|
|
|
1427 |
|
1428 |
-
var toUnit = function toUnit(bytes) {
|
1429 |
-
var i = Math.floor(Math.log(bytes) / Math.log(1024));
|
1430 |
-
return (bytes / Math.pow(1024, i)).toFixed(2) * 1 + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][i];
|
1431 |
-
};
|
1432 |
|
1433 |
-
|
1434 |
-
|
1435 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1436 |
|
1437 |
-
|
1438 |
-
|
1439 |
-
|
1440 |
-
|
1441 |
-
$('.wpstg--drag').hide();
|
1442 |
-
$('.wpstg--drag-or-upload').show();
|
1443 |
|
1444 |
-
|
1445 |
-
|
1446 |
-
|
1447 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1448 |
},
|
1449 |
-
|
1450 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1451 |
file: null,
|
1452 |
-
|
1453 |
-
|
1454 |
-
|
1455 |
-
|
1456 |
-
|
1457 |
-
|
1458 |
-
WARNING: 'warning',
|
1459 |
-
ERROR: 'error',
|
1460 |
-
INFO: 'info',
|
1461 |
-
DEBUG: 'debug',
|
1462 |
-
CRITICAL: 'critical',
|
1463 |
-
data: {
|
1464 |
-
all: [],
|
1465 |
-
// TODO RPoC
|
1466 |
-
info: [],
|
1467 |
-
error: [],
|
1468 |
-
critical: [],
|
1469 |
-
warning: [],
|
1470 |
-
debug: []
|
1471 |
-
},
|
1472 |
-
shouldWarn: function shouldWarn() {
|
1473 |
-
return that.backups.messages.data.error.length > 0 || that.backups.messages.data.critical.length > 0;
|
1474 |
-
},
|
1475 |
-
countByType: function countByType(type) {
|
1476 |
-
if (type === void 0) {
|
1477 |
-
type = that.backups.messages.ERROR;
|
1478 |
-
}
|
1479 |
-
|
1480 |
-
return that.backups.messages.data[type].length;
|
1481 |
-
},
|
1482 |
-
addMessage: function addMessage(message) {
|
1483 |
-
if (Array.isArray(message)) {
|
1484 |
-
message.forEach(function (item) {
|
1485 |
-
that.backups.messages.addMessage(item);
|
1486 |
-
});
|
1487 |
-
return;
|
1488 |
-
}
|
1489 |
|
1490 |
-
|
|
|
|
|
|
|
1491 |
|
1492 |
-
|
1493 |
-
|
1494 |
-
|
1495 |
|
1496 |
-
|
|
|
|
|
|
|
|
|
1497 |
|
1498 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1499 |
},
|
1500 |
-
|
1501 |
-
|
|
|
|
|
|
|
|
|
|
|
1502 |
all: [],
|
|
|
1503 |
info: [],
|
1504 |
error: [],
|
1505 |
critical: [],
|
1506 |
warning: [],
|
1507 |
debug: []
|
1508 |
-
}
|
1509 |
-
|
1510 |
-
|
1511 |
-
|
1512 |
-
|
1513 |
-
|
1514 |
-
|
1515 |
-
|
1516 |
-
return;
|
1517 |
-
}
|
1518 |
-
|
1519 |
-
var prettify = function prettify(seconds) {
|
1520 |
-
console.log("Process running for " + seconds + " seconds"); // If potentially anything can exceed 24h execution time than that;
|
1521 |
-
// const _seconds = parseInt(seconds, 10)
|
1522 |
-
// const hours = Math.floor(_seconds / 3600)
|
1523 |
-
// const minutes = Math.floor(_seconds / 60) % 60
|
1524 |
-
// seconds = _seconds % 60
|
1525 |
-
//
|
1526 |
-
// return [hours, minutes, seconds]
|
1527 |
-
// .map(v => v < 10 ? '0' + v : v)
|
1528 |
-
// .filter((v,i) => v !== '00' || i > 0)
|
1529 |
-
// .join(':')
|
1530 |
-
// ;
|
1531 |
-
// Are we sure we won't create anything that exceeds 24h execution time? If not then this;
|
1532 |
-
|
1533 |
-
return "" + new Date(seconds * 1000).toISOString().substr(11, 8);
|
1534 |
-
};
|
1535 |
|
1536 |
-
|
1537 |
-
|
1538 |
-
|
1539 |
-
|
1540 |
-
|
1541 |
-
|
1542 |
-
|
1543 |
-
|
1544 |
-
|
1545 |
-
clearInterval(that.backups.timer.interval);
|
1546 |
-
that.backups.timer.interval = null;
|
1547 |
-
}
|
1548 |
-
}
|
1549 |
-
},
|
1550 |
-
upload: {
|
1551 |
-
reader: null,
|
1552 |
-
file: null,
|
1553 |
-
iop: 1000 * 1024,
|
1554 |
-
uploadInfo: function uploadInfo(isShow) {
|
1555 |
-
var $containerUpload = $('.wpstg--modal--import--upload--process');
|
1556 |
-
var $containerUploader = $('.wpstg--uploader');
|
1557 |
-
|
1558 |
-
if (isShow) {
|
1559 |
-
$containerUpload.css('display', 'flex');
|
1560 |
-
$containerUploader.hide();
|
1561 |
-
return;
|
1562 |
-
}
|
1563 |
|
1564 |
-
|
1565 |
-
$containerUpload.hide();
|
1566 |
-
},
|
1567 |
-
start: function start() {
|
1568 |
-
console.log("file " + that.backups.modal["import"].data.file);
|
1569 |
-
that.backups.upload.reader = new FileReader();
|
1570 |
-
that.backups.upload.file = that.backups.modal["import"].file;
|
1571 |
-
that.backups.upload.uploadInfo(true);
|
1572 |
-
that.backups.upload.sendChunk();
|
1573 |
-
},
|
1574 |
-
sendChunk: function sendChunk(startsAt) {
|
1575 |
-
if (startsAt === void 0) {
|
1576 |
-
startsAt = 0;
|
1577 |
-
}
|
1578 |
|
1579 |
-
|
1580 |
-
|
1581 |
-
|
1582 |
|
1583 |
-
|
1584 |
-
var endsAt = startsAt + that.backups.upload.iop + 1;
|
1585 |
-
var blob = that.backups.upload.file.slice(startsAt, endsAt);
|
1586 |
|
1587 |
-
|
1588 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1589 |
return;
|
1590 |
}
|
1591 |
|
1592 |
-
var
|
1593 |
-
|
1594 |
-
|
1595 |
-
|
1596 |
-
|
1597 |
-
|
1598 |
-
|
1599 |
-
|
1600 |
-
|
1601 |
-
|
1602 |
-
|
1603 |
-
|
1604 |
-
|
1605 |
-
|
1606 |
-
|
1607 |
-
|
1608 |
-
if (endsAt >= that.backups.upload.file.size) {
|
1609 |
-
that.backups.upload.uploadInfo(false);
|
1610 |
-
isLoading(false);
|
1611 |
-
that.backups.switchModalToConfigure();
|
1612 |
-
return;
|
1613 |
-
}
|
1614 |
-
|
1615 |
-
$('.wpstg--modal--import--upload--progress--title > span').text(percent);
|
1616 |
-
$('.wpstg--modal--import--upload--progress').css('width', percent + "%");
|
1617 |
-
that.backups.upload.sendChunk(endsAt);
|
1618 |
-
})["catch"](function (e) {
|
1619 |
-
return showAjaxFatalError(e, '', 'Submit an error report.');
|
1620 |
-
});
|
1621 |
-
};
|
1622 |
-
|
1623 |
-
that.backups.upload.reader.readAsDataURL(blob);
|
1624 |
-
}
|
1625 |
-
},
|
1626 |
-
status: {
|
1627 |
-
hasResponse: null,
|
1628 |
-
reTryAfter: 5000
|
1629 |
-
},
|
1630 |
-
init: function init() {
|
1631 |
-
this.create();
|
1632 |
-
this["delete"]();
|
1633 |
-
this.edit(); // noinspection JSIgnoredPromiseFromCall
|
1634 |
|
1635 |
-
|
1636 |
-
|
1637 |
-
|
|
|
|
|
|
|
|
|
1638 |
|
1639 |
-
|
1640 |
-
|
1641 |
-
|
|
|
1642 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1643 |
|
1644 |
-
|
1645 |
-
|
1646 |
-
|
1647 |
-
|
1648 |
-
|
1649 |
-
|
1650 |
-
|
1651 |
-
|
1652 |
-
|
1653 |
-
|
1654 |
-
|
1655 |
-
|
1656 |
-
|
1657 |
-
}).off('click', '#wpstg-import-backup').on('click', '#wpstg-import-backup', function () {
|
1658 |
-
that.backups.importModal();
|
1659 |
-
}) // Import
|
1660 |
-
.off('click', '.wpstg--backup--import--choose-option').on('click', '.wpstg--backup--import--choose-option', function () {
|
1661 |
-
var $this = $(this);
|
1662 |
-
var $parent = $this.parent();
|
1663 |
|
1664 |
-
|
1665 |
-
|
1666 |
-
|
1667 |
-
} else {
|
1668 |
-
$parent.removeClass('wpstg--show-options');
|
1669 |
-
$this.text($this.attr('data-txtOther'));
|
1670 |
-
}
|
1671 |
-
}).off('click', '.wpstg--modal--backup--import--search-replace--new').on('click', '.wpstg--modal--backup--import--search-replace--new', function (e) {
|
1672 |
-
e.preventDefault();
|
1673 |
-
var $container = $(Swal.getContainer()).find('.wpstg--modal--backup--import--search-replace--input--container');
|
1674 |
-
var total = $container.find('.wpstg--modal--backup--import--search-replace--input-group').length;
|
1675 |
-
$container.append(that.backups.modal["import"].searchReplaceForm.replace(/{i}/g, total));
|
1676 |
-
}).off('click', '.wpstg--modal--backup--import--search-replace--remove').on('click', '.wpstg--modal--backup--import--search-replace--remove', function (e) {
|
1677 |
-
e.preventDefault();
|
1678 |
-
$(e.target).closest('.wpstg--modal--backup--import--search-replace--input-group').remove();
|
1679 |
-
}).off('input', '.wpstg--backup--import--search').on('input', '.wpstg--backup--import--search', function () {
|
1680 |
-
var index = parseInt(this.getAttribute('data-index'));
|
1681 |
|
1682 |
-
|
1683 |
-
that.backups.
|
1684 |
-
|
1685 |
-
}).off('input', '.wpstg--backup--import--replace').on('input', '.wpstg--backup--import--replace', function () {
|
1686 |
-
var index = parseInt(this.getAttribute('data-index'));
|
1687 |
|
1688 |
-
|
1689 |
-
|
1690 |
-
|
1691 |
-
|
1692 |
-
.off('click', '.wpstg--backup--import--option[data-option]').on('click', '.wpstg--backup--import--option[data-option]', function () {
|
1693 |
-
var option = this.getAttribute('data-option');
|
1694 |
|
1695 |
-
|
1696 |
-
|
1697 |
-
|
1698 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1699 |
|
1700 |
-
|
1701 |
-
|
1702 |
-
|
1703 |
-
|
|
|
|
|
|
|
1704 |
|
1705 |
-
|
1706 |
-
return;
|
1707 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1708 |
|
1709 |
-
that.backups.
|
1710 |
-
|
1711 |
-
|
1712 |
-
fetch(ajaxurl + "?action=wpstg--backups--import--file-list&_=" + Math.random() + "&accessToken=" + wpstg.accessToken + "&nonce=" + wpstg.nonce).then(handleFetchErrors).then(function (res) {
|
1713 |
-
return res.json();
|
1714 |
-
}).then(function (res) {
|
1715 |
-
var $ul = $('.wpstg--modal--backup--import--filesystem ul');
|
1716 |
-
$ul.empty();
|
1717 |
|
1718 |
-
if (
|
1719 |
-
|
1720 |
-
$('.wpstg--modal--backup--import--search-replace--wrapper').hide();
|
1721 |
return;
|
1722 |
}
|
1723 |
|
1724 |
-
|
1725 |
-
|
1726 |
-
|
|
|
|
|
|
|
1727 |
});
|
1728 |
-
|
1729 |
-
|
1730 |
-
|
1731 |
-
|
1732 |
-
|
1733 |
-
|
1734 |
-
|
1735 |
-
|
1736 |
-
|
1737 |
-
|
1738 |
-
|
1739 |
-
|
1740 |
-
|
1741 |
-
|
1742 |
-
|
1743 |
-
|
1744 |
-
|
1745 |
-
|
1746 |
-
|
1747 |
-
|
1748 |
-
|
1749 |
-
|
1750 |
-
|
1751 |
-
|
1752 |
-
|
1753 |
-
|
1754 |
-
|
1755 |
-
|
1756 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1757 |
|
1758 |
-
|
1759 |
-
|
1760 |
-
|
1761 |
-
|
1762 |
-
|
1763 |
-
|
1764 |
-
* This allows us to read from the DOM whether the checkbox is checked or not,
|
1765 |
-
* instead of having to read from the event, which would require a lengthier code
|
1766 |
-
* to account for all elements we might want to read.
|
1767 |
-
*/
|
1768 |
-
setTimeout(function (e) {
|
1769 |
-
// Reset
|
1770 |
-
document.getElementById('exportUploadsWithoutDatabaseWarning').style.display = 'none'; // Exporting Media Library without Database
|
1771 |
|
1772 |
-
|
1773 |
-
|
|
|
|
|
1774 |
|
1775 |
-
if (
|
1776 |
-
|
|
|
1777 |
}
|
1778 |
-
}, 100);
|
1779 |
-
});
|
1780 |
-
},
|
1781 |
-
fetchListing: function fetchListing(isResetErrors) {
|
1782 |
-
if (isResetErrors === void 0) {
|
1783 |
-
isResetErrors = true;
|
1784 |
-
}
|
1785 |
|
1786 |
-
|
|
|
|
|
1787 |
|
1788 |
-
|
1789 |
-
|
1790 |
-
|
|
|
|
|
|
|
|
|
|
|
1791 |
|
1792 |
-
|
1793 |
-
|
1794 |
-
|
1795 |
-
|
1796 |
-
|
1797 |
-
isLoading(false);
|
1798 |
-
window.dispatchEvent(new Event('backupListingFinished'));
|
1799 |
-
return res;
|
1800 |
-
})["catch"](function (e) {
|
1801 |
-
return showAjaxFatalError(e, '', 'Submit an error report.');
|
1802 |
-
});
|
1803 |
-
},
|
1804 |
-
"delete": function _delete() {
|
1805 |
-
$('#wpstg--tab--backup').off('click', '.wpstg-delete-backup[data-md5]').on('click', '.wpstg-delete-backup[data-md5]', function (e) {
|
1806 |
-
e.preventDefault();
|
1807 |
-
resetErrors();
|
1808 |
|
1809 |
-
|
1810 |
-
|
1811 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1812 |
|
1813 |
-
|
1814 |
-
|
1815 |
-
|
1816 |
-
|
1817 |
-
|
1818 |
-
|
1819 |
-
|
1820 |
-
|
1821 |
-
|
1822 |
-
|
1823 |
-
|
1824 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1825 |
});
|
1826 |
-
}
|
1827 |
-
|
|
|
|
|
|
|
1828 |
|
1829 |
-
$('#wpstg-error-wrapper').off('click', '#wpstg-backup-force-delete').on('click', '#wpstg-backup-force-delete', function (e) {
|
1830 |
-
e.preventDefault();
|
1831 |
-
resetErrors();
|
1832 |
isLoading(true);
|
1833 |
-
var id = this.getAttribute('data-id');
|
1834 |
|
1835 |
-
if (
|
1836 |
-
|
1837 |
-
return false;
|
1838 |
}
|
1839 |
|
1840 |
-
|
1841 |
-
|
1842 |
-
|
1843 |
-
|
1844 |
-
|
1845 |
-
}, function (response) {
|
1846 |
-
showAjaxFatalError(response, '', ' Please submit an error report by using the REPORT ISSUE button.'); // noinspection JSIgnoredPromiseFromCall
|
1847 |
-
|
1848 |
-
that.backups.fetchListing();
|
1849 |
isLoading(false);
|
|
|
|
|
|
|
|
|
1850 |
});
|
1851 |
-
}
|
1852 |
-
|
1853 |
-
|
1854 |
-
|
1855 |
-
|
1856 |
-
|
1857 |
-
|
1858 |
-
|
1859 |
-
wpstgExportData: data
|
1860 |
-
}, function (response) {
|
1861 |
-
if (response.success) {
|
1862 |
-
that.backups.timer.start();
|
1863 |
-
createBackup();
|
1864 |
-
} else {
|
1865 |
-
showAjaxFatalError(response.data, '', 'Submit an error report.');
|
1866 |
}
|
1867 |
-
}, 'json', false, 0, 1.25);
|
1868 |
-
};
|
1869 |
|
1870 |
-
|
1871 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1872 |
|
1873 |
-
|
1874 |
-
|
1875 |
-
|
1876 |
-
|
|
|
|
|
|
|
1877 |
|
1878 |
-
|
1879 |
-
|
1880 |
-
|
1881 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1882 |
};
|
1883 |
|
1884 |
-
var
|
1885 |
-
|
|
|
|
|
|
|
1886 |
return;
|
1887 |
}
|
1888 |
|
1889 |
-
|
1890 |
-
|
1891 |
-
|
1892 |
-
|
1893 |
-
return;
|
1894 |
-
}
|
1895 |
|
1896 |
-
|
|
|
1897 |
return;
|
1898 |
}
|
1899 |
|
1900 |
-
that.backups.
|
1901 |
-
|
1902 |
-
return res.json();
|
1903 |
-
}).then(function (res) {
|
1904 |
-
that.backups.status.hasResponse = true;
|
1905 |
-
|
1906 |
-
if (typeof res === 'undefined') {
|
1907 |
statusStop();
|
|
|
1908 |
}
|
1909 |
|
1910 |
-
if (that.backups.
|
1911 |
return;
|
1912 |
}
|
1913 |
|
1914 |
-
that.backups.
|
1915 |
-
|
1916 |
-
|
1917 |
-
|
1918 |
-
|
1919 |
-
that.backups.status.hasResponse = true;
|
1920 |
-
showAjaxFatalError(e, '', 'Submit an error report.');
|
1921 |
-
});
|
1922 |
-
}, 5000);
|
1923 |
-
};
|
1924 |
-
|
1925 |
-
WPStaging.ajax({
|
1926 |
-
action: 'wpstg--backups--export',
|
1927 |
-
accessToken: wpstg.accessToken,
|
1928 |
-
nonce: wpstg.nonce
|
1929 |
-
}, function (response) {
|
1930 |
-
console.log(response);
|
1931 |
|
1932 |
-
|
1933 |
-
|
1934 |
-
|
1935 |
-
}, wpstg.delayReq);
|
1936 |
-
return;
|
1937 |
-
}
|
1938 |
|
1939 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1940 |
|
1941 |
-
|
1942 |
-
|
1943 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1944 |
|
1945 |
-
|
1946 |
-
createBackup();
|
1947 |
-
} else if (response.status === true) {
|
1948 |
-
$('#wpstg--progress--status').text('Backup successfully created!');
|
1949 |
-
that.backups.type = null;
|
1950 |
|
1951 |
-
if (that.backups.
|
1952 |
-
|
1953 |
-
that.backups.fetchListing();
|
1954 |
-
that.backups.logsModal();
|
1955 |
-
return;
|
1956 |
}
|
1957 |
|
1958 |
-
|
1959 |
-
|
1960 |
-
|
1961 |
-
|
1962 |
-
|
|
|
|
|
|
|
|
|
|
|
1963 |
return;
|
1964 |
-
}
|
1965 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1966 |
|
1967 |
-
var $el = '';
|
1968 |
-
var timesWaited = 0;
|
1969 |
-
var intervalWaitForBackupInDom = setInterval(function () {
|
1970 |
-
timesWaited++;
|
1971 |
-
$el = $(".wpstg--backup--download[data-md5=\"" + response.backupMd5 + "\"]"); // Could not find element, let's try again...
|
1972 |
|
1973 |
-
|
1974 |
-
|
1975 |
-
|
1976 |
-
|
1977 |
-
|
1978 |
|
1979 |
-
|
1980 |
-
|
1981 |
-
|
1982 |
-
|
1983 |
-
|
1984 |
-
var backupSize = response.hasOwnProperty('backupSize') ? ' (' + response.backupSize + ')' : '';
|
1985 |
-
that.backups.downloadModal({
|
1986 |
-
id: $el.data('id'),
|
1987 |
-
url: $el.data('url'),
|
1988 |
-
title: $el.data('title'),
|
1989 |
-
titleExport: $el.data('title-export'),
|
1990 |
-
btnTxtCancel: $el.data('btn-cancel-txt'),
|
1991 |
-
btnTxtConfirm: $el.data('btn-download-txt') + backupSize
|
1992 |
-
});
|
1993 |
-
$('.wpstg--modal--download--logs--wrapper').show();
|
1994 |
-
var $logsContainer = $('.wpstg--modal--process--logs');
|
1995 |
-
that.backups.messages.data.all.forEach(function (message) {
|
1996 |
-
var msgClass = "wpstg--modal--process--msg--" + message.type.toLowerCase();
|
1997 |
-
$logsContainer.append("<p class=\"" + msgClass + "\">[" + message.type + "] - [" + message.date + "] - " + message.message + "</p>");
|
1998 |
-
});
|
1999 |
-
}, 200);
|
2000 |
-
});
|
2001 |
-
} else {
|
2002 |
-
setTimeout(function () {
|
2003 |
-
createBackup();
|
2004 |
-
}, wpstg.delayReq);
|
2005 |
-
}
|
2006 |
-
}, 'json', false, 0, // Don't retry upon failure
|
2007 |
-
1.25);
|
2008 |
-
};
|
2009 |
|
2010 |
-
|
2011 |
-
|
2012 |
-
var $this = $(this);
|
2013 |
-
var $target = $($this.attr('data-target'));
|
2014 |
-
$target.toggle();
|
2015 |
|
2016 |
-
if ($target.is(':visible')) {
|
2017 |
-
$this.find('span').text('▼');
|
2018 |
-
} else {
|
2019 |
-
$this.find('span').text('►');
|
2020 |
-
}
|
2021 |
-
}).off('change', '[name="includedDirectories\[\]"], input#includeDatabaseInBackup, input#includeOtherFilesInWpContent').on('change', '[type="checkbox"][name="includedDirectories\[\]"], input#includeDatabaseInBackup, input#includeOtherFilesInWpContent', function () {
|
2022 |
-
var isExportingAnyDir = $('[type="checkbox"][name="includedDirectories\[\]"]:checked').length > 0;
|
2023 |
-
var isExportingDatabase = $('input#includeDatabaseInBackup:checked').length === 1;
|
2024 |
-
var isExportingOtherFilesInWpContent = $('input#includeOtherFilesInWpContent:checked').length === 1;
|
2025 |
|
2026 |
-
|
2027 |
-
|
2028 |
-
|
2029 |
-
|
2030 |
-
|
2031 |
-
|
2032 |
-
|
2033 |
-
|
2034 |
-
|
2035 |
-
var $newBackupModal, html, btnTxt, _yield$Swal$fire, formValues;
|
2036 |
-
|
2037 |
-
return regeneratorRuntime.wrap(function _callee$(_context) {
|
2038 |
-
while (1) {
|
2039 |
-
switch (_context.prev = _context.next) {
|
2040 |
-
case 0:
|
2041 |
-
resetErrors();
|
2042 |
-
e.preventDefault();
|
2043 |
-
that.backups.isCancelled = false;
|
2044 |
-
|
2045 |
-
if (!that.backups.modal.create.html || !that.backups.modal.create.confirmBtnTxt) {
|
2046 |
-
$newBackupModal = $('#wpstg--modal--backup--new');
|
2047 |
-
html = $newBackupModal.html();
|
2048 |
-
btnTxt = $newBackupModal.attr('data-confirmButtonText');
|
2049 |
-
that.backups.modal.create.html = html || null;
|
2050 |
-
that.backups.modal.create.confirmBtnTxt = btnTxt || null;
|
2051 |
-
$newBackupModal.remove();
|
2052 |
-
}
|
2053 |
-
|
2054 |
-
_context.next = 6;
|
2055 |
-
return Swal.fire({
|
2056 |
-
title: '',
|
2057 |
-
html: that.backups.modal.create.html,
|
2058 |
-
focusConfirm: false,
|
2059 |
-
confirmButtonText: that.backups.modal.create.confirmBtnTxt,
|
2060 |
-
showCancelButton: true,
|
2061 |
-
preConfirm: function preConfirm() {
|
2062 |
-
var container = Swal.getContainer();
|
2063 |
-
return {
|
2064 |
-
name: container.querySelector('input[name="backup_name"]').value || null,
|
2065 |
-
isExportingPlugins: container.querySelector('#includePluginsInBackup:checked') !== null,
|
2066 |
-
isExportingMuPlugins: container.querySelector('#includeMuPluginsInBackup:checked') !== null,
|
2067 |
-
isExportingThemes: container.querySelector('#includeThemesInBackup:checked') !== null,
|
2068 |
-
isExportingUploads: container.querySelector('#includeMediaLibraryInBackup:checked') !== null,
|
2069 |
-
isExportingOtherWpContentFiles: container.querySelector('#includeOtherFilesInWpContent:checked') !== null,
|
2070 |
-
isExportingDatabase: container.querySelector('#includeDatabaseInBackup:checked') !== null
|
2071 |
-
};
|
2072 |
-
}
|
2073 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2074 |
|
2075 |
-
|
2076 |
-
|
2077 |
-
|
|
|
|
|
2078 |
|
2079 |
-
|
2080 |
-
|
2081 |
-
|
2082 |
-
|
|
|
|
|
|
|
|
|
|
|
2083 |
|
2084 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2085 |
|
2086 |
-
|
2087 |
-
|
2088 |
-
|
2089 |
-
that.backups.
|
2090 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2091 |
}
|
2092 |
-
});
|
2093 |
|
2094 |
-
|
2095 |
-
case "end":
|
2096 |
-
return _context.stop();
|
2097 |
-
}
|
2098 |
-
}
|
2099 |
-
}, _callee);
|
2100 |
-
}));
|
2101 |
|
2102 |
-
|
2103 |
-
|
2104 |
-
|
2105 |
-
|
2106 |
-
|
2107 |
-
|
2108 |
-
|
2109 |
-
that.backups.modal["import"].containerFilesystem.hide();
|
2110 |
-
that.backups.modal["import"].containerConfigure.show();
|
2111 |
-
},
|
2112 |
-
// Edit backups name and notes
|
2113 |
-
edit: function edit() {
|
2114 |
-
$('#wpstg--tab--backup').off('click', '.wpstg--backup--edit[data-md5]').on('click', '.wpstg--backup--edit[data-md5]', /*#__PURE__*/function () {
|
2115 |
-
var _ref2 = _asyncToGenerator( /*#__PURE__*/regeneratorRuntime.mark(function _callee2(e) {
|
2116 |
-
var $this, name, notes, _yield$Swal$fire2, formValues;
|
2117 |
-
|
2118 |
-
return regeneratorRuntime.wrap(function _callee2$(_context2) {
|
2119 |
-
while (1) {
|
2120 |
-
switch (_context2.prev = _context2.next) {
|
2121 |
-
case 0:
|
2122 |
-
e.preventDefault();
|
2123 |
-
$this = $(this);
|
2124 |
-
name = $this.data('name');
|
2125 |
-
notes = $this.data('notes');
|
2126 |
-
_context2.next = 6;
|
2127 |
-
return Swal.fire({
|
2128 |
-
title: '',
|
2129 |
-
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 ",
|
2130 |
-
focusConfirm: false,
|
2131 |
-
confirmButtonText: 'Update Backup',
|
2132 |
-
showCancelButton: true,
|
2133 |
-
preConfirm: function preConfirm() {
|
2134 |
-
return {
|
2135 |
-
name: document.getElementById('wpstg-backup-edit-name-input').value || null,
|
2136 |
-
notes: document.getElementById('wpstg-backup-edit-notes-textarea').value || null
|
2137 |
-
};
|
2138 |
-
}
|
2139 |
-
});
|
2140 |
|
2141 |
-
|
2142 |
-
|
2143 |
-
|
2144 |
-
|
2145 |
-
|
2146 |
-
|
2147 |
-
|
2148 |
-
|
2149 |
-
|
2150 |
-
|
2151 |
-
|
2152 |
-
|
2153 |
-
|
2154 |
-
|
2155 |
-
|
2156 |
-
|
2157 |
-
|
2158 |
-
|
2159 |
-
|
2160 |
-
|
2161 |
-
|
2162 |
-
|
2163 |
-
|
2164 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2165 |
|
2166 |
-
|
2167 |
-
|
2168 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2169 |
}
|
2170 |
-
}
|
2171 |
-
}
|
2172 |
-
}));
|
2173 |
-
|
2174 |
-
return function (_x2) {
|
2175 |
-
return _ref2.apply(this, arguments);
|
2176 |
-
};
|
2177 |
-
}());
|
2178 |
-
},
|
2179 |
-
cancel: function cancel() {
|
2180 |
-
that.backups.timer.stop();
|
2181 |
-
that.backups.isCancelled = true;
|
2182 |
-
Swal.close();
|
2183 |
-
setTimeout(function () {
|
2184 |
-
return that.ajax({
|
2185 |
-
action: 'wpstg--backups--cancel',
|
2186 |
-
accessToken: wpstg.accessToken,
|
2187 |
-
nonce: wpstg.nonce,
|
2188 |
-
type: that.backups.type
|
2189 |
-
}, function (response) {
|
2190 |
-
showAjaxFatalError(response, '', 'Submit an error report.');
|
2191 |
-
});
|
2192 |
-
}, 500);
|
2193 |
-
},
|
2194 |
|
2195 |
-
|
2196 |
-
|
2197 |
-
|
2198 |
-
|
2199 |
-
|
2200 |
-
|
2201 |
-
|
|
|
2202 |
Swal.close();
|
2203 |
-
|
2204 |
-
|
2205 |
-
|
2206 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2207 |
|
2208 |
-
|
2209 |
-
|
2210 |
-
|
2211 |
-
|
2212 |
-
|
2213 |
-
|
2214 |
-
|
2215 |
-
|
|
|
|
|
|
|
2216 |
|
2217 |
-
$('body').off('click', '.wpstg--modal--process--logs--tail').on('click', '.wpstg--modal--process--logs--tail', function (e) {
|
2218 |
-
e.preventDefault();
|
2219 |
-
var container = Swal.getContainer();
|
2220 |
-
var $logs = $(container).find('.wpstg--modal--process--logs');
|
2221 |
-
$logs.toggle();
|
2222 |
|
2223 |
-
if (
|
2224 |
-
|
2225 |
-
|
2226 |
-
|
2227 |
-
|
|
|
|
|
2228 |
}
|
2229 |
-
});
|
2230 |
-
_process.isShowCancelButton = false !== _process.isShowCancelButton;
|
2231 |
-
that.backups.modal.process.modal = Swal.mixin({
|
2232 |
-
customClass: {
|
2233 |
-
cancelButton: 'wpstg--btn--cancel wpstg-blue-primary wpstg-link-btn',
|
2234 |
-
content: 'wpstg--process--content'
|
2235 |
-
},
|
2236 |
-
buttonsStyling: false
|
2237 |
-
}).fire({
|
2238 |
-
html: that.backups.modal.process.html,
|
2239 |
-
cancelButtonText: that.backups.modal.process.cancelBtnTxt,
|
2240 |
-
showCancelButton: _process.isShowCancelButton,
|
2241 |
-
showConfirmButton: false,
|
2242 |
-
allowOutsideClick: false,
|
2243 |
-
allowEscapeKey: false,
|
2244 |
-
width: 600,
|
2245 |
-
onRender: function onRender() {
|
2246 |
-
var _btnCancel = Swal.getContainer().getElementsByClassName('swal2-cancel wpstg--btn--cancel')[0];
|
2247 |
-
|
2248 |
-
var btnCancel = _btnCancel.cloneNode(true);
|
2249 |
-
|
2250 |
-
_btnCancel.parentNode.replaceChild(btnCancel, _btnCancel);
|
2251 |
-
|
2252 |
-
btnCancel.addEventListener('click', function (e) {
|
2253 |
-
if (confirm('Are You Sure? This will cancel the process!')) {
|
2254 |
-
Swal.close();
|
2255 |
-
}
|
2256 |
-
});
|
2257 |
|
2258 |
-
|
2259 |
-
|
2260 |
-
|
2261 |
-
|
2262 |
-
|
2263 |
|
2264 |
-
if (
|
2265 |
-
|
2266 |
-
|
2267 |
-
|
|
|
2268 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2269 |
|
2270 |
-
|
2271 |
-
},
|
2272 |
-
onAfterClose: function onAfterClose() {
|
2273 |
-
return typeof _process.onAfterClose === 'function' && _process.onAfterClose();
|
2274 |
-
},
|
2275 |
-
onClose: function onClose() {
|
2276 |
-
console.log('cancelled');
|
2277 |
-
that.backups.cancel();
|
2278 |
-
}
|
2279 |
-
});
|
2280 |
-
},
|
2281 |
-
processResponse: function processResponse(response, useTitle) {
|
2282 |
-
if (response === null) {
|
2283 |
-
Swal.close();
|
2284 |
-
showError('Invalid Response; null');
|
2285 |
-
throw new Error("Invalid Response; " + response);
|
2286 |
-
}
|
2287 |
-
|
2288 |
-
var $container = $(Swal.getContainer());
|
2289 |
|
2290 |
-
|
2291 |
-
if ((response.title || response.statusTitle) && useTitle === true) {
|
2292 |
-
$container.find('.wpstg--modal--process--title').text(response.title || response.statusTitle);
|
2293 |
-
}
|
2294 |
-
};
|
2295 |
|
2296 |
-
|
2297 |
-
|
2298 |
-
|
2299 |
-
|
2300 |
-
|
2301 |
|
2302 |
-
|
2303 |
-
|
2304 |
-
return;
|
2305 |
-
}
|
2306 |
|
2307 |
-
|
2308 |
-
|
2309 |
|
2310 |
-
|
2311 |
-
|
2312 |
-
|
2313 |
-
|
2314 |
-
appendMessage(item);
|
2315 |
}
|
2316 |
|
2317 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
2318 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2319 |
|
2320 |
-
|
2321 |
-
$logsContainer.append("<p class=\"" + msgClass + "\">[" + message.type + "] - [" + message.date + "] - " + message.message + "</p>");
|
2322 |
|
2323 |
-
|
2324 |
-
|
2325 |
-
|
2326 |
}
|
2327 |
};
|
2328 |
|
2329 |
-
|
2330 |
-
|
|
|
|
|
|
|
2331 |
|
2332 |
-
|
2333 |
-
|
|
|
2334 |
}
|
2335 |
|
2336 |
-
|
2337 |
-
|
2338 |
-
}
|
2339 |
|
2340 |
-
|
2341 |
-
|
2342 |
-
|
|
|
|
|
|
|
2343 |
|
2344 |
-
|
2345 |
-
|
2346 |
-
}
|
2347 |
|
2348 |
-
|
2349 |
-
|
2350 |
-
$btnShowLogs.find('.wpstg--modal--logs--critical-count').text(that.backups.messages.countByType(that.backups.messages.CRITICAL));
|
2351 |
-
$btnShowLogs.find('.wpstg--modal--logs--error-count').text(that.backups.messages.countByType(that.backups.messages.ERROR));
|
2352 |
-
$btnShowLogs.find('.wpstg--modal--logs--warning-count').text(that.backups.messages.countByType(that.backups.messages.WARNING));
|
2353 |
-
};
|
2354 |
|
2355 |
-
|
2356 |
-
|
2357 |
-
|
|
|
|
|
2358 |
|
2359 |
-
|
2360 |
-
|
2361 |
-
|
2362 |
-
|
2363 |
-
|
2364 |
-
|
2365 |
-
|
2366 |
-
|
2367 |
-
|
2368 |
-
|
2369 |
-
|
2370 |
-
|
2371 |
-
|
2372 |
-
|
2373 |
-
logsModal: function logsModal() {
|
2374 |
-
Swal.fire({
|
2375 |
-
html: "<div class=\"wpstg--modal--error--logs\" style=\"display:block\"></div><div class=\"wpstg--modal--process--logs\" style=\"display:block\"></div>",
|
2376 |
-
width: '95%',
|
2377 |
-
onRender: function onRender() {
|
2378 |
-
var $container = $(Swal.getContainer());
|
2379 |
-
$container[0].style['z-index'] = 9999;
|
2380 |
-
var $logsContainer = $container.find('.wpstg--modal--process--logs');
|
2381 |
-
var $errorContainer = $container.find('.wpstg--modal--error--logs');
|
2382 |
-
var $translations = $('#wpstg--js--translations');
|
2383 |
-
var messages = that.backups.messages;
|
2384 |
-
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));
|
2385 |
-
$errorContainer.before("<h3>" + title + "</h3>");
|
2386 |
-
var warnings = [that.backups.messages.CRITICAL, that.backups.messages.ERROR, that.backups.messages.WARNING];
|
2387 |
|
2388 |
if (!that.backups.messages.shouldWarn()) {
|
2389 |
-
|
2390 |
}
|
2391 |
|
2392 |
-
|
2393 |
-
|
2394 |
-
|
|
|
|
|
|
|
2395 |
|
2396 |
-
|
2397 |
-
|
2398 |
-
|
2399 |
|
2400 |
-
|
2401 |
-
|
2402 |
-
|
2403 |
-
onOpen: function onOpen(container) {
|
2404 |
-
var $logsContainer = $(container).find('.wpstg--modal--process--logs');
|
2405 |
-
$logsContainer.scrollTop($logsContainer[0].scrollHeight);
|
2406 |
}
|
2407 |
-
}
|
2408 |
-
|
2409 |
-
|
2410 |
-
|
2411 |
-
|
2412 |
-
|
2413 |
-
|
2414 |
-
|
2415 |
-
|
2416 |
-
|
2417 |
-
|
2418 |
-
|
2419 |
-
|
2420 |
-
|
2421 |
-
btnTxtConfirm = _ref3$btnTxtConfirm === void 0 ? 'Download' : _ref3$btnTxtConfirm;
|
2422 |
-
|
2423 |
-
if (null === that.backups.modal.download.html) {
|
2424 |
-
var $el = $('#wpstg--modal--backup--download');
|
2425 |
-
that.backups.modal.download.html = $el.html();
|
2426 |
-
$el.remove();
|
2427 |
-
}
|
2428 |
-
|
2429 |
-
var exportModal = function exportModal() {
|
2430 |
-
return Swal.fire({
|
2431 |
-
html: "<h2>" + titleExport + "</h2><span class=\"wpstg-loader\"></span>",
|
2432 |
-
showCancelButton: false,
|
2433 |
-
showConfirmButton: false,
|
2434 |
onRender: function onRender() {
|
2435 |
-
|
2436 |
-
|
2437 |
-
|
2438 |
-
|
2439 |
-
|
2440 |
-
|
2441 |
-
|
2442 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2443 |
}
|
2444 |
|
2445 |
-
|
2446 |
-
|
2447 |
-
|
2448 |
-
|
2449 |
-
|
2450 |
-
|
2451 |
-
Swal.close();
|
2452 |
-
});
|
2453 |
}
|
2454 |
});
|
2455 |
-
}
|
2456 |
-
|
2457 |
-
|
2458 |
-
|
2459 |
-
|
2460 |
-
|
2461 |
-
|
2462 |
-
|
2463 |
-
|
2464 |
-
|
2465 |
-
|
2466 |
-
|
2467 |
-
|
2468 |
-
|
2469 |
-
|
2470 |
-
|
2471 |
-
|
2472 |
-
|
2473 |
-
|
2474 |
-
}
|
2475 |
-
|
2476 |
-
if (url && url.length > 0) {
|
2477 |
-
window.location.href = url;
|
2478 |
-
return;
|
2479 |
}
|
2480 |
|
2481 |
-
exportModal()
|
2482 |
-
|
2483 |
-
|
2484 |
-
|
2485 |
-
|
2486 |
-
|
2487 |
-
|
2488 |
-
|
2489 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2490 |
|
2491 |
-
|
2492 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2493 |
|
2494 |
-
|
|
|
|
|
|
|
2495 |
|
2496 |
-
|
2497 |
-
|
2498 |
-
|
2499 |
-
|
2500 |
-
|
|
|
2501 |
|
2502 |
-
|
2503 |
-
|
2504 |
return;
|
2505 |
}
|
2506 |
|
2507 |
-
|
2508 |
-
|
2509 |
-
|
2510 |
-
|
2511 |
-
|
2512 |
-
|
2513 |
|
2514 |
-
|
|
|
2515 |
return;
|
2516 |
}
|
2517 |
|
2518 |
-
that.backups.
|
2519 |
-
|
2520 |
-
return res.json();
|
2521 |
-
}).then(function (res) {
|
2522 |
-
that.backups.status.hasResponse = true;
|
2523 |
-
|
2524 |
-
if (typeof res === 'undefined') {
|
2525 |
statusStop();
|
|
|
2526 |
}
|
2527 |
|
2528 |
-
if (that.backups.
|
2529 |
return;
|
2530 |
}
|
2531 |
|
2532 |
-
that.backups.
|
2533 |
-
|
2534 |
-
|
2535 |
-
|
2536 |
-
|
2537 |
-
that.backups.status.hasResponse = true;
|
2538 |
-
showAjaxFatalError(e, '', 'Submit an error report.');
|
2539 |
-
});
|
2540 |
-
}, 5000);
|
2541 |
-
};
|
2542 |
|
2543 |
-
|
2544 |
-
|
2545 |
-
|
2546 |
-
nonce: wpstg.nonce
|
2547 |
-
}, function (response) {
|
2548 |
-
if (typeof response === 'undefined') {
|
2549 |
-
setTimeout(function () {
|
2550 |
-
importSiteBackup(data);
|
2551 |
-
}, wpstg.delayReq);
|
2552 |
-
return;
|
2553 |
-
}
|
2554 |
|
2555 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2556 |
|
2557 |
-
|
2558 |
-
|
2559 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2560 |
|
2561 |
-
|
2562 |
-
importSiteBackup(data);
|
2563 |
-
} else if (response.status === true) {
|
2564 |
-
$('#wpstg--progress--status').text('Backup successfully imported!');
|
2565 |
-
that.backups.type = null;
|
2566 |
|
2567 |
-
if (that.backups.
|
2568 |
-
|
2569 |
-
that.backups.fetchListing();
|
2570 |
-
that.backups.logsModal();
|
2571 |
-
return;
|
2572 |
}
|
2573 |
|
2574 |
-
|
2575 |
-
|
2576 |
-
|
2577 |
-
|
2578 |
-
|
2579 |
-
// var Message = warningMessage + errorMessage;
|
2580 |
-
// Swal.close();
|
2581 |
|
2582 |
-
|
2583 |
-
|
2584 |
-
|
2585 |
-
|
2586 |
-
|
|
|
2587 |
|
2588 |
-
|
2589 |
-
|
2590 |
-
|
2591 |
-
|
2592 |
-
|
2593 |
-
|
2594 |
-
|
2595 |
-
|
2596 |
-
|
|
|
|
|
|
|
2597 |
|
2598 |
-
|
2599 |
-
|
2600 |
-
|
2601 |
-
|
2602 |
-
|
2603 |
-
|
2604 |
-
|
2605 |
-
|
2606 |
-
|
2607 |
-
|
2608 |
-
that.backups.modal["import"].
|
2609 |
-
|
2610 |
-
|
2611 |
-
|
2612 |
-
|
2613 |
-
|
2614 |
-
|
2615 |
-
|
2616 |
-
|
2617 |
-
|
2618 |
-
|
2619 |
-
|
2620 |
-
|
2621 |
-
},
|
2622 |
-
buttonsStyling: false // progressSteps: ['1', '2']
|
2623 |
-
|
2624 |
-
}).queue([{
|
2625 |
-
html: that.backups.modal["import"].html,
|
2626 |
-
confirmButtonText: that.backups.modal["import"].btnTxtNext,
|
2627 |
-
showCancelButton: false,
|
2628 |
-
showConfirmButton: true,
|
2629 |
-
showLoaderOnConfirm: true,
|
2630 |
-
width: 650,
|
2631 |
-
onRender: function onRender() {
|
2632 |
-
// $('.wpstg--modal--actions .swal2-confirm').hide();
|
2633 |
-
// todo: hide this again
|
2634 |
-
$('.wpstg--modal--actions .swal2-confirm').show();
|
2635 |
-
$('.wpstg--modal--actions .swal2-confirm').prop('disabled', false);
|
2636 |
-
that.backups.modal["import"].containerUpload = $('.wpstg--modal--backup--import--upload');
|
2637 |
-
that.backups.modal["import"].containerFilesystem = $('.wpstg--modal--backup--import--filesystem');
|
2638 |
-
that.backups.modal["import"].containerConfigure = $('.wpstg--modal--backup--import--configure');
|
2639 |
-
},
|
2640 |
-
preConfirm: function preConfirm() {
|
2641 |
-
var body = new FormData();
|
2642 |
-
body.append('accessToken', wpstg.accessToken);
|
2643 |
-
body.append('nonce', wpstg.nonce);
|
2644 |
-
body.append('filePath', that.backups.modal["import"].data.file);
|
2645 |
-
that.backups.modal["import"].data.search.forEach(function (item, index) {
|
2646 |
-
body.append("search[" + index + "]", item);
|
2647 |
-
});
|
2648 |
-
that.backups.modal["import"].data.replace.forEach(function (item, index) {
|
2649 |
-
body.append("replace[" + index + "]", item);
|
2650 |
-
});
|
2651 |
-
return fetch(ajaxurl + "?action=wpstg--backups--import--file-info", {
|
2652 |
-
method: 'POST',
|
2653 |
-
body: body
|
2654 |
-
}).then(handleFetchErrors).then(function (res) {
|
2655 |
-
return res.json();
|
2656 |
-
}).then(function (html) {
|
2657 |
-
return Swal.insertQueueStep({
|
2658 |
-
html: html,
|
2659 |
-
confirmButtonText: that.backups.modal["import"].btnTxtConfirm,
|
2660 |
-
cancelButtonText: that.backups.modal["import"].btnTxtCancel,
|
2661 |
-
showCancelButton: true
|
2662 |
-
});
|
2663 |
-
})["catch"](function (e) {
|
2664 |
-
return showAjaxFatalError(e, '', 'Submit an error report.');
|
2665 |
-
});
|
2666 |
-
}
|
2667 |
-
}]).then(function (res) {
|
2668 |
-
if (!res || !res.value || !res.value[1] || res.value[1] !== true) {
|
2669 |
-
return;
|
2670 |
}
|
2671 |
|
2672 |
-
that.backups.
|
2673 |
-
|
2674 |
-
|
2675 |
-
|
2676 |
-
|
2677 |
-
|
2678 |
-
|
2679 |
-
|
2680 |
-
|
2681 |
-
|
2682 |
-
|
2683 |
-
|
2684 |
-
|
2685 |
-
|
2686 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2687 |
});
|
2688 |
-
|
2689 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2690 |
}
|
2691 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2692 |
});
|
2693 |
-
}
|
2694 |
-
};
|
2695 |
-
window.addEventListener('backupListingFinished', function () {
|
2696 |
-
fetch(ajaxurl + "?action=wpstg--backups--import--file-list&_=" + Math.random() + "&accessToken=" + wpstg.accessToken + "&nonce=" + wpstg.nonce + "&withTemplate=true").then(handleFetchErrors).then(function (res) {
|
2697 |
-
return res.json();
|
2698 |
-
}).then(function (res) {
|
2699 |
-
var $ul = $('.wpstg-backup-list ul');
|
2700 |
-
$ul.empty();
|
2701 |
-
$ul.html(res);
|
2702 |
-
})["catch"](function (e) {
|
2703 |
-
return showAjaxFatalError(e, '', 'Submit an error report.');
|
2704 |
});
|
2705 |
-
|
2706 |
-
|
2707 |
-
}(jQuery);
|
2708 |
-
|
2709 |
-
jQuery(document).ready(function () {
|
2710 |
-
WPStaging.init(); // This is necessary to make WPStaging var accessibile in WP Staging PRO js script
|
2711 |
-
|
2712 |
-
window.WPStaging = WPStaging;
|
2713 |
-
});
|
2714 |
-
/**
|
2715 |
-
* Report Issue modal
|
2716 |
-
*/
|
2717 |
-
|
2718 |
-
jQuery(document).ready(function ($) {
|
2719 |
-
$('#wpstg-report-issue-button').on('click', function (e) {
|
2720 |
-
$('.wpstg-report-issue-form').toggleClass('wpstg-report-show');
|
2721 |
-
e.preventDefault();
|
2722 |
-
});
|
2723 |
-
$('body').on('click', '#wpstg-backups-report-issue-button', function (e) {
|
2724 |
-
$('.wpstg-report-issue-form').toggleClass('wpstg-report-show');
|
2725 |
-
console.log('test');
|
2726 |
-
e.preventDefault();
|
2727 |
-
});
|
2728 |
-
$('#wpstg-report-cancel').on('click', function (e) {
|
2729 |
-
$('.wpstg-report-issue-form').removeClass('wpstg-report-show');
|
2730 |
-
e.preventDefault();
|
2731 |
-
});
|
2732 |
-
/*
|
2733 |
-
* Close Success Modal
|
2734 |
-
*/
|
2735 |
|
2736 |
-
|
2737 |
-
|
2738 |
-
|
|
|
2739 |
});
|
|
|
|
|
|
|
2740 |
|
2741 |
-
function
|
2742 |
-
|
2743 |
-
|
2744 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2745 |
|
2746 |
-
|
2747 |
-
|
2748 |
-
|
2749 |
-
|
2750 |
-
var syslog = $('.wpstg-report-syslog').is(':checked');
|
2751 |
-
var terms = $('.wpstg-report-terms').is(':checked');
|
2752 |
-
button.attr('disabled', true);
|
2753 |
-
spinner.css('visibility', 'visible');
|
2754 |
-
$.ajax({
|
2755 |
-
url: ajaxurl,
|
2756 |
-
type: 'POST',
|
2757 |
-
dataType: 'json',
|
2758 |
-
async: true,
|
2759 |
-
data: {
|
2760 |
-
'action': 'wpstg_send_report',
|
2761 |
-
'accessToken': wpstg.accessToken,
|
2762 |
-
'nonce': wpstg.nonce,
|
2763 |
-
'wpstg_email': email,
|
2764 |
-
'wpstg_provider': hosting_provider,
|
2765 |
-
'wpstg_message': message,
|
2766 |
-
'wpstg_syslog': +syslog,
|
2767 |
-
'wpstg_terms': +terms,
|
2768 |
-
'wpstg_force_send': forceSend
|
2769 |
-
}
|
2770 |
-
}).done(function (data) {
|
2771 |
-
button.attr('disabled', false);
|
2772 |
-
spinner.css('visibility', 'hidden');
|
2773 |
-
|
2774 |
-
if (data.errors.length > 0) {
|
2775 |
-
$('.wpstg-report-issue-form .wpstg-message').remove();
|
2776 |
-
var errorMessage = $('<div />').addClass('wpstg-message wpstg-error-message');
|
2777 |
-
$.each(data.errors, function (key, value) {
|
2778 |
-
if (value.status === 'already_submitted') {
|
2779 |
-
errorMessage = '';
|
2780 |
-
Swal.fire({
|
2781 |
-
title: '',
|
2782 |
-
customClass: {
|
2783 |
-
container: 'wpstg-issue-resubmit-confirmation'
|
2784 |
-
},
|
2785 |
-
icon: 'warning',
|
2786 |
-
html: value.message,
|
2787 |
-
showCloseButton: true,
|
2788 |
-
showCancelButton: true,
|
2789 |
-
focusConfirm: false,
|
2790 |
-
confirmButtonText: 'Yes',
|
2791 |
-
cancelButtonText: 'No'
|
2792 |
-
}).then(function (result) {
|
2793 |
-
if (result.isConfirmed) {
|
2794 |
-
sendIssueReport(button, 'true');
|
2795 |
-
}
|
2796 |
-
});
|
2797 |
-
} else {
|
2798 |
-
errorMessage.append('<p>' + value + '</p>');
|
2799 |
-
}
|
2800 |
-
});
|
2801 |
-
$('.wpstg-report-issue-form').prepend(errorMessage);
|
2802 |
-
} else {
|
2803 |
-
var successMessage = $('<div />').addClass('wpstg-message wpstg-success-message');
|
2804 |
-
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>');
|
2805 |
-
$('.wpstg-report-issue-form').html(successMessage);
|
2806 |
-
$('.wpstg-success-message').append('<div style="float:right;margin-top:10px;"><a id="wpstg-success-button" href="#">Close</a></div>'); // Hide message
|
2807 |
|
2808 |
-
|
2809 |
-
|
2810 |
-
|
2811 |
}
|
2812 |
-
});
|
2813 |
-
}
|
2814 |
|
2815 |
-
|
2816 |
-
|
2817 |
-
|
2818 |
-
|
2819 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2820 |
|
2821 |
-
|
2822 |
-
|
2823 |
-
|
2824 |
-
|
2825 |
|
2826 |
-
|
2827 |
-
|
2828 |
|
2829 |
-
|
2830 |
-
|
2831 |
|
2832 |
-
|
2833 |
-
|
|
|
2834 |
}
|
2835 |
-
}
|
2836 |
});
|
2837 |
-
|
|
|
|
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++) {
|
43 |
+
var source = arguments[i];
|
44 |
|
45 |
+
for (var key in source) {
|
46 |
+
if (Object.prototype.hasOwnProperty.call(source, key)) {
|
47 |
+
target[key] = source[key];
|
48 |
+
}
|
49 |
+
}
|
50 |
+
}
|
|
|
51 |
|
52 |
+
return target;
|
53 |
+
};
|
54 |
|
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 |
+
/**
|
105 |
+
* Shortcut for document.querySelector() or jQuery's $()
|
106 |
+
* Return single element only
|
107 |
+
*/
|
108 |
+
function qs(selector) {
|
109 |
+
return document.querySelector(selector);
|
110 |
+
}
|
111 |
+
/**
|
112 |
+
* Shortcut for document.querySelector() or jQuery's $()
|
113 |
+
* Return collection of elements
|
114 |
+
*/
|
115 |
|
116 |
+
function all(selector) {
|
117 |
+
return document.querySelectorAll(selector);
|
118 |
+
}
|
119 |
+
/**
|
120 |
+
* alternative of jQuery - $(parent).on(event, selector, handler)
|
121 |
+
*/
|
122 |
|
123 |
+
function addEvent(parent, evt, selector, handler) {
|
124 |
+
parent.addEventListener(evt, function (event) {
|
125 |
+
if (event.target.matches(selector + ', ' + selector + ' *')) {
|
126 |
+
handler(event.target.closest(selector), event);
|
127 |
+
}
|
128 |
+
}, false);
|
129 |
+
}
|
130 |
+
function slideDown(element, duration) {
|
131 |
+
if (duration === void 0) {
|
132 |
+
duration = 400;
|
133 |
}
|
134 |
|
135 |
+
element.style.display = 'block';
|
136 |
+
element.style.overflow = 'hidden';
|
137 |
+
var height = element.offsetHeight;
|
138 |
+
element.style.height = '0px';
|
139 |
+
element.style.transitionProperty = 'height';
|
140 |
+
element.style.transitionDuration = duration + 'ms';
|
141 |
+
setTimeout(function () {
|
142 |
+
element.style.height = height + 'px';
|
143 |
+
window.setTimeout(function () {
|
144 |
+
element.style.removeProperty('height');
|
145 |
+
element.style.removeProperty('overflow');
|
146 |
+
element.style.removeProperty('transition-duration');
|
147 |
+
element.style.removeProperty('transition-property');
|
148 |
+
}, duration);
|
149 |
+
}, 0);
|
150 |
+
}
|
151 |
+
function slideUp(element, duration) {
|
152 |
+
if (duration === void 0) {
|
153 |
+
duration = 400;
|
154 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
155 |
|
156 |
+
element.style.display = 'block';
|
157 |
+
element.style.overflow = 'hidden';
|
158 |
+
var height = element.offsetHeight;
|
159 |
+
element.style.height = height + 'px';
|
160 |
+
element.style.transitionProperty = 'height';
|
161 |
+
element.style.transitionDuration = duration + 'ms';
|
162 |
+
setTimeout(function () {
|
163 |
+
element.style.height = '0px';
|
164 |
+
window.setTimeout(function () {
|
165 |
+
element.style.display = 'none';
|
166 |
+
element.style.removeProperty('height');
|
167 |
+
element.style.removeProperty('overflow');
|
168 |
+
element.style.removeProperty('transition-duration');
|
169 |
+
element.style.removeProperty('transition-property');
|
170 |
+
}, duration);
|
171 |
+
}, 0);
|
172 |
+
}
|
173 |
+
function getNextSibling(element, selector) {
|
174 |
+
var sibling = element.nextElementSibling;
|
175 |
|
176 |
+
while (sibling) {
|
177 |
+
if (sibling.matches(selector)) {
|
178 |
+
return sibling;
|
179 |
+
}
|
180 |
|
181 |
+
sibling = sibling.nextElementSibling;
|
182 |
+
}
|
183 |
+
}
|
184 |
+
function getParents(element, selector) {
|
185 |
+
var result = [];
|
186 |
|
187 |
+
for (var parent = element && element.parentElement; parent; parent = parent.parentElement) {
|
188 |
+
if (parent.matches(selector)) {
|
189 |
+
result.push(parent);
|
190 |
+
}
|
191 |
+
}
|
192 |
|
193 |
+
return result;
|
194 |
+
}
|
|
|
195 |
|
|
|
|
|
|
|
196 |
/**
|
197 |
+
* Enable/Disable cloning for staging site
|
198 |
+
*/
|
199 |
|
200 |
+
var WpstgCloneStaging = /*#__PURE__*/function () {
|
201 |
+
function WpstgCloneStaging(pageWrapperId, wpstgObject) {
|
202 |
+
if (pageWrapperId === void 0) {
|
203 |
+
pageWrapperId = '#wpstg-clonepage-wrapper';
|
204 |
+
}
|
205 |
|
206 |
+
if (wpstgObject === void 0) {
|
207 |
+
wpstgObject = wpstg;
|
208 |
+
}
|
|
|
|
|
209 |
|
210 |
+
this.pageWrapper = qs(pageWrapperId);
|
211 |
+
this.wpstgObject = wpstgObject;
|
212 |
+
this.enableButtonId = '#wpstg-enable-staging-cloning';
|
213 |
+
this.enableAction = 'wpstg_enable_staging_cloning';
|
214 |
+
this.notyf = new Notyf({
|
215 |
+
duration: 10000,
|
216 |
+
position: {
|
217 |
+
x: 'center',
|
218 |
+
y: 'bottom'
|
219 |
+
},
|
220 |
+
dismissible: true,
|
221 |
+
types: [{
|
222 |
+
type: 'warning',
|
223 |
+
background: 'orange',
|
224 |
+
icon: false
|
225 |
+
}]
|
226 |
+
});
|
227 |
+
this.init();
|
228 |
}
|
229 |
|
230 |
+
var _proto = WpstgCloneStaging.prototype;
|
|
|
231 |
|
232 |
+
_proto.addEvents = function addEvents() {
|
233 |
+
var _this = this;
|
234 |
+
|
235 |
+
if (this.pageWrapper === null) {
|
236 |
+
return;
|
237 |
+
}
|
238 |
+
|
239 |
+
addEvent(this.pageWrapper, 'click', this.enableButtonId, function () {
|
240 |
+
_this.sendRequest(_this.enableAction);
|
241 |
+
});
|
242 |
};
|
243 |
|
244 |
+
_proto.init = function init() {
|
245 |
+
this.addEvents();
|
246 |
+
};
|
247 |
|
248 |
+
_proto.sendRequest = function sendRequest(action) {
|
249 |
+
var _this2 = this;
|
250 |
+
|
251 |
+
fetch(this.wpstgObject.ajaxUrl, {
|
252 |
+
method: 'POST',
|
253 |
+
credentials: 'same-origin',
|
254 |
+
body: new URLSearchParams({
|
255 |
+
action: action,
|
256 |
+
accessToken: this.wpstgObject.accessToken,
|
257 |
+
nonce: this.wpstgObject.nonce
|
258 |
+
}),
|
259 |
+
headers: {
|
260 |
+
'Content-Type': 'application/x-www-form-urlencoded'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
261 |
}
|
262 |
+
}).then(function (response) {
|
263 |
+
if (response.ok) {
|
264 |
+
return response.json();
|
|
|
|
|
|
|
|
|
265 |
}
|
|
|
|
|
|
|
|
|
|
|
266 |
|
267 |
+
return Promise.reject(response);
|
268 |
+
}).then(function (data) {
|
269 |
+
// Reload current page if successful.
|
270 |
+
if ('undefined' !== typeof data.success && data.success) {
|
271 |
+
location.reload();
|
272 |
+
return;
|
273 |
+
} // There will be message probably in case of error
|
274 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
275 |
|
276 |
+
if ('undefined' !== typeof data.message) {
|
277 |
+
_this2.notyf.error(data.message);
|
|
|
278 |
|
279 |
+
return;
|
280 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
281 |
|
282 |
+
_this2.notyf.error(_this2.wpstgObject.i18n['somethingWentWrong']);
|
283 |
+
})["catch"](function (error) {
|
284 |
+
console.warn(_this2.wpstgObject.i18n['somethingWentWrong'], error);
|
285 |
+
});
|
286 |
+
};
|
287 |
|
288 |
+
return WpstgCloneStaging;
|
289 |
+
}();
|
|
|
290 |
|
291 |
+
/**
|
292 |
+
* Fetch directory direct child directories
|
293 |
+
*/
|
294 |
|
295 |
+
var WpstgDirectoryNavigation = /*#__PURE__*/function () {
|
296 |
+
function WpstgDirectoryNavigation(directoryListingSelector, wpstgObject, notyf) {
|
297 |
+
if (directoryListingSelector === void 0) {
|
298 |
+
directoryListingSelector = '#wpstg-directories-listing';
|
|
|
|
|
|
|
|
|
|
|
|
|
299 |
}
|
300 |
|
301 |
+
if (wpstgObject === void 0) {
|
302 |
+
wpstgObject = wpstg;
|
303 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
304 |
|
305 |
+
if (notyf === void 0) {
|
306 |
+
notyf = null;
|
307 |
+
}
|
|
|
|
|
308 |
|
309 |
+
this.directoryListingContainer = qs(directoryListingSelector);
|
310 |
+
this.wpstgObject = wpstgObject;
|
311 |
+
this.dirCheckboxSelector = '.wpstg-check-dir';
|
312 |
+
this.dirExpandSelector = '.wpstg-expand-dirs';
|
313 |
+
this.unselectAllDirsSelector = '.wpstg-unselect-dirs';
|
314 |
+
this.selectDefaultDirsSelector = '.wpstg-select-dirs-default';
|
315 |
+
this.fetchChildrenAction = 'wpstg_fetch_dir_childrens';
|
316 |
+
this.currentCheckboxElement = null;
|
317 |
+
this.currentParentDiv = null;
|
318 |
+
this.currentLoader = null;
|
319 |
+
this.existingExcludes = [];
|
320 |
+
this.excludedDirectories = [];
|
321 |
+
this.isDefaultSelected = false;
|
322 |
+
this.notyf = notyf;
|
323 |
+
this.init();
|
324 |
}
|
325 |
|
326 |
+
var _proto = WpstgDirectoryNavigation.prototype;
|
|
|
|
|
|
|
|
|
327 |
|
328 |
+
_proto.addEvents = function addEvents() {
|
329 |
+
var _this = this;
|
330 |
|
331 |
+
if (this.directoryListingContainer === null) {
|
332 |
+
console.log('Error: directory navigation add events');
|
333 |
+
return;
|
|
|
|
|
|
|
334 |
}
|
335 |
|
336 |
+
addEvent(this.directoryListingContainer, 'click', this.dirExpandSelector, function (element, event) {
|
337 |
+
event.preventDefault();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
338 |
|
339 |
+
if (_this.toggleDirExpand(element)) {
|
340 |
+
_this.sendRequest(_this.fetchChildrenAction, element);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
341 |
}
|
342 |
});
|
343 |
+
addEvent(this.directoryListingContainer, 'click', this.unselectAllDirsSelector, function () {
|
344 |
+
_this.unselectAll();
|
345 |
+
});
|
346 |
+
addEvent(this.directoryListingContainer, 'click', this.selectDefaultDirsSelector, function () {
|
347 |
+
_this.selectDefault();
|
348 |
+
});
|
349 |
+
};
|
|
|
|
|
|
|
|
|
|
|
|
|
350 |
|
351 |
+
_proto.init = function init() {
|
352 |
+
this.addEvents();
|
353 |
+
this.parseExcludes();
|
354 |
}
|
355 |
+
/**
|
356 |
+
* Toggle Dir Expand,
|
357 |
+
* Return true if children aren't fetched
|
358 |
+
* @param {HTMLElement} element
|
359 |
+
* @return {boolean}
|
360 |
+
*/
|
361 |
+
;
|
362 |
|
363 |
+
_proto.toggleDirExpand = function toggleDirExpand(element) {
|
364 |
+
this.currentParentDiv = element.parentElement;
|
365 |
+
this.currentCheckboxElement = element.previousSibling;
|
366 |
+
this.currentLoader = this.currentParentDiv.querySelector('.wpstg-is-dir-loading');
|
367 |
|
368 |
+
if (this.currentCheckboxElement.getAttribute('data-navigateable', 'false') === 'false') {
|
369 |
+
return false;
|
370 |
+
}
|
371 |
|
372 |
+
if (this.currentCheckboxElement.getAttribute('data-scanned', 'false') === 'false') {
|
373 |
+
return true;
|
374 |
+
}
|
|
|
375 |
|
376 |
+
return false;
|
377 |
+
};
|
|
|
378 |
|
379 |
+
_proto.sendRequest = function sendRequest(action) {
|
380 |
+
var _this2 = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
381 |
|
382 |
+
if (this.currentLoader !== null) {
|
383 |
+
this.currentLoader.style.display = 'inline-block';
|
384 |
+
}
|
385 |
|
386 |
+
fetch(this.wpstgObject.ajaxUrl, {
|
387 |
+
method: 'POST',
|
388 |
+
credentials: 'same-origin',
|
389 |
+
body: new URLSearchParams({
|
390 |
+
action: action,
|
391 |
+
accessToken: this.wpstgObject.accessToken,
|
392 |
+
nonce: this.wpstgObject.nonce,
|
393 |
+
dirPath: this.currentCheckboxElement.value,
|
394 |
+
isChecked: this.currentCheckboxElement.checked,
|
395 |
+
forceDefault: this.isDefaultSelected
|
396 |
+
}),
|
397 |
+
headers: {
|
398 |
+
'Content-Type': 'application/x-www-form-urlencoded'
|
399 |
}
|
400 |
+
}).then(function (response) {
|
401 |
+
if (response.ok) {
|
402 |
+
return response.json();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
403 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
404 |
|
405 |
+
return Promise.reject(response);
|
406 |
+
}).then(function (data) {
|
407 |
+
if ('undefined' !== typeof data.success && data.success) {
|
408 |
+
_this2.currentCheckboxElement.setAttribute('data-scanned', true);
|
409 |
|
410 |
+
var dirContainer = document.createElement('div');
|
411 |
+
dirContainer.classList.add('wpstg-dir');
|
412 |
+
dirContainer.classList.add('wpstg-subdir');
|
413 |
+
dirContainer.innerHTML = JSON.parse(data.directoryListing);
|
|
|
|
|
|
|
414 |
|
415 |
+
_this2.currentParentDiv.appendChild(dirContainer);
|
|
|
|
|
|
|
416 |
|
417 |
+
if (_this2.currentLoader !== null) {
|
418 |
+
_this2.currentLoader.style.display = 'none';
|
419 |
+
}
|
420 |
|
421 |
+
slideDown(dirContainer);
|
422 |
+
return;
|
423 |
}
|
424 |
|
425 |
+
if (_this2.notyf !== null) {
|
426 |
+
_this2.notyf.error(_this2.wpstgObject.i18n['somethingWentWrong']);
|
427 |
+
} else {
|
428 |
+
alert('Error: ' + _this2.wpstgObject.i18n['somethingWentWrong']);
|
429 |
}
|
430 |
+
})["catch"](function (error) {
|
431 |
+
console.warn(_this2.wpstgObject.i18n['somethingWentWrong'], error);
|
432 |
+
});
|
433 |
+
};
|
434 |
|
435 |
+
_proto.getExcludedDirectories = function getExcludedDirectories() {
|
436 |
+
var _this3 = this;
|
437 |
|
438 |
+
this.excludedDirectories = [];
|
439 |
+
this.directoryListingContainer.querySelectorAll('.wpstg-dir input:not(:checked)').forEach(function (element) {
|
440 |
+
if (!_this3.isParentExcluded(element.value)) {
|
441 |
+
_this3.excludedDirectories.push(element.value);
|
442 |
+
}
|
443 |
+
});
|
444 |
+
this.existingExcludes.forEach(function (exclude) {
|
445 |
+
if (!_this3.isParentExcluded(exclude) && !_this3.isExcludeScanned(exclude)) {
|
446 |
+
_this3.excludedDirectories.push(exclude);
|
447 |
+
}
|
448 |
+
});
|
449 |
+
return this.excludedDirectories.join(this.wpstgObject.settings.directorySeparator);
|
450 |
+
}
|
451 |
+
/**
|
452 |
+
* @param {string} path
|
453 |
+
* @return {bool}
|
454 |
+
*/
|
455 |
+
;
|
456 |
|
457 |
+
_proto.isParentExcluded = function isParentExcluded(path) {
|
458 |
+
var isParentAlreadyExcluded = false;
|
459 |
+
this.excludedDirectories.forEach(function (dir) {
|
460 |
+
if (path.startsWith(dir + '/')) {
|
461 |
+
isParentAlreadyExcluded = true;
|
462 |
}
|
463 |
+
});
|
464 |
+
return isParentAlreadyExcluded;
|
465 |
+
};
|
466 |
+
|
467 |
+
_proto.getExtraDirectoriesRootOnly = function getExtraDirectoriesRootOnly() {
|
468 |
+
this.getExcludedDirectories();
|
469 |
+
var extraDirectories = [];
|
470 |
+
this.directoryListingContainer.querySelectorAll(':not(.wpstg-subdir)>.wpstg-dir>input.wpstg-wp-non-core-dir:checked').forEach(function (element) {
|
471 |
+
extraDirectories.push(element.value);
|
472 |
+
}); // Check if extra directories text area exists
|
473 |
+
// TODO: remove extraCustomDirectories code if no one require extraCustomDirectories...
|
474 |
+
|
475 |
+
var extraDirectoriesTextArea = qs('#wpstg_extraDirectories');
|
476 |
+
|
477 |
+
if (extraDirectoriesTextArea === null || extraDirectoriesTextArea.value === '') {
|
478 |
+
return extraDirectories.join(this.wpstgObject.settings.directorySeparator);
|
479 |
}
|
480 |
|
481 |
+
var extraCustomDirectories = extraDirectoriesTextArea.value.split(/\r?\n/);
|
482 |
+
return extraDirectories.concat(extraCustomDirectories).join(this.wpstgObject.settings.directorySeparator);
|
483 |
+
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
484 |
|
485 |
+
_proto.unselectAll = function unselectAll() {
|
486 |
+
this.directoryListingContainer.querySelectorAll('.wpstg-dir input').forEach(function (element) {
|
487 |
+
element.checked = false;
|
488 |
+
});
|
489 |
+
};
|
490 |
|
491 |
+
_proto.selectDefault = function selectDefault() {
|
492 |
+
// unselect all checkboxes
|
493 |
+
this.unselectAll(); // only select those checkboxes whose class is wpstg-wp-core-dir
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
494 |
|
495 |
+
this.directoryListingContainer.querySelectorAll('.wpstg-dir input.wpstg-wp-core-dir').forEach(function (element) {
|
496 |
+
element.checked = true;
|
497 |
+
}); // then unselect those checkboxes whose parent has wpstg extra checkbox
|
498 |
|
499 |
+
this.directoryListingContainer.querySelectorAll('.wpstg-dir > .wpstg-wp-non-core-dir').forEach(function (element) {
|
500 |
+
element.parentElement.querySelectorAll('input.wpstg-wp-core-dir').forEach(function (element) {
|
501 |
+
element.checked = false;
|
502 |
+
});
|
503 |
+
});
|
504 |
+
this.isDefaultSelected = true;
|
505 |
+
};
|
|
|
|
|
|
|
|
|
506 |
|
507 |
+
_proto.parseExcludes = function parseExcludes() {
|
508 |
+
this.existingExcludes = this.directoryListingContainer.getAttribute('data-existing-excludes', []);
|
509 |
|
510 |
+
if (this.existingExcludes === '') {
|
511 |
+
this.existingExcludes = [];
|
512 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
513 |
|
514 |
+
if (this.existingExcludes.length !== 0) {
|
515 |
+
this.existingExcludes = this.existingExcludes.split(',');
|
516 |
+
}
|
517 |
+
};
|
518 |
+
|
519 |
+
_proto.isExcludeScanned = function isExcludeScanned(exclude) {
|
520 |
+
this.directoryListingContainer.querySelectorAll('.wpstg-dir input').forEach(function (element) {
|
521 |
+
if (element.value === exclude) {
|
522 |
+
return true;
|
523 |
+
}
|
524 |
+
});
|
525 |
+
return false;
|
526 |
+
};
|
527 |
+
|
528 |
+
return WpstgDirectoryNavigation;
|
529 |
+
}();
|
530 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
531 |
/**
|
532 |
+
* Rich Exclude Filter Module
|
|
|
|
|
533 |
*/
|
534 |
|
535 |
+
var WpstgExcludeFilters = /*#__PURE__*/function () {
|
536 |
+
function WpstgExcludeFilters(excludeFilterContainerSelector, wpstgObject) {
|
537 |
+
if (excludeFilterContainerSelector === void 0) {
|
538 |
+
excludeFilterContainerSelector = '#wpstg-exclude-filters-container';
|
539 |
+
}
|
540 |
|
541 |
+
if (wpstgObject === void 0) {
|
542 |
+
wpstgObject = wpstg;
|
543 |
+
}
|
|
|
|
|
|
|
|
|
544 |
|
545 |
+
this.excludeContainer = qs(excludeFilterContainerSelector);
|
546 |
+
this.excludeTableBody = qs(excludeFilterContainerSelector + " tbody");
|
547 |
+
this.wpstgObject = wpstgObject;
|
548 |
+
this.init();
|
549 |
}
|
550 |
|
551 |
+
var _proto = WpstgExcludeFilters.prototype;
|
|
|
|
|
|
|
|
|
|
|
552 |
|
553 |
+
_proto.addEvents = function addEvents() {
|
554 |
+
var _this = this;
|
555 |
|
556 |
+
addEvent(this.excludeContainer, 'click', '.wpstg-file-size-rule', function () {
|
557 |
+
_this.addFileSizeExclude();
|
558 |
+
});
|
559 |
+
addEvent(this.excludeContainer, 'click', '.wpstg-file-ext-rule', function () {
|
560 |
+
_this.addFileExtExclude();
|
561 |
+
});
|
562 |
+
addEvent(this.excludeContainer, 'click', '.wpstg-file-name-rule', function () {
|
563 |
+
_this.addFileNameExclude();
|
564 |
+
});
|
565 |
+
addEvent(this.excludeContainer, 'click', '.wpstg-dir-name-rule', function () {
|
566 |
+
_this.addDirNameExclude();
|
567 |
+
});
|
568 |
+
addEvent(this.excludeContainer, 'click', '.wpstg-clear-all-rules', function () {
|
569 |
+
_this.clearExcludes();
|
570 |
+
});
|
571 |
+
addEvent(this.excludeContainer, 'click', '.wpstg-remove-exclude-rule', function (target) {
|
572 |
+
_this.removeExclude(target);
|
573 |
+
});
|
574 |
+
};
|
575 |
|
576 |
+
_proto.init = function init() {
|
577 |
+
if (this.excludeContainer === null) {
|
578 |
+
console.log('Error: Given table selector not found!');
|
579 |
return;
|
580 |
}
|
581 |
|
582 |
+
this.addEvents();
|
583 |
+
};
|
|
|
|
|
|
|
584 |
|
585 |
+
_proto.addFileSizeExclude = function addFileSizeExclude() {
|
586 |
+
this.addExcludeRuleRow('#wpstg-file-size-exclude-filter-template');
|
587 |
+
};
|
|
|
|
|
588 |
|
589 |
+
_proto.addFileExtExclude = function addFileExtExclude() {
|
590 |
+
this.addExcludeRuleRow('#wpstg-file-ext-exclude-filter-template');
|
591 |
+
};
|
592 |
|
593 |
+
_proto.addFileNameExclude = function addFileNameExclude() {
|
594 |
+
this.addExcludeRuleRow('#wpstg-file-name-exclude-filter-template');
|
595 |
+
};
|
596 |
+
|
597 |
+
_proto.addDirNameExclude = function addDirNameExclude() {
|
598 |
+
this.addExcludeRuleRow('#wpstg-dir-name-exclude-filter-template');
|
599 |
+
};
|
600 |
+
|
601 |
+
_proto.addExcludeRuleRow = function addExcludeRuleRow(templateName) {
|
602 |
+
var excludeRowTemplate = qs(templateName);
|
603 |
+
|
604 |
+
if (excludeRowTemplate !== null) {
|
605 |
+
var clone = excludeRowTemplate.content.cloneNode(true);
|
606 |
+
var excludeRow = clone.querySelector('tr');
|
607 |
+
this.excludeTableBody.appendChild(excludeRow);
|
608 |
+
all('.wpstg-has-exclude-rules').forEach(function (e) {
|
609 |
+
e.style.display = 'inherit';
|
610 |
});
|
|
|
611 |
}
|
612 |
+
};
|
613 |
|
614 |
+
_proto.clearExcludes = function clearExcludes() {
|
615 |
+
this.excludeTableBody.innerHTML = '';
|
616 |
+
all('.wpstg-has-exclude-rules').forEach(function (e) {
|
617 |
+
e.style.display = 'none';
|
|
|
|
|
|
|
618 |
});
|
619 |
+
};
|
|
|
|
|
|
|
|
|
|
|
620 |
|
621 |
+
_proto.removeExclude = function removeExclude(target) {
|
622 |
+
if (target.parentElement !== null && target.parentElement.parentElement !== null) {
|
623 |
+
this.excludeTableBody.removeChild(target.parentElement.parentElement);
|
624 |
+
}
|
625 |
|
626 |
+
if (this.excludeTableBody.innerHTML.trim() === '') {
|
627 |
+
all('.wpstg-has-exclude-rules').forEach(function (e) {
|
628 |
+
e.style.display = 'none';
|
629 |
+
});
|
630 |
+
}
|
631 |
}
|
632 |
+
/**
|
633 |
+
* Converts all the exclude filters arrays into one single string to keep size of post request small
|
634 |
+
* @return {string}
|
635 |
+
*/
|
636 |
+
;
|
637 |
|
638 |
+
_proto.getExcludeFilters = function getExcludeFilters() {
|
639 |
+
var _this2 = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
640 |
|
641 |
+
var globExcludes = [];
|
642 |
+
var sizeExcludes = [];
|
643 |
+
var sizeCompares = this.excludeTableBody.querySelectorAll('select[name="wpstgFileSizeExcludeRuleCompare[]"]');
|
644 |
+
var sizeSizes = this.excludeTableBody.querySelectorAll('input[name="wpstgFileSizeExcludeRuleSize[]"]');
|
645 |
+
var sizeByte = this.excludeTableBody.querySelectorAll('select[name="wpstgFileSizeExcludeRuleByte[]"]');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
646 |
|
647 |
+
for (var _i = 0, _Object$entries = Object.entries(sizeSizes); _i < _Object$entries.length; _i++) {
|
648 |
+
var _Object$entries$_i = _Object$entries[_i],
|
649 |
+
key = _Object$entries$_i[0],
|
650 |
+
sizeInput = _Object$entries$_i[1];
|
651 |
|
652 |
+
if (sizeInput.value !== '') {
|
653 |
+
sizeExcludes.push(sizeCompares[key].value + ' ' + sizeInput.value + sizeByte[key].value);
|
654 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
655 |
}
|
656 |
|
657 |
+
var extensionInputs = this.excludeTableBody.querySelectorAll('input[name="wpstgFileExtExcludeRule[]"]');
|
658 |
+
extensionInputs.forEach(function (x) {
|
659 |
+
var ext = _this2.cleanStringForGlob(x.value);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
660 |
|
661 |
+
if (ext !== '') {
|
662 |
+
globExcludes.push('ext:' + ext.trim());
|
663 |
+
}
|
664 |
+
});
|
665 |
+
var fileNamesPos = this.excludeTableBody.querySelectorAll('select[name="wpstgFileNameExcludeRulePos[]"]');
|
666 |
+
var fileNames = this.excludeTableBody.querySelectorAll('input[name="wpstgFileNameExcludeRulePath[]"]');
|
667 |
|
668 |
+
for (var _i2 = 0, _Object$entries2 = Object.entries(fileNames); _i2 < _Object$entries2.length; _i2++) {
|
669 |
+
var _Object$entries2$_i = _Object$entries2[_i2],
|
670 |
+
_key = _Object$entries2$_i[0],
|
671 |
+
fileInput = _Object$entries2$_i[1];
|
672 |
+
var fileName = this.cleanStringForGlob(fileInput.value);
|
|
|
|
|
673 |
|
674 |
+
if (fileName !== '') {
|
675 |
+
globExcludes.push('file:' + fileNamesPos[_key].value + ' ' + fileName.trim());
|
676 |
+
}
|
|
|
677 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
678 |
|
679 |
+
var dirNamesPos = this.excludeTableBody.querySelectorAll('select[name="wpstgDirNameExcludeRulePos[]"]');
|
680 |
+
var dirNames = this.excludeTableBody.querySelectorAll('input[name="wpstgDirNameExcludeRulePath[]"]');
|
681 |
|
682 |
+
for (var _i3 = 0, _Object$entries3 = Object.entries(dirNames); _i3 < _Object$entries3.length; _i3++) {
|
683 |
+
var _Object$entries3$_i = _Object$entries3[_i3],
|
684 |
+
_key2 = _Object$entries3$_i[0],
|
685 |
+
dirInput = _Object$entries3$_i[1];
|
686 |
+
var dirName = this.cleanStringForGlob(dirInput.value);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
687 |
|
688 |
+
if (dirName !== '') {
|
689 |
+
globExcludes.push('dir:' + dirNamesPos[_key2].value + ' ' + dirName.trim());
|
690 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
691 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
692 |
|
693 |
+
return {
|
694 |
+
'sizes': sizeExcludes.filter(this.onlyUnique).join(','),
|
695 |
+
// return set of unique rules
|
696 |
+
'globs': globExcludes.filter(this.onlyUnique).join(',')
|
697 |
+
};
|
698 |
+
};
|
699 |
|
700 |
+
_proto.onlyUnique = function onlyUnique(value, index, self) {
|
701 |
+
return self.indexOf(value) === index;
|
702 |
}
|
703 |
+
/**
|
704 |
+
* Remove most of the comment glob characters from the string
|
705 |
+
* @param {String} value
|
706 |
+
* @return {String}
|
707 |
+
*/
|
708 |
+
;
|
709 |
|
710 |
+
_proto.cleanStringForGlob = function cleanStringForGlob(value) {
|
711 |
+
// will replace character like * ^ / \ ! ? [ from the string
|
712 |
+
return value.replace(/[*^//!\.[?]/g, '');
|
713 |
+
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
714 |
|
715 |
+
return WpstgExcludeFilters;
|
716 |
+
}();
|
717 |
|
|
|
|
|
|
|
718 |
/**
|
719 |
+
* Basic WP Staging Modal implemented with help of Sweetalerts
|
720 |
*/
|
721 |
+
var WpstgModal = /*#__PURE__*/function () {
|
722 |
+
function WpstgModal(confirmAction, wpstgObject) {
|
723 |
+
if (wpstgObject === void 0) {
|
724 |
+
wpstgObject = wpstg;
|
725 |
+
}
|
726 |
|
727 |
+
this.confirmAction = confirmAction;
|
728 |
+
this.wpstgObject = wpstgObject;
|
|
|
|
|
729 |
}
|
730 |
|
731 |
+
var _proto = WpstgModal.prototype;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
732 |
|
733 |
+
_proto.show = function show(swalOptions, additionalParams, callback) {
|
734 |
+
var _this = this;
|
|
|
|
|
|
|
735 |
|
736 |
+
if (additionalParams === void 0) {
|
737 |
+
additionalParams = {};
|
738 |
+
}
|
739 |
|
740 |
+
if (callback === void 0) {
|
741 |
+
callback = null;
|
742 |
+
}
|
|
|
|
|
|
|
743 |
|
744 |
+
Swal.fire(swalOptions).then(function (result) {
|
745 |
+
if (result.value && _this.error !== null) {
|
746 |
+
_this.triggerConfirmAction(additionalParams, callback);
|
747 |
+
}
|
748 |
+
});
|
749 |
+
};
|
750 |
|
751 |
+
_proto.triggerConfirmAction = function triggerConfirmAction(additionalParams, callback) {
|
752 |
+
var _this2 = this;
|
|
|
|
|
753 |
|
754 |
+
if (additionalParams === void 0) {
|
755 |
+
additionalParams = {};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
756 |
}
|
757 |
|
758 |
+
if (callback === void 0) {
|
759 |
+
callback = null;
|
760 |
+
}
|
|
|
|
|
|
|
761 |
|
762 |
+
fetch(this.wpstgObject.ajaxUrl, {
|
763 |
+
method: 'POST',
|
764 |
+
credentials: 'same-origin',
|
765 |
+
body: new URLSearchParams(Object.assign({
|
766 |
+
action: this.confirmAction,
|
767 |
+
accessToken: this.wpstgObject.accessToken,
|
768 |
+
nonce: this.wpstgObject.nonce
|
769 |
+
}, additionalParams)),
|
770 |
+
headers: {
|
771 |
+
'Content-Type': 'application/x-www-form-urlencoded'
|
772 |
+
}
|
773 |
+
}).then(function (response) {
|
774 |
+
if (response.ok) {
|
775 |
+
return response.json();
|
776 |
+
}
|
777 |
|
778 |
+
return Promise.reject(response);
|
779 |
+
}).then(function (response) {
|
780 |
+
if (callback !== null) {
|
781 |
+
callback(response);
|
782 |
+
}
|
783 |
+
})["catch"](function (error) {
|
784 |
+
console.log(_this2.wpstgObject.i18n['somethingWentWrong'], error);
|
785 |
+
});
|
786 |
+
};
|
787 |
|
788 |
+
return WpstgModal;
|
789 |
+
}();
|
790 |
|
|
|
|
|
|
|
|
|
791 |
/**
|
792 |
+
* Manage RESET MODAL
|
|
|
|
|
793 |
*/
|
794 |
|
795 |
+
var WpstgResetModal = /*#__PURE__*/function () {
|
796 |
+
function WpstgResetModal(cloneID, workflowSelector, fetchExcludeSettingsAction, modalErrorAction, wpstgObject) {
|
797 |
+
if (workflowSelector === void 0) {
|
798 |
+
workflowSelector = '#wpstg-workflow';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
799 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
800 |
|
801 |
+
if (fetchExcludeSettingsAction === void 0) {
|
802 |
+
fetchExcludeSettingsAction = 'wpstg_clone_excludes_settings';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
803 |
}
|
804 |
|
805 |
+
if (modalErrorAction === void 0) {
|
806 |
+
modalErrorAction = 'wpstg_modal_error';
|
807 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
808 |
|
809 |
+
if (wpstgObject === void 0) {
|
810 |
+
wpstgObject = wpstg;
|
811 |
+
}
|
812 |
|
813 |
+
this.cloneID = cloneID;
|
814 |
+
this.workflow = qs(workflowSelector);
|
815 |
+
this.wpstgObject = wpstgObject;
|
816 |
+
this.fetchExcludeSettingsAction = fetchExcludeSettingsAction;
|
817 |
+
this.modalErrorAction = modalErrorAction;
|
818 |
+
this.resetButtonClass = 'wpstg-confirm-reset-clone';
|
819 |
+
this.resetModalContainerClass = 'wpstg-reset-confirmation';
|
820 |
+
this.resetTabSelector = '.wpstg-reset-exclude-tab';
|
821 |
+
this.directoryNavigator = null;
|
822 |
+
this.excludeFilters = null;
|
823 |
+
this.isAllTablesChecked = true;
|
824 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
825 |
|
826 |
+
var _proto = WpstgResetModal.prototype;
|
827 |
|
828 |
+
_proto.addEvents = function addEvents() {
|
829 |
+
var _this = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
830 |
|
831 |
+
var resetModalContainer = qs('.' + this.resetModalContainerClass);
|
832 |
|
833 |
+
if (resetModalContainer === null) {
|
834 |
+
console.log('Exit');
|
835 |
+
return;
|
836 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
837 |
|
838 |
+
addEvent(resetModalContainer, 'click', this.resetTabSelector, function (target) {
|
839 |
+
_this.toggleContent(target);
|
840 |
+
});
|
841 |
+
addEvent(resetModalContainer, 'click', '.wpstg-button-select', function () {
|
842 |
+
_this.selectDefaultTables();
|
843 |
+
});
|
844 |
+
addEvent(resetModalContainer, 'click', '.wpstg-button-unselect', function () {
|
845 |
+
_this.toggleTableSelection();
|
846 |
+
});
|
847 |
+
addEvent(resetModalContainer, 'click', '.wpstg-expand-dirs', function (target, event) {
|
848 |
+
event.preventDefault();
|
849 |
|
850 |
+
_this.toggleDirectoryNavigation(target);
|
851 |
+
});
|
852 |
+
addEvent(resetModalContainer, 'change', 'input.wpstg-check-dir', function (target) {
|
853 |
+
_this.updateDirectorySelection(target);
|
854 |
+
});
|
855 |
+
};
|
856 |
|
857 |
+
_proto.init = function init() {
|
858 |
+
this.addEvents();
|
859 |
+
};
|
860 |
|
861 |
+
_proto.toggleContent = function toggleContent(target) {
|
862 |
+
var resetModalContainer = qs('.' + this.resetModalContainerClass);
|
863 |
+
var contentId = target.getAttribute('data-id');
|
864 |
+
var tabTriangle = target.querySelector('.wpstg-tab-triangle');
|
865 |
+
var isCollapsed = target.getAttribute('data-collapsed', 'true');
|
866 |
+
var content = qs(contentId);
|
867 |
|
868 |
+
if (isCollapsed === 'true') {
|
869 |
+
if (resetModalContainer.classList.contains('has-collapsible-open')) {
|
870 |
+
resetModalContainer.classList.add('has-collapsible-open-2');
|
871 |
+
} else {
|
872 |
+
resetModalContainer.classList.add('has-collapsible-open');
|
873 |
+
}
|
874 |
|
875 |
+
slideDown(content);
|
876 |
+
tabTriangle.style.transform = 'rotate(90deg)';
|
877 |
+
target.setAttribute('data-collapsed', 'false');
|
878 |
+
} else {
|
879 |
+
if (resetModalContainer.classList.contains('has-collapsible-open-2')) {
|
880 |
+
resetModalContainer.classList.remove('has-collapsible-open-2');
|
881 |
+
} else {
|
882 |
+
resetModalContainer.classList.remove('has-collapsible-open');
|
883 |
+
}
|
884 |
|
885 |
+
slideUp(content);
|
886 |
+
tabTriangle.style.removeProperty('transform');
|
887 |
+
target.setAttribute('data-collapsed', 'true');
|
888 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
889 |
}
|
890 |
/**
|
891 |
+
* Show Swal alert with loader and send ajax request to fetch content of alert.
|
892 |
+
* @return Promise
|
893 |
*/
|
894 |
+
;
|
895 |
|
896 |
+
_proto.showModal = function showModal() {
|
897 |
+
var swalPromise = this.loadModal();
|
898 |
+
this.init();
|
899 |
+
this.fetchCloneExcludes();
|
900 |
+
return swalPromise;
|
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 |
+
});
|
917 |
+
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
918 |
|
919 |
+
_proto.fetchCloneExcludes = function fetchCloneExcludes() {
|
920 |
+
var _this2 = this;
|
921 |
+
|
922 |
+
this.error = null; // send ajax request and fetch preserved exclude settings
|
923 |
+
|
924 |
+
fetch(this.wpstgObject.ajaxUrl, {
|
925 |
+
method: 'POST',
|
926 |
+
credentials: 'same-origin',
|
927 |
+
body: new URLSearchParams({
|
928 |
+
action: this.fetchExcludeSettingsAction,
|
929 |
+
accessToken: this.wpstgObject.accessToken,
|
930 |
+
nonce: this.wpstgObject.nonce,
|
931 |
+
clone: this.cloneID,
|
932 |
+
job: 'resetting'
|
933 |
+
}),
|
934 |
+
headers: {
|
935 |
+
'Content-Type': 'application/x-www-form-urlencoded'
|
936 |
+
}
|
937 |
+
}).then(function (response) {
|
938 |
+
if (response.ok) {
|
939 |
+
return response.json();
|
940 |
}
|
941 |
|
942 |
+
return Promise.reject(response);
|
943 |
+
}).then(function (data) {
|
944 |
+
if (!data.success) {
|
945 |
+
var errorModal = new WpstgModal(_this2.modalErrorAction, _this2.wpstgObject);
|
946 |
+
errorModal.show(Object.assign({
|
947 |
+
title: 'Error',
|
948 |
+
icon: 'error',
|
949 |
+
html: _this2.wpstgObject.i18n['somethingWentWrong'],
|
950 |
+
width: '500px',
|
951 |
+
confirmButtonText: 'Ok',
|
952 |
+
showCancelButton: false
|
953 |
+
}, data.swalOptions), {
|
954 |
+
type: data.type
|
955 |
+
});
|
956 |
+
return;
|
957 |
+
}
|
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();
|
965 |
+
})["catch"](function (error) {
|
966 |
+
_this2.renderError({
|
967 |
+
'html': _this2.wpstgObject.i18n['somethingWentWrong'] + ' ' + error
|
968 |
+
});
|
969 |
+
});
|
970 |
+
};
|
971 |
|
972 |
+
_proto.getDirectoryNavigator = function getDirectoryNavigator() {
|
973 |
+
return this.directoryNavigator;
|
974 |
+
};
|
975 |
|
976 |
+
_proto.getExcludeFilters = function getExcludeFilters() {
|
977 |
+
return this.excludeFilters;
|
978 |
+
};
|
979 |
|
980 |
+
_proto.getAjaxLoader = function getAjaxLoader() {
|
981 |
+
return '<div class="wpstg-swal2-ajax-loader"><img src="' + this.wpstgObject.wpstgIcon + '" /></div>';
|
982 |
+
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
983 |
|
984 |
+
_proto.toggleDirectoryNavigation = function toggleDirectoryNavigation(element) {
|
985 |
+
var cbElement = element.previousSibling;
|
986 |
|
987 |
+
if (cbElement.getAttribute('data-navigateable', 'false') === 'false') {
|
988 |
+
return;
|
|
|
989 |
}
|
990 |
|
991 |
+
if (cbElement.getAttribute('data-scanned', 'false') === 'false') {
|
992 |
+
return;
|
|
|
993 |
}
|
994 |
|
995 |
+
var subDirectories = getNextSibling(element, '.wpstg-subdir');
|
|
|
|
|
|
|
996 |
|
997 |
+
if (subDirectories.style.display === 'none') {
|
998 |
+
slideDown(subDirectories);
|
999 |
+
} else {
|
1000 |
+
slideUp(subDirectories);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1001 |
}
|
1002 |
+
};
|
1003 |
|
1004 |
+
_proto.updateDirectorySelection = function updateDirectorySelection(element) {
|
1005 |
+
var parent = element.parentElement;
|
|
|
|
|
|
|
|
|
|
|
1006 |
|
1007 |
+
if (element.checked) {
|
1008 |
+
getParents(parent, '.wpstg-dir').forEach(function (parElem) {
|
1009 |
+
for (var i = 0; i < parElem.children.length; i++) {
|
1010 |
+
if (parElem.children[i].matches('.wpstg-check-dir')) {
|
1011 |
+
parElem.children[i].checked = true;
|
1012 |
+
}
|
1013 |
+
}
|
1014 |
+
});
|
1015 |
+
parent.querySelectorAll('.wpstg-expand-dirs').forEach(function (x) {
|
1016 |
+
x.classList.remove('disabled');
|
1017 |
+
});
|
1018 |
+
parent.querySelectorAll('.wpstg-subdir .wpstg-check-dir').forEach(function (x) {
|
1019 |
+
x.checked = true;
|
1020 |
+
});
|
1021 |
+
} else {
|
1022 |
+
parent.querySelectorAll('.wpstg-expand-dirs, .wpstg-check-subdirs').forEach(function (x) {
|
1023 |
+
x.classList.add('disabled');
|
1024 |
+
});
|
1025 |
+
parent.querySelectorAll('.wpstg-dir .wpstg-check-dir').forEach(function (x) {
|
1026 |
+
x.checked = false;
|
1027 |
+
});
|
1028 |
}
|
1029 |
};
|
|
|
1030 |
|
1031 |
+
_proto.selectDefaultTables = function selectDefaultTables() {
|
1032 |
+
var _this3 = this;
|
|
|
|
|
|
|
|
|
|
|
|
|
1033 |
|
1034 |
+
var resetModalContainer = qs('.' + this.resetModalContainerClass);
|
1035 |
+
var options = resetModalContainer.querySelectorAll('#wpstg_select_tables_cloning .wpstg-db-table');
|
1036 |
+
var multisitePattern = '^' + this.wpstgObject.tblprefix + '([^0-9])_*';
|
1037 |
+
var singleSitePattern = '^' + this.wpstgObject.tblprefix;
|
1038 |
+
options.forEach(function (option) {
|
1039 |
+
var name = option.getAttribute('name', '');
|
1040 |
|
1041 |
+
if (_this3.wpstgObject.isMultisite === '1' && name.match(multisitePattern)) {
|
1042 |
+
option.setAttribute('selected', 'selected');
|
1043 |
+
} else if (_this3.wpstgObject.isMultisite === '' && name.match(singleSitePattern)) {
|
1044 |
+
option.setAttribute('selected', 'selected');
|
1045 |
+
} else {
|
1046 |
+
option.removeAttribute('selected');
|
1047 |
+
}
|
1048 |
+
});
|
1049 |
+
};
|
1050 |
+
|
1051 |
+
_proto.toggleTableSelection = function toggleTableSelection() {
|
1052 |
+
var resetModalContainer = qs('.' + this.resetModalContainerClass);
|
1053 |
+
|
1054 |
+
if (false === this.isAllTablesChecked) {
|
1055 |
+
resetModalContainer.querySelectorAll('#wpstg_select_tables_cloning .wpstg-db-table').forEach(function (option) {
|
1056 |
+
option.setAttribute('selected', 'selected');
|
1057 |
+
});
|
1058 |
+
resetModalContainer.querySelector('.wpstg-button-unselect').innerHTML = 'Unselect All'; // cache.get('.wpstg-db-table-checkboxes').prop('checked', true);
|
1059 |
+
|
1060 |
+
this.isAllTablesChecked = true;
|
1061 |
+
} else {
|
1062 |
+
resetModalContainer.querySelectorAll('#wpstg_select_tables_cloning .wpstg-db-table').forEach(function (option) {
|
1063 |
+
option.removeAttribute('selected');
|
1064 |
+
});
|
1065 |
+
resetModalContainer.querySelector('.wpstg-button-unselect').innerHTML = 'Select All'; // cache.get('.wpstg-db-table-checkboxes').prop('checked', false);
|
1066 |
+
|
1067 |
+
this.isAllTablesChecked = false;
|
1068 |
+
}
|
1069 |
+
};
|
1070 |
+
|
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 |
+
*/
|
1107 |
+
|
1108 |
+
cache.get = function (selector) {
|
1109 |
+
// It is already cached!
|
1110 |
+
if ($.inArray(selector, cache.elements) !== -1) {
|
1111 |
+
return cache.elements[selector];
|
1112 |
+
} // Create cache and return
|
1113 |
+
|
1114 |
+
|
1115 |
+
cache.elements[selector] = jQuery(selector);
|
1116 |
+
return cache.elements[selector];
|
1117 |
+
};
|
1118 |
+
/**
|
1119 |
+
* Refreshes given cache
|
1120 |
+
* @param {String} selector
|
1121 |
+
*/
|
1122 |
+
|
1123 |
+
|
1124 |
+
cache.refresh = function (selector) {
|
1125 |
+
selector.elements[selector] = jQuery(selector);
|
1126 |
+
};
|
1127 |
+
/**
|
1128 |
+
* Show and Log Error Message
|
1129 |
+
* @param {String} message
|
1130 |
+
*/
|
1131 |
+
|
1132 |
+
|
1133 |
+
var showError = function showError(message) {
|
1134 |
+
cache.get('#wpstg-try-again').css('display', 'inline-block');
|
1135 |
+
cache.get('#wpstg-cancel-cloning').text('Reset');
|
1136 |
+
cache.get('#wpstg-resume-cloning').show();
|
1137 |
+
cache.get('#wpstg-error-wrapper').show();
|
1138 |
+
cache.get('#wpstg-error-details').show().html(message);
|
1139 |
+
cache.get('#wpstg-removing-clone').removeClass('loading');
|
1140 |
+
cache.get('.wpstg-loader').hide();
|
1141 |
+
$('.wpstg--modal--process--generic-problem').show().html(message);
|
1142 |
+
};
|
1143 |
+
/**
|
1144 |
+
* Show warning during cloning or push process when closing tab or browser, or changing page
|
1145 |
+
* @param {beforeunload} event
|
1146 |
+
* @return {null}
|
1147 |
+
*/
|
1148 |
+
|
1149 |
+
|
1150 |
+
that.warnIfClosingDuringProcess = function (event) {
|
1151 |
+
// 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?"
|
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
|
1174 |
+
* @param prependMessage Overwrite default error message at beginning
|
1175 |
+
* @param appendMessage Overwrite default error message at end
|
1176 |
+
* @returns void
|
1177 |
+
*/
|
1178 |
+
|
1179 |
+
|
1180 |
+
var showAjaxFatalError = function showAjaxFatalError(response, prependMessage, appendMessage) {
|
1181 |
+
prependMessage = prependMessage ? prependMessage + '<br/><br/>' : 'Something went wrong! <br/><br/>';
|
1182 |
+
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.';
|
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 |
+
|
1214 |
+
var resetErrors = function resetErrors() {
|
1215 |
+
cache.get('#wpstg-error-details').hide().html('');
|
1216 |
+
};
|
1217 |
+
|
1218 |
+
var slugify = function slugify(url) {
|
1219 |
+
return url.toString().toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, '').replace(/\s+/g, '-').replace(/&/g, '-and-').replace(/[^a-z0-9\-]/g, '').replace(/-+/g, '-').replace(/^-*/, '').replace(/-*$/, '');
|
1220 |
+
};
|
1221 |
+
/**
|
1222 |
+
* Common Elements
|
1223 |
+
*/
|
1224 |
+
|
1225 |
+
|
1226 |
+
var elements = function elements() {
|
1227 |
+
var $workFlow = cache.get('#wpstg-workflow');
|
1228 |
+
var isAllChecked = true;
|
1229 |
+
var urlSpinner = ajaxurl.replace('/admin-ajax.php', '') + '/images/spinner';
|
1230 |
+
var timer;
|
1231 |
+
|
1232 |
+
if (2 < window.devicePixelRatio) {
|
1233 |
+
urlSpinner += '-2x';
|
1234 |
+
}
|
1235 |
+
|
1236 |
+
urlSpinner += '.gif';
|
1237 |
+
ajaxSpinner = '<img src=\'\'' + urlSpinner + '\' alt=\'\' class=\'ajax-spinner general-spinner\' />';
|
1238 |
+
|
1239 |
+
$workFlow // Check / Un-check All Database Tables New
|
1240 |
+
.on('click', '.wpstg-button-unselect', function (e) {
|
1241 |
+
e.preventDefault();
|
1242 |
+
|
1243 |
+
if (false === isAllChecked) {
|
1244 |
+
cache.get('#wpstg_select_tables_cloning .wpstg-db-table').prop('selected', 'selected');
|
1245 |
+
cache.get('.wpstg-button-unselect').text('Unselect All');
|
1246 |
+
cache.get('.wpstg-db-table-checkboxes').prop('checked', true);
|
1247 |
+
isAllChecked = true;
|
1248 |
+
} else {
|
1249 |
+
cache.get('#wpstg_select_tables_cloning .wpstg-db-table').prop('selected', false);
|
1250 |
+
cache.get('.wpstg-button-unselect').text('Select All');
|
1251 |
+
cache.get('.wpstg-db-table-checkboxes').prop('checked', false);
|
1252 |
+
isAllChecked = false;
|
1253 |
+
}
|
1254 |
+
})
|
1255 |
+
/**
|
1256 |
+
* Select tables with certain tbl prefix | NEW
|
1257 |
+
* @param obj e
|
1258 |
+
* @returns {undefined}
|
1259 |
+
*/
|
1260 |
+
.on('click', '.wpstg-button-select', function (e) {
|
1261 |
+
e.preventDefault();
|
1262 |
+
$('#wpstg_select_tables_cloning .wpstg-db-table').each(function () {
|
1263 |
+
if (wpstg.isMultisite == 1) {
|
1264 |
+
if ($(this).attr('name').match('^' + wpstg.tblprefix + '([^0-9])_*')) {
|
1265 |
+
$(this).prop('selected', 'selected');
|
1266 |
+
} else {
|
1267 |
+
$(this).prop('selected', false);
|
1268 |
+
}
|
1269 |
+
}
|
1270 |
+
|
1271 |
+
if (wpstg.isMultisite == 0) {
|
1272 |
+
if ($(this).attr('name').match('^' + wpstg.tblprefix)) {
|
1273 |
+
$(this).prop('selected', 'selected');
|
1274 |
+
} else {
|
1275 |
+
$(this).prop('selected', false);
|
1276 |
+
}
|
1277 |
+
}
|
1278 |
+
});
|
1279 |
+
}) // Expand Directories
|
1280 |
+
.on('click', '.wpstg-expand-dirs', function (e) {
|
1281 |
+
e.preventDefault();
|
1282 |
+
var $this = $(this);
|
1283 |
+
$this.siblings('.wpstg-subdir').slideToggle();
|
1284 |
+
}) // When a directory checkbox is Selected
|
1285 |
+
.on('change', 'input.wpstg-check-dir', function () {
|
1286 |
+
var $directory = $(this).parent('.wpstg-dir');
|
1287 |
+
|
1288 |
+
if (this.checked) {
|
1289 |
+
$directory.parents('.wpstg-dir').children('.wpstg-check-dir').prop('checked', true);
|
1290 |
+
$directory.find('.wpstg-expand-dirs').removeClass('disabled');
|
1291 |
+
$directory.find('.wpstg-subdir .wpstg-check-dir').prop('checked', true);
|
1292 |
+
} else {
|
1293 |
+
$directory.find('.wpstg-dir .wpstg-check-dir').prop('checked', false);
|
1294 |
+
$directory.find('.wpstg-expand-dirs, .wpstg-check-subdirs').addClass('disabled');
|
1295 |
+
$directory.find('.wpstg-check-subdirs').data('action', 'check').text('check');
|
1296 |
+
}
|
1297 |
+
}) // When a directory name is Selected
|
1298 |
+
.on('change', 'href.wpstg-check-dir', function () {
|
1299 |
+
var $directory = $(this).parent('.wpstg-dir');
|
1300 |
+
|
1301 |
+
if (this.checked) {
|
1302 |
+
$directory.parents('.wpstg-dir').children('.wpstg-check-dir').prop('checked', true);
|
1303 |
+
$directory.find('.wpstg-expand-dirs').removeClass('disabled');
|
1304 |
+
$directory.find('.wpstg-subdir .wpstg-check-dir').prop('checked', true);
|
1305 |
+
} else {
|
1306 |
+
$directory.find('.wpstg-dir .wpstg-check-dir').prop('checked', false);
|
1307 |
+
$directory.find('.wpstg-expand-dirs, .wpstg-check-subdirs').addClass('disabled');
|
1308 |
+
$directory.find('.wpstg-check-subdirs').data('action', 'check').text('check');
|
1309 |
+
}
|
1310 |
+
}) // Check the max length of the clone name and if the clone name already exists
|
1311 |
+
.on('keyup', '#wpstg-new-clone-id', function () {
|
1312 |
+
// Hide previous errors
|
1313 |
+
document.getElementById('wpstg-error-details').style.display = 'none'; // This request was already sent, clear it up!
|
1314 |
+
|
1315 |
+
if ('number' === typeof timer) {
|
1316 |
+
clearInterval(timer);
|
1317 |
+
}
|
1318 |
+
|
1319 |
+
var cloneID = this.value;
|
1320 |
+
timer = setTimeout(function () {
|
1321 |
+
ajax({
|
1322 |
+
action: 'wpstg_check_clone',
|
1323 |
+
accessToken: wpstg.accessToken,
|
1324 |
+
nonce: wpstg.nonce,
|
1325 |
+
cloneID: cloneID
|
1326 |
+
}, function (response) {
|
1327 |
+
if (response.status === 'success') {
|
1328 |
+
cache.get('#wpstg-new-clone-id').removeClass('wpstg-error-input');
|
1329 |
+
cache.get('#wpstg-start-cloning').removeAttr('disabled');
|
1330 |
+
cache.get('#wpstg-clone-id-error').text('').hide();
|
1331 |
+
} else {
|
1332 |
+
cache.get('#wpstg-new-clone-id').addClass('wpstg-error-input');
|
1333 |
+
cache.get('#wpstg-start-cloning').prop('disabled', true);
|
1334 |
+
cache.get('#wpstg-clone-id-error').text(response.message).show();
|
1335 |
+
}
|
1336 |
+
});
|
1337 |
+
}, 500);
|
1338 |
+
}) // Restart cloning process
|
1339 |
+
.on('click', '#wpstg-start-cloning', function () {
|
1340 |
+
resetErrors();
|
1341 |
+
that.isCancelled = false;
|
1342 |
+
that.getLogs = false;
|
1343 |
+
that.progressBar = 0;
|
1344 |
+
}).on('input', '#wpstg-new-clone-id', function () {
|
1345 |
+
if ($('#wpstg-clone-directory').length < 1) {
|
1346 |
+
return;
|
1347 |
+
}
|
1348 |
+
|
1349 |
+
var slug = slugify(this.value);
|
1350 |
+
var $targetDir = $('#wpstg-use-target-dir');
|
1351 |
+
var $targetUri = $('#wpstg-use-target-hostname');
|
1352 |
+
var path = $targetDir.data('base-path');
|
1353 |
+
var uri = $targetUri.data('base-uri');
|
1354 |
+
|
1355 |
+
if (path) {
|
1356 |
+
path = path.replace(/\/+$/g, '') + '/' + slug + '/';
|
1357 |
+
}
|
1358 |
+
|
1359 |
+
if (uri) {
|
1360 |
+
uri = uri.replace(/\/+$/g, '') + '/' + slug;
|
1361 |
+
}
|
1362 |
+
|
1363 |
+
$('.wpstg-use-target-dir--value').text(path);
|
1364 |
+
$('.wpstg-use-target-hostname--value').text(uri);
|
1365 |
+
$targetDir.attr('data-path', path);
|
1366 |
+
$targetUri.attr('data-uri', uri);
|
1367 |
+
$('#wpstg_clone_dir').attr('placeholder', path);
|
1368 |
+
$('#wpstg_clone_hostname').attr('placeholder', uri);
|
1369 |
+
}).on('input', '#wpstg_clone_hostname', function () {
|
1370 |
+
if ($(this).val() === '' || validateTargetHost()) {
|
1371 |
+
$('#wpstg_clone_hostname_error').remove();
|
1372 |
+
return;
|
1373 |
+
}
|
1374 |
+
|
1375 |
+
if (!validateTargetHost() && !$('#wpstg_clone_hostname_error').length) {
|
1376 |
+
$('#wpstg-clone-directory tr:last-of-type').after('<tr><td> </td><td><p id="wpstg_clone_hostname_error" style="color: red;"> Invalid host name. Please provide it in a format like http://example.com</p></td></tr>');
|
1377 |
+
}
|
1378 |
+
});
|
1379 |
+
cloneActions();
|
1380 |
+
};
|
1381 |
+
/* @returns {boolean} */
|
1382 |
+
|
1383 |
+
|
1384 |
+
var validateTargetHost = function validateTargetHost() {
|
1385 |
+
var the_domain = $('#wpstg_clone_hostname').val();
|
1386 |
+
|
1387 |
+
if (the_domain === '') {
|
1388 |
+
return true;
|
1389 |
+
}
|
1390 |
+
|
1391 |
+
var reg = /^http(s)?:\/\/.*$/;
|
1392 |
+
|
1393 |
+
if (reg.test(the_domain) === false) {
|
1394 |
+
return false;
|
1395 |
+
}
|
1396 |
+
|
1397 |
+
return true;
|
1398 |
+
};
|
1399 |
+
/**
|
1400 |
+
* Clone actions
|
1401 |
+
*/
|
1402 |
+
|
1403 |
+
|
1404 |
+
var cloneActions = function cloneActions() {
|
1405 |
+
var $workFlow = cache.get('#wpstg-workflow');
|
1406 |
+
$workFlow // Cancel cloning
|
1407 |
+
.on('click', '#wpstg-cancel-cloning', function () {
|
1408 |
+
if (!confirm('Are you sure you want to cancel cloning process?')) {
|
1409 |
+
return false;
|
1410 |
+
}
|
1411 |
+
|
1412 |
+
var $this = $(this);
|
1413 |
+
$('#wpstg-try-again, #wpstg-home-link').hide();
|
1414 |
+
$this.prop('disabled', true);
|
1415 |
+
that.isCancelled = true;
|
1416 |
+
that.progressBar = 0;
|
1417 |
+
$('#wpstg-processing-status').text('Please wait...this can take up a while.');
|
1418 |
+
$('.wpstg-loader, #wpstg-show-log-button').hide();
|
1419 |
+
$this.parent().append(ajaxSpinner);
|
1420 |
+
cancelCloning();
|
1421 |
+
}) // Resume cloning
|
1422 |
+
.on('click', '#wpstg-resume-cloning', function () {
|
1423 |
+
resetErrors();
|
1424 |
+
var $this = $(this);
|
1425 |
+
$('#wpstg-try-again, #wpstg-home-link').hide();
|
1426 |
+
that.isCancelled = false;
|
1427 |
+
$('#wpstg-processing-status').text('Try to resume cloning process...');
|
1428 |
+
$('#wpstg-error-details').hide();
|
1429 |
+
$('.wpstg-loader').show();
|
1430 |
+
$this.parent().append(ajaxSpinner);
|
1431 |
+
that.startCloning();
|
1432 |
+
}) // Cancel update cloning
|
1433 |
+
.on('click', '#wpstg-cancel-cloning-update', function () {
|
1434 |
+
resetErrors();
|
1435 |
+
var $this = $(this);
|
1436 |
+
$('#wpstg-try-again, #wpstg-home-link').hide();
|
1437 |
+
$this.prop('disabled', true);
|
1438 |
+
that.isCancelled = true;
|
1439 |
+
$('#wpstg-cloning-result').text('Please wait...this can take up a while.');
|
1440 |
+
$('.wpstg-loader, #wpstg-show-log-button').hide();
|
1441 |
+
$this.parent().append(ajaxSpinner);
|
1442 |
+
cancelCloningUpdate();
|
1443 |
+
}) // Restart cloning
|
1444 |
+
.on('click', '#wpstg-restart-cloning', function () {
|
1445 |
+
resetErrors();
|
1446 |
+
var $this = $(this);
|
1447 |
+
$('#wpstg-try-again, #wpstg-home-link').hide();
|
1448 |
+
$this.prop('disabled', true);
|
1449 |
+
that.isCancelled = true;
|
1450 |
+
$('#wpstg-cloning-result').text('Please wait...this can take up a while.');
|
1451 |
+
$('.wpstg-loader, #wpstg-show-log-button').hide();
|
1452 |
+
$this.parent().append(ajaxSpinner);
|
1453 |
+
restart();
|
1454 |
+
}) // Delete clone - confirmation
|
1455 |
+
.on('click', '.wpstg-remove-clone[data-clone]', function (e) {
|
1456 |
+
resetErrors();
|
1457 |
+
e.preventDefault();
|
1458 |
+
var $existingClones = cache.get('#wpstg-existing-clones');
|
1459 |
+
$workFlow.removeClass('active');
|
1460 |
+
cache.get('.wpstg-loader').show();
|
1461 |
+
ajax({
|
1462 |
+
action: 'wpstg_confirm_delete_clone',
|
1463 |
+
accessToken: wpstg.accessToken,
|
1464 |
+
nonce: wpstg.nonce,
|
1465 |
+
clone: $(this).data('clone')
|
1466 |
+
}, function (response) {
|
1467 |
+
cache.get('#wpstg-removing-clone').html(response);
|
1468 |
+
$existingClones.children('img').remove();
|
1469 |
+
cache.get('.wpstg-loader').hide();
|
1470 |
+
$('html, body').animate({
|
1471 |
+
// This logic is meant to be a "scrollBottom"
|
1472 |
+
scrollTop: $('#wpstg-remove-clone').offset().top - $(window).height() + $('#wpstg-remove-clone').height() + 50
|
1473 |
+
}, 100);
|
1474 |
+
}, 'HTML');
|
1475 |
+
}) // Delete clone - confirmed
|
1476 |
+
.on('click', '#wpstg-remove-clone', function (e) {
|
1477 |
+
resetErrors();
|
1478 |
+
e.preventDefault();
|
1479 |
+
cache.get('#wpstg-removing-clone').addClass('loading');
|
1480 |
+
cache.get('.wpstg-loader').show();
|
1481 |
+
deleteClone($(this).data('clone'));
|
1482 |
+
}) // Cancel deleting clone
|
1483 |
+
.on('click', '#wpstg-cancel-removing', function (e) {
|
1484 |
+
e.preventDefault();
|
1485 |
+
$('.wpstg-clone').removeClass('active');
|
1486 |
+
cache.get('#wpstg-removing-clone').html('');
|
1487 |
+
}) // Update
|
1488 |
+
.on('click', '.wpstg-execute-clone', function (e) {
|
1489 |
+
e.preventDefault();
|
1490 |
+
var clone = $(this).data('clone');
|
1491 |
+
$workFlow.addClass('loading');
|
1492 |
+
that.cloneExcludeFilters = null;
|
1493 |
+
ajax({
|
1494 |
+
action: 'wpstg_scanning',
|
1495 |
+
clone: clone,
|
1496 |
+
accessToken: wpstg.accessToken,
|
1497 |
+
nonce: wpstg.nonce
|
1498 |
+
}, function (response) {
|
1499 |
+
if (response.length < 1) {
|
1500 |
+
showError('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.');
|
1501 |
+
}
|
1502 |
+
|
1503 |
+
var jsonResponse = tryParseJson(response);
|
1504 |
+
|
1505 |
+
if (jsonResponse !== false && jsonResponse.success === false) {
|
1506 |
+
$workFlow.removeClass('loading');
|
1507 |
+
showErrorModal(jsonResponse);
|
1508 |
+
return;
|
1509 |
+
}
|
1510 |
+
|
1511 |
+
$workFlow.removeClass('loading').html(response); // register check disk space function for clone update process.
|
1512 |
+
|
1513 |
+
checkDiskSpace();
|
1514 |
+
that.directoryNavigator = new WpstgDirectoryNavigation('#wpstg-directories-listing', wpstg, that.notyf);
|
1515 |
+
that.cloneExcludeFilters = new WpstgExcludeFilters();
|
1516 |
+
that.switchStep(2);
|
1517 |
+
}, 'HTML');
|
1518 |
+
}) // Reset Clone
|
1519 |
+
.on('click', '.wpstg-reset-clone', function (e) {
|
1520 |
+
e.preventDefault();
|
1521 |
+
var clone = $(this).data('clone');
|
1522 |
+
var resetModal = new WpstgResetModal(clone);
|
1523 |
+
var promise = resetModal.showModal();
|
1524 |
+
promise.then(function (result) {
|
1525 |
+
if (result.value) {
|
1526 |
+
var dirNavigator = resetModal.getDirectoryNavigator();
|
1527 |
+
var exclFilters = resetModal.getExcludeFilters().getExcludeFilters();
|
1528 |
+
resetClone(clone, {
|
1529 |
+
includedTables: getIncludedTables(),
|
1530 |
+
excludeSizeRules: encodeURIComponent(exclFilters.sizes),
|
1531 |
+
excludeGlobRules: encodeURIComponent(exclFilters.globs),
|
1532 |
+
excludedDirectories: dirNavigator.getExcludedDirectories(),
|
1533 |
+
extraDirectories: dirNavigator.getExtraDirectoriesRootOnly()
|
1534 |
+
});
|
1535 |
+
}
|
1536 |
+
});
|
1537 |
+
return;
|
1538 |
+
});
|
1539 |
+
};
|
1540 |
+
/**
|
1541 |
+
* Ajax Requests
|
1542 |
+
* @param Object data
|
1543 |
+
* @param Function callback
|
1544 |
+
* @param string dataType
|
1545 |
+
* @param bool showErrors
|
1546 |
+
* @param int tryCount
|
1547 |
+
* @param float incrementRatio
|
1548 |
+
*/
|
1549 |
+
|
1550 |
+
|
1551 |
+
var ajax = function ajax(data, callback, dataType, showErrors, tryCount, incrementRatio) {
|
1552 |
+
if (incrementRatio === void 0) {
|
1553 |
+
incrementRatio = null;
|
1554 |
+
}
|
1555 |
+
|
1556 |
+
if ('undefined' === typeof dataType) {
|
1557 |
+
dataType = 'json';
|
1558 |
+
}
|
1559 |
+
|
1560 |
+
if (false !== showErrors) {
|
1561 |
+
showErrors = true;
|
1562 |
+
}
|
1563 |
+
|
1564 |
+
tryCount = 'undefined' === typeof tryCount ? 0 : tryCount;
|
1565 |
+
var retryLimit = 10;
|
1566 |
+
var retryTimeout = 10000 * tryCount;
|
1567 |
+
incrementRatio = parseInt(incrementRatio);
|
1568 |
+
|
1569 |
+
if (!isNaN(incrementRatio)) {
|
1570 |
+
retryTimeout *= incrementRatio;
|
1571 |
+
}
|
1572 |
+
|
1573 |
+
$.ajax({
|
1574 |
+
url: ajaxurl + '?action=wpstg_processing&_=' + Date.now() / 1000,
|
1575 |
+
type: 'POST',
|
1576 |
+
dataType: dataType,
|
1577 |
+
cache: false,
|
1578 |
+
data: data,
|
1579 |
+
error: function error(xhr, textStatus, errorThrown) {
|
1580 |
+
// try again after 10 seconds
|
1581 |
+
tryCount++;
|
1582 |
+
|
1583 |
+
if (tryCount <= retryLimit) {
|
1584 |
+
setTimeout(function () {
|
1585 |
+
ajax(data, callback, dataType, showErrors, tryCount, incrementRatio);
|
1586 |
+
return;
|
1587 |
+
}, retryTimeout);
|
1588 |
+
} else {
|
1589 |
+
var errorCode = 'undefined' === typeof xhr.status ? 'Unknown' : xhr.status;
|
1590 |
+
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.');
|
1591 |
+
}
|
1592 |
+
},
|
1593 |
+
success: function success(data) {
|
1594 |
+
if ('function' === typeof callback) {
|
1595 |
+
callback(data);
|
1596 |
+
}
|
1597 |
+
},
|
1598 |
+
statusCode: {
|
1599 |
+
404: function _() {
|
1600 |
+
if (tryCount >= retryLimit) {
|
1601 |
+
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.');
|
1602 |
+
}
|
1603 |
+
},
|
1604 |
+
500: function _() {
|
1605 |
+
if (tryCount >= retryLimit) {
|
1606 |
+
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.');
|
1607 |
+
}
|
1608 |
+
},
|
1609 |
+
504: function _() {
|
1610 |
+
if (tryCount > retryLimit) {
|
1611 |
+
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\ ');
|
1612 |
+
}
|
1613 |
+
},
|
1614 |
+
502: function _() {
|
1615 |
+
if (tryCount >= retryLimit) {
|
1616 |
+
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\ ');
|
1617 |
+
}
|
1618 |
+
},
|
1619 |
+
503: function _() {
|
1620 |
+
if (tryCount >= retryLimit) {
|
1621 |
+
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\ ');
|
1622 |
+
}
|
1623 |
+
},
|
1624 |
+
429: function _() {
|
1625 |
+
if (tryCount >= retryLimit) {
|
1626 |
+
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\ ');
|
1627 |
+
}
|
1628 |
+
},
|
1629 |
+
403: function _() {
|
1630 |
+
if (tryCount >= retryLimit) {
|
1631 |
+
showError('Refresh page or login again! The process should be finished successfully. \n\ ');
|
1632 |
+
}
|
1633 |
+
}
|
1634 |
+
}
|
1635 |
+
});
|
1636 |
+
};
|
1637 |
+
/**
|
1638 |
+
* Next / Previous Step Clicks to Navigate Through Staging Job
|
1639 |
+
*/
|
1640 |
+
|
1641 |
+
|
1642 |
+
var stepButtons = function stepButtons() {
|
1643 |
+
var $workFlow = cache.get('#wpstg-workflow');
|
1644 |
+
$workFlow // Next Button
|
1645 |
+
.on('click', '.wpstg-next-step-link', function (e) {
|
1646 |
+
e.preventDefault();
|
1647 |
+
var $this = $(this);
|
1648 |
+
|
1649 |
+
if ($('#wpstg_clone_hostname').length && !validateTargetHost()) {
|
1650 |
+
$('#wpstg_clone_hostname').focus();
|
1651 |
+
return false;
|
1652 |
+
}
|
1653 |
+
|
1654 |
+
if ($this.data('action') === 'wpstg_update' || $this.data('action') === 'wpstg_reset') {
|
1655 |
+
// Update / Reset Clone - confirmed
|
1656 |
+
var onlyUpdateMessage = '';
|
1657 |
+
|
1658 |
+
if ($this.data('action') === 'wpstg_update') {
|
1659 |
+
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.';
|
1660 |
+
}
|
1661 |
+
|
1662 |
+
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)) {
|
1663 |
+
return false;
|
1664 |
+
}
|
1665 |
+
} // Button is disabled
|
1666 |
+
|
1667 |
+
|
1668 |
+
if ($this.attr('disabled')) {
|
1669 |
+
return false;
|
1670 |
+
}
|
1671 |
+
|
1672 |
+
if ($this.data('action') === 'wpstg_cloning') {
|
1673 |
+
// Verify External Database If Checked and Not Skipped
|
1674 |
+
if ($('#wpstg-ext-db').is(':checked')) {
|
1675 |
+
verifyExternalDatabase($this, $workFlow);
|
1676 |
+
return;
|
1677 |
+
}
|
1678 |
+
}
|
1679 |
+
|
1680 |
+
proceedCloning($this, $workFlow);
|
1681 |
+
}) // Previous Button
|
1682 |
+
.on('click', '.wpstg-prev-step-link', function (e) {
|
1683 |
+
e.preventDefault();
|
1684 |
+
cache.get('.wpstg-loader').removeClass('wpstg-finished');
|
1685 |
+
cache.get('.wpstg-loader').hide();
|
1686 |
+
loadOverview();
|
1687 |
+
});
|
1688 |
+
};
|
1689 |
+
/**
|
1690 |
+
* Get Included (Checked) Database Tables
|
1691 |
+
* @return {Array}
|
1692 |
+
*/
|
1693 |
+
|
1694 |
+
|
1695 |
+
var getIncludedTables = function getIncludedTables() {
|
1696 |
+
var includedTables = [];
|
1697 |
+
$('#wpstg_select_tables_cloning option:selected').each(function () {
|
1698 |
+
includedTables.push(this.value);
|
1699 |
+
});
|
1700 |
+
return includedTables;
|
1701 |
+
};
|
1702 |
+
/**
|
1703 |
+
* Get Excluded (Unchecked) Database Tables
|
1704 |
+
* Not used anymore!
|
1705 |
+
* @return {Array}
|
1706 |
+
*/
|
1707 |
+
|
1708 |
+
|
1709 |
+
var getExcludedTables = function getExcludedTables() {
|
1710 |
+
var excludedTables = [];
|
1711 |
+
$('.wpstg-db-table input:not(:checked)').each(function () {
|
1712 |
+
excludedTables.push(this.name);
|
1713 |
+
});
|
1714 |
+
return excludedTables;
|
1715 |
+
};
|
1716 |
+
/**
|
1717 |
+
* Verify External Database for Cloning
|
1718 |
+
*/
|
1719 |
+
|
1720 |
+
|
1721 |
+
var verifyExternalDatabase = function verifyExternalDatabase($this, workflow) {
|
1722 |
+
cache.get('.wpstg-loader').show();
|
1723 |
+
ajax({
|
1724 |
+
action: 'wpstg_database_verification',
|
1725 |
+
accessToken: wpstg.accessToken,
|
1726 |
+
nonce: wpstg.nonce,
|
1727 |
+
databaseUser: cache.get('#wpstg_db_username').val(),
|
1728 |
+
databasePassword: cache.get('#wpstg_db_password').val(),
|
1729 |
+
databaseServer: cache.get('#wpstg_db_server').val(),
|
1730 |
+
databaseDatabase: cache.get('#wpstg_db_database').val()
|
1731 |
+
}, function (response) {
|
1732 |
+
// Undefined Error
|
1733 |
+
if (false === response) {
|
1734 |
+
showError('Something went wrong! Error: No response.' + 'Please try again. If that does not help, ' + '<a href=\'https://wp-staging.com/support/\' target=\'_blank\'>open a support ticket</a> ');
|
1735 |
+
cache.get('.wpstg-loader').hide();
|
1736 |
+
return;
|
1737 |
+
} // Throw Error
|
1738 |
+
|
1739 |
+
|
1740 |
+
if ('undefined' === typeof response.success) {
|
1741 |
+
showError('Something went wrong! Error: Invalid response.' + 'Please try again. If that does not help, ' + '<a href=\'https://wp-staging.com/support/\' target=\'_blank\'>open a support ticket</a> ');
|
1742 |
+
cache.get('.wpstg-loader').hide();
|
1743 |
+
return;
|
1744 |
+
}
|
1745 |
+
|
1746 |
+
if (response.success) {
|
1747 |
+
cache.get('.wpstg-loader').hide();
|
1748 |
+
proceedCloning($this, workflow);
|
1749 |
+
return;
|
1750 |
+
}
|
1751 |
+
|
1752 |
+
if (response.error_type === 'comparison') {
|
1753 |
+
cache.get('.wpstg-loader').hide();
|
1754 |
+
var render = '<table style="width: 100%;"><thead><tr><th>Property</th><th>Production DB</th><th>Staging DB</th><th>Status</th></tr></thead><tbody>';
|
1755 |
+
response.checks.forEach(function (x) {
|
1756 |
+
var icon = '<i style="color: #00ff00">✔</i>';
|
1757 |
+
|
1758 |
+
if (x.production !== x.staging) {
|
1759 |
+
icon = '<i style="color: #ff0000">❌</i>';
|
1760 |
+
}
|
1761 |
+
|
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,
|
1769 |
+
width: '650px',
|
1770 |
+
focusConfirm: false,
|
1771 |
+
confirmButtonText: 'Proceed Anyway',
|
1772 |
+
showCancelButton: true
|
1773 |
+
}).then(function (result) {
|
1774 |
+
if (result.value) {
|
1775 |
+
proceedCloning($this, workflow);
|
1776 |
+
}
|
1777 |
+
});
|
1778 |
+
return;
|
1779 |
+
}
|
1780 |
+
|
1781 |
+
Swal.fire({
|
1782 |
+
title: 'Different Database Properties',
|
1783 |
+
icon: 'error',
|
1784 |
+
html: response.message,
|
1785 |
+
focusConfirm: true,
|
1786 |
+
confirmButtonText: 'Ok',
|
1787 |
+
showCancelButton: false
|
1788 |
+
});
|
1789 |
+
cache.get('.wpstg-loader').hide();
|
1790 |
+
}, 'json', false);
|
1791 |
+
};
|
1792 |
+
/**
|
1793 |
+
* Get Cloning Step Data
|
1794 |
+
*/
|
1795 |
+
|
1796 |
+
|
1797 |
+
var getCloningData = function getCloningData() {
|
1798 |
+
if ('wpstg_cloning' !== that.data.action && 'wpstg_update' !== that.data.action && 'wpstg_reset' !== that.data.action) {
|
1799 |
+
return;
|
1800 |
+
}
|
1801 |
+
|
1802 |
+
that.data.cloneID = $('#wpstg-new-clone-id').val() || new Date().getTime().toString(); // Remove this to keep &_POST[] small otherwise mod_security will throw error 404
|
1803 |
+
// that.data.excludedTables = getExcludedTables();
|
1804 |
+
|
1805 |
+
if (that.directoryNavigator !== null) {
|
1806 |
+
that.data.excludedDirectories = encodeURIComponent(that.directoryNavigator.getExcludedDirectories());
|
1807 |
+
that.data.extraDirectories = encodeURIComponent(that.directoryNavigator.getExtraDirectoriesRootOnly());
|
1808 |
+
}
|
1809 |
+
|
1810 |
+
that.data.excludeGlobRules = '';
|
1811 |
+
that.data.excludeSizeRules = '';
|
1812 |
+
|
1813 |
+
if (that.cloneExcludeFilters instanceof WpstgExcludeFilters) {
|
1814 |
+
var rules = that.cloneExcludeFilters.getExcludeFilters();
|
1815 |
+
that.data.excludeGlobRules = encodeURIComponent(rules.globs);
|
1816 |
+
that.data.excludeSizeRules = encodeURIComponent(rules.sizes);
|
1817 |
+
}
|
1818 |
+
|
1819 |
+
that.data.includedTables = getIncludedTables();
|
1820 |
+
that.data.databaseServer = $('#wpstg_db_server').val();
|
1821 |
+
that.data.databaseUser = $('#wpstg_db_username').val();
|
1822 |
+
that.data.databasePassword = $('#wpstg_db_password').val();
|
1823 |
+
that.data.databaseDatabase = $('#wpstg_db_database').val();
|
1824 |
+
that.data.databasePrefix = $('#wpstg_db_prefix').val();
|
1825 |
+
var cloneDir = $('#wpstg_clone_dir').val();
|
1826 |
+
that.data.cloneDir = encodeURIComponent($.trim(cloneDir));
|
1827 |
+
that.data.cloneHostname = $('#wpstg_clone_hostname').val();
|
1828 |
+
that.data.emailsAllowed = $('#wpstg_allow_emails').is(':checked');
|
1829 |
+
that.data.uploadsSymlinked = $('#wpstg_symlink_upload').is(':checked');
|
1830 |
+
that.data.cleanPluginsThemes = $('#wpstg-clean-plugins-themes').is(':checked');
|
1831 |
+
that.data.cleanUploadsDir = $('#wpstg-clean-uploads').is(':checked');
|
1832 |
+
};
|
1833 |
+
|
1834 |
+
var proceedCloning = function proceedCloning($this, workflow) {
|
1835 |
+
// Add loading overlay
|
1836 |
+
workflow.addClass('loading'); // Prepare data
|
1837 |
+
|
1838 |
+
that.data = {
|
1839 |
+
action: $this.data('action'),
|
1840 |
+
accessToken: wpstg.accessToken,
|
1841 |
+
nonce: wpstg.nonce
|
1842 |
+
}; // Cloning data
|
1843 |
+
|
1844 |
+
getCloningData();
|
1845 |
+
sendCloningAjax(workflow);
|
1846 |
+
};
|
1847 |
+
|
1848 |
+
var sendCloningAjax = function sendCloningAjax(workflow) {
|
1849 |
+
// Send ajax request
|
1850 |
+
ajax(that.data, function (response) {
|
1851 |
+
// Undefined Error
|
1852 |
+
if (false === response) {
|
1853 |
+
showError('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 \'' + 'and try again. If that does not help, ' + '<a href=\'https://wp-staging.com/support/\' target=\'_blank\'>open a support ticket</a> ');
|
1854 |
+
}
|
1855 |
+
|
1856 |
+
if (response.length < 1) {
|
1857 |
+
showError('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 \'' + 'and try again. If that does not help, ' + '<a href=\'https://wp-staging.com/support/\' target=\'_blank\'>open a support ticket</a> ');
|
1858 |
+
}
|
1859 |
+
|
1860 |
+
var jsonResponse = tryParseJson(response);
|
1861 |
+
|
1862 |
+
if (jsonResponse !== false && jsonResponse.success === false) {
|
1863 |
+
workflow.removeClass('loading');
|
1864 |
+
showErrorModal(jsonResponse);
|
1865 |
+
return;
|
1866 |
+
} // Styling of elements
|
1867 |
+
|
1868 |
+
|
1869 |
+
workflow.removeClass('loading').html(response);
|
1870 |
+
that.cloneExcludeFilters = null;
|
1871 |
+
|
1872 |
+
if (that.data.action === 'wpstg_scanning') {
|
1873 |
+
that.directoryNavigator = new WpstgDirectoryNavigation('#wpstg-directories-listing', wpstg, that.notyf);
|
1874 |
+
that.switchStep(2);
|
1875 |
+
that.cloneExcludeFilters = new WpstgExcludeFilters();
|
1876 |
+
} else if (that.data.action === 'wpstg_cloning' || that.data.action === 'wpstg_update' || that.data.action === 'wpstg_reset') {
|
1877 |
+
that.switchStep(3);
|
1878 |
+
} // Start cloning
|
1879 |
+
|
1880 |
+
|
1881 |
+
that.startCloning();
|
1882 |
+
}, 'HTML');
|
1883 |
+
};
|
1884 |
+
|
1885 |
+
var showErrorModal = function showErrorModal(response) {
|
1886 |
+
var errorModal = new WpstgModal('wpstg_modal_error', wpstg);
|
1887 |
+
errorModal.show(Object.assign({
|
1888 |
+
title: 'Error',
|
1889 |
+
icon: 'error',
|
1890 |
+
html: wpstg.i18n['somethingWentWrong'],
|
1891 |
+
width: '500px',
|
1892 |
+
confirmButtonText: 'Ok',
|
1893 |
+
showCancelButton: false
|
1894 |
+
}, response.swalOptions), {
|
1895 |
+
type: response.type
|
1896 |
+
});
|
1897 |
+
};
|
1898 |
+
|
1899 |
+
var tryParseJson = function tryParseJson(json) {
|
1900 |
+
// early bail if not string
|
1901 |
+
if (!json) {
|
1902 |
+
return false;
|
1903 |
+
}
|
1904 |
+
|
1905 |
+
try {
|
1906 |
+
var object = JSON.parse(json);
|
1907 |
+
|
1908 |
+
if (object && typeof object === 'object') {
|
1909 |
+
return object;
|
1910 |
+
}
|
1911 |
+
} catch (e) {// do nothing on catch
|
1912 |
+
}
|
1913 |
+
|
1914 |
+
return false;
|
1915 |
+
};
|
1916 |
+
|
1917 |
+
var resetClone = function resetClone(clone, excludeOptions) {
|
1918 |
+
that.data = {
|
1919 |
+
action: 'wpstg_reset',
|
1920 |
+
accessToken: wpstg.accessToken,
|
1921 |
+
nonce: wpstg.nonce,
|
1922 |
+
cloneID: clone
|
1923 |
+
};
|
1924 |
+
that.data = _extends({}, that.data, excludeOptions);
|
1925 |
+
var $workFlow = cache.get('#wpstg-workflow');
|
1926 |
+
sendCloningAjax($workFlow);
|
1927 |
+
};
|
1928 |
+
/**
|
1929 |
+
* Loads Overview (first step) of Staging Job
|
1930 |
+
*/
|
1931 |
+
|
1932 |
+
|
1933 |
+
var loadOverview = function loadOverview() {
|
1934 |
+
var $workFlow = cache.get('#wpstg-workflow');
|
1935 |
+
$workFlow.addClass('loading');
|
1936 |
+
ajax({
|
1937 |
+
action: 'wpstg_overview',
|
1938 |
+
accessToken: wpstg.accessToken,
|
1939 |
+
nonce: wpstg.nonce
|
1940 |
+
}, function (response) {
|
1941 |
+
if (response.length < 1) {
|
1942 |
+
showError('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.');
|
1943 |
+
}
|
1944 |
|
1945 |
+
cache.get('.wpstg-current-step'); // Styling of elements
|
1946 |
|
1947 |
+
$workFlow.removeClass('loading').html(response);
|
1948 |
+
}, 'HTML');
|
1949 |
+
that.switchStep(1);
|
1950 |
+
cache.get('.wpstg-step3-cloning').show();
|
1951 |
+
cache.get('.wpstg-step3-pushing').hide();
|
1952 |
+
};
|
1953 |
+
/**
|
1954 |
+
* Load Tabs
|
1955 |
+
*/
|
1956 |
+
|
1957 |
+
|
1958 |
+
var tabs = function tabs() {
|
1959 |
+
cache.get('#wpstg-workflow').on('click', '.wpstg-tab-header', function (e) {
|
1960 |
+
e.preventDefault();
|
1961 |
+
var $this = $(this);
|
1962 |
+
var $section = cache.get($this.data('id'));
|
1963 |
+
$this.toggleClass('expand');
|
1964 |
+
$section.slideToggle();
|
1965 |
+
|
1966 |
+
if ($this.hasClass('expand')) {
|
1967 |
+
$this.find('.wpstg-tab-triangle').html('▼');
|
1968 |
+
} else {
|
1969 |
+
$this.find('.wpstg-tab-triangle').html('►');
|
1970 |
+
}
|
1971 |
+
});
|
1972 |
+
};
|
1973 |
+
/**
|
1974 |
+
* Delete Clone
|
1975 |
+
* @param {String} clone
|
1976 |
+
*/
|
1977 |
+
|
1978 |
+
|
1979 |
+
var deleteClone = function deleteClone(clone) {
|
1980 |
+
var deleteDir = $('#deleteDirectory:checked').data('deletepath');
|
1981 |
+
ajax({
|
1982 |
+
action: 'wpstg_delete_clone',
|
1983 |
+
clone: clone,
|
1984 |
+
accessToken: wpstg.accessToken,
|
1985 |
+
nonce: wpstg.nonce,
|
1986 |
+
excludedTables: getExcludedTables(),
|
1987 |
+
deleteDir: deleteDir
|
1988 |
+
}, function (response) {
|
1989 |
+
if (response) {
|
1990 |
+
showAjaxFatalError(response); // Finished
|
1991 |
+
|
1992 |
+
if ('undefined' !== typeof response["delete"] && (response["delete"] === 'finished' || response["delete"] === 'unfinished')) {
|
1993 |
+
cache.get('#wpstg-removing-clone').removeClass('loading').html('');
|
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();
|
2004 |
+
return;
|
2005 |
}
|
2006 |
+
} // continue
|
2007 |
|
|
|
|
|
|
|
|
|
2008 |
|
2009 |
+
if (true !== response) {
|
2010 |
+
deleteClone(clone);
|
2011 |
+
return;
|
2012 |
+
}
|
2013 |
+
});
|
2014 |
+
};
|
2015 |
+
/**
|
2016 |
+
* Cancel Cloning Process
|
2017 |
+
*/
|
2018 |
+
|
2019 |
+
|
2020 |
+
var cancelCloning = function cancelCloning() {
|
2021 |
+
that.timer('stop');
|
2022 |
+
|
2023 |
+
if (true === that.isFinished) {
|
2024 |
+
return true;
|
2025 |
+
}
|
2026 |
+
|
2027 |
+
ajax({
|
2028 |
+
action: 'wpstg_cancel_clone',
|
2029 |
+
clone: that.data.cloneID,
|
2030 |
+
accessToken: wpstg.accessToken,
|
2031 |
+
nonce: wpstg.nonce
|
2032 |
+
}, function (response) {
|
2033 |
+
if (response && 'undefined' !== typeof response["delete"] && response["delete"] === 'finished') {
|
2034 |
+
cache.get('.wpstg-loader').hide(); // Load overview
|
2035 |
+
|
2036 |
+
loadOverview();
|
2037 |
+
return;
|
2038 |
+
}
|
2039 |
+
|
2040 |
+
if (true !== response) {
|
2041 |
+
// continue
|
2042 |
+
cancelCloning();
|
2043 |
+
return;
|
2044 |
+
} // Load overview
|
2045 |
+
|
2046 |
+
|
2047 |
+
loadOverview();
|
2048 |
+
});
|
2049 |
+
};
|
2050 |
+
/**
|
2051 |
+
* Cancel Cloning Process
|
2052 |
+
*/
|
2053 |
+
|
2054 |
+
|
2055 |
+
var cancelCloningUpdate = function cancelCloningUpdate() {
|
2056 |
+
if (true === that.isFinished) {
|
2057 |
+
return true;
|
2058 |
+
}
|
2059 |
+
|
2060 |
+
ajax({
|
2061 |
+
action: 'wpstg_cancel_update',
|
2062 |
+
clone: that.data.cloneID,
|
2063 |
+
accessToken: wpstg.accessToken,
|
2064 |
+
nonce: wpstg.nonce
|
2065 |
+
}, function (response) {
|
2066 |
+
if (response && 'undefined' !== typeof response["delete"] && response["delete"] === 'finished') {
|
2067 |
+
// Load overview
|
2068 |
+
loadOverview();
|
2069 |
+
return;
|
2070 |
+
}
|
2071 |
+
|
2072 |
+
if (true !== response) {
|
2073 |
+
// continue
|
2074 |
+
cancelCloningUpdate();
|
2075 |
+
return;
|
2076 |
+
} // Load overview
|
2077 |
+
|
2078 |
+
|
2079 |
+
loadOverview();
|
2080 |
+
});
|
2081 |
+
};
|
2082 |
+
/**
|
2083 |
+
* Cancel Cloning Process
|
2084 |
+
*/
|
2085 |
+
|
2086 |
+
|
2087 |
+
var restart = function restart() {
|
2088 |
+
if (true === that.isFinished) {
|
2089 |
+
return true;
|
2090 |
+
}
|
2091 |
+
|
2092 |
+
ajax({
|
2093 |
+
action: 'wpstg_restart',
|
2094 |
+
// clone: that.data.cloneID,
|
2095 |
+
accessToken: wpstg.accessToken,
|
2096 |
+
nonce: wpstg.nonce
|
2097 |
+
}, function (response) {
|
2098 |
+
if (response && 'undefined' !== typeof response["delete"] && response["delete"] === 'finished') {
|
2099 |
+
// Load overview
|
2100 |
+
loadOverview();
|
2101 |
+
return;
|
2102 |
+
}
|
2103 |
+
|
2104 |
+
if (true !== response) {
|
2105 |
+
// continue
|
2106 |
+
cancelCloningUpdate();
|
2107 |
+
return;
|
2108 |
+
} // Load overview
|
2109 |
+
|
2110 |
+
|
2111 |
+
loadOverview();
|
2112 |
+
});
|
2113 |
+
};
|
2114 |
+
/**
|
2115 |
+
* Scroll the window log to bottom
|
2116 |
+
* @return void
|
2117 |
+
*/
|
2118 |
+
|
2119 |
+
|
2120 |
+
var logscroll = function logscroll() {
|
2121 |
+
var $div = cache.get('.wpstg-log-details');
|
2122 |
+
|
2123 |
+
if ('undefined' !== typeof $div[0]) {
|
2124 |
+
$div.scrollTop($div[0].scrollHeight);
|
2125 |
+
}
|
2126 |
+
};
|
2127 |
+
/**
|
2128 |
+
* Append the log to the logging window
|
2129 |
+
* @param string log
|
2130 |
+
* @return void
|
2131 |
+
*/
|
2132 |
+
|
2133 |
+
|
2134 |
+
var getLogs = function getLogs(log) {
|
2135 |
+
if (log != null && 'undefined' !== typeof log) {
|
2136 |
+
if (log.constructor === Array) {
|
2137 |
+
$.each(log, function (index, value) {
|
2138 |
+
if (value === null) {
|
2139 |
+
return;
|
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 |
+
}
|
2147 |
+
});
|
2148 |
+
} else {
|
2149 |
+
cache.get('.wpstg-log-details').append('[' + log.type + ']-' + '[' + log.date + '] ' + log.message + '</br>');
|
2150 |
+
}
|
2151 |
+
}
|
2152 |
+
|
2153 |
+
logscroll();
|
2154 |
+
};
|
2155 |
+
/**
|
2156 |
+
* Check diskspace
|
2157 |
+
* @return string json
|
2158 |
+
*/
|
2159 |
+
|
2160 |
+
|
2161 |
+
var checkDiskSpace = function checkDiskSpace() {
|
2162 |
+
cache.get('#wpstg-check-space').on('click', function (e) {
|
2163 |
+
cache.get('.wpstg-loader').show();
|
2164 |
+
var excludedDirectories = encodeURIComponent(that.directoryNavigator.getExcludedDirectories());
|
2165 |
+
var extraDirectories = encodeURIComponent(that.directoryNavigator.getExtraDirectoriesRootOnly());
|
2166 |
+
ajax({
|
2167 |
+
action: 'wpstg_check_disk_space',
|
2168 |
+
accessToken: wpstg.accessToken,
|
2169 |
+
nonce: wpstg.nonce,
|
2170 |
+
excludedDirectories: excludedDirectories,
|
2171 |
+
extraDirectories: extraDirectories
|
2172 |
+
}, function (response) {
|
2173 |
+
if (false === response) {
|
2174 |
+
cache.get('#wpstg-clone-id-error').text('Can not detect required disk space').show();
|
2175 |
+
cache.get('.wpstg-loader').hide();
|
2176 |
+
return;
|
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
|
2210 |
+
*/
|
2211 |
+
|
2212 |
+
|
2213 |
+
var isLoading = function isLoading(_isLoading) {
|
2214 |
+
if (!_isLoading || _isLoading === false) {
|
2215 |
+
cache.get('.wpstg-loader').hide();
|
2216 |
+
} else {
|
2217 |
+
cache.get('.wpstg-loader').show();
|
2218 |
+
}
|
2219 |
+
};
|
2220 |
+
/**
|
2221 |
+
* Count up processing execution time
|
2222 |
+
* @param string status
|
2223 |
+
* @return html
|
2224 |
+
*/
|
2225 |
+
|
2226 |
+
|
2227 |
+
that.timer = function (status) {
|
2228 |
+
if (status === 'stop') {
|
2229 |
+
var time = that.time;
|
2230 |
+
that.time = 1;
|
2231 |
+
clearInterval(that.executionTime);
|
2232 |
+
return that.convertSeconds(time);
|
2233 |
+
}
|
2234 |
+
|
2235 |
+
that.executionTime = setInterval(function () {
|
2236 |
+
if (null !== document.getElementById('wpstg-processing-timer')) {
|
2237 |
+
document.getElementById('wpstg-processing-timer').innerHTML = 'Elapsed Time: ' + that.convertSeconds(that.time);
|
2238 |
+
}
|
2239 |
+
|
2240 |
+
that.time++;
|
2241 |
+
|
2242 |
+
if (status === 'stop') {
|
2243 |
+
that.time = 1;
|
2244 |
+
clearInterval(that.executionTime);
|
2245 |
+
}
|
2246 |
+
}, 1000);
|
2247 |
+
};
|
2248 |
+
/**
|
2249 |
+
* Convert seconds to hourly format
|
2250 |
+
* @param int seconds
|
2251 |
+
* @return string
|
2252 |
+
*/
|
2253 |
+
|
2254 |
+
|
2255 |
+
that.convertSeconds = function (seconds) {
|
2256 |
+
var date = new Date(null);
|
2257 |
+
date.setSeconds(seconds); // specify value for SECONDS here
|
2258 |
+
|
2259 |
+
return date.toISOString().substr(11, 8);
|
2260 |
+
};
|
2261 |
+
/**
|
2262 |
+
* Start Cloning Process
|
2263 |
+
* @type {Function}
|
2264 |
+
*/
|
2265 |
+
|
2266 |
+
|
2267 |
+
that.startCloning = function () {
|
2268 |
+
resetErrors(); // Register function for checking disk space
|
2269 |
+
|
2270 |
+
checkDiskSpace();
|
2271 |
+
|
2272 |
+
if ('wpstg_cloning' !== that.data.action && 'wpstg_update' !== that.data.action && 'wpstg_reset' !== that.data.action) {
|
2273 |
+
return;
|
2274 |
+
}
|
2275 |
+
|
2276 |
+
that.isCancelled = false; // Start the process
|
2277 |
+
|
2278 |
+
start(); // Functions
|
2279 |
+
// Start
|
2280 |
+
|
2281 |
+
function start() {
|
2282 |
+
cache.get('.wpstg-loader').show();
|
2283 |
+
cache.get('#wpstg-cancel-cloning').text('Cancel');
|
2284 |
+
cache.get('#wpstg-resume-cloning').hide();
|
2285 |
+
cache.get('#wpstg-error-details').hide(); // Clone Database
|
2286 |
+
|
2287 |
+
setTimeout(function () {
|
2288 |
+
// cloneDatabase();
|
2289 |
+
window.addEventListener('beforeunload', WPStaging.warnIfClosingDuringProcess);
|
2290 |
+
processing();
|
2291 |
+
}, wpstg.delayReq);
|
2292 |
+
that.timer('start');
|
2293 |
+
}
|
2294 |
+
/**
|
2295 |
+
* Start ajax processing
|
2296 |
+
* @return string
|
2297 |
+
*/
|
2298 |
+
|
2299 |
+
|
2300 |
+
var processing = function processing() {
|
2301 |
+
if (true === that.isCancelled) {
|
2302 |
+
window.removeEventListener('beforeunload', WPStaging.warnIfClosingDuringProcess);
|
2303 |
+
return false;
|
2304 |
+
}
|
2305 |
+
|
2306 |
+
isLoading(true);
|
2307 |
+
var excludedDirectories = '';
|
2308 |
+
var extraDirectories = '';
|
2309 |
+
|
2310 |
+
if (that.directoryNavigator !== null) {
|
2311 |
+
excludedDirectories = that.directoryNavigator.getExcludedDirectories();
|
2312 |
+
extraDirectories = that.directoryNavigator.getExtraDirectoriesRootOnly();
|
2313 |
+
} // Show logging window
|
2314 |
+
|
2315 |
+
|
2316 |
+
cache.get('.wpstg-log-details').show();
|
2317 |
+
WPStaging.ajax({
|
2318 |
+
action: 'wpstg_processing',
|
2319 |
+
accessToken: wpstg.accessToken,
|
2320 |
+
nonce: wpstg.nonce,
|
2321 |
+
excludedTables: getExcludedTables(),
|
2322 |
+
excludedDirectories: encodeURIComponent(excludedDirectories),
|
2323 |
+
extraDirectories: encodeURIComponent(extraDirectories)
|
2324 |
+
}, function (response) {
|
2325 |
+
showAjaxFatalError(response); // Add Log messages
|
2326 |
+
|
2327 |
+
if ('undefined' !== typeof response.last_msg && response.last_msg) {
|
2328 |
+
getLogs(response.last_msg);
|
2329 |
+
} // Continue processing
|
2330 |
+
|
2331 |
+
|
2332 |
+
if (false === response.status) {
|
2333 |
+
progressBar(response);
|
2334 |
+
setTimeout(function () {
|
2335 |
+
cache.get('.wpstg-loader').show();
|
2336 |
+
processing();
|
2337 |
+
}, wpstg.delayReq);
|
2338 |
+
} else if (true === response.status && 'finished' !== response.status) {
|
2339 |
+
cache.get('#wpstg-error-details').hide();
|
2340 |
+
cache.get('#wpstg-error-wrapper').hide();
|
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);
|
2348 |
+
}; // Finish
|
2349 |
+
|
2350 |
+
|
2351 |
+
function finish(response) {
|
2352 |
+
if (true === that.getLogs) {
|
2353 |
+
getLogs();
|
2354 |
+
}
|
2355 |
+
|
2356 |
+
progressBar(response); // Add Log
|
2357 |
+
|
2358 |
+
if ('undefined' !== typeof response.last_msg) {
|
2359 |
+
getLogs(response.last_msg);
|
2360 |
+
}
|
2361 |
+
|
2362 |
+
cache.get('.wpstg-loader').hide();
|
2363 |
+
cache.get('#wpstg-processing-header').html('Processing Complete');
|
2364 |
+
$('#wpstg-processing-status').text('Succesfully finished');
|
2365 |
+
cache.get('#wpstg_staging_name').html(that.data.cloneID);
|
2366 |
+
cache.get('#wpstg-finished-result').show();
|
2367 |
+
cache.get('#wpstg-cancel-cloning').hide();
|
2368 |
+
cache.get('#wpstg-resume-cloning').hide();
|
2369 |
+
cache.get('#wpstg-cancel-cloning-update').prop('disabled', true);
|
2370 |
+
var $link1 = cache.get('#wpstg-clone-url-1');
|
2371 |
+
var $link = cache.get('#wpstg-clone-url');
|
2372 |
+
$link1.attr('href', response.url);
|
2373 |
+
$link1.html(response.url);
|
2374 |
+
$link.attr('href', response.url);
|
2375 |
+
cache.get('#wpstg-remove-clone').data('clone', that.data.cloneID); // Finished
|
2376 |
+
|
2377 |
+
that.isFinished = true;
|
2378 |
+
that.timer('stop');
|
2379 |
+
cache.get('.wpstg-loader').hide();
|
2380 |
+
cache.get('#wpstg-processing-header').html('Processing Complete'); // show alert
|
2381 |
+
|
2382 |
+
var msg = wpstg.i18n.cloneResetComplete;
|
2383 |
+
|
2384 |
+
if (that.data.action === 'wpstg_update') {
|
2385 |
+
msg = wpstg.i18n.cloneUpdateComplete;
|
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,
|
2393 |
+
width: '500px',
|
2394 |
+
focusConfirm: true
|
2395 |
+
});
|
2396 |
+
}
|
2397 |
+
|
2398 |
+
return false;
|
2399 |
+
}
|
2400 |
+
/**
|
2401 |
+
* Add percentage progress bar
|
2402 |
+
* @param object response
|
2403 |
+
* @return {Boolean}
|
2404 |
+
*/
|
2405 |
+
|
2406 |
+
|
2407 |
+
var progressBar = function progressBar(response, restart) {
|
2408 |
+
if ('undefined' === typeof response.percentage) {
|
2409 |
+
return false;
|
2410 |
+
}
|
2411 |
+
|
2412 |
+
if (response.job === 'database') {
|
2413 |
+
cache.get('#wpstg-progress-db').width(response.percentage * 0.2 + '%').html(response.percentage + '%');
|
2414 |
+
cache.get('#wpstg-processing-status').html(response.percentage.toFixed(0) + '%' + ' - Step 1 of 4 Cloning Database Tables...');
|
2415 |
+
}
|
2416 |
+
|
2417 |
+
if (response.job === 'SearchReplace') {
|
2418 |
+
cache.get('#wpstg-progress-db').css('background-color', '#3bc36b');
|
2419 |
+
cache.get('#wpstg-progress-db').html('1. Database'); // Assumption: All previous steps are done.
|
2420 |
+
// This avoids bugs where some steps are skipped and the progress bar is incomplete as a result
|
2421 |
+
|
2422 |
+
cache.get('#wpstg-progress-db').width('20%');
|
2423 |
+
cache.get('#wpstg-progress-sr').width(response.percentage * 0.1 + '%').html(response.percentage + '%');
|
2424 |
+
cache.get('#wpstg-processing-status').html(response.percentage.toFixed(0) + '%' + ' - Step 2 of 4 Preparing Database Data...');
|
2425 |
+
}
|
2426 |
+
|
2427 |
+
if (response.job === 'directories') {
|
2428 |
+
cache.get('#wpstg-progress-sr').css('background-color', '#3bc36b');
|
2429 |
+
cache.get('#wpstg-progress-sr').html('2. Data');
|
2430 |
+
cache.get('#wpstg-progress-sr').width('10%');
|
2431 |
+
cache.get('#wpstg-progress-dirs').width(response.percentage * 0.1 + '%').html(response.percentage + '%');
|
2432 |
+
cache.get('#wpstg-processing-status').html(response.percentage.toFixed(0) + '%' + ' - Step 3 of 4 Getting files...');
|
2433 |
+
}
|
2434 |
+
|
2435 |
+
if (response.job === 'files') {
|
2436 |
+
cache.get('#wpstg-progress-dirs').css('background-color', '#3bc36b');
|
2437 |
+
cache.get('#wpstg-progress-dirs').html('3. Files');
|
2438 |
+
cache.get('#wpstg-progress-dirs').width('10%');
|
2439 |
+
cache.get('#wpstg-progress-files').width(response.percentage * 0.6 + '%').html(response.percentage + '%');
|
2440 |
+
cache.get('#wpstg-processing-status').html(response.percentage.toFixed(0) + '%' + ' - Step 4 of 4 Copy files...');
|
2441 |
+
}
|
2442 |
+
|
2443 |
+
if (response.job === 'finish') {
|
2444 |
+
cache.get('#wpstg-progress-files').css('background-color', '#3bc36b');
|
2445 |
+
cache.get('#wpstg-progress-files').html('4. Copy Files');
|
2446 |
+
cache.get('#wpstg-progress-files').width('60%');
|
2447 |
+
cache.get('#wpstg-processing-status').html(response.percentage.toFixed(0) + '%' + ' - Cloning Process Finished');
|
2448 |
+
}
|
2449 |
+
};
|
2450 |
+
};
|
2451 |
+
|
2452 |
+
that.switchStep = function (step) {
|
2453 |
+
cache.get('.wpstg-current-step').removeClass('wpstg-current-step');
|
2454 |
+
cache.get('.wpstg-step' + step).addClass('wpstg-current-step');
|
2455 |
+
};
|
2456 |
+
/**
|
2457 |
+
* Initiation
|
2458 |
+
* @type {Function}
|
2459 |
+
*/
|
2460 |
+
|
2461 |
+
|
2462 |
+
that.init = function () {
|
2463 |
+
loadOverview();
|
2464 |
+
elements();
|
2465 |
+
stepButtons();
|
2466 |
+
tabs();
|
2467 |
+
mainTabs();
|
2468 |
+
new WpstgCloneStaging();
|
2469 |
+
};
|
2470 |
+
/**
|
2471 |
+
* Ajax call
|
2472 |
+
* @type {ajax}
|
2473 |
+
*/
|
2474 |
+
|
2475 |
|
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 |
+
/*
|
3806 |
+
* Close Success Modal
|
3807 |
+
*/
|
3808 |
|
3809 |
+
$('body').on('click', '#wpstg-success-button', function (e) {
|
3810 |
+
e.preventDefault();
|
3811 |
+
$('.wpstg-report-issue-form').removeClass('wpstg-report-show');
|
3812 |
+
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3813 |
|
3814 |
+
function sendIssueReport(button, forceSend) {
|
3815 |
+
if (forceSend === void 0) {
|
3816 |
+
forceSend = 'false';
|
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({
|
3828 |
+
url: ajaxurl,
|
3829 |
+
type: 'POST',
|
3830 |
+
dataType: 'json',
|
3831 |
+
async: true,
|
3832 |
+
data: {
|
3833 |
+
'action': 'wpstg_send_report',
|
3834 |
+
'accessToken': wpstg.accessToken,
|
3835 |
+
'nonce': wpstg.nonce,
|
3836 |
+
'wpstg_email': email,
|
3837 |
+
'wpstg_provider': hosting_provider,
|
3838 |
+
'wpstg_message': message,
|
3839 |
+
'wpstg_syslog': +syslog,
|
3840 |
+
'wpstg_terms': +terms,
|
3841 |
+
'wpstg_force_send': forceSend
|
3842 |
+
}
|
3843 |
+
}).done(function (data) {
|
3844 |
+
button.attr('disabled', false);
|
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',
|
3864 |
+
cancelButtonText: 'No'
|
3865 |
+
}).then(function (result) {
|
3866 |
+
if (result.isConfirmed) {
|
3867 |
+
sendIssueReport(button, 'true');
|
3868 |
+
}
|
3869 |
+
});
|
3870 |
+
} else {
|
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) {
|
3900 |
+
var isClickInside = event.target.closest('.wpstg-dropdown-toggler');
|
3901 |
|
3902 |
+
if (!isClickInside) {
|
3903 |
+
var dropDown = document.getElementsByClassName('wpstg-dropdown-menu');
|
3904 |
|
3905 |
+
for (var i = 0; i < dropDown.length; i++) {
|
3906 |
+
dropDown[i].classList.remove('shown');
|
3907 |
+
}
|
3908 |
}
|
3909 |
+
});
|
3910 |
});
|
3911 |
+
|
3912 |
+
}());
|
3913 |
+
//# sourceMappingURL=wpstg-admin.js.map
|
assets/js/dist/wpstg-admin.js.map
ADDED
@@ -0,0 +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> </td><td><p id=\"wpstg_clone_hostname_error\" style=\"color: red;\"> 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('▼');\n } else {\n $this.find('.wpstg-tab-triangle').html('►');\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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
|