first commit
This commit is contained in:
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator messages sections
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Libs\Snap\SnapWP;
|
||||
use Duplicator\Models\Storages\Local\LocalStorage;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var LocalStorage $storage
|
||||
*/
|
||||
$storage = $tplData["storage"];
|
||||
/** @var int */
|
||||
$maxPackages = $tplData["maxPackages"];
|
||||
/** @var int */
|
||||
$isFilderProtection = $tplData["isFilderProtection"];
|
||||
/** @var string */
|
||||
$storageFolder = $tplData["storageFolder"];
|
||||
|
||||
$tplMng->render('admin_pages/storages/parts/provider_head');
|
||||
?>
|
||||
<tr valign="top">
|
||||
<th scope="row">
|
||||
<?php $home_path = SnapWP::getHomePath(true); ?>
|
||||
<label onclick="jQuery('#_local_storage_folder').val('<?php echo esc_js($home_path); ?>')">
|
||||
<?php esc_html_e("Storage Folder", 'duplicator-pro'); ?>
|
||||
</label>
|
||||
</th>
|
||||
<td>
|
||||
<div class="horizontal-input-row">
|
||||
<input
|
||||
data-parsley-errors-container="#_local_storage_folder_error_container"
|
||||
data-parsley-required="true"
|
||||
type="text"
|
||||
id="_local_storage_folder"
|
||||
class="dup-empty-field-on-submit"
|
||||
name="_local_storage_folder"
|
||||
data-parsley-pattern=".*"
|
||||
data-parsley-not-core-paths="true"
|
||||
value="<?php echo esc_attr($storageFolder); ?>">
|
||||
<i class="fa-solid fa-question-circle fa-sm dark-gray-color margin-left-1"
|
||||
data-tooltip-title="<?php esc_attr_e('Server storage folder', 'duplicator-pro'); ?>"
|
||||
data-tooltip="<?php $tplMng->renderEscAttr('admin_pages/storages/configs/local_storage_folder_tooltip'); ?>">
|
||||
</i>
|
||||
</div>
|
||||
<div id="_local_storage_folder_error_container" class="duplicator-error-container"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for="local_filter_protection"><?php esc_html_e("Filter Protection", 'duplicator-pro'); ?></label></th>
|
||||
<td>
|
||||
<div class="horizontal-input-row">
|
||||
<input
|
||||
id="_local_filter_protection"
|
||||
name="_local_filter_protection"
|
||||
type="checkbox" <?php checked($isFilderProtection); ?>
|
||||
onchange="DupliJs.Storage.LocalFilterToggle()">
|
||||
<label for="_local_filter_protection">
|
||||
<?php esc_html_e("Filter the Storage Folder (recommended)", 'duplicator-pro'); ?>
|
||||
</label>
|
||||
</div>
|
||||
<div style="padding-top:6px">
|
||||
<i>
|
||||
<?php
|
||||
esc_html_e(
|
||||
"When checked this will exclude the 'Storage Folder' and all of its content and sub-folders from Backup builds.",
|
||||
'duplicator-pro'
|
||||
); ?>
|
||||
</i>
|
||||
<div id="_local_filter_protection_message" style="display:none; color:maroon">
|
||||
<i>
|
||||
<?php
|
||||
esc_html_e(
|
||||
"Unchecking filter protection is not recommended. This setting helps to prevents Backups from getting bundled in other Backups.",
|
||||
'duplicator-pro'
|
||||
); ?>
|
||||
</i>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for=""><?php esc_html_e("Max Backups", 'duplicator-pro'); ?></label></th>
|
||||
<td>
|
||||
<div class="horizontal-input-row">
|
||||
<input
|
||||
id="local_max_files"
|
||||
name="local_max_files"
|
||||
type="number"
|
||||
value="<?php echo (int) $maxPackages; ?>"
|
||||
min="0"
|
||||
maxlength="4"
|
||||
data-parsley-errors-container="#local_max_files_error_container"
|
||||
data-parsley-required="true"
|
||||
data-parsley-type="number"
|
||||
data-parsley-min="0">
|
||||
<label for="local_max_files"><?php esc_html_e("Number of Backups to keep in folder.", 'duplicator-pro'); ?><br /></label>
|
||||
</div>
|
||||
<?php $tplMng->render('admin_pages/storages/parts/max_backups_description'); ?>
|
||||
<div id="local_max_files_error_container" class="duplicator-error-container"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php $tplMng->render('admin_pages/storages/parts/provider_foot'); ?>
|
||||
|
||||
<script>
|
||||
jQuery(document).ready(function($) {
|
||||
|
||||
let validatorMsg = <?php
|
||||
echo json_encode(
|
||||
__(
|
||||
'Storage Folder should not be root directory path, content directory path and upload directory path',
|
||||
'duplicator-pro'
|
||||
)
|
||||
); ?>;
|
||||
window.Parsley.addValidator('notCorePaths', {
|
||||
requirementType: 'string',
|
||||
validateString: function(value) {
|
||||
<?php
|
||||
$home_path = SnapWP::getHomePath(true);
|
||||
$wp_upload_dir = wp_upload_dir();
|
||||
$wp_upload_dir_basedir = str_replace('\\', '/', $wp_upload_dir['basedir']);
|
||||
?>
|
||||
var corePaths = [
|
||||
'<?php echo esc_js($home_path); ?>',
|
||||
'<?php echo esc_js(untrailingslashit($home_path)); ?>',
|
||||
|
||||
'<?php echo esc_js($home_path . 'wp-content'); ?>',
|
||||
'<?php echo esc_js($home_path . 'wp-content/'); ?>',
|
||||
|
||||
'<?php echo esc_js($home_path . 'wp-admin'); ?>',
|
||||
'<?php echo esc_js($home_path . 'wp-admin/'); ?>',
|
||||
|
||||
'<?php echo esc_js($home_path . 'wp-includes'); ?>',
|
||||
'<?php echo esc_js($home_path . 'wp-includes/'); ?>',
|
||||
|
||||
'<?php echo esc_js($wp_upload_dir_basedir); ?>',
|
||||
'<?php echo esc_js(trailingslashit($wp_upload_dir_basedir)); ?>'
|
||||
];
|
||||
// console.log(value);
|
||||
|
||||
for (var i = 0; i < corePaths.length; i++) {
|
||||
if (value === corePaths[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
messages: {
|
||||
en: validatorMsg
|
||||
}
|
||||
});
|
||||
|
||||
DupliJs.Storage.LocalFilterToggle = function() {
|
||||
$("#_local_filter_protection").is(":checked") ?
|
||||
$("#_local_filter_protection_message").hide(400) :
|
||||
$("#_local_filter_protection_message").show(400);
|
||||
|
||||
};
|
||||
//Init
|
||||
DupliJs.Storage.LocalFilterToggle();
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator messages sections
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Models\Storages\Local\LocalStorage;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var LocalStorage $storage
|
||||
*/
|
||||
$storage = $tplData["storage"];
|
||||
/** @var int */
|
||||
$maxPackages = $tplData["maxPackages"];
|
||||
/** @var string */
|
||||
$storageFolder = $tplData["storageFolder"];
|
||||
|
||||
$tplMng->render('admin_pages/storages/parts/provider_head');
|
||||
?>
|
||||
<tr valign="top">
|
||||
<th scope="row"><label><?php esc_html_e("Location", 'duplicator-pro'); ?></label></th>
|
||||
<td><?php echo esc_html($storageFolder); ?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label for=""><?php esc_html_e("Max Backups", 'duplicator-pro'); ?></label></th>
|
||||
<td>
|
||||
<div class="horizontal-input-row">
|
||||
<input
|
||||
data-parsley-errors-container="#max_default_store_files_error_container"
|
||||
id="max_default_store_files"
|
||||
name="max_default_store_files"
|
||||
type="text"
|
||||
data-parsley-type="number"
|
||||
data-parsley-min="0"
|
||||
data-parsley-required="true"
|
||||
value="<?php echo intval($maxPackages); ?>"
|
||||
maxlength="4"
|
||||
>
|
||||
<label for="max_default_store_files">
|
||||
<?php esc_html_e("Number of Backups to keep in folder. ", 'duplicator-pro'); ?><br/>
|
||||
</label>
|
||||
</div>
|
||||
<?php $tplMng->render('admin_pages/storages/parts/max_backups_description'); ?>
|
||||
<div id="max_default_store_files_error_container" class="duplicator-error-container"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php $tplMng->render('admin_pages/storages/parts/provider_foot'); ?>
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator messages sections
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Libs\Snap\SnapWP;
|
||||
use Duplicator\Models\Storages\Local\LocalStorage;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var LocalStorage $storage
|
||||
*/
|
||||
$storage = $tplData["storage"];
|
||||
/** @var int */
|
||||
$maxPackages = $tplData["maxPackages"];
|
||||
/** @var int */
|
||||
$isFilderProtection = $tplData["isFilderProtection"];
|
||||
/** @var string */
|
||||
$storageFolder = $tplData["storageFolder"];
|
||||
|
||||
$tplMng->render('admin_pages/storages/parts/provider_head');
|
||||
?>
|
||||
|
||||
<?php esc_html_e("Where to store on the server hosting this site.", 'duplicator-pro'); ?><br>
|
||||
<?php
|
||||
printf(
|
||||
esc_html_x(
|
||||
'The folder can be either a child of the home directory (%1$s) or be outside it as well.',
|
||||
'%1$s represents the home directory path',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<b>' . esc_html(SnapWP::getHomePath(true)) . '</b>'
|
||||
); ?><br>
|
||||
<?php esc_html_e("On Linux servers start with '/' (e.g. /mypath). On Windows use drive letters (e.g. E:/mypath).", 'duplicator-pro'); ?><br>
|
||||
<?php esc_html_e("If you are unsure of the path, contact your hosting provider.", 'duplicator-pro'); ?><br>
|
||||
<br>
|
||||
<b><?php esc_html_e('Note: This will not store to your local computer unless that is where this web-site is hosted.', 'duplicator-pro'); ?></b><br>
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator messages sections
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Models\Storages\UnknownStorage;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var UnknownStorage $storage
|
||||
*/
|
||||
$storage = $tplData["storage"];
|
||||
|
||||
$tplMng->render('admin_pages/storages/parts/provider_head');
|
||||
?>
|
||||
<tr valign="top">
|
||||
<th scope="row">
|
||||
<label>
|
||||
<?php esc_html_e("Unknown Storage Type", 'duplicator-pro'); ?>
|
||||
</label>
|
||||
</th>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
<?php $tplMng->render('admin_pages/storages/parts/provider_foot');
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Storage authorization success message template
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var string $storagePageUrl Storage page URL
|
||||
* @var string $storageName Storage name
|
||||
* @var bool $isSettingsPage Whether authorization was from Settings page
|
||||
*/
|
||||
|
||||
$storagePageUrl = $tplMng->getDataValueString('storagePageUrl');
|
||||
$storageName = $tplMng->getDataValueString('storageName');
|
||||
$isSettingsPage = $tplMng->getDataValueBool('isSettingsPage');
|
||||
|
||||
if ($isSettingsPage) {
|
||||
printf(
|
||||
esc_html__('Successfully connected to %1$s! You can manage/edit it from the %2$sStorage page%3$s.', 'duplicator-pro'),
|
||||
'<strong>' . esc_html($storageName) . '</strong>',
|
||||
'<a href="' . esc_url($storagePageUrl) . '">',
|
||||
'</a>'
|
||||
);
|
||||
} else {
|
||||
printf(
|
||||
esc_html__('Successfully connected to %s!', 'duplicator-pro'),
|
||||
'<strong>' . esc_html($storageName) . '</strong>'
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator messages sections
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Core\Controllers\ControllersManager;
|
||||
use Duplicator\Models\Storages\AbstractStorageEntity;
|
||||
use Duplicator\Models\Storages\Local\DefaultLocalStorage;
|
||||
use Duplicator\Models\Storages\Local\LocalStorage;
|
||||
use Duplicator\Models\Storages\StoragesUtil;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var AbstractStorageEntity $storage
|
||||
*/
|
||||
$storage = $tplData["storage"];
|
||||
/** @var bool */
|
||||
$blur = $tplData['blur'];
|
||||
/** @var int */
|
||||
$storage_id = $tplData["storage_id"];
|
||||
|
||||
$storage_tab_url = ControllersManager::getMenuLink(
|
||||
ControllersManager::STORAGE_SUBMENU_SLUG
|
||||
);
|
||||
|
||||
$baseCopyUrl = ControllersManager::getMenuLink(
|
||||
ControllersManager::STORAGE_SUBMENU_SLUG,
|
||||
null,
|
||||
null,
|
||||
[
|
||||
ControllersManager::QUERY_STRING_INNER_PAGE => 'edit',
|
||||
'action' => $tplData['actions']['copy-storage']->getKey(),
|
||||
'_wpnonce' => $tplData['actions']['copy-storage']->getNonce(),
|
||||
'storage_id' => $storage_id,
|
||||
]
|
||||
);
|
||||
|
||||
if ($storage->getId() > 0) {
|
||||
$storages = AbstractStorageEntity::getAllBySType($storage->getSType());
|
||||
} else {
|
||||
$storages = AbstractStorageEntity::getAll(
|
||||
0,
|
||||
0,
|
||||
[
|
||||
StoragesUtil::class,
|
||||
'sortByPriority',
|
||||
],
|
||||
fn(AbstractStorageEntity $s): bool => $s->getSType() !== LocalStorage::getSType() // Exclude local storage from the "Copy From" option list
|
||||
);
|
||||
}
|
||||
|
||||
if ($storages === false) {
|
||||
$storages = [];
|
||||
}
|
||||
|
||||
$storages = array_filter($storages, function (AbstractStorageEntity $s) use ($storage): bool {
|
||||
if ($s->getId() == $storage->getId()) {
|
||||
return false;
|
||||
}
|
||||
if ($s->getSType() == DefaultLocalStorage::getSType()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
$storage_count = count($storages);
|
||||
?>
|
||||
<div class="dup-toolbar <?php echo ($blur ? 'dup-mock-blur' : ''); ?>">
|
||||
<label for="dup-copy-source-id-select" class="screen-reader-text">Copy storage action</label>
|
||||
<select
|
||||
id="dup-copy-source-id-select"
|
||||
name="dupli-source-storage-id"
|
||||
class="small"
|
||||
<?php disabled($storage_count < 1 || $storage->isLocal(), true); ?>>
|
||||
<option value="-1" selected="selected" disabled="true">
|
||||
<?php esc_html_e('Copy From', 'duplicator-pro'); ?>
|
||||
</option>
|
||||
<?php foreach ($storages as $copy_storage) { ?>
|
||||
<option value="<?php echo (int) $copy_storage->getId(); ?>" data-stype="<?php echo (int) $copy_storage->getSType(); ?>">
|
||||
<?php echo esc_html($copy_storage->getName()); ?> [<?php echo esc_html($copy_storage->getStypeName()); ?>]
|
||||
</option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
<input
|
||||
type="button"
|
||||
id="dup-copy-storage-btn"
|
||||
class="button hollow secondary small action"
|
||||
value="<?php esc_attr_e("Apply", 'duplicator-pro') ?>"
|
||||
onclick="DupliJs.Storage.Copy()"
|
||||
<?php disabled($storage_count < 1 || $storage->isLocal(), true); ?>>
|
||||
<span class="separator"></span>
|
||||
<a
|
||||
href="<?php echo esc_url($storage_tab_url); ?>"
|
||||
class="button hollow secondary small "
|
||||
title="<?php esc_attr_e('Back to storages list.', 'duplicator-pro'); ?>">
|
||||
<i class="fas fa-server fa-sm"></i> <?php esc_html_e('Storages', 'duplicator-pro'); ?>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<hr class="dup-toolbar-divider" />
|
||||
<script>
|
||||
jQuery(document).ready(function($) {
|
||||
// COMMON STORAGE RELATED METHODS
|
||||
DupliJs.Storage.Copy = function() {
|
||||
document.location.href = <?php echo json_encode($baseCopyUrl); ?> +
|
||||
'&dupli-source-storage-id=' + $("#dup-copy-source-id-select option:selected").val();
|
||||
};
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator messages sections
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Controllers\SettingsPageController;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
?>
|
||||
<p class="description">
|
||||
<?php esc_html_e("When this limit is exceeded, the oldest Backup will be deleted. Set to 0 for no limit.", 'duplicator-pro'); ?>
|
||||
<i
|
||||
class="fa-solid fa-question-circle fa-sm dark-gray-color"
|
||||
data-tooltip="<?php echo esc_attr(
|
||||
sprintf(
|
||||
_x(
|
||||
'To configure how the associated backup record in the "Backups" screen is handled checkout the
|
||||
%1$s"Delete Backup Records"%2$s setting.',
|
||||
'1: <a> tag, 2: </a> tag',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<a href="' . esc_url(SettingsPageController::getInstance()->getMenuLink(SettingsPageController::L2_SLUG_STORAGE)) . '">',
|
||||
'</a>'
|
||||
)
|
||||
); ?>"
|
||||
>
|
||||
</i>
|
||||
</p>
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator messages sections
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Models\Storages\AbstractStorageEntity;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var AbstractStorageEntity $storage
|
||||
*/
|
||||
$storage = $tplData["storage"];
|
||||
|
||||
?>
|
||||
</table>
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator messages sections
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Models\Storages\AbstractStorageEntity;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var AbstractStorageEntity $storage
|
||||
*/
|
||||
$storage = $tplData["storage"];
|
||||
?>
|
||||
<table id="provider-<?php echo (int) $storage->getSType() ?>" class="provider form-table dup-remove-on-submit-if-hidden">
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator messages sections
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Controllers\StoragePageController;
|
||||
use Duplicator\Models\Storages\AbstractStorageEntity;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var AbstractStorageEntity $storage
|
||||
*/
|
||||
$storage = $tplData["storage"];
|
||||
/** @var bool */
|
||||
$failed = $tplData["failed"];
|
||||
/** @var bool */
|
||||
$cancelled = $tplData["cancelled"];
|
||||
/** @var bool */
|
||||
$packageExists = $tplData["packageExists"];
|
||||
|
||||
$containerClasses = ['dup-dlg-store-endpoint'];
|
||||
if ($failed) {
|
||||
$containerClasses[] = 'dup-dlg-store-endpoint-failed';
|
||||
}
|
||||
if ($cancelled) {
|
||||
$containerClasses[] = 'dup-dlg-store-endpoint-cancelled';
|
||||
}
|
||||
if (!$packageExists) {
|
||||
$containerClasses[] = 'dup-dlg-store-package-not-found';
|
||||
}
|
||||
?>
|
||||
<div class="<?php echo esc_attr(implode(' ', $containerClasses)); ?>" >
|
||||
<h4 class="dup-dlg-store-names">
|
||||
<?php
|
||||
echo wp_kses(
|
||||
$storage->getStypeIcon(),
|
||||
[
|
||||
'i' => [
|
||||
'class' => [],
|
||||
],
|
||||
'img' => [
|
||||
'src' => [],
|
||||
'class' => [],
|
||||
'alt' => [],
|
||||
],
|
||||
]
|
||||
);
|
||||
?>
|
||||
<?php echo esc_html($storage->getStypeName()) ?>:
|
||||
<span>
|
||||
<?php echo esc_html($storage->getName()); ?>
|
||||
<i>
|
||||
<?php if ($failed) { ?>
|
||||
(<?php esc_html_e('failed', 'duplicator-pro'); ?>)
|
||||
<?php } elseif ($cancelled) { ?>
|
||||
(<?php esc_html_e('cancelled', 'duplicator-pro'); ?>)
|
||||
<?php } elseif (!$packageExists) { ?>
|
||||
(<?php esc_html_e('backup not found', 'duplicator-pro'); ?>)
|
||||
<?php } ?>
|
||||
</i>
|
||||
</span>
|
||||
</h4>
|
||||
<div class="dup-dlg-store-links">
|
||||
<?php
|
||||
echo wp_kses(
|
||||
$storage->getHtmlLocationLink(),
|
||||
[
|
||||
'a' => [
|
||||
'href' => [],
|
||||
'target' => [],
|
||||
],
|
||||
]
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
<div class="dup-dlg-store-test">
|
||||
<a href="<?php echo esc_url(StoragePageController::getEditUrl($storage)); ?>" target='_blank'>
|
||||
[ <?php esc_html_e('Test Storage', 'duplicator-pro'); ?> ]
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator storage error template
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Ajax\ServicesTools;
|
||||
use Duplicator\Core\Controllers\ControllersManager;
|
||||
use Duplicator\Utils\Support\SupportToolkit;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var Exception $e
|
||||
*/
|
||||
$e = $tplData["exception"];
|
||||
$settings_url = ControllersManager::getMenuLink(ControllersManager::SETTINGS_SUBMENU_SLUG);
|
||||
$fullError = $e->getMessage() . "\n\n" . $e->getTraceAsString();
|
||||
?>
|
||||
<div class="dup-storage-error-wrapper">
|
||||
<div class="error-txt">
|
||||
<h3><?php esc_html_e('Oops, there was a problem...', 'duplicator-pro'); ?></h3>
|
||||
<p>
|
||||
<?php esc_html_e('An error has occurred while trying to read a storage item! ', 'duplicator-pro'); ?>
|
||||
<?php esc_html_e(
|
||||
'To resolve this issue edit the storage, re-enter its information and if appropriate re-authorize the plugin. ',
|
||||
'duplicator-pro'
|
||||
); ?>
|
||||
</p>
|
||||
<p>
|
||||
<?php esc_html_e(
|
||||
'This problem can be due to a security plugin changing keys in wp-config.php, causing the storage information to become unreadable.',
|
||||
'duplicator-pro'
|
||||
); ?>
|
||||
<?php
|
||||
printf(
|
||||
esc_html__(
|
||||
'If such a plugin is doing this then either disable the key changing functionality
|
||||
in the security plugin or go to %1$sDuplicator Pro > Settings%2$s and disable settings encryption.',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<a href="' . esc_url($settings_url) . '">',
|
||||
'</a>'
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
<p>
|
||||
<?php esc_html_e('If the problem persists after doing these things then please contact the support team.', 'duplicator-pro'); ?>
|
||||
<?php if (SupportToolkit::isAvailable()) {
|
||||
printf(
|
||||
esc_html__(
|
||||
'Please make sure to attach the %1$sdiagnostic data%2$s and the error message below to your ticket.',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<a href="' . esc_url(SupportToolkit::getSupportToolkitDownloadUrl()) . '">',
|
||||
'</a>'
|
||||
);
|
||||
} ?>
|
||||
</p>
|
||||
</div>
|
||||
<div class="error-trace-copy">
|
||||
<textarea class="dup-error-message-textarea" disabled ><?php echo esc_textarea($fullError); ?></textarea>
|
||||
<button
|
||||
data-dup-copy-value="<?php echo esc_attr($fullError); ?>"
|
||||
data-dup-copy-title="<?php echo esc_attr("Copy Error Message to clipboard"); ?>"
|
||||
data-dup-copied-title="<?php echo esc_attr("Error Message copied to clipboard"); ?>"
|
||||
class="button dup-btn-copy-error-message">
|
||||
<?php esc_html_e('Copy error details', 'duplicator-pro'); ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,295 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator messages sections
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Models\Storages\AbstractStorageEntity;
|
||||
use Duplicator\Core\Addons\AddonsManager;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var AbstractStorageEntity $storage
|
||||
*/
|
||||
$storage = $tplData["storage"];
|
||||
|
||||
$sTypeSelected = ($storage->isSelectable() ? $storage->getSType() : -1);
|
||||
$types = AbstractStorageEntity::getResisteredTypesByPriority();
|
||||
$isEditMode = ($storage->getId() < 0);
|
||||
|
||||
// Collect storage types for display
|
||||
$storageTypes = [];
|
||||
foreach ($types as $type) {
|
||||
$class = AbstractStorageEntity::getSTypePHPClass($type);
|
||||
if (!call_user_func([$class, 'isSelectable'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$disabledReason = '';
|
||||
$isDisabled = call_user_func_array([$class, 'isSelectDisabled'], [&$disabledReason]);
|
||||
|
||||
$storageTypes[] = [
|
||||
'type' => $type,
|
||||
'class' => $class,
|
||||
'name' => call_user_func([$class, 'getStypeName']),
|
||||
'icon' => call_user_func([$class, 'getStypeIcon']),
|
||||
'disabled' => $isDisabled,
|
||||
'reason' => $disabledReason,
|
||||
'gridBreak' => call_user_func([$class, 'isGridBreakAfter']),
|
||||
];
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="dup-storage-type-selector" id="dup-storage-type-selector">
|
||||
<span class="dup-storage-type-selector__current" id="dup-storage-current">
|
||||
<?php
|
||||
echo wp_kses(
|
||||
$storage->getStypeIcon(),
|
||||
[
|
||||
'i' => [
|
||||
'class' => [],
|
||||
],
|
||||
'img' => [
|
||||
'src' => [],
|
||||
'class' => [],
|
||||
'alt' => [],
|
||||
],
|
||||
]
|
||||
);
|
||||
?>
|
||||
<span><?php echo esc_html($storage->getStypeName()); ?></span>
|
||||
</span>
|
||||
|
||||
<?php if ($isEditMode) : ?>
|
||||
<button type="button" class="dup-storage-type-selector__toggle button primary hollow margin-bottom-0" id="dup-storage-toggle">
|
||||
<?php esc_html_e('Select', 'duplicator-pro'); ?>
|
||||
</button>
|
||||
|
||||
<div class="dup-storage-type-selector__grid" id="dup-storage-grid">
|
||||
<div class="dup-storage-type-selector__grid-inner">
|
||||
<?php foreach ($storageTypes as $storageType) : ?>
|
||||
<?php
|
||||
$cardClasses = 'dup-storage-card';
|
||||
$cardClasses .= ($sTypeSelected === $storageType['type']) ? ' is-selected' : '';
|
||||
$cardClasses .= $storageType['disabled'] ? ' is-disabled' : '';
|
||||
$cardTitle = $storageType['disabled'] ? $storageType['reason'] : $storageType['name'];
|
||||
?>
|
||||
<label
|
||||
class="<?php echo esc_attr($cardClasses); ?>"
|
||||
title="<?php echo esc_attr($cardTitle); ?>"
|
||||
data-storage-type="<?php echo (int) $storageType['type']; ?>"
|
||||
data-storage-name="<?php echo esc_attr($storageType['name']); ?>"
|
||||
data-storage-disabled="<?php echo $storageType['disabled'] ? '1' : '0'; ?>"
|
||||
>
|
||||
<input
|
||||
type="radio"
|
||||
name="storage_type_radio"
|
||||
value="<?php echo (int) $storageType['type']; ?>"
|
||||
<?php checked($sTypeSelected, $storageType['type']); ?>
|
||||
<?php disabled($storageType['disabled']); ?>
|
||||
>
|
||||
<?php
|
||||
echo wp_kses(
|
||||
$storageType['icon'],
|
||||
[
|
||||
'i' => ['class' => []],
|
||||
'img' => [
|
||||
'src' => [],
|
||||
'class' => [],
|
||||
'alt' => [],
|
||||
],
|
||||
]
|
||||
);
|
||||
?>
|
||||
<div class="label" >
|
||||
<?php echo esc_attr($storageType['name']); ?>
|
||||
</div>
|
||||
<?php if ($storageType['disabled']) : ?>
|
||||
<span class="dup-storage-card__disabled-overlay"></span>
|
||||
<?php endif; ?>
|
||||
</label>
|
||||
<?php if ($storageType['gridBreak']) : ?>
|
||||
<div class="dup-storage-grid-break"></div>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<select id="change-mode" name="storage_type" onchange="DupliJs.Storage.ChangeMode()" class="width-medium" style="display: none;">
|
||||
<?php foreach ($storageTypes as $storageType) : ?>
|
||||
<option
|
||||
value="<?php echo (int) $storageType['type']; ?>"
|
||||
<?php selected($sTypeSelected, $storageType['type']); ?>
|
||||
<?php disabled($storageType['disabled']); ?>
|
||||
>
|
||||
<?php echo esc_html($storageType['name']); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<?php else : ?>
|
||||
<span id="dup-storage-mode-fixed" data-storage-type="<?php echo (int) $storage->getSType(); ?>" style="display: none;"></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
jQuery(document).ready(function ($) {
|
||||
DupliJs.Storage.InitTypeSelector = function($container) {
|
||||
const $toggle = $container.find('.dup-storage-type-selector__toggle');
|
||||
const $cards = $container.find('.dup-storage-card');
|
||||
const $current = $container.find('.dup-storage-type-selector__current');
|
||||
const $select = $('#change-mode');
|
||||
|
||||
$toggle.on('click', function() {
|
||||
$container.toggleClass('is-open');
|
||||
});
|
||||
|
||||
$cards.on('click', function() {
|
||||
const $card = $(this);
|
||||
const isDisabled = $card.data('storage-disabled') === 1;
|
||||
|
||||
// Prevent selection of disabled storage types
|
||||
if (isDisabled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const storageType = $card.data('storage-type');
|
||||
const storageName = $card.data('storage-name');
|
||||
const $icon = $card.find('i, img').clone();
|
||||
|
||||
$card.find('input[type="radio"]').prop('checked', true);
|
||||
|
||||
$select.val(storageType).trigger('change');
|
||||
|
||||
$cards.removeClass('is-selected');
|
||||
$card.addClass('is-selected');
|
||||
|
||||
$current.html($icon.add('<span>' + storageName + '</span>'));
|
||||
|
||||
$container.removeClass('is-open');
|
||||
|
||||
DupliJs.Storage.ChangeMode();
|
||||
});
|
||||
};
|
||||
|
||||
// Initialize the type selector if it exists
|
||||
const $typeSelector = $('#dup-storage-type-selector');
|
||||
if ($typeSelector.length > 0) {
|
||||
DupliJs.Storage.InitTypeSelector($typeSelector);
|
||||
}
|
||||
|
||||
DupliJs.Storage.BindParsley = function (node)
|
||||
{
|
||||
$('#dup-storage-form').parsley().destroy();
|
||||
$('#dup-storage-form .provider input').attr('data-parsley-excluded', 'true');
|
||||
|
||||
node.find('input').removeAttr('data-parsley-excluded');
|
||||
|
||||
$('#dup-storage-form').parsley();
|
||||
};
|
||||
|
||||
DupliJs.Storage.Autofill = function (mode) {
|
||||
<?php if (AddonsManager::getInstance()->isAddonEnabled('AmazonS3Addon')) : ?>
|
||||
switch (parseInt(mode)) {
|
||||
case <?php echo (int) \Duplicator\Addons\AmazonS3Addon\Models\BackblazeStorage::getSType(); ?>:
|
||||
case <?php echo (int) \Duplicator\Addons\AmazonS3Addon\Models\DreamStorage::getSType(); ?>:
|
||||
autoFillRegion(mode, 1);
|
||||
break;
|
||||
case <?php echo (int) \Duplicator\Addons\AmazonS3Addon\Models\VultrStorage::getSType(); ?>:
|
||||
case <?php echo (int) \Duplicator\Addons\AmazonS3Addon\Models\DigitalOceanStorage::getSType(); ?>:
|
||||
autoFillRegion(mode, 0);
|
||||
break;
|
||||
case <?php echo (int) \Duplicator\Addons\AmazonS3Addon\Models\WasabiStorage::getSType(); ?>:
|
||||
let wasabiRegion = $("#s3_region_" + mode);
|
||||
let wasabiEndpoint = $("#s3_endpoint_" + mode);
|
||||
|
||||
wasabiRegion.change(function(e) {
|
||||
if (wasabiEndpoint.val().length > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
let regionVal = $(this).val();
|
||||
if (regionVal.length > 0) {
|
||||
wasabiEndpoint.val("s3." + regionVal + ".wasabisys.com");
|
||||
} else {
|
||||
wasabiEndpoint.val("");
|
||||
}
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
function autoFillRegion(type, regionPos) {
|
||||
let region = $("#s3_region_" + type);
|
||||
let endpoint = $("#s3_endpoint_" + type);
|
||||
|
||||
endpoint.change(function(e) {
|
||||
bindEndpointToRegion(region, endpoint, regionPos);
|
||||
});
|
||||
}
|
||||
|
||||
function bindEndpointToRegion(region, endpoint, pos) {
|
||||
if (region.val().length > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (endpoint.val().length > 0) {
|
||||
let regionStr = endpoint.val().replace(/.*:\/\//g,'').split(".")[pos];
|
||||
region.val(regionStr);
|
||||
} else {
|
||||
region.val("");
|
||||
}
|
||||
}
|
||||
<?php else : ?>
|
||||
return;
|
||||
<?php endif; ?>
|
||||
}
|
||||
|
||||
// GENERAL STORAGE LOGIC
|
||||
DupliJs.Storage.ChangeMode = function (animateOverride = 400) {
|
||||
const mode = $('#dup-storage-mode-fixed').length > 0
|
||||
? $('#dup-storage-mode-fixed').data('storage-type')
|
||||
: $('#change-mode option:selected').val();
|
||||
|
||||
// Reset the copy source ID select
|
||||
$('#dup-copy-source-id-select').val(-1);
|
||||
|
||||
// Disable copy controls for local storage
|
||||
const isCopyDisabled = parseInt(mode) === 0;
|
||||
$('#dup-copy-source-id-select, #dup-copy-storage-btn').prop('disabled', isCopyDisabled);
|
||||
|
||||
// Disable non-matching options
|
||||
$('#dup-copy-source-id-select option').each(function () {
|
||||
const option = $(this);
|
||||
const optionType = option.data('stype');
|
||||
option.prop('disabled', optionType !== parseInt(mode));
|
||||
|
||||
// Hide options that are disabled
|
||||
if (option.prop('disabled')) {
|
||||
option.hide();
|
||||
} else {
|
||||
option.show();
|
||||
}
|
||||
});
|
||||
|
||||
const providerConfigNode = $('#provider-' + mode);
|
||||
|
||||
$('.provider').hide();
|
||||
providerConfigNode.show(animateOverride);
|
||||
|
||||
DupliJs.Storage.BindParsley(providerConfigNode);
|
||||
DupliJs.Storage.Autofill(mode);
|
||||
}
|
||||
|
||||
$('#dup-storage-form').parsley();
|
||||
DupliJs.Storage.ChangeMode(0);
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Models\Storages\AbstractStorageEntity;
|
||||
use Duplicator\Views\UI\UiDialog;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var AbstractStorageEntity $storage
|
||||
*/
|
||||
$storage = $tplData["storage"];
|
||||
|
||||
$errorMessage = '';
|
||||
$buttonDisabled = ($storage->getId() < 0 || $storage->isValid($errorMessage, true) == false);
|
||||
?>
|
||||
<table class="form-table">
|
||||
<tr>
|
||||
<th scope="row">
|
||||
<label for=""><?php esc_html_e("Validation", 'duplicator-pro'); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<button
|
||||
id="button_file_test"
|
||||
class="button secondary hollow small button_file_test margin-bottom-0"
|
||||
type="button"
|
||||
onclick="DupliJs.Storage.Test(); return false;"
|
||||
<?php disabled($buttonDisabled); ?>>
|
||||
<i class="fas fa-cloud-upload-alt fa-sm"></i> <?php esc_html_e('Test Storage', 'duplicator-pro'); ?>
|
||||
</button>
|
||||
<p>
|
||||
<i><?php esc_html_e("Test creating and deleting a small file on storage.", 'duplicator-pro'); ?></i>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<?php
|
||||
|
||||
$alertStorageStatus = new UiDialog();
|
||||
$alertStorageStatus->title = __('Storage Status', 'duplicator-pro');
|
||||
$alertStorageStatus->height = 185;
|
||||
$alertStorageStatus->message = 'testings'; // javascript inserted message
|
||||
$alertStorageStatus->initAlert();
|
||||
|
||||
$alertStorageStatusLong = new UiDialog();
|
||||
$alertStorageStatusLong->title = __('Storage Status', 'duplicator-pro');
|
||||
$alertStorageStatusLong->width = 800;
|
||||
$alertStorageStatusLong->height = 520;
|
||||
$alertStorageStatusLong->showTextArea = true;
|
||||
$alertStorageStatusLong->textAreaRows = 15;
|
||||
$alertStorageStatusLong->textAreaCols = 100;
|
||||
$alertStorageStatusLong->message = ''; // javascript inserted message
|
||||
$alertStorageStatusLong->initAlert();
|
||||
|
||||
?>
|
||||
|
||||
<script>
|
||||
jQuery(document).ready(function($) {
|
||||
|
||||
DupliJs.Storage.Test = function() {
|
||||
var $test_button = $('#button_file_test');
|
||||
$test_button.html('<i class="fas fa-circle-notch fa-spin"></i> <?php esc_html_e('Attempting to test storage', 'duplicator-pro'); ?>');
|
||||
|
||||
DupliJs.Util.ajaxWrapper({
|
||||
action: 'duplicator_storage_test',
|
||||
storage_id: <?php echo (int) $storage->getId(); ?>,
|
||||
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_storage_test')); ?>'
|
||||
},
|
||||
function(result, data, funcData, textStatus, jqXHR) {
|
||||
console.log('Func data', funcData);
|
||||
if (funcData.success) {
|
||||
if (funcData.status_msgs.length == 0) {
|
||||
<?php $alertStorageStatus->showAlert(); ?>
|
||||
let alertMsg = "<span style='color:green'><b><input type='checkbox' class='checkbox' checked disabled='disabled'>" +
|
||||
funcData.message + "</b></span>";
|
||||
<?php $alertStorageStatus->updateMessage("alertMsg"); ?>
|
||||
} else {
|
||||
<?php $alertStorageStatusLong->showAlert(); ?>
|
||||
<?php $alertStorageStatusLong->updateTextareaMessage("funcData.status_msgs"); ?>
|
||||
let alertMsg = "<span style='color:green'><b><input type='checkbox' class='checkbox' checked disabled='disabled'>" +
|
||||
funcData.message + "</b></span>";
|
||||
<?php $alertStorageStatusLong->updateMessage("alertMsg"); ?>
|
||||
}
|
||||
} else {
|
||||
if (funcData.status_msgs.length == 0) {
|
||||
<?php $alertStorageStatus->showAlert(); ?>
|
||||
let alertMsg = "<i class='fas fa-exclamation-triangle'></i> " + funcData.message;
|
||||
<?php $alertStorageStatus->updateMessage("alertMsg"); ?>
|
||||
} else {
|
||||
<?php $alertStorageStatusLong->showAlert(); ?>
|
||||
<?php $alertStorageStatusLong->updateTextareaMessage("funcData.status_msgs"); ?>
|
||||
let alertMsg = "<i class='fas fa-exclamation-triangle'></i> " + funcData.message;
|
||||
<?php $alertStorageStatusLong->updateMessage("alertMsg"); ?>
|
||||
}
|
||||
}
|
||||
$test_button.html('<i class="fas fa-cloud-upload-alt fa-sm"></i> <?php esc_html_e('Test Storage', 'duplicator-pro'); ?>');
|
||||
return '';
|
||||
},
|
||||
function(result, data, funcData, textStatus, jqXHR) {
|
||||
$test_button.html('<i class="fas fa-cloud-upload-alt fa-sm"></i> <?php esc_html_e('Test Storage', 'duplicator-pro'); ?>');
|
||||
<?php $alertStorageStatus->showAlert(); ?>
|
||||
let alertMsg = "<i class='fas fa-exclamation-triangle'></i> <?php esc_html_e('AJAX error while testing storage.', 'duplicator-pro'); ?> ";
|
||||
<?php $alertStorageStatus->updateMessage("alertMsg"); ?>
|
||||
console.log(data);
|
||||
return '';
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator Backup row in table Backups list
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Controllers\StoragePageController;
|
||||
use Duplicator\Core\CapMng;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var bool $blur
|
||||
*/
|
||||
$blur = $tplData['blur'];
|
||||
|
||||
if (CapMng::can(CapMng::CAP_STORAGE, false) && !$blur) {
|
||||
$edit_storage_url = $ctrlMng::getMenuLink(
|
||||
$ctrlMng::STORAGE_SUBMENU_SLUG,
|
||||
null,
|
||||
null,
|
||||
[
|
||||
$ctrlMng::QUERY_STRING_INNER_PAGE => StoragePageController::INNER_PAGE_EDIT,
|
||||
]
|
||||
);
|
||||
|
||||
$tipContent = __(
|
||||
'Create a new Storage.',
|
||||
'duplicator-pro'
|
||||
);
|
||||
?>
|
||||
<span
|
||||
class="dup-new-package-wrapper"
|
||||
data-tooltip="<?php echo esc_attr($tipContent); ?>"
|
||||
>
|
||||
<a
|
||||
href="<?php echo esc_url($edit_storage_url); ?>"
|
||||
id="dupli-create-new"
|
||||
class="button primary tiny font-bold margin-bottom-0"
|
||||
>
|
||||
<?php esc_html_e('Add New', 'duplicator-pro'); ?>
|
||||
</a>
|
||||
</span>
|
||||
<?php
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
use Duplicator\Controllers\SettingsPageController;
|
||||
use Duplicator\Core\Controllers\ControllersManager;
|
||||
use Duplicator\Models\Storages\AbstractStorageEntity;
|
||||
use Duplicator\Views\AdminNotices;
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var bool $blur
|
||||
*/
|
||||
$blur = $tplData['blur'];
|
||||
/** @var int */
|
||||
$storage_id = $tplData["storage_id"];
|
||||
/** @var Duplicator\Models\Storages\AbstractStorageEntity */
|
||||
$storage = $tplData["storage"];
|
||||
/** @var ?string */
|
||||
$error_message = $tplData["error_message"];
|
||||
/** @var ?string */
|
||||
$success_message = $tplData["success_message"];
|
||||
|
||||
$relativeEditUrl = ControllersManager::getMenuLink(
|
||||
ControllersManager::STORAGE_SUBMENU_SLUG,
|
||||
SettingsPageController::L2_SLUG_STORAGE,
|
||||
null,
|
||||
[ControllersManager::QUERY_STRING_INNER_PAGE => 'edit']
|
||||
);
|
||||
|
||||
$fullEditUrl = ControllersManager::getMenuLink(
|
||||
ControllersManager::STORAGE_SUBMENU_SLUG,
|
||||
SettingsPageController::L2_SLUG_STORAGE,
|
||||
null,
|
||||
[ControllersManager::QUERY_STRING_INNER_PAGE => 'edit'],
|
||||
false
|
||||
);
|
||||
|
||||
?>
|
||||
<form
|
||||
id="dup-storage-form"
|
||||
class="dup-monitored-form <?php echo ($blur ? 'dup-mock-blur' : ''); ?>"
|
||||
action="<?php echo esc_url($relativeEditUrl); ?>"
|
||||
method="post"
|
||||
data-parsley-ui-enabled="true"
|
||||
target="_self"
|
||||
>
|
||||
<?php $tplData['actions']['save']->getActionNonceFileds(); ?>
|
||||
<input type="hidden" name="storage_id" id="storage_id" value="<?php echo (int) $storage->getId(); ?>">
|
||||
|
||||
<?php
|
||||
$tplMng->render('admin_pages/storages/parts/edit_toolbar');
|
||||
|
||||
if (!is_null($error_message)) {
|
||||
AdminNotices::displayGeneralAdminNotice($error_message, AdminNotices::GEN_ERROR_NOTICE, true);
|
||||
} elseif (!is_null($success_message)) {
|
||||
AdminNotices::displayGeneralAdminNotice($success_message, AdminNotices::GEN_SUCCESS_NOTICE, true);
|
||||
}
|
||||
?>
|
||||
<div class="form-table dup-settings-wrapper">
|
||||
<label class="lbl-larger">
|
||||
<?php esc_html_e("Name", 'duplicator-pro'); ?>
|
||||
</label>
|
||||
<div class="margin-bottom-1">
|
||||
<?php if ($storage->isDefault()) {
|
||||
esc_html_e('Default', 'duplicator-pro');
|
||||
$tCont = __('The "Default" storage type is a built in type that cannot be removed.', 'duplicator-pro') . ' ' .
|
||||
__(' This storage type is used by default should no other storage types be available.', 'duplicator-pro') . ' ' .
|
||||
__('This storage type is always stored to the local server.', 'duplicator-pro');
|
||||
?>
|
||||
<i
|
||||
class="fa-solid fa-question-circle fa-sm dark-gray-color"
|
||||
data-tooltip-title="<?php esc_attr_e("Default Storage Type", 'duplicator-pro'); ?>"
|
||||
data-tooltip="<?php echo esc_attr($tCont); ?>"
|
||||
>
|
||||
</i>
|
||||
<?php } else { ?>
|
||||
<input
|
||||
data-parsley-errors-container="#name_error_container"
|
||||
type="text"
|
||||
id="name"
|
||||
name="name"
|
||||
value="<?php echo esc_attr($storage->getName()); ?>" autocomplete="off"
|
||||
>
|
||||
<?php } ?>
|
||||
<div id="name_error_container" class="duplicator-error-container"></div>
|
||||
</div>
|
||||
<label class="lbl-larger">
|
||||
<?php esc_html_e("Notes", 'duplicator-pro'); ?>
|
||||
</label>
|
||||
<div class="margin-bottom-1">
|
||||
<textarea id="notes" name="notes" style="width:100%; max-width: 500px"><?php echo esc_textarea($storage->getNotes()); ?></textarea>
|
||||
</div>
|
||||
<label class="lbl-larger">
|
||||
<?php esc_html_e("Type", 'duplicator-pro'); ?>
|
||||
</label>
|
||||
<div class="margin-bottom-0">
|
||||
<?php $tplMng->render('admin_pages/storages/parts/storage_type_select'); ?>
|
||||
</div>
|
||||
</div>
|
||||
<hr size="1" />
|
||||
<?php
|
||||
if ($storage->getId() > 0) {
|
||||
$storage->renderConfigFields();
|
||||
} else {
|
||||
$types = AbstractStorageEntity::getResisteredTypes();
|
||||
foreach ($types as $type) {
|
||||
AbstractStorageEntity::renderSTypeConfigFields($type);
|
||||
}
|
||||
}
|
||||
|
||||
$tplMng->render('admin_pages/storages/parts/test_button');
|
||||
?>
|
||||
<br style="clear:both" />
|
||||
<button
|
||||
id="button_save_provider"
|
||||
class="button primary small"
|
||||
type="submit"
|
||||
>
|
||||
<?php esc_html_e('Save Provider', 'duplicator-pro'); ?>
|
||||
</button>
|
||||
</form>
|
||||
<?php
|
||||
$tplMng->render('admin_pages/storages/storage_scripts');
|
||||
@@ -0,0 +1,358 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
use Duplicator\Ajax\ServicesStorage;
|
||||
use Duplicator\Controllers\SettingsPageController;
|
||||
use Duplicator\Controllers\StoragePageController;
|
||||
use Duplicator\Core\CapMng;
|
||||
use Duplicator\Core\Controllers\ControllersManager;
|
||||
use Duplicator\Core\Views\TplMng;
|
||||
use Duplicator\Models\Storages\AbstractStorageEntity;
|
||||
use Duplicator\Models\Storages\StoragesUtil;
|
||||
use Duplicator\Views\UI\UiDialog;
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
$blur = $tplMng->getDataValueBool('blur');
|
||||
|
||||
$storages = AbstractStorageEntity::getAll(0, 0, [StoragesUtil::class, 'sortDefaultFirst']);
|
||||
$numStorages = ($storages === false) ? 0 : count($storages);
|
||||
|
||||
$edit_storage_url = ControllersManager::getMenuLink(
|
||||
ControllersManager::STORAGE_SUBMENU_SLUG,
|
||||
null,
|
||||
null,
|
||||
[
|
||||
ControllersManager::QUERY_STRING_INNER_PAGE => StoragePageController::INNER_PAGE_EDIT,
|
||||
]
|
||||
);
|
||||
$storage_tab_url = ControllersManager::getMenuLink(
|
||||
ControllersManager::STORAGE_SUBMENU_SLUG,
|
||||
SettingsPageController::L2_SLUG_STORAGE
|
||||
);
|
||||
|
||||
$settingsStorageUrl = ControllersManager::getMenuLink(
|
||||
ControllersManager::SETTINGS_SUBMENU_SLUG,
|
||||
SettingsPageController::L2_SLUG_STORAGE
|
||||
);
|
||||
|
||||
$baseCopyUrl = ControllersManager::getMenuLink(
|
||||
ControllersManager::STORAGE_SUBMENU_SLUG,
|
||||
SettingsPageController::L2_SLUG_STORAGE,
|
||||
null,
|
||||
[
|
||||
ControllersManager::QUERY_STRING_INNER_PAGE => 'edit',
|
||||
'action' => $tplData['actions']['copy-storage']->getKey(),
|
||||
'_wpnonce' => $tplData['actions']['copy-storage']->getNonce(),
|
||||
]
|
||||
);
|
||||
|
||||
?>
|
||||
<div class="dup-toolbar <?php echo ($blur ? 'dup-mock-blur' : ''); ?>">
|
||||
<label for="bulk_action" class="screen-reader-text">Select bulk action</label>
|
||||
<select id="bulk_action" class="small">
|
||||
<option value="-1" selected>
|
||||
<?php esc_html_e("Bulk Actions", 'duplicator-pro') ?>
|
||||
</option>
|
||||
<?php if (CapMng::can(CapMng::CAP_STORAGE, false)) { ?>
|
||||
<option value="<?php echo (int) ServicesStorage::STORAGE_BULK_DELETE; ?>" title="Delete selected storage endpoint(s)">
|
||||
<?php esc_html_e('Delete', 'duplicator-pro'); ?>
|
||||
</option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
<input
|
||||
type="button"
|
||||
id="dup-pack-bulk-apply"
|
||||
class="button hollow secondary small"
|
||||
value="<?php esc_attr_e("Apply", 'duplicator-pro') ?>"
|
||||
onclick="DupliJs.Storage.BulkAction()">
|
||||
<span class="separator"></span>
|
||||
<?php if (CapMng::can(CapMng::CAP_SETTINGS, false)) { ?>
|
||||
<a href="<?php echo esc_url($settingsStorageUrl); ?>"
|
||||
class="button hollow secondary small dupli-toolbar-settings"
|
||||
title="<?php esc_attr_e("Storage Settings", 'duplicator-pro'); ?>">
|
||||
<i class="fas fa-sliders-h fa-fw"></i>
|
||||
</a>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<form
|
||||
id="dup-storage-form"
|
||||
action="<?php echo esc_url($storage_tab_url); ?>"
|
||||
method="post"
|
||||
class="<?php echo ($blur ? 'dup-mock-blur' : ''); ?>">
|
||||
<input type="hidden" id="dup-selected-storage" name="storage_id" value="null" />
|
||||
|
||||
<!-- ====================
|
||||
LIST ALL STORAGE -->
|
||||
<table class="widefat storage-tbl dup-table-list valign-top dup-packtbl">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style='width:10px;'>
|
||||
<input
|
||||
type="checkbox"
|
||||
id="dupli-chk-all"
|
||||
title="Select all storage endpoints" onclick="DupliJs.Storage.SetAll(this)"
|
||||
class="margin-bottom-0">
|
||||
</th>
|
||||
<th style='width:275px;'>Name</th>
|
||||
<th><?php esc_html_e('Type', 'duplicator-pro'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
if ($storages === false) {
|
||||
$tplMng->render('admin_pages/storages/storage_list_row_error');
|
||||
} else {
|
||||
foreach ($storages as $index => $storage) {
|
||||
if ($storage->isHidden()) {
|
||||
continue;
|
||||
}
|
||||
$tplMng->render('admin_pages/storages/storage_list_row', [
|
||||
'storage' => $storage,
|
||||
'index' => $index,
|
||||
]);
|
||||
};
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th colspan="8" style="text-align:right; font-size:12px">
|
||||
<?php echo esc_html__('Total', 'duplicator-pro') . ': ' . (int) $numStorages; ?>
|
||||
</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
</form>
|
||||
<?php
|
||||
//Select Action Alert
|
||||
$alert1 = new UiDialog();
|
||||
$alert1->title = __('Bulk Action Required', 'duplicator-pro');
|
||||
$alert1->message = __('Please select an action from the "Bulk Actions" drop down menu!', 'duplicator-pro');
|
||||
$alert1->initAlert();
|
||||
|
||||
//Select Storage Alert
|
||||
$alert2 = new UiDialog();
|
||||
$alert2->title = __('Selection Required', 'duplicator-pro');
|
||||
$alert2->message = __('Please select at least one storage to delete!', 'duplicator-pro');
|
||||
$alert2->initAlert();
|
||||
|
||||
//Delete Dialog
|
||||
$dlgDelete = new UiDialog();
|
||||
$dlgDelete->height = 525;
|
||||
$dlgDelete->title = __('Delete Storage(s)?', 'duplicator-pro');
|
||||
$dlgDelete->progressText = __('Removing Storages, Please Wait...', 'duplicator-pro');
|
||||
$dlgDelete->jsCallback = 'DupliJs.Storage.deleteAjax()';
|
||||
$dlgDelete->initConfirm();
|
||||
$storage_bulk_action_nonce = wp_create_nonce("duplicator_storage_bulk_actions");
|
||||
?>
|
||||
<script>
|
||||
jQuery(document).ready(function($) {
|
||||
//Shows detail view
|
||||
DupliJs.Storage.Edit = function(id) {
|
||||
document.location.href = <?php echo json_encode($edit_storage_url); ?> + '&storage_id=' + id;
|
||||
};
|
||||
|
||||
//Copy and edit
|
||||
DupliJs.Storage.CopyEdit = function(id) {
|
||||
document.location.href = <?php echo json_encode($baseCopyUrl); ?> + '&dupli-source-storage-id=' + id;
|
||||
};
|
||||
|
||||
//Shows detail view
|
||||
DupliJs.Storage.View = function(id) {
|
||||
$('#quick-view-' + id).toggle();
|
||||
};
|
||||
|
||||
//Select all checked items
|
||||
DupliJs.Storage.SelectedList = function() {
|
||||
var arr = [];
|
||||
$("input[name^='selected_id[]']").each(function() {
|
||||
if ($(this).is(':checked')) {
|
||||
arr.push($(this).val());
|
||||
}
|
||||
});
|
||||
return arr;
|
||||
};
|
||||
|
||||
//Sets all for deletion
|
||||
DupliJs.Storage.SetAll = function(chkbox) {
|
||||
$('.item-chk').each(function() {
|
||||
this.checked = chkbox.checked;
|
||||
});
|
||||
};
|
||||
|
||||
// Bulk action
|
||||
DupliJs.Storage.BulkAction = function() {
|
||||
var list = DupliJs.Storage.SelectedList();
|
||||
var action = $('#bulk_action').val();
|
||||
|
||||
if (list.length === 0) {
|
||||
<?php $alert2->showAlert(); ?>
|
||||
return;
|
||||
}
|
||||
|
||||
switch (action) {
|
||||
case '<?php echo (int) ServicesStorage::STORAGE_BULK_DELETE; ?>':
|
||||
DupliJs.Storage.deleteConfirm(list);
|
||||
break;
|
||||
default:
|
||||
<?php $alert1->showAlert(); ?>
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
//Delete via the delete link
|
||||
DupliJs.Storage.deleteSingle = function(id) {
|
||||
$('#dup-selected-storage').val(id);
|
||||
DupliJs.Storage.deleteConfirm([id]);
|
||||
};
|
||||
|
||||
//Load the delete confirm dialog
|
||||
DupliJs.Storage.deleteConfirm = function(idList) {
|
||||
var $rowData;
|
||||
var name, id, typeName, html;
|
||||
|
||||
var storeCount = idList.length;
|
||||
var isSingle = (storeCount == 1) ? true : false;
|
||||
var dlgID = "<?php echo esc_js($dlgDelete->getID()); ?>";
|
||||
var $content = $(`#${dlgID}_message`);
|
||||
|
||||
html = (isSingle) ?
|
||||
"<i><?php esc_html_e('Are you sure you want to delete this storage item?', 'duplicator-pro') ?></i>" :
|
||||
`<i><?php esc_html_e('Are you sure you want to delete these ${storeCount} storage items?', 'duplicator-pro') ?></i>`;
|
||||
|
||||
// Build storage item html
|
||||
html += '<div class="store-items">';
|
||||
idList.forEach(v => {
|
||||
html += $('#main-view-' + v).data('delete-view');
|
||||
});
|
||||
html += '</div>';
|
||||
|
||||
$content.html(html);
|
||||
<?php $dlgDelete->showConfirm(); ?>
|
||||
|
||||
html = `<div class="schedule-area">
|
||||
<b><?php esc_html_e('Linked Schedules', 'duplicator-pro') ?>:</b><br/>
|
||||
<small><?php esc_html_e("Schedules linked to the storage items above", 'duplicator-pro'); ?>:</small>
|
||||
<div class="schedule-progress" id="${dlgID}-schedule-progress">
|
||||
<i class="fas fa-circle-notch fa-spin"></i>
|
||||
<?php esc_html_e('Finding Schedule Links... Please wait', 'duplicator-pro') ?>
|
||||
</div>
|
||||
<small>
|
||||
<?php
|
||||
esc_html_e("To remove storage items and unlink schedules click OK. ", 'duplicator-pro');
|
||||
printf(
|
||||
esc_html_x(
|
||||
'Schedules with asterisk%1$s will be deactivated if storage is removed.',
|
||||
'%1$s is an asterisk symbol',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<span class="maroon">*</span>'
|
||||
);
|
||||
?>
|
||||
</small>
|
||||
</div>`;
|
||||
$content.append(html);
|
||||
|
||||
function loadSchedules(idList, dlgID) {
|
||||
let result = DupliJs.Storage.getScheduleData(idList);
|
||||
(result != null) ?
|
||||
$(`#${dlgID}-schedule-progress`).html(result):
|
||||
$(`#${dlgID}-schedule-progress`).html("<?php esc_html_e('- No linked schedules found -', 'duplicator-pro') ?>");
|
||||
}
|
||||
setTimeout(loadSchedules, 100, idList, dlgID);
|
||||
};
|
||||
|
||||
//Get the linked schedule data
|
||||
DupliJs.Storage.getScheduleData = function(storageIDs) {
|
||||
|
||||
var result = null;
|
||||
var html;
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: ajaxurl,
|
||||
async: false,
|
||||
dataType: "json",
|
||||
data: {
|
||||
action: 'duplicator_storage_bulk_actions',
|
||||
perform: <?php echo (int) ServicesStorage::STORAGE_GET_SCHEDULES; ?>,
|
||||
storage_ids: storageIDs,
|
||||
nonce: '<?php echo esc_js($storage_bulk_action_nonce); ?>'
|
||||
}
|
||||
})
|
||||
.done(function(data) {
|
||||
//__sleepFor(1000); //Test delays
|
||||
if (data.schedules !== undefined && data.schedules.length > 0) {
|
||||
html = '';
|
||||
data.schedules.forEach(function(schedule) {
|
||||
let name = $("<div/>").text(schedule.name).html();
|
||||
let asterisk = schedule.hasOneStorage ? "*" : "";
|
||||
html += `<div class="schedule-item">
|
||||
<i class="far fa-clock"></i> <a href="${schedule.editURL}">${name}</a> <span class="maroon">${asterisk}</span>
|
||||
</div>`;
|
||||
});
|
||||
result = html;
|
||||
}
|
||||
})
|
||||
.fail(function() {
|
||||
result = '<i class="fas fa-exclamation-triangle"></i> <?php esc_html_e('Unable to get schedule data.', 'duplicator-pro') ?>';
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
//Perform the delete via ajax
|
||||
DupliJs.Storage.deleteAjax = function() {
|
||||
|
||||
var dlgID = "<?php echo esc_js($dlgDelete->getID()); ?>";
|
||||
var list = DupliJs.Storage.SelectedList();
|
||||
|
||||
//Delete from the quick link
|
||||
if (list.length == 0) {
|
||||
var singleID = $('#dup-selected-storage').val();
|
||||
list = (singleID > 0) ? [singleID] : null;
|
||||
}
|
||||
|
||||
$(`#${dlgID}_message`).hide();
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: ajaxurl,
|
||||
dataType: "json",
|
||||
data: {
|
||||
action: 'duplicator_storage_bulk_actions',
|
||||
perform: <?php echo (int) ServicesStorage::STORAGE_BULK_DELETE; ?>,
|
||||
storage_ids: list,
|
||||
nonce: '<?php echo esc_js($storage_bulk_action_nonce); ?>'
|
||||
}
|
||||
})
|
||||
.done(function() {
|
||||
$('#dup-storage-form').submit()
|
||||
})
|
||||
.always(function() {
|
||||
$('#dup-selected-storage').val(null)
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
//Used to test ajax delays
|
||||
function __sleepFor(sleepDuration) {
|
||||
var now = new Date().getTime();
|
||||
while (new Date().getTime() < now + sleepDuration) {
|
||||
/* Do nothing */
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,167 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
use Duplicator\Core\Views\TplMng;
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var Duplicator\Models\Storages\AbstractStorageEntity $storage
|
||||
*/
|
||||
$storage = $tplData['storage'];
|
||||
/** @var int */
|
||||
$index = $tplData['index'];
|
||||
|
||||
$typeName = $storage->getStypeName();
|
||||
$typeId = $storage->getSType();
|
||||
$invalidErrorMsg = __('Invalid storage configuration', 'duplicator-pro');
|
||||
$isValid = $storage->isValid($invalidErrorMsg);
|
||||
$isSupported = $storage::isSupported();
|
||||
|
||||
$row_classes = [ 'storage-row' ];
|
||||
|
||||
if ($index % 2) {
|
||||
$row_classes[] = 'alternate';
|
||||
}
|
||||
|
||||
if (!$isSupported) {
|
||||
$row_classes[] = 'unsupported';
|
||||
$shortDescWarning = __('Storage Type Not Supported', 'duplicator-pro');
|
||||
$longDescWarning = __(
|
||||
'This storage type is not supported on this server. Please remove this storage or contact your host to install the required extensions.',
|
||||
'duplicator-pro'
|
||||
);
|
||||
} elseif (!$isValid) {
|
||||
$row_classes[] = 'invalid';
|
||||
$shortDescWarning = $invalidErrorMsg;
|
||||
$longDescWarning = __(
|
||||
'This storage has invalid configuration and cannot be used. Please edit and fix the configuration.',
|
||||
'duplicator-pro'
|
||||
);
|
||||
} else {
|
||||
$shortDescWarning = '';
|
||||
$longDescWarning = '';
|
||||
}
|
||||
|
||||
?>
|
||||
<tr id="main-view-<?php echo (int) $storage->getId() ?>"
|
||||
class="<?php echo esc_attr(implode(' ', $row_classes)); ?>"
|
||||
data-delete-view="<?php echo esc_attr($storage->getDeleteView(false)); ?>"
|
||||
>
|
||||
<td class="storage-checkbox">
|
||||
<?php if ($storage->isDefault()) : ?>
|
||||
<input type="checkbox" disabled="disabled" />
|
||||
<?php else : ?>
|
||||
<input name="selected_id[]" type="checkbox" value="<?php echo (int) $storage->getId(); ?>" class="item-chk" />
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td class="storage-name">
|
||||
<a href="javascript:void(0);" onclick="DupliJs.Storage.Edit('<?php echo (int) $storage->getId(); ?>')">
|
||||
<b><?php echo esc_html($storage->getName()); ?></b>
|
||||
<?php if (!$isSupported || !$isValid) : ?>
|
||||
<i class="fas fa-exclamation-triangle alert-color" title="<?php echo esc_attr($shortDescWarning); ?>"></i>
|
||||
<?php endif; ?>
|
||||
</a>
|
||||
<div class="sub-menu">
|
||||
<a href="javascript:void(0);" onclick="DupliJs.Storage.Edit('<?php echo (int) $storage->getId(); ?>')">
|
||||
<?php esc_html_e('Edit', 'duplicator-pro'); ?>
|
||||
</a>
|
||||
|
|
||||
<a href="javascript:void(0);" onclick="DupliJs.Storage.View('<?php echo (int) $storage->getId(); ?>');">
|
||||
<?php esc_html_e('Quick View', 'duplicator-pro'); ?>
|
||||
</a>
|
||||
<?php if (!$storage->isDefault()) : ?>
|
||||
<?php if (!$storage->isLocal()) : ?>
|
||||
|
|
||||
<a href="javascript:void(0);" onclick="DupliJs.Storage.CopyEdit('<?php echo (int) $storage->getId(); ?>');">
|
||||
<?php esc_html_e('Copy', 'duplicator-pro'); ?>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
|
|
||||
<a href="javascript:void(0);" onclick="DupliJs.Storage.deleteSingle('<?php echo (int) $storage->getId(); ?>');">
|
||||
<?php esc_html_e('Delete', 'duplicator-pro'); ?>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</td>
|
||||
<td class="storage-type">
|
||||
<?php
|
||||
echo wp_kses(
|
||||
$storage->getStypeIcon(),
|
||||
[
|
||||
'i' => [
|
||||
'class' => [],
|
||||
],
|
||||
'img' => [
|
||||
'src' => [],
|
||||
'class' => [],
|
||||
'alt' => [],
|
||||
],
|
||||
]
|
||||
),
|
||||
' ',
|
||||
esc_html($storage->getStypeName());
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
ob_start();
|
||||
try { ?>
|
||||
<tr id='quick-view-<?php echo (int) $storage->getId(); ?>'
|
||||
class='<?php echo ($index % 2) ? 'alternate' : ''; ?> storage-detail'>
|
||||
<td colspan="3">
|
||||
<b><?php esc_html_e('QUICK VIEW', 'duplicator-pro') ?></b> <br/>
|
||||
<div>
|
||||
<label><?php esc_html_e('Name', 'duplicator-pro') ?>:</label>
|
||||
<?php echo esc_html($storage->getName()); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label><?php esc_html_e('Notes', 'duplicator-pro') ?>:</label>
|
||||
<?php echo (strlen($storage->getNotes())) ? esc_html($storage->getNotes()) : esc_html__('(no notes)', 'duplicator-pro'); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label><?php esc_html_e('Type', 'duplicator-pro') ?>:</label>
|
||||
<?php echo esc_html($storage->getStypeName()); ?>
|
||||
</div>
|
||||
<?php $storage->getListQuickView(); ?>
|
||||
<?php if (!$isSupported || !$isValid) : ?>
|
||||
<div class="storage-status-warning">
|
||||
<p>
|
||||
<i class="fas fa-exclamation-triangle alert-color"></i>
|
||||
<strong><?php echo esc_html($shortDescWarning); ?></strong>
|
||||
</p>
|
||||
<?php echo esc_html($longDescWarning); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<button type="button" class="button secondary hollow tiny"
|
||||
onclick="DupliJs.Storage.View('<?php echo (int) $storage->getId(); ?>');">
|
||||
<?php esc_html_e('Close', 'duplicator-pro') ?>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
} catch (Exception $e) {
|
||||
ob_clean(); ?>
|
||||
<tr id='quick-view-<?php echo intval($storage->getId()); ?>' class='<?php echo ($index % 2) ? 'alternate' : ''; ?>'>
|
||||
<td colspan="3">
|
||||
<?php TplMng::getInstance()->render(
|
||||
'admin_pages/storages/parts/storage_error',
|
||||
['exception' => $e]
|
||||
); ?>
|
||||
<br><br>
|
||||
<button type="button" class="button" onclick="DupliJs.Storage.View('<?php echo intval($storage->getId()); ?>');">
|
||||
<?php esc_html_e('Close', 'duplicator-pro') ?>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
ob_end_flush();
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Admin page packages list
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
*/
|
||||
|
||||
|
||||
?>
|
||||
<tr>
|
||||
<td colspan="3">
|
||||
<div class="maroon">
|
||||
<?php esc_html_e('Error reading storages', 'duplicator-pro'); ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
use Duplicator\Controllers\SettingsPageController;
|
||||
use Duplicator\Core\Controllers\ControllersManager;
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
*/
|
||||
|
||||
?>
|
||||
<script>
|
||||
jQuery(document).ready(function ($) {
|
||||
// Quick fix for submint/enter error
|
||||
$(window).on('keyup keydown', function (e) {
|
||||
if (!$(e.target).is('textarea'))
|
||||
{
|
||||
var keycode = (typeof e.keyCode != 'undefined' && e.keyCode > -1 ? e.keyCode : e.which);
|
||||
if ((keycode === 13)) {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Removes the values of hidden input fields marked with class dup-empty-field-on-submit
|
||||
DupliJs.Storage.EmptyValues = function () {
|
||||
$(':hidden .dup-empty-field-on-submit').val('');
|
||||
}
|
||||
|
||||
// Removes tags marked with class dup-remove-on-submit-if-hidden, if they are hidden
|
||||
DupliJs.Storage.RemoveMarkedHiddenTags = function () {
|
||||
$('.dup-remove-on-submit-if-hidden:hidden').each(function() {
|
||||
$(this).remove();
|
||||
});
|
||||
}
|
||||
|
||||
DupliJs.Storage.PrepareForSubmit = function () {
|
||||
DupliJs.Storage.EmptyValues();
|
||||
if ($('#dup-storage-form').parsley().isValid()) {
|
||||
// The form is about to be submitted.
|
||||
DupliJs.Storage.RemoveMarkedHiddenTags();
|
||||
}
|
||||
}
|
||||
|
||||
$('#dup-storage-form').submit(DupliJs.Storage.PrepareForSubmit);
|
||||
|
||||
DupliJs.Storage.AuthMessages = function () {
|
||||
let reloadUrl = new URL(window.location.href);
|
||||
let authMessage = reloadUrl.searchParams.get('dup-auth-message');
|
||||
let revokeMessage = reloadUrl.searchParams.get('dup-revoke-message');
|
||||
|
||||
if (authMessage || revokeMessage) {
|
||||
// Display messages
|
||||
if (authMessage) {
|
||||
DupliJs.addAdminMessage(authMessage, 'notice');
|
||||
}
|
||||
if (revokeMessage) {
|
||||
DupliJs.addAdminMessage(revokeMessage, 'notice');
|
||||
}
|
||||
|
||||
// Remove the params from URL to prevent persistence
|
||||
reloadUrl.searchParams.delete('dup-auth-message');
|
||||
reloadUrl.searchParams.delete('dup-revoke-message');
|
||||
reloadUrl.searchParams.delete('dup-storage-id');
|
||||
window.history.replaceState({}, '', reloadUrl.href);
|
||||
}
|
||||
}
|
||||
|
||||
DupliJs.Storage.RevokeAuth = function (storageId)
|
||||
{
|
||||
// Get current page slug from URL
|
||||
const currentPage = new URL(window.location.href).searchParams.get('page') || '';
|
||||
|
||||
DupliJs.Util.ajaxWrapper(
|
||||
{
|
||||
action: 'duplicator_revoke_storage',
|
||||
storage_id: storageId,
|
||||
current_page: currentPage,
|
||||
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_revoke_storage')); ?>'
|
||||
},
|
||||
function (result, data, funcData, textStatus, jqXHR) {
|
||||
if (funcData.success) {
|
||||
// Backend provides the complete redirect URL
|
||||
if (funcData.redirect_url) {
|
||||
window.location.href = funcData.redirect_url;
|
||||
} else {
|
||||
// Fallback: simple reload
|
||||
window.location.reload();
|
||||
}
|
||||
} else {
|
||||
DupliJs.addAdminMessage(funcData.message, 'error');
|
||||
}
|
||||
return '';
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
DupliJs.Storage.Authorize = function (storageId, storageType, extraData)
|
||||
{
|
||||
// Get current page slug from URL
|
||||
const currentPage = new URL(window.location.href).searchParams.get('page') || '';
|
||||
|
||||
extraData.action = 'duplicator_auth_storage';
|
||||
extraData.storage_id = storageId;
|
||||
extraData.storage_type = storageType;
|
||||
extraData.current_page = currentPage;
|
||||
extraData.nonce = '<?php echo esc_js(wp_create_nonce('duplicator_auth_storage')); ?>';
|
||||
|
||||
DupliJs.Util.ajaxWrapper(
|
||||
extraData,
|
||||
function (result, data, funcData, textStatus, jqXHR) {
|
||||
if (funcData.success) {
|
||||
// Backend provides the complete redirect URL
|
||||
if (funcData.redirect_url) {
|
||||
// Set unsaved changes to false, not to trigger alert during finalization
|
||||
DupliJs.UI.hasUnsavedChanges = false;
|
||||
window.location.href = funcData.redirect_url;
|
||||
} else {
|
||||
// Fallback: simple reload
|
||||
DupliJs.UI.hasUnsavedChanges = false;
|
||||
window.location.reload();
|
||||
}
|
||||
} else {
|
||||
DupliJs.addAdminMessage(funcData.message, 'error');
|
||||
}
|
||||
return '';
|
||||
}
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Toggles Save Provider button for existing Storages only
|
||||
DupliJs.UI.formOnChangeValues($('#dup-storage-form'), function() {
|
||||
$('#button_file_test').prop('disabled', true);
|
||||
});
|
||||
|
||||
//Init
|
||||
DupliJs.Storage.AuthMessages();
|
||||
jQuery('#name').focus().select();
|
||||
});
|
||||
|
||||
</script>
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
use Duplicator\Utils\Support\SupportToolkit;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Admin page packages list
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
$storageInfos = $tplData['storageInfos'] ?? [];
|
||||
if (count($storageInfos) < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
$isAllDownload = $tplData['isAllDownload'] ?? false;
|
||||
$isAllUpload = $tplData['isAllUpload'] ?? false;
|
||||
$failureMessage = $tplData['failureMessage'] ?? __('There was a problem transferring the backup(s).', 'duplicator-pro');
|
||||
?>
|
||||
|
||||
<p> <?php echo wp_kses($failureMessage, [ 'b' => [], 'i' => [] ]); ?> </p>
|
||||
<?php if (count($storageInfos) > 1) { ?>
|
||||
<ul>
|
||||
<?php foreach ($storageInfos as $info) { ?>
|
||||
<li>
|
||||
<b><?php echo esc_html($info['name']); ?></b> (<?php echo esc_html($info['type']); ?>)
|
||||
<?php if (!$isAllDownload && !$isAllUpload) { ?>
|
||||
-
|
||||
<b class="maroon">
|
||||
<?php echo $info['isDownload'] ? esc_html__('Download Failed', 'duplicator-pro') : esc_html__('Upload Failed', 'duplicator-pro'); ?>
|
||||
</b>
|
||||
<?php } ?>
|
||||
</li>
|
||||
<?php } ?>
|
||||
</ul>
|
||||
<?php } ?>
|
||||
<p><?php esc_html_e('Please try transferring again.', 'duplicator-pro'); ?></p>
|
||||
<p>
|
||||
<?php echo wp_kses(
|
||||
sprintf(
|
||||
esc_html_x(
|
||||
'If the issue persists, %1$scontact support%2$s with the %3$s attached to the ticket.',
|
||||
'1: open link tag, 2: close link tag, 3: diagnostic data link with label or link to instructions to download the Backup logs',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<a href="' . esc_url(DUPLICATOR_BLOG_URL . 'my-account/support/') . '" target="_blank">',
|
||||
'</a>',
|
||||
SupportToolkit::getDiagnosticInfoLinks(['package'])
|
||||
),
|
||||
[
|
||||
'a' => [
|
||||
'href' => [],
|
||||
'target' => [],
|
||||
],
|
||||
]
|
||||
); ?>
|
||||
</p>
|
||||
Reference in New Issue
Block a user