first commit
This commit is contained in:
9
wp-content/plugins/duplicator-pro/template/.htaccess
Normal file
9
wp-content/plugins/duplicator-pro/template/.htaccess
Normal file
@@ -0,0 +1,9 @@
|
||||
<Files *.php>
|
||||
Order Deny,Allow
|
||||
Deny from all
|
||||
</Files>
|
||||
|
||||
<Files index.php>
|
||||
Order Allow,Deny
|
||||
Allow from all
|
||||
</Files>
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Activity Log detail modal template
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2024, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Controllers\ActivityLogPageController;
|
||||
use Duplicator\Models\ActivityLog\AbstractLogEvent;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
*/
|
||||
|
||||
$log = $tplMng->getDataValueObjRequired('log', AbstractLogEvent::class);
|
||||
?>
|
||||
<div class="dup-box dup-log-detail-modal margin-0">
|
||||
<div class="dup-box-title">
|
||||
<i class="fas fa-list-ul"></i> <?php echo esc_html($log->getTitle()); ?>
|
||||
</div>
|
||||
<div class="dup-box-panel">
|
||||
<div class="dup-log-detail-meta">
|
||||
<div class="dup-log-type-wrapper">
|
||||
<strong><?php esc_html_e('Event:', 'duplicator-pro'); ?></strong>
|
||||
<span class="dup-log-type">
|
||||
<?php echo esc_html($log->getObjectTypeLabel()); ?>
|
||||
</span>
|
||||
</div>
|
||||
<div class="dup-log-severity-wrapper">
|
||||
<strong><?php esc_html_e('Type:', 'duplicator-pro'); ?></strong>
|
||||
<span class="dup-log-severity <?php echo esc_attr(ActivityLogPageController::getSeverityClass($log->getSeverity())); ?>">
|
||||
<?php echo esc_html($log->getSeverityLabel()); ?>
|
||||
</span>
|
||||
</div>
|
||||
<div class="dup-log-date-wrapper">
|
||||
<strong><?php esc_html_e('Activity Date:', 'duplicator-pro'); ?></strong>
|
||||
<span class="dup-log-date">
|
||||
<?php echo esc_html(date_i18n(get_option('date_format') . ' ' . get_option('time_format'), strtotime($log->getCreatedAt()))); ?>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="dup-log-detail-content">
|
||||
<?php $log->detailHtml(); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Activity Log list template
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2024, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Ajax\ServicesActivityLog;
|
||||
use Duplicator\Models\ActivityLog\AbstractLogEvent;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
*/
|
||||
|
||||
$page = $tplMng->getDataValueIntRequired('page');
|
||||
$perPage = $tplMng->getDataValueInt('perPage', 50);
|
||||
$totalItems = $tplMng->getDataValueIntRequired('totalItems');
|
||||
$totalPages = $tplMng->getDataValueIntRequired('totalPages');
|
||||
$logTypes = $tplMng->getDataValueArrayRequired('logTypes');
|
||||
$severityLevels = $tplMng->getDataValueArrayRequired('severityLevels');
|
||||
$filters = $tplMng->getDataValueArrayRequired('filters');
|
||||
/** @var array<AbstractLogEvent> */
|
||||
$logs = $tplMng->getDataValueArrayRequired('logs');
|
||||
|
||||
?>
|
||||
|
||||
<div class="wrap">
|
||||
<?php $tplMng->render('admin_pages/activity_log/parts/toolbar'); ?>
|
||||
|
||||
<table class="widefat dup-table-list striped dup-activity-log-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" class="manage-column column-date"><?php esc_html_e('Date', 'duplicator-pro'); ?></th>
|
||||
<th scope="col" class="manage-column column-severity"><?php esc_html_e('Type', 'duplicator-pro'); ?></th>
|
||||
<th scope="col" class="manage-column column-type"><?php esc_html_e('Event', 'duplicator-pro'); ?></th>
|
||||
<th scope="col" class="manage-column column-title"><?php esc_html_e('Title', 'duplicator-pro'); ?></th>
|
||||
<th scope="col" class="manage-column column-description"><?php esc_html_e('Description', 'duplicator-pro'); ?></th>
|
||||
<th scope="col" class="manage-column column-actions"><?php esc_html_e('Actions', 'duplicator-pro'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (empty($logs)) : ?>
|
||||
<tr>
|
||||
<td colspan="6" class="no-items">
|
||||
<?php esc_html_e('No activity logs found.', 'duplicator-pro'); ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php else : ?>
|
||||
<?php foreach ($logs as $log) : ?>
|
||||
<?php
|
||||
$tplMng->render('admin_pages/activity_log/parts/table_row', ['log' => $log]);
|
||||
?>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th scope="col" class="manage-column column-date"><?php esc_html_e('Date', 'duplicator-pro'); ?></th>
|
||||
<th scope="col" class="manage-column column-severity"><?php esc_html_e('Type', 'duplicator-pro'); ?></th>
|
||||
<th scope="col" class="manage-column column-type"><?php esc_html_e('Event', 'duplicator-pro'); ?></th>
|
||||
<th scope="col" class="manage-column column-title"><?php esc_html_e('Title', 'duplicator-pro'); ?></th>
|
||||
<th scope="col" class="manage-column column-description"><?php esc_html_e('Description', 'duplicator-pro'); ?></th>
|
||||
<th scope="col" class="manage-column column-actions"><?php esc_html_e('Actions', 'duplicator-pro'); ?></th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
<script>
|
||||
jQuery(document).ready(function($) {
|
||||
|
||||
DupliJs.ActivityLog = {
|
||||
modalBox: null,
|
||||
init: function() {
|
||||
this.modalBox = new DuplicatorModalBox();
|
||||
this.initEvents();
|
||||
},
|
||||
initEvents: function() {
|
||||
$(document).on('click', '.dup-log-view-btn', function() {
|
||||
const logId = $(this).data('log-id');
|
||||
DupliJs.ActivityLog.openDetail(logId);
|
||||
});
|
||||
},
|
||||
openDetail: function(logId) {
|
||||
if (this.modalBox) {
|
||||
this.modalBox.close();
|
||||
}
|
||||
|
||||
DupliJs.Util.ajaxWrapper({
|
||||
'action': '<?php echo esc_js(ServicesActivityLog::NONCE_GET_DETAIL); ?>',
|
||||
'nonce': '<?php echo esc_js(wp_create_nonce(ServicesActivityLog::NONCE_GET_DETAIL)); ?>',
|
||||
'log_id': logId
|
||||
},
|
||||
function(result, data, funcData) {
|
||||
if (funcData.success) {
|
||||
DupliJs.ActivityLog.modalBox.setOptions({
|
||||
htmlContent: funcData.html,
|
||||
closeInContent: true,
|
||||
closeColor: '#000'
|
||||
});
|
||||
DupliJs.ActivityLog.modalBox.open();
|
||||
} else {
|
||||
DupliJs.addAdminMessage(funcData.message, 'error');
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
DupliJs.ActivityLog.init();
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Template for displaying backup log context in activity log error events
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2025, Snap Creek LLC
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var string[] $logLines Array of log lines to display
|
||||
* @var string $logUrl URL to the full log file
|
||||
*/
|
||||
|
||||
$logLines = $tplMng->getDataValueArray('logLines', []);
|
||||
$logUrl = $tplMng->getDataValueString('logUrl', '');
|
||||
?>
|
||||
<div class="dup-error-logs-section">
|
||||
<div class="dup-error-logs-content">
|
||||
<div class="dup-log-content">
|
||||
<pre><?php echo esc_html(implode("\n", $logLines)); ?></pre>
|
||||
</div>
|
||||
|
||||
<div class="dup-log-meta">
|
||||
<?php printf(esc_html__('Showing %d lines from when error occurred', 'duplicator-pro'), count($logLines)); ?>
|
||||
<?php if (!empty($logUrl)) : ?>
|
||||
| <a href="<?php echo esc_url($logUrl); ?>" target="_blank"><?php esc_html_e('View complete log file', 'duplicator-pro'); ?></a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Activity Log list template
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2024, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Controllers\ActivityLogPageController;
|
||||
use Duplicator\Models\ActivityLog\AbstractLogEvent;
|
||||
use Duplicator\Models\ActivityLog\LogUtils;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<AbstractLogEvent> $logs Array of log events to display
|
||||
*/
|
||||
|
||||
$severityLevels = LogUtils::getSeverityLabels();
|
||||
/** @var array<AbstractLogEvent> */
|
||||
$logs = $tplMng->getDataValueArrayRequired('logs');
|
||||
?>
|
||||
<table class="widefat dup-table-list striped dup-activity-log-table small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" class="manage-column column-date"><?php esc_html_e('Date', 'duplicator-pro'); ?></th>
|
||||
<th scope="col" class="manage-column column-severity"><?php esc_html_e('Type', 'duplicator-pro'); ?></th>
|
||||
<th scope="col" class="manage-column column-title"><?php esc_html_e('Title', 'duplicator-pro'); ?></th>
|
||||
<th scope="col" class="manage-column column-description"><?php esc_html_e('Description', 'duplicator-pro'); ?></th>
|
||||
<th scope="col" class="manage-column column-duration"><?php esc_html_e('Duration', 'duplicator-pro'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if (empty($logs)) : ?>
|
||||
<tr>
|
||||
<td colspan="5" class="no-items">
|
||||
<?php esc_html_e('No activity logs found.', 'duplicator-pro'); ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php else : ?>
|
||||
<?php
|
||||
$lastLogId = $logs[count($logs) - 1]->getId();
|
||||
foreach ($logs as $currentLog) :
|
||||
// Get execution time directly from current log using its atomic timing data
|
||||
if (method_exists($currentLog, 'getExecutionTimeForPhase')) {
|
||||
$durationFormatted = $currentLog->getExecutionTimeForPhase($currentLog->getSubType());
|
||||
} else {
|
||||
// Fallback for log types that don't support timing
|
||||
$durationFormatted = __('N/A', 'duplicator-pro');
|
||||
}
|
||||
?>
|
||||
<tr>
|
||||
<td class="column-date">
|
||||
<?php echo esc_html(date_i18n(get_option('date_format') . ' ' . get_option('time_format'), strtotime($currentLog->getCreatedAt()))); ?>
|
||||
</td>
|
||||
<td class="column-severity">
|
||||
<span class="dup-log-severity <?php echo esc_attr(ActivityLogPageController::getSeverityClass($currentLog->getSeverity())); ?>">
|
||||
<?php echo esc_html($severityLevels[$currentLog->getSeverity()] ?? __('Unknown', 'duplicator-pro')); ?>
|
||||
</span>
|
||||
</td>
|
||||
<td class="column-title">
|
||||
<?php echo esc_html($currentLog->getTitle()); ?>
|
||||
</td>
|
||||
<td class="column-description">
|
||||
<?php echo wp_kses_post($currentLog->getShortDescription()); ?>
|
||||
</td>
|
||||
<td class="column-duration">
|
||||
<?php if ($currentLog->getId() === $lastLogId) : ?>
|
||||
<?php echo esc_html(sprintf(__('Total: %s', 'duplicator-pro'), $durationFormatted)); ?>
|
||||
<?php else : ?>
|
||||
<?php echo esc_html($durationFormatted); ?>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<?php endif; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Activity Log table row template
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2024, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Controllers\ActivityLogPageController;
|
||||
use Duplicator\Models\ActivityLog\AbstractLogEvent;
|
||||
|
||||
defined("ABSPATH") || exit;
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
*/
|
||||
|
||||
$log = $tplMng->getDataValueObjRequired('log', AbstractLogEvent::class);
|
||||
$severityLevels = $tplMng->getDataValueArrayRequired('severityLevels');
|
||||
$isMainEvent = ($log->getParentId() <= 0);
|
||||
$rowClasses = [];
|
||||
|
||||
if ($isMainEvent) {
|
||||
$rowClasses[] = 'main-event';
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<tr class="<?php echo esc_attr(implode(' ', $rowClasses)); ?>">
|
||||
<td class="column-date">
|
||||
<?php echo esc_html(date_i18n(get_option('date_format') . ' ' . get_option('time_format'), strtotime($log->getCreatedAt()))); ?>
|
||||
</td>
|
||||
<td class="column-severity">
|
||||
<span class="dup-log-severity <?php echo esc_attr(ActivityLogPageController::getSeverityClass($log->getSeverity())); ?>">
|
||||
<?php echo esc_html($severityLevels[$log->getSeverity()] ?? __('Unknown', 'duplicator-pro')); ?>
|
||||
</span>
|
||||
</td>
|
||||
<td class="column-type">
|
||||
<?php echo esc_html($log->getObjectTypeLabel()); ?>
|
||||
</td>
|
||||
<td class="column-title">
|
||||
<span class="link-style dup-log-view-btn" data-log-id="<?php echo (int) $log->getId(); ?>">
|
||||
<?php echo esc_html($log->getTitle()); ?>
|
||||
</span>
|
||||
</td>
|
||||
<td class="column-description">
|
||||
<?php echo wp_kses_post($log->getShortDescription()); ?>
|
||||
</td>
|
||||
<td class="column-actions">
|
||||
<button type="button" class="button small secondary hollow margin-bottom-0 dup-log-view-btn" data-log-id="<?php echo (int) $log->getId(); ?>">
|
||||
<?php esc_html_e('Details', 'duplicator-pro'); ?>
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -0,0 +1,123 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Activity Log toolbar template (filters and bulk actions)
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2024, Snap Creek LLC
|
||||
*/
|
||||
|
||||
defined("ABSPATH") || exit;
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
*/
|
||||
|
||||
$page = $tplMng->getDataValueIntRequired('page');
|
||||
$totalItems = $tplMng->getDataValueIntRequired('totalItems');
|
||||
$totalPages = $tplMng->getDataValueIntRequired('totalPages');
|
||||
$filters = $tplMng->getDataValueArrayRequired('filters');
|
||||
$severityLevels = $tplMng->getDataValueArrayRequired('severityLevels');
|
||||
|
||||
$currentUrl = self_admin_url('admin.php?page=' . $_REQUEST['page']);
|
||||
$showAllTitle = __(
|
||||
'When enabled, shows a detailed view with all sub-events expanded. When disabled, shows a compact view with only main events.',
|
||||
'duplicator-pro'
|
||||
);
|
||||
?>
|
||||
<div class="tablenav top">
|
||||
<form method="get" class="dup-activity-log-filters float-left" action="<?php echo esc_url($currentUrl); ?>">
|
||||
<div class="dup-toolbar">
|
||||
<input type="hidden" name="page" value="<?php echo esc_attr($_REQUEST['page']); ?>">
|
||||
<input type="checkbox"
|
||||
id="filter_show_all"
|
||||
name="filter_show_all"
|
||||
value="1"
|
||||
title="<?php echo esc_attr($showAllTitle); ?>"
|
||||
<?php checked(!empty($filters['show_all'])); ?>>
|
||||
<label for="filter_show_all">
|
||||
<?php esc_html_e('Detailed list', 'duplicator-pro'); ?>
|
||||
</label>
|
||||
|
||||
<div class="separator"></div>
|
||||
|
||||
<input type="date"
|
||||
id="filter_date_from"
|
||||
name="filter_date_from"
|
||||
title="<?php esc_attr_e('Filter by date from', 'duplicator-pro'); ?>"
|
||||
value="<?php echo esc_attr($filters['date_from']); ?>">
|
||||
|
||||
<span> - </span>
|
||||
|
||||
<input type="date"
|
||||
id="filter_date_to"
|
||||
name="filter_date_to"
|
||||
title="<?php esc_attr_e('Filter by date to', 'duplicator-pro'); ?>"
|
||||
value="<?php echo esc_attr($filters['date_to']); ?>">
|
||||
|
||||
<div class="separator"></div>
|
||||
|
||||
<select id="filter_severity"
|
||||
name="filter_severity"
|
||||
title="<?php esc_attr_e('Filter by severity level', 'duplicator-pro'); ?>">
|
||||
<option value="-1" <?php selected($filters['severity'], -1); ?>>
|
||||
<?php esc_html_e('All Severities', 'duplicator-pro'); ?>
|
||||
</option>
|
||||
<?php foreach ($severityLevels as $severityValue => $severityLabel) : ?>
|
||||
<option value="<?php echo esc_attr($severityValue); ?>" <?php selected($filters['severity'], $severityValue); ?>>
|
||||
<?php echo esc_html($severityLabel); ?>
|
||||
</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
|
||||
<div class="separator"></div>
|
||||
|
||||
<input type="submit"
|
||||
name="filter_action"
|
||||
class="button primary small"
|
||||
value="<?php esc_attr_e('Filter', 'duplicator-pro'); ?>">
|
||||
|
||||
<a href="<?php echo esc_url($currentUrl); ?>"
|
||||
class="button secondary small hollow">
|
||||
<?php esc_html_e('Reset', 'duplicator-pro'); ?>
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<?php if ($totalPages > 1) : ?>
|
||||
<div class="tablenav-pages">
|
||||
<span class="displaying-num">
|
||||
<?php echo esc_html(sprintf(__('%d items', 'duplicator-pro'), $totalItems)); ?>
|
||||
</span>
|
||||
|
||||
<span class="pagination-links">
|
||||
<?php if ($page > 1) : ?>
|
||||
<a class="first-page button" href="<?php echo esc_url(add_query_arg('paged', 1)); ?>">
|
||||
<span aria-hidden="true">«</span>
|
||||
</a>
|
||||
<a class="prev-page button" href="<?php echo esc_url(add_query_arg('paged', $page - 1)); ?>">
|
||||
<span aria-hidden="true">‹</span>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
|
||||
<span class="paging-input">
|
||||
<?php echo esc_html(sprintf(__('%1$d of %2$d', 'duplicator-pro'), $page, $totalPages)); ?>
|
||||
</span>
|
||||
|
||||
<?php if ($page < $totalPages) : ?>
|
||||
<a class="next-page button" href="<?php echo esc_url(add_query_arg('paged', $page + 1)); ?>">
|
||||
<span aria-hidden="true">›</span>
|
||||
</a>
|
||||
<a class="last-page button" href="<?php echo esc_url(add_query_arg('paged', $totalPages)); ?>">
|
||||
<span aria-hidden="true">»</span>
|
||||
</a>
|
||||
<?php endif; ?>
|
||||
</span>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<br class="clear">
|
||||
</div>
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
use Duplicator\Views\UserUIOptions;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
$uiOpts = UserUIOptions::getInstance();
|
||||
|
||||
$perPage = $uiOpts->get(UserUIOptions::VAL_ACTIVITY_LOG_PER_PAGE);
|
||||
?>
|
||||
<fieldset class="screen-options margin-b-20px" >
|
||||
<legend>
|
||||
<?php esc_html_e('Pagination', 'duplicator-pro'); ?>
|
||||
</legend>
|
||||
<label for="activity_log_per_page" class="inline-display" >
|
||||
<?php esc_html_e('Activity Logs Per Page', 'duplicator-pro'); ?>
|
||||
</label>
|
||||
<input
|
||||
type="number"
|
||||
step="1"
|
||||
min="1"
|
||||
max="999"
|
||||
class="screen-per-page inline-display margin-0 width-small"
|
||||
name="activity_log_per_page"
|
||||
id="activity_log_per_page"
|
||||
maxlength="3"
|
||||
value="<?php echo esc_html($perPage); ?>"
|
||||
>
|
||||
</fieldset>
|
||||
<input type="hidden" name="wp_screen_options[option]" value="activity_log_screen_options">
|
||||
<input type="hidden" name="wp_screen_options[value]" value="val">
|
||||
<input
|
||||
type="submit"
|
||||
name="screen-options-apply"
|
||||
id="screen-options-apply"
|
||||
class="button secondary hollow small margin-0"
|
||||
value="Apply"
|
||||
>
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
if (!isset($tplData['tmpCleanUpSuccess'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$messageClasses = [
|
||||
'notice',
|
||||
'dupli-admin-notice',
|
||||
'is-dismissible',
|
||||
'dupli-diagnostic-action-tmp-cache',
|
||||
'notice-success',
|
||||
];
|
||||
|
||||
?>
|
||||
<div id="message" class="<?php echo esc_attr(implode(' ', $messageClasses)); ?>">
|
||||
<p>
|
||||
<?php esc_html_e('Build cache removed.', 'duplicator-pro'); ?>
|
||||
</p>
|
||||
</div>
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
if (!isset($tplData['purgeOrphansSuccess'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$messageClasses = [
|
||||
'notice',
|
||||
'dupli-admin-notice',
|
||||
'is-dismissible',
|
||||
'dupli-diagnostic-action-purge-orphans',
|
||||
($tplData['purgeOrphansSuccess'] ? 'notice-success' : 'notice-error'),
|
||||
];
|
||||
?>
|
||||
<div id="message" class="<?php echo esc_attr(implode(' ', $messageClasses)); ?>">
|
||||
<p>
|
||||
<?php esc_html_e('Cleaned up orphaned Backup files!', 'duplicator-pro'); ?>
|
||||
</p>
|
||||
<?php
|
||||
foreach ($tplData['purgeOrphansFiles'] as $path => $deleted) {
|
||||
if ($deleted) {
|
||||
?>
|
||||
<div class='success'>
|
||||
<i class='fa fa-check'></i> <?php echo esc_html($path); ?>
|
||||
</div>
|
||||
<?php } else { ?>
|
||||
<div class='failed'>
|
||||
<i class='fa fa-exclamation-triangle'></i> <?php echo esc_html($path); ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
<p>
|
||||
<i>
|
||||
<?php esc_html_e('If any orphaned files didn\'t get removed then delete them manually', 'duplicator-pro') ?>.
|
||||
</i>
|
||||
</p>
|
||||
</div>
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
?>
|
||||
<div class="wrap">
|
||||
<h1>
|
||||
<?php esc_html_e("Install Backup error", 'duplicator-pro'); ?>
|
||||
</h1>
|
||||
<p>
|
||||
<?php esc_html_e("Error on Backup prepare, please go back and try again.", 'duplicator-pro'); ?>
|
||||
</p>
|
||||
</div>
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Controllers\ImportPageController;
|
||||
use Duplicator\Package\Import\PackageImporter;
|
||||
use Duplicator\Package\Recovery\RecoveryPackage;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var PackageImporter $importObj
|
||||
*/
|
||||
$importObj = $tplData['importObj'];
|
||||
/** @var string $iframeSrc */
|
||||
$iframeSrc = $tplData['iframeSrc'];
|
||||
$importFailMessage = '';
|
||||
|
||||
if (!$importObj->isImportable($importFailMessage)) {
|
||||
?>
|
||||
<div class="wrap dup-styles">
|
||||
<h1>
|
||||
<?php esc_html_e("Install Backup", 'duplicator-pro'); ?>
|
||||
</h1>
|
||||
<div class="dupli-import-installer-content-wrapper" >
|
||||
<p class="orangered">
|
||||
<?php echo esc_html($importFailMessage); ?>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<?php } else { ?>
|
||||
<div id="dupli-import-installer-wrapper" class="dup-styles" >
|
||||
<div id="dupli-import-installer-top-bar" class="dupli-recovery-details-max-width-wrapper" >
|
||||
<a href="<?php echo esc_url(ImportPageController::getImportPageLink()); ?>" class="button secondary hollow small margin-bottom-0" >
|
||||
<i class="fa fa-caret-left"></i> <?php esc_html_e("Back to Import", 'duplicator-pro'); ?>
|
||||
</a>
|
||||
<span class="link-style no-decoration recovery-copy-top-wrapper" >
|
||||
<?php if (($recoverPackage = RecoveryPackage::getRecoverPackage()) !== false) { ?>
|
||||
<span class="button secondary hollow small margin-bottom-0"
|
||||
data-tooltip-placement="right"
|
||||
data-dup-copy-value="<?php echo esc_url($recoverPackage->getInstallLink()); ?>"
|
||||
data-dup-copy-title="<?php esc_attr_e("Copy Recovery URL to clipboard", 'duplicator-pro'); ?>"
|
||||
data-dup-copied-title="<?php esc_attr_e("Recovery URL copied to clipboard", 'duplicator-pro'); ?>" >
|
||||
<?php esc_html_e("Copy Recovery URL", 'duplicator-pro'); ?>
|
||||
</span>
|
||||
<?php } else { ?>
|
||||
<span class="button secondary hollow disabled small margin-bottom-0">
|
||||
<i class="fas fa-exclamation-circle"></i> <?php esc_html_e("Recovery Point Not Set", 'duplicator-pro'); ?>
|
||||
</span>
|
||||
<?php } ?>
|
||||
</span>
|
||||
</div>
|
||||
<div id="dupli-import-installer-modal" class="no-display"></div>
|
||||
<iframe id="dupli-import-installer-iframe" src="<?php echo esc_url($iframeSrc); ?>" ></iframe>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Controllers\SettingsPageController;
|
||||
use Duplicator\Core\Controllers\ControllersManager;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
$importSettingsUrl = $ctrlMng->getMenuLink(
|
||||
ControllersManager::SETTINGS_SUBMENU_SLUG,
|
||||
SettingsPageController::L2_SLUG_IMPORT
|
||||
);
|
||||
|
||||
?>
|
||||
<div class="dupli-import-upload-message" >
|
||||
<p class="import-upload-reset-message-error">
|
||||
<i class="fa fa-exclamation-triangle"></i> <b><?php esc_html_e('UPLOAD FILE PROBLEM', 'duplicator-pro'); ?></b>
|
||||
</p>
|
||||
<p>
|
||||
<?php esc_html_e('Error message:', 'duplicator-pro'); ?>
|
||||
<b><span class="import-upload-error-message"><!-- here is set the message received from the server --></span></b>
|
||||
</p>
|
||||
<div><?php esc_html_e('Possible solutions:', 'duplicator-pro'); ?></div>
|
||||
<ul class="dupli-simple-style-list" >
|
||||
<li>
|
||||
<?php esc_html_e('If you are using Server to Server transfer function make sure the URL is a valid URL', 'duplicator-pro'); ?>
|
||||
</li>
|
||||
<li>
|
||||
<?php
|
||||
printf(
|
||||
esc_html_x(
|
||||
'If you are using the upload function try to change the chunk size in %1$ssettings%2$s and try again',
|
||||
'%1$s and %2$s represents the opening and closing HTML tags for an anchor or link',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<a href="' . esc_url($importSettingsUrl) . '">',
|
||||
'</a>'
|
||||
);
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<?php
|
||||
printf(
|
||||
esc_html__('Upload the file via FTP/file manager to the "%s" folder and reload the page.', 'duplicator-pro'),
|
||||
esc_html(DUPLICATOR_IMPORTS_PATH)
|
||||
);
|
||||
?>
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
<b>
|
||||
<?php
|
||||
printf(
|
||||
esc_html_x(
|
||||
'For more information see %1$s[this FAQ item]%2$s',
|
||||
'%1$s and %2$s represents the opening and closing HTML tags for an anchor or link',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<a href="' . esc_url(DUPLICATOR_DUPLICATOR_DOCS_URL . 'how-to-handle-import-install-upload-launch-issues') . '" target="_blank">',
|
||||
'</a>'
|
||||
);
|
||||
?>
|
||||
</b>
|
||||
</p>
|
||||
</div>
|
||||
@@ -0,0 +1,202 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Installer\Package\PComponents;
|
||||
use Duplicator\Libs\Snap\SnapString;
|
||||
use Duplicator\Package\Create\BuildComponents;
|
||||
use Duplicator\Package\Import\PackageImporter;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
/* passed values */
|
||||
/** @var PackageImporter $importObj */
|
||||
$importObj = $tplData['importObj'];
|
||||
|
||||
if (!$importObj instanceof PackageImporter) {
|
||||
return;
|
||||
}
|
||||
?>
|
||||
<div class="dupli-import-package-detail-content">
|
||||
<?php
|
||||
$errorMsg = '';
|
||||
if (!$importObj->encryptCheck($errorMsg)) {
|
||||
?>
|
||||
<p class="maroon">
|
||||
<b>
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
<?php
|
||||
echo wp_kses(
|
||||
$errorMsg,
|
||||
[
|
||||
'a' => [
|
||||
'href' => [],
|
||||
'target' => [],
|
||||
],
|
||||
]
|
||||
);
|
||||
?>
|
||||
</b>
|
||||
</p>
|
||||
<?php
|
||||
} elseif (!$importObj->passwordCheck()) {
|
||||
?>
|
||||
<p class="maroon">
|
||||
<b><i class="fas fa-exclamation-triangle"></i> <?php esc_html_e('Valid password required', 'duplicator-pro'); ?></b>
|
||||
</p>
|
||||
<div class="dup-import-archive-password-request">
|
||||
<input type="password" class="dup-import-archive-password" name="password" value="">
|
||||
<button type="button" class="dup-import-set-archive-password button">
|
||||
<?php esc_html_e('Submit', 'duplicator-pro'); ?>
|
||||
</button>
|
||||
</div>
|
||||
<?php
|
||||
} elseif (!$importObj->isImportable($importFailMessage)) {
|
||||
?>
|
||||
<p class="maroon">
|
||||
<b>
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
<?php
|
||||
echo wp_kses(
|
||||
$importFailMessage,
|
||||
[
|
||||
'br' => [],
|
||||
'a' => [
|
||||
'href' => [],
|
||||
'target' => [],
|
||||
],
|
||||
]
|
||||
);
|
||||
?>
|
||||
</b>
|
||||
</p>
|
||||
<?php
|
||||
} elseif ($importObj->haveImportWaring($importWarnMessage)) {
|
||||
?>
|
||||
<p class="gray">
|
||||
<b><i class="fas fa-exclamation-triangle"></i> <?php echo wp_kses($importWarnMessage, ['br' => []]); ?></b>
|
||||
</p>
|
||||
<?php
|
||||
} else {
|
||||
?>
|
||||
<p class="green">
|
||||
<b>
|
||||
<i class="fas fa-check-circle"></i>
|
||||
<?php esc_html_e('This Backup is ready to install, click the continue button to proceed.', 'duplicator-pro'); ?>
|
||||
</b><br />
|
||||
<b><?php esc_html_e('The information below is related to the Backup and the source site where the Backup was created.', 'duplicator-pro'); ?></b>
|
||||
</p>
|
||||
<?php
|
||||
}
|
||||
|
||||
if ($importObj->isValid()) {
|
||||
?>
|
||||
<ul class="no-bullet">
|
||||
<li>
|
||||
<span class="label title"><?php esc_html_e('Site Details:', 'duplicator-pro'); ?></span>
|
||||
</li>
|
||||
<li>
|
||||
<span class="label"><?php esc_html_e('URL', 'duplicator-pro'); ?>:</span>
|
||||
<span class="value"><?php echo esc_html($importObj->getHomeUrl()); ?></span>
|
||||
</li>
|
||||
<li>
|
||||
<span class="label"><?php esc_html_e('Path', 'duplicator-pro'); ?>:</span>
|
||||
<span class="value"><?php echo esc_html($importObj->getHomePath()); ?></span>
|
||||
</li>
|
||||
<li>
|
||||
<span class="label title"><?php esc_html_e('Versions:', 'duplicator-pro'); ?></span>
|
||||
</li>
|
||||
<li>
|
||||
<span class="label"><?php esc_html_e('Duplicator', 'duplicator-pro'); ?>:</span>
|
||||
<span class="value"><?php echo esc_html($importObj->getDupVersion()); ?></span>
|
||||
</li>
|
||||
<li>
|
||||
<span class="label"><?php esc_html_e('WordPress', 'duplicator-pro'); ?>:</span>
|
||||
<span class="value"><?php echo esc_html($importObj->getWPVersion()); ?></span>
|
||||
</li>
|
||||
<li>
|
||||
<span class="label"><?php esc_html_e('PHP', 'duplicator-pro'); ?>:</span>
|
||||
<span class="value"><?php echo esc_html($importObj->getPhpVersion()); ?></span>
|
||||
</li>
|
||||
<?php if ($importObj->getPackageComponents() !== false) { ?>
|
||||
<li>
|
||||
<span class="label title"><?php esc_html_e('Backup components:', 'duplicator-pro'); ?></span>
|
||||
</li>
|
||||
<?php
|
||||
$packComponents = $importObj->getPackageComponents();
|
||||
foreach (BuildComponents::COMPONENTS_DEFAULT as $component) {
|
||||
?>
|
||||
<li>
|
||||
<span class="label"><?php echo esc_html(BuildComponents::getLabel($component)); ?>:</span>
|
||||
<span class="value">
|
||||
<?php if (in_array($component, $packComponents)) { ?>
|
||||
<i class="fas fa-check-circle green"></i> <?php esc_html_e('included', 'duplicator-pro'); ?>
|
||||
<?php } else { ?>
|
||||
<i class="fas fa-times-circle maroon"></i> <?php esc_html_e('excluded', 'duplicator-pro'); ?>
|
||||
<?php } ?>
|
||||
</span>
|
||||
</li>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<li>
|
||||
<span class="label title"><?php esc_html_e('Archive:', 'duplicator-pro'); ?></span>
|
||||
</li>
|
||||
<li>
|
||||
<span class="label"><?php esc_html_e('Created', 'duplicator-pro'); ?>:</span>
|
||||
<span class="value"><?php echo esc_html($importObj->getCreated()); ?></span>
|
||||
</li>
|
||||
<li>
|
||||
<span class="label"><?php esc_html_e('Size', 'duplicator-pro'); ?>:</span>
|
||||
<span class="value"><?php echo esc_html(SnapString::byteSize($importObj->getSize())); ?></span>
|
||||
</li>
|
||||
<?php if (!$importObj->isLite()) { ?>
|
||||
<li>
|
||||
<span class="label"><?php esc_html_e('Folders', 'duplicator-pro'); ?>:</span>
|
||||
<span class="value"><?php echo esc_html(number_format($importObj->getNumFolders())); ?></span>
|
||||
</li>
|
||||
<li>
|
||||
<span class="label"><?php esc_html_e('Files', 'duplicator-pro'); ?>:</span>
|
||||
<span class="value"><?php echo esc_html(number_format($importObj->getNumFiles())); ?></span>
|
||||
</li>
|
||||
<?php } ?>
|
||||
<li>
|
||||
<span class="label title"><?php esc_html_e('Database:', 'duplicator-pro'); ?></span>
|
||||
</li>
|
||||
<?php
|
||||
if (
|
||||
$importObj->getPackageComponents() === false ||
|
||||
in_array(PComponents::COMP_DB, $importObj->getPackageComponents())
|
||||
) {
|
||||
?>
|
||||
<li>
|
||||
<span class="label"><?php esc_html_e('Size', 'duplicator-pro'); ?>:</span>
|
||||
<span class="value"><?php echo esc_html($importObj->getDbSize()); ?></span>
|
||||
</li>
|
||||
<li>
|
||||
<span class="label"><?php esc_html_e('Tables', 'duplicator-pro'); ?>:</span>
|
||||
<span class="value"><?php echo (int) $importObj->getNumTables(); ?></span>
|
||||
</li>
|
||||
<li>
|
||||
<span class="label"><?php esc_html_e('Rows', 'duplicator-pro'); ?>:</span>
|
||||
<span class="value"><?php echo esc_html(number_format($importObj->getNumRows())); ?></span>
|
||||
</li>
|
||||
<?php } else { ?>
|
||||
<li>
|
||||
<span class="label"><?php esc_html_e('Database', 'duplicator-pro'); ?>:</span>
|
||||
<span class="value"><?php esc_html_e('Not Included', 'duplicator-pro'); ?></span>
|
||||
</li>
|
||||
<?php } ?>
|
||||
</ul>
|
||||
<?php } ?>
|
||||
</div>
|
||||
@@ -0,0 +1,646 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Controllers\ImportPageController;
|
||||
use Duplicator\Views\UI\UiDialog;
|
||||
use Duplicator\Views\UI\UiMessages;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
$packageDeteleConfirm = new UiDialog();
|
||||
$packageDeteleConfirm->title = __('Delete Backup?', 'duplicator-pro');
|
||||
$packageDeteleConfirm->wrapperClassButtons = 'dupli-dlg-import-detete-package-btns';
|
||||
$packageDeteleConfirm->progressOn = false;
|
||||
$packageDeteleConfirm->closeOnConfirm = true;
|
||||
$packageDeteleConfirm->message = __('Are you sure you want to delete the selected Backup?', 'duplicator-pro');
|
||||
$packageDeteleConfirm->jsCallback = 'DupliJs.ImportManager.removePackage()';
|
||||
$packageDeteleConfirm->initConfirm();
|
||||
|
||||
$packageInvalidName = new UiMessages(
|
||||
__(
|
||||
'<b>Invalid archive name:</b> The archive name must follow the Duplicator Backup name pattern
|
||||
e.g. BACKUP_NAME_[HASH]_[YYYYMMDDHHSS]_archive.zip (or with a .daf extension).
|
||||
<br>Please make sure not to rename the archive after downloading it and try again!',
|
||||
'duplicator-pro'
|
||||
),
|
||||
UiMessages::ERROR
|
||||
);
|
||||
$packageInvalidName->hide_on_init = true;
|
||||
$packageInvalidName->is_dismissible = true;
|
||||
$packageInvalidName->auto_hide_delay = 10000;
|
||||
$packageInvalidName->initMessage();
|
||||
|
||||
$packageAlreadyExists = new UiMessages(
|
||||
__('Archive file name already exists! <br>Please remove it and try again!', 'duplicator-pro'),
|
||||
UiMessages::ERROR
|
||||
);
|
||||
$packageAlreadyExists->hide_on_init = true;
|
||||
$packageAlreadyExists->is_dismissible = true;
|
||||
$packageAlreadyExists->auto_hide_delay = 5000;
|
||||
$packageAlreadyExists->initMessage();
|
||||
|
||||
$packageUploaded = new UiMessages(__('Backup uploaded', 'duplicator-pro'), UiMessages::NOTICE);
|
||||
$packageUploaded->hide_on_init = true;
|
||||
$packageUploaded->is_dismissible = true;
|
||||
$packageUploaded->auto_hide_delay = 5000;
|
||||
$packageUploaded->initMessage();
|
||||
|
||||
$packageCancelUpload = new UiMessages(__('Backup upload cancelled', 'duplicator-pro'), UiMessages::ERROR);
|
||||
$packageCancelUpload->hide_on_init = true;
|
||||
$packageCancelUpload->is_dismissible = true;
|
||||
$packageCancelUpload->auto_hide_delay = 5000;
|
||||
$packageCancelUpload->initMessage();
|
||||
|
||||
$packageRemoved = new UiMessages(__('Backup removed', 'duplicator-pro'), UiMessages::NOTICE);
|
||||
$packageRemoved->hide_on_init = true;
|
||||
$packageRemoved->is_dismissible = true;
|
||||
$packageRemoved->auto_hide_delay = 5000;
|
||||
$packageRemoved->initMessage();
|
||||
|
||||
$importChunkSize = ImportPageController::getChunkSize();
|
||||
?><script>
|
||||
jQuery(document).ready(function($) {
|
||||
var uploadFileMessageContent = <?php $tplMng->renderJson('admin_pages/import/import-message-upload-error'); ?>;
|
||||
|
||||
DupliJs.ImportManager = {
|
||||
uploaderWrapper: $('#dupli-import-upload-tabs-wrapper'),
|
||||
uploaderDisabler: $('<div>'),
|
||||
uploader: $('#dupli-import-upload-file'),
|
||||
uploaderContent: $('#dupli-import-upload-file-content'),
|
||||
packageRowTemplate: $('#dupli-import-row-template'),
|
||||
packageRowNoFoundTemplate: $('#dupli-import-available-packages-templates .dupli-import-no-package-found'),
|
||||
packagesAviable: $('#dupli-import-available-packages'),
|
||||
packagesList: $('#dupli-import-available-packages .packages-list'),
|
||||
packageRowUploading: null,
|
||||
packageRowToDelete: null,
|
||||
autoLaunchAfterUpload: false,
|
||||
autoLaunchLink: false,
|
||||
confirmLaunchLink: false,
|
||||
startUpload: false,
|
||||
lastUploadsTimes: [],
|
||||
debug: true,
|
||||
init: function() {
|
||||
$('#dupli-import-instructions-toggle').click(function() {
|
||||
$('#dupli-import-instructions-content').toggle(300);
|
||||
})
|
||||
|
||||
DupliJs.ImportManager.uploaderWrapper.css('position', 'relative');
|
||||
DupliJs.ImportManager.uploaderDisabler = $('<div>').css({
|
||||
'position': 'absolute',
|
||||
'top': 0,
|
||||
'left': 0,
|
||||
'width': '100%',
|
||||
'height': '100%',
|
||||
'z-index': '10',
|
||||
'cursor': 'not-allowed',
|
||||
'display': 'none'
|
||||
});
|
||||
DupliJs.ImportManager.uploaderDisabler.appendTo(DupliJs.ImportManager.uploaderWrapper);
|
||||
|
||||
DupliJs.ImportManager.uploader.upload({
|
||||
autoUpload: true,
|
||||
multiple: false,
|
||||
maxSize: <?php echo empty($importChunkSize) ? (int) wp_max_upload_size() : 10737418240; ?>, //100GB get value from upload_max_filesize
|
||||
maxConcurrent: 1,
|
||||
maxFiles: 1,
|
||||
postData: {
|
||||
action: 'duplicator_import_upload',
|
||||
nonce: <?php echo json_encode(wp_create_nonce('duplicator_import_upload')); ?>
|
||||
},
|
||||
chunkSize: <?php echo (int) $importChunkSize; ?>, // This is in kb
|
||||
action: <?php echo json_encode(get_admin_url(null, 'admin-ajax.php')); ?>,
|
||||
chunked: <?php echo empty($importChunkSize) ? 'false' : 'true'; ?>,
|
||||
label: DupliJs.ImportManager.uploaderContent.parent().html(),
|
||||
leave: '<?php echo esc_js(__('You have uploads pending, are you sure you want to leave this page?', 'duplicator-pro')); ?>'
|
||||
})
|
||||
.on("start.upload", DupliJs.ImportManager.onStart)
|
||||
.on("complete.upload", DupliJs.ImportManager.onComplete)
|
||||
.on("filestart.upload", DupliJs.ImportManager.onFileStart)
|
||||
.on("fileprogress.upload", DupliJs.ImportManager.onFileProgress)
|
||||
.on("filecomplete.upload", DupliJs.ImportManager.onFileComplete)
|
||||
.on("fileerror.upload", DupliJs.ImportManager.onFileError)
|
||||
.on("fileerror.chunkerror", DupliJs.ImportManager.onChunkError);
|
||||
|
||||
DupliJs.ImportManager.uploaderContent.remove();
|
||||
DupliJs.ImportManager.uploaderContent = $('#dupli-import-upload-file #dupli-import-upload-file-content');
|
||||
DupliJs.ImportManager.initPageButtons();
|
||||
DupliJs.ImportManager.checkMaxUploadedFiles();
|
||||
|
||||
DupliJs.ImportManager.packagesList.on('click', '.dupli-import-action-remove', function(event) {
|
||||
event.stopPropagation();
|
||||
DupliJs.ImportManager.packageRowToDelete = $(this).closest('.dupli-import-package');
|
||||
<?php $packageDeteleConfirm->showConfirm(); ?>
|
||||
return false;
|
||||
});
|
||||
|
||||
DupliJs.ImportManager.packagesList.on('click', '.dupli-import-action-package-detail-toggle', function(event) {
|
||||
event.stopPropagation();
|
||||
let button = $(this);
|
||||
let details = button.closest('.dupli-import-package').find('.dupli-import-package-detail');
|
||||
if (details.hasClass('no-display')) {
|
||||
button.find('.fa').removeClass('fa-caret-down').addClass('fa-caret-up');
|
||||
details.removeClass('no-display');
|
||||
} else {
|
||||
button.find('.fa').removeClass('fa-caret-up').addClass('fa-caret-down');
|
||||
details.addClass('no-display');
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
DupliJs.ImportManager.packagesList.on('click', '.dupli-import-action-cancel-upload', function(event) {
|
||||
event.stopPropagation();
|
||||
DupliJs.ImportManager.abortUpload();
|
||||
<?php $packageCancelUpload->showMessage(); ?>
|
||||
return false;
|
||||
});
|
||||
|
||||
DupliJs.ImportManager.packagesList.on('click', '.dupli-import-action-install', function(event) {
|
||||
event.stopPropagation();
|
||||
DupliJs.ImportManager.confirmLaunchLink = $(this).data('install-url');
|
||||
$('#dupli-import-phase-one').addClass('no-display');
|
||||
$('#dupli-import-phase-two').removeClass('no-display');
|
||||
return false;
|
||||
});
|
||||
|
||||
DupliJs.ImportManager.packagesList.on('click', '.dup-import-set-archive-password', function(event) {
|
||||
event.stopPropagation();
|
||||
DupliJs.ImportManager.setArchivePassword($(this));
|
||||
return false;
|
||||
});
|
||||
|
||||
DupliJs.ImportManager.initRemoteUpload();
|
||||
},
|
||||
initRemoteUpload: function() {
|
||||
$('#dupli-import-remote-upload').click(function() {
|
||||
let uploadUrl = $('#dupli-import-remote-url').val();
|
||||
let parsedUrl = null;
|
||||
|
||||
try {
|
||||
parsedUrl = new URL(uploadUrl);
|
||||
} catch (error) {
|
||||
DupliJs.addAdminMessage('<?php echo esc_js(__('Invalid URL', 'duplicator-pro')) ?>', 'error');
|
||||
}
|
||||
|
||||
let files = [{
|
||||
'name': parsedUrl.pathname.split('/').pop(),
|
||||
'size': -1
|
||||
}];
|
||||
if (DupliJs.ImportManager.onStart(null, files) == false) {
|
||||
DupliJs.ImportManager.onComplete(null);
|
||||
return false;
|
||||
}
|
||||
DupliJs.ImportManager.onFileStart(null, files[0]);
|
||||
DupliJs.ImportManager.remoteUploadCall(uploadUrl, null);
|
||||
});
|
||||
},
|
||||
remoteUploadCall: function(uploadUrl, restoreDownload) {
|
||||
DupliJs.Util.ajaxWrapper({
|
||||
action: 'duplicator_import_remote_download',
|
||||
url: uploadUrl,
|
||||
restoreDownload: (restoreDownload == null ? '' : JSON.stringify(restoreDownload)),
|
||||
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_remote_download')); ?>'
|
||||
},
|
||||
function(result, data, funcData, textStatus, jqXHR) {
|
||||
if (DupliJs.ImportManager.packageRowUploading == null) {
|
||||
// if row don't exitst the upload is aboted
|
||||
DupliJs.ImportManager.onComplete(null);
|
||||
return '';
|
||||
}
|
||||
|
||||
if (funcData.status == 'complete') {
|
||||
DupliJs.ImportManager.onFileComplete(null, uploadUrl, result);
|
||||
DupliJs.ImportManager.onComplete(null);
|
||||
} else {
|
||||
DupliJs.ImportManager.updateProgress(funcData.remoteChunk.offset, funcData.remoteChunk.fullSize);
|
||||
|
||||
// Update filename display with real archive name from cloud processing
|
||||
if (funcData.remoteChunk.extraData && funcData.remoteChunk.extraData.archiveName) {
|
||||
DupliJs.ImportManager.packageRowUploading.find('.name .text').text(funcData.remoteChunk.extraData.archiveName);
|
||||
}
|
||||
|
||||
DupliJs.ImportManager.remoteUploadCall(uploadUrl, funcData.remoteChunk);
|
||||
}
|
||||
return '';
|
||||
},
|
||||
function(result, data, funcData, textStatus, jqXHR) {
|
||||
DupliJs.ImportManager.uploadError(result.data.message);
|
||||
DupliJs.ImportManager.onComplete(null);
|
||||
return '';
|
||||
}, {
|
||||
timeout: 30000 // 30 seconds for large cloud file downloads
|
||||
}
|
||||
);
|
||||
},
|
||||
setArchivePassword: function(button) {
|
||||
let row = button.closest('.dupli-import-package');
|
||||
let archiveFile = row.data('path');
|
||||
let password = row.find('.dup-import-archive-password-request .dup-import-archive-password').val();
|
||||
|
||||
DupliJs.Util.ajaxWrapper({
|
||||
action: 'duplicator_import_set_archive_password',
|
||||
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_import_set_archive_password')); ?>',
|
||||
archive: archiveFile,
|
||||
password: password
|
||||
},
|
||||
function(result, data, funcData, textStatus, jqXHR) {
|
||||
DupliJs.ImportManager.packageRowUploading = row;
|
||||
DupliJs.ImportManager.onFileComplete(null, archiveFile, result, false);
|
||||
DupliJs.ImportManager.onComplete(null);
|
||||
return '';
|
||||
},
|
||||
function(result, data, funcData, textStatus, jqXHR) {
|
||||
DupliJs.addAdminMessage(data.message, 'error', {
|
||||
'hideDelay': 5000
|
||||
});
|
||||
return '';
|
||||
}
|
||||
);
|
||||
},
|
||||
initPageButtons: function() {
|
||||
$('.dupli-import-view-list').click(function(event) {
|
||||
event.stopPropagation();
|
||||
DupliJs.ImportManager.updateViewMode('<?php echo esc_js(ImportPageController::VIEW_MODE_ADVANCED); ?>');
|
||||
});
|
||||
|
||||
$('.dupli-import-view-single').click(function(event) {
|
||||
event.stopPropagation();
|
||||
DupliJs.ImportManager.updateViewMode('<?php echo esc_js(ImportPageController::VIEW_MODE_BASIC); ?>');
|
||||
});
|
||||
|
||||
$('#dupli-import-launch-installer-confirm').click(function(event) {
|
||||
event.stopPropagation();
|
||||
DupliJs.ImportManager.confirmLaunchInstaller();
|
||||
});
|
||||
|
||||
$('#dupli-import-launch-installer-cancel').click(function(event) {
|
||||
event.stopPropagation();
|
||||
DupliJs.ImportManager.confirmLaunchLink = false;
|
||||
$('#dupli-import-phase-two').addClass('no-display');
|
||||
$('#dupli-import-phase-one').removeClass('no-display');
|
||||
return false;
|
||||
});
|
||||
|
||||
$('#wpbody-content').each(function() {
|
||||
let tabWrapper = $(this);
|
||||
|
||||
tabWrapper.find('[data-tab-target]').click(function() {
|
||||
let targetId = $(this).data('tab-target');
|
||||
tabWrapper.find('[data-tab-target]').removeClass('active');
|
||||
tabWrapper.find('.tab-content').addClass('no-display');
|
||||
|
||||
$(this).addClass('active');
|
||||
tabWrapper.find('#' + targetId).removeClass('no-display');
|
||||
});
|
||||
});
|
||||
},
|
||||
confirmLaunchInstaller: function() {
|
||||
window.location.href = DupliJs.ImportManager.confirmLaunchLink;
|
||||
return false;
|
||||
},
|
||||
onStart: function(e, files) {
|
||||
DupliJs.ImportManager.uploaderDisabler.show();
|
||||
DupliJs.ImportManager.startUpload = true;
|
||||
DupliJs.ImportManager.uploader.upload("disable");
|
||||
DupliJs.ImportManager.autoLaunchLink = false;
|
||||
|
||||
let isValidName = true;
|
||||
let alreadyExists = false;
|
||||
|
||||
$.each(files, function(index, value) {
|
||||
if (!DupliJs.ImportManager.isValidFileName(value.name)) {
|
||||
isValidName = false;
|
||||
}
|
||||
|
||||
if (DupliJs.ImportManager.isAlreadyExists(value.name)) {
|
||||
alreadyExists = true;
|
||||
}
|
||||
});
|
||||
|
||||
/*if (!isValidName) {
|
||||
<?php $packageInvalidName->showMessage(); ?>
|
||||
DupliJs.ImportManager.abortUpload();
|
||||
return false;
|
||||
}*/
|
||||
|
||||
if (alreadyExists) {
|
||||
<?php $packageAlreadyExists->showMessage(); ?>
|
||||
DupliJs.ImportManager.abortUpload();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
onComplete: function(e) {
|
||||
$('#dupli-import-remote-url').val('');
|
||||
|
||||
if (DupliJs.ImportManager.autoLaunchAfterUpload && DupliJs.ImportManager.autoLaunchLink) {
|
||||
document.location.href = DupliJs.ImportManager.autoLaunchLink;
|
||||
}
|
||||
DupliJs.ImportManager.checkMaxUploadedFiles();
|
||||
},
|
||||
onFileStart: function(e, file) {
|
||||
DupliJs.ImportManager.resetUploadTimes();
|
||||
DupliJs.ImportManager.packagesList.find('.dupli-import-no-package-found').remove();
|
||||
DupliJs.ImportManager.packageRowUploading = DupliJs.ImportManager.packageRowTemplate.clone().prependTo(DupliJs.ImportManager.packagesList);
|
||||
|
||||
DupliJs.ImportManager.packageRowUploading.removeAttr('id');
|
||||
DupliJs.ImportManager.packageRowUploading.find('.name .text').text(file.name);
|
||||
DupliJs.ImportManager.packageRowUploading.find('.size').text(DupliJs.Util.humanFileSize(file.size));
|
||||
DupliJs.ImportManager.packageRowUploading.find('.created').html("<i><?php esc_html_e('loading...', 'duplicator-pro'); ?></i>");
|
||||
|
||||
let loader = DupliJs.ImportManager.packageRowUploading.find('.funcs .dupli-loader').removeClass('no-display');
|
||||
loader.find('.dupli-meter > span').css('width', '0%');
|
||||
loader.find('.text').text('0%');
|
||||
},
|
||||
onFileProgress: function(e, file, percent, eventObj) {
|
||||
let position = 0;
|
||||
if ('currentChunk' in file) {
|
||||
position = file.currentChunk * file.chunkSize;
|
||||
} else {
|
||||
if (eventObj.lengthComputable) {
|
||||
position = eventObj.loaded || eventObj.position;
|
||||
} else {
|
||||
position = false;
|
||||
}
|
||||
}
|
||||
|
||||
DupliJs.ImportManager.updateProgress(position, file.size);
|
||||
},
|
||||
onFileComplete: function(e, file, response, showMessage = true) {
|
||||
let result = null;
|
||||
if (typeof response === 'string' || response instanceof String) {
|
||||
result = JSON.parse(response);
|
||||
} else {
|
||||
result = response;
|
||||
}
|
||||
DupliJs.ImportManager.resetUploadTimes();
|
||||
|
||||
if (result.success == false) {
|
||||
DupliJs.ImportManager.uploadError(result.data.message);
|
||||
return;
|
||||
}
|
||||
|
||||
DupliJs.ImportManager.packageRowUploading.data('path', result.data.funcData.archivePath);
|
||||
if (result.data.funcData.isImportable) {
|
||||
DupliJs.ImportManager.packageRowUploading.addClass('is-importable');
|
||||
DupliJs.ImportManager.packageRowUploading
|
||||
.find('.dupli-import-action-install')
|
||||
.prop('disabled', false)
|
||||
.data('install-url', result.data.funcData.installerPageLink);
|
||||
DupliJs.ImportManager.autoLaunchLink = result.data.funcData.installerPageLink;
|
||||
} else {
|
||||
DupliJs.ImportManager.autoLaunchLink = false;
|
||||
DupliJs.ImportManager.packageRowUploading.find('.dupli-import-action-package-detail-toggle').trigger('click');
|
||||
}
|
||||
DupliJs.ImportManager.packageRowUploading.find('.dupli-import-package-detail').html(result.data.funcData.htmlDetails);
|
||||
DupliJs.ImportManager.packageRowUploading.find('.size').text(DupliJs.Util.humanFileSize(result.data.funcData.archiveSize));
|
||||
DupliJs.ImportManager.packageRowUploading.find('.created').text(result.data.funcData.created);
|
||||
DupliJs.ImportManager.packageRowUploading.find('.funcs .dupli-loader').addClass('no-display');
|
||||
DupliJs.ImportManager.packageRowUploading.find('.funcs .actions').removeClass('no-display');
|
||||
DupliJs.ImportManager.packageRowUploading = null;
|
||||
if (showMessage) {
|
||||
<?php $packageUploaded->showMessage(); ?>
|
||||
}
|
||||
},
|
||||
onFileError: function(e, file, error) {
|
||||
if (error === 'abort') {
|
||||
// no message for abort
|
||||
DupliJs.ImportManager.uploadError(null);
|
||||
} else if (error === 'size') {
|
||||
DupliJs.ImportManager.uploadError(<?php echo json_encode(__('The file size exceeds the maximum upload limit.', 'duplicator-pro')); ?>);
|
||||
} else {
|
||||
DupliJs.ImportManager.uploadError(error);
|
||||
}
|
||||
},
|
||||
getTimeLeft: function(sizeToFinish) {
|
||||
if (DupliJs.ImportManager.lastUploadsTimes.length < 2) {
|
||||
return false;
|
||||
}
|
||||
let pos1 = DupliJs.ImportManager.lastUploadsTimes[0].pos;
|
||||
let time1 = DupliJs.ImportManager.lastUploadsTimes[0].time;
|
||||
|
||||
let index = DupliJs.ImportManager.lastUploadsTimes.length - 1
|
||||
let pos2 = DupliJs.ImportManager.lastUploadsTimes[index].pos;
|
||||
let time2 = DupliJs.ImportManager.lastUploadsTimes[index].time;
|
||||
|
||||
let deltaPos = pos2 - pos1;
|
||||
let deltaTime = time2 - time1;
|
||||
|
||||
return deltaTime / deltaPos * sizeToFinish;
|
||||
},
|
||||
millisecToTime: function(s) {
|
||||
if (s <= 0) {
|
||||
return '<?php echo esc_js(__('loading...', 'duplicator-pro')) ?>';
|
||||
}
|
||||
|
||||
var ms = s % 1000;
|
||||
s = (s - ms) / 1000;
|
||||
var secs = s % 60;
|
||||
s = (s - secs) / 60;
|
||||
var mins = s % 60;
|
||||
var hrs = (s - mins) / 60;
|
||||
|
||||
let result = '';
|
||||
if (hrs > 0) {
|
||||
result += ' ' + hrs + ' <?php echo esc_js(__('hr', 'duplicator-pro')) ?>';
|
||||
}
|
||||
|
||||
if (mins > 0) {
|
||||
result += ' ' + (mins + 1) + ' <?php echo esc_js(__('min', 'duplicator-pro')) ?>';
|
||||
return result;
|
||||
}
|
||||
|
||||
return secs + ' <?php echo esc_js(__('sec', 'duplicator-pro')) ?>';
|
||||
},
|
||||
resetUploadTimes: function() {
|
||||
DupliJs.ImportManager.lastUploadsTimes = [];
|
||||
},
|
||||
addUploadTime: function(postion) {
|
||||
if (DupliJs.ImportManager.lastUploadsTimes.length > 20) {
|
||||
DupliJs.ImportManager.lastUploadsTimes.shift();
|
||||
}
|
||||
|
||||
DupliJs.ImportManager.lastUploadsTimes.push({
|
||||
'pos': postion,
|
||||
'time': Date.now()
|
||||
});
|
||||
},
|
||||
updateProgress: function(position, total) {
|
||||
let percent = 0;
|
||||
|
||||
if (position !== false) {
|
||||
DupliJs.ImportManager.addUploadTime(position);
|
||||
percent = Math.round((position / total) * 100 * 10) / 10;
|
||||
percent = Number.isInteger(percent) ? percent + ".0" : percent;
|
||||
}
|
||||
|
||||
DupliJs.ImportManager.packageRowUploading.find('.size').text(DupliJs.Util.humanFileSize(total));
|
||||
let timeLeft = DupliJs.ImportManager.getTimeLeft(total - position);
|
||||
let loader = DupliJs.ImportManager.packageRowUploading.find('.funcs .dupli-loader');
|
||||
loader.find('.dupli-meter > span').css("width", percent + "%");
|
||||
loader.find('.text').text(percent + "% - " + DupliJs.ImportManager.millisecToTime(timeLeft));
|
||||
},
|
||||
updateContentMessage: function(icon, line1, line2) {
|
||||
DupliJs.ImportManager.uploaderContent.find('.message').html('<i class="fas ' + icon + ' fa-sm"></i> ' + line1 + '<br>' + line2);
|
||||
},
|
||||
uploadError: function(message) {
|
||||
DupliJs.ImportManager.removeRow(DupliJs.ImportManager.packageRowUploading);
|
||||
DupliJs.ImportManager.packageRowUploading = null;
|
||||
|
||||
if (message != null) {
|
||||
DupliJs.addAdminMessage(uploadFileMessageContent, 'error', {
|
||||
'hideDelay': 60000,
|
||||
'updateCallback': function(msgNode) {
|
||||
msgNode.find('.import-upload-error-message').text(message);
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
isAlreadyExists: function(name) {
|
||||
let alreadyExists = false;
|
||||
DupliJs.ImportManager.packagesList.find('tbody .name .text').each(function() {
|
||||
if (name === $(this).text()) {
|
||||
alreadyExists = true;
|
||||
}
|
||||
});
|
||||
|
||||
return alreadyExists;
|
||||
},
|
||||
isValidFileName: function(name) {
|
||||
if (!name.match(<?php echo wp_json_encode(DUPLICATOR_ARCHIVE_REGEX_PATTERN); ?>)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
abortUpload: function() {
|
||||
try {
|
||||
DupliJs.ImportManager.uploader.upload("abort");
|
||||
} catch (err) {
|
||||
// prevent abort error
|
||||
}
|
||||
DupliJs.ImportManager.removeRow(DupliJs.ImportManager.packageRowUploading);
|
||||
DupliJs.ImportManager.packageRowUploading = null;
|
||||
},
|
||||
removePackage: function() {
|
||||
DupliJs.Util.ajaxWrapper({
|
||||
action: 'duplicator_import_package_delete',
|
||||
path: DupliJs.ImportManager.packageRowToDelete.data('path'),
|
||||
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_import_package_delete')); ?>'
|
||||
},
|
||||
function(result, data, funcData, textStatus, jqXHR) {
|
||||
DupliJs.ImportManager.removeRow(DupliJs.ImportManager.packageRowToDelete);
|
||||
<?php $packageRemoved->showMessage(); ?>;
|
||||
return '';
|
||||
}
|
||||
);
|
||||
},
|
||||
removeRow: function(row) {
|
||||
if (!row) {
|
||||
return;
|
||||
}
|
||||
row.fadeOut(
|
||||
'fast',
|
||||
function() {
|
||||
row.remove();
|
||||
if (DupliJs.ImportManager.packagesList.find('.dupli-import-package').length === 0) {
|
||||
DupliJs.ImportManager.packageRowNoFoundTemplate.clone().appendTo(DupliJs.ImportManager.packagesList);
|
||||
}
|
||||
DupliJs.ImportManager.checkMaxUploadedFiles();
|
||||
}
|
||||
);
|
||||
},
|
||||
checkMaxUploadedFiles: function() {
|
||||
let limit = 0; // 0 no limit
|
||||
let numPackages = $('.packages-list .dupli-import-package').length;
|
||||
|
||||
if ($('#dupli-import-available-packages').hasClass('view-single-item')) {
|
||||
limit = 1;
|
||||
}
|
||||
|
||||
if (limit > 0 && numPackages >= limit) {
|
||||
DupliJs.ImportManager.uploaderDisabler.show();
|
||||
DupliJs.ImportManager.uploader.upload("disable");
|
||||
} else {
|
||||
DupliJs.ImportManager.uploaderDisabler.hide();
|
||||
DupliJs.ImportManager.uploader.upload("enable");
|
||||
}
|
||||
},
|
||||
disableWrapper: function() {
|
||||
DupliJs.ImportManager.uploaderWrapper
|
||||
},
|
||||
updateViewMode: function(viewMode) {
|
||||
DupliJs.Util.ajaxWrapper({
|
||||
action: 'duplicator_import_set_view_mode',
|
||||
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_import_set_view_mode')); ?>',
|
||||
view_mode: viewMode
|
||||
},
|
||||
function(result, data, funcData, textStatus, jqXHR) {
|
||||
switch (funcData) {
|
||||
case '<?php echo esc_js(ImportPageController::VIEW_MODE_ADVANCED); ?>':
|
||||
$('.dupli-import-view-single').removeClass('active');
|
||||
$('.dupli-import-view-list').addClass('active');
|
||||
$('#dupli-basic-mode-message').addClass('no-display');
|
||||
DupliJs.ImportManager.packagesAviable.removeClass('view-single-item').addClass('view-list-item');
|
||||
break;
|
||||
case '<?php echo esc_js(ImportPageController::VIEW_MODE_BASIC); ?>':
|
||||
$('.dupli-import-view-list').removeClass('active');
|
||||
$('.dupli-import-view-single').addClass('active');
|
||||
$('#dupli-basic-mode-message').removeClass('no-display');
|
||||
DupliJs.ImportManager.packagesAviable.removeClass('view-list-item').addClass('view-single-item');
|
||||
break;
|
||||
default:
|
||||
throw '<?php echo esc_js(__('Invalid view mode', 'duplicator-pro')); ?>';
|
||||
}
|
||||
DupliJs.ImportManager.checkMaxUploadedFiles();
|
||||
return '';
|
||||
|
||||
},
|
||||
function(result, data, funcData, textStatus, jqXHR) {
|
||||
DupliJs.addAdminMessage(data.message, 'error', {
|
||||
'hideDelay': 5000
|
||||
});
|
||||
return '';
|
||||
}
|
||||
);
|
||||
},
|
||||
console: function() {
|
||||
if (this.debug) {
|
||||
if (arguments.length > 1) {
|
||||
console.log(arguments[0], arguments[1]);
|
||||
} else {
|
||||
console.log(arguments[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// wait form stone init, it's not a great method but for now I haven't found a better one.
|
||||
window.setTimeout(DupliJs.ImportManager.init, 500);
|
||||
|
||||
$('.dupli-import-box.closable').each(function() {
|
||||
let box = $(this);
|
||||
let title = $(this).find('.box-title');
|
||||
let content = $(this).find('.box-content');
|
||||
|
||||
title.click(function() {
|
||||
if (box.hasClass('opened')) {
|
||||
box.removeClass('opened').addClass('closed');
|
||||
} else {
|
||||
box.removeClass('closed').addClass('opened');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
use Duplicator\Controllers\RecoveryController;
|
||||
use Duplicator\Libs\Snap\SnapWP;
|
||||
use Duplicator\Package\Recovery\RecoveryPackage;
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
$postTypeCount = SnapWP::getPostTypesCount();
|
||||
if (
|
||||
($recoverPackage = RecoveryPackage::getRecoverPackage()) == false ||
|
||||
$recoverPackage->isOutToDate()
|
||||
) {
|
||||
$badgeClass = 'badge-warn';
|
||||
$badgeLabel = 'Notice';
|
||||
} else {
|
||||
$badgeClass = 'badge-pass';
|
||||
$badgeLabel = 'Good';
|
||||
}
|
||||
?>
|
||||
<div class="dupli-import-header" >
|
||||
<h2 class="title">
|
||||
<b>
|
||||
<?php printf(esc_html__("Step %s of 2: Confirmation", 'duplicator-pro'), '<span class="red">2</span>'); ?>
|
||||
</b>
|
||||
</h2>
|
||||
</div>
|
||||
<div class="dupli-recovery-details-max-width-wrapper" >
|
||||
<div class="dupli-import-box closable opened" >
|
||||
<div class="box-title" >
|
||||
<?php esc_html_e('Disaster Recovery', 'duplicator-pro'); ?>
|
||||
<div class="badge <?php echo esc_attr($badgeClass); ?> margin-right-1">
|
||||
<?php echo esc_html($badgeLabel); ?>
|
||||
</div>
|
||||
</div>
|
||||
<div class="box-content">
|
||||
<div id="dupli-recovery-details-select-entry" class="dupli-recovery-info-set" >
|
||||
<?php
|
||||
RecoveryController::renderRecoveryWidged([
|
||||
'selector' => true,
|
||||
'subtitle' => '',
|
||||
'copyLink' => true,
|
||||
'copyButton' => true,
|
||||
'launch' => false,
|
||||
'download' => true,
|
||||
'info' => true,
|
||||
]);
|
||||
?>
|
||||
</div>
|
||||
<hr>
|
||||
|
||||
<div class="dupli-recovery-not-required">
|
||||
<i class="far fa-arrow-alt-circle-right"></i>
|
||||
<?php
|
||||
esc_html_e(
|
||||
'The Recovery Point is not mandatory to perform an import.
|
||||
However, it can assist in restoring this site if there is a problem during install.
|
||||
If you have no need to recover this site then you can continue without creating the Recovery Point.',
|
||||
'duplicator-pro'
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div><br/>
|
||||
|
||||
<div class="dupli-import-box closable opened" >
|
||||
<div class="box-title" >
|
||||
<?php esc_html_e('System Overview', 'duplicator-pro'); ?>
|
||||
</div>
|
||||
<div class="box-content">
|
||||
<div id="dupli-recovery-details-overview" >
|
||||
<div>
|
||||
<?php esc_html_e("This site currently contains", 'duplicator-pro'); ?>:
|
||||
</div>
|
||||
|
||||
<table class="margin-left-2" >
|
||||
<?php foreach ($postTypeCount as $label => $count) { ?>
|
||||
<tr>
|
||||
<td><?php echo esc_html($label); ?></td>
|
||||
<td class="text-right"><?php echo (int) $count; ?></td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
</table>
|
||||
<p>
|
||||
<?php esc_html_e("This process will:", 'duplicator-pro') ?>
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<i class="far fa-check-circle"></i>
|
||||
<?php esc_html_e("Launch the interactive installer wizard to install this new Backup.", 'duplicator-pro'); ?>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dupli-import-confirm-buttons">
|
||||
<input
|
||||
id="dupli-import-launch-installer-cancel"
|
||||
type="button" class="button secondary hollow small recovery-reset"
|
||||
value="<?php esc_attr_e('Cancel', 'duplicator-pro'); ?>"
|
||||
>
|
||||
<button
|
||||
id="dupli-import-launch-installer-confirm"
|
||||
type="button"
|
||||
class="button primary small"
|
||||
onclick="DupliJs.ImportManager.confirmLaunchInstaller();"
|
||||
>
|
||||
<i class="fa fa-bolt fa-sm"></i> <?php esc_html_e('Launch Installer', 'duplicator-pro'); ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
?>
|
||||
|
||||
<div class="dupli-tab-content-wrapper" >
|
||||
<div id="dupli-import-phase-one" >
|
||||
<?php $tplMng->render('admin_pages/import/step1/import-step1'); ?>
|
||||
</div>
|
||||
<div id="dupli-import-phase-two" class="no-display" >
|
||||
<?php $tplMng->render('admin_pages/import/import-step2'); ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
$tplMng->render('admin_pages/tools/recovery/widget/recovery-widget-scripts');
|
||||
|
||||
$tplMng->render('admin_pages/import/import-scripts');
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Controllers\SettingsPageController;
|
||||
use Duplicator\Core\Controllers\ControllersManager;
|
||||
use Duplicator\Core\Controllers\SubMenuItem;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string,mixed> $tplData
|
||||
* @var string $pageTitle
|
||||
*/
|
||||
$pageTitle = $tplData['pageTitle'];
|
||||
/** @var string */
|
||||
$templateSecondaryPart = ($tplData['templateSecondaryPart'] ?? '');
|
||||
/** @var array<string,mixed> */
|
||||
$templateSecondaryArgs = ($tplData['templateSecondaryArgs'] ?? []);
|
||||
/** @var bool $blur */
|
||||
$blur = $tplData['blur'];
|
||||
|
||||
$importSettingsUrl = $ctrlMng->getMenuLink(
|
||||
ControllersManager::SETTINGS_SUBMENU_SLUG,
|
||||
SettingsPageController::L2_SLUG_IMPORT
|
||||
);
|
||||
|
||||
$items = [];
|
||||
$item = new SubMenuItem(
|
||||
'mode-upload-tab',
|
||||
__('Import File', 'duplicator-pro'),
|
||||
'',
|
||||
true
|
||||
);
|
||||
$item->link = '';
|
||||
$item->active = true;
|
||||
$item->attributes = ['data-tab-target' => "dupli-import-upload-file-tab"];
|
||||
$items[] = $item;
|
||||
|
||||
$item = new SubMenuItem(
|
||||
'mode-remote-tab',
|
||||
__('Import Link', 'duplicator-pro'),
|
||||
'',
|
||||
true
|
||||
);
|
||||
$item->link = '';
|
||||
$item->active = false;
|
||||
$item->attributes = ['data-tab-target' => "dupli-import-remote-file-tab"];
|
||||
$items[] = $item;
|
||||
|
||||
$item = new SubMenuItem(
|
||||
'import-settings',
|
||||
__('Settings', 'duplicator-pro'),
|
||||
'',
|
||||
true
|
||||
);
|
||||
$item->link = $importSettingsUrl;
|
||||
$item->active = false;
|
||||
$items[] = $item;
|
||||
?>
|
||||
|
||||
<div class="dup-body-header">
|
||||
<h1><?php echo esc_html($pageTitle); ?></h1>
|
||||
<?php
|
||||
if (!$blur) {
|
||||
$tplMng->render('parts/tabs_menu_l2', ['menuItemsL2' => $items]);
|
||||
}
|
||||
if (strlen($templateSecondaryPart) > 0) {
|
||||
$tplMng->render($templateSecondaryPart, $templateSecondaryArgs);
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<hr class="wp-header-end margin-top-0">
|
||||
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Controllers\ImportPageController;
|
||||
use Duplicator\Models\GlobalEntity;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
if (GlobalEntity::getInstance()->import_chunk_size == 0) {
|
||||
$footerChunkInfo = sprintf(__('<b>Chunk Size:</b> N/A | <b>Max Size:</b> %s', 'duplicator-pro'), size_format(wp_max_upload_size()));
|
||||
$toolTipContent = __('If you need to upload a larger file, go to [Settings > Import] and set Upload Chunk Size', 'duplicator-pro');
|
||||
} else {
|
||||
$footerChunkInfo = sprintf(
|
||||
__(
|
||||
'<b>Chunk Size:</b> %s | <b>Max Size:</b> No Limit',
|
||||
'duplicator-pro'
|
||||
),
|
||||
size_format(ImportPageController::getChunkSize() * 1024)
|
||||
);
|
||||
$toolTipContent = __(
|
||||
'The max file size limit is ignored when chunk size is enabled.
|
||||
Use a large chunk size with fast connections and a small size with slower connections.
|
||||
You can change the chunk size by going to [Settings > Import].',
|
||||
'duplicator-pro'
|
||||
);
|
||||
}
|
||||
|
||||
/** @var string */
|
||||
$openTab = $tplData['defSubtab'];
|
||||
|
||||
$hlpUpload = __(
|
||||
'Upload speeds can be affected by different server connections and settings.
|
||||
The chunk size can also impact upload speed [Settings > Import].
|
||||
If adjusting the chunk size doesn\'t help, try these steps to manually upload the archive:',
|
||||
'duplicator-pro'
|
||||
);
|
||||
|
||||
$hlpUpload .= '<ul>' .
|
||||
'<li>' . __('1. Cancel the current upload.', 'duplicator-pro') . '</li>' .
|
||||
'<li>' . __('2. Manually upload the archive to:<br/> <i>/wp-content/duplicator-backups/imports/</i>', 'duplicator-pro') . '</li>' .
|
||||
'<li>' . __('3. Refresh the Import screen.', 'duplicator-pro') . '</li>' .
|
||||
'</ul>';
|
||||
?>
|
||||
<!-- ==============================
|
||||
DRAG/DROP AREA -->
|
||||
<div id="dupli-import-upload-tabs-wrapper" class="dupli-tabs-wrapper margin-bottom-2">
|
||||
<div
|
||||
id="dupli-import-upload-file-tab"
|
||||
class="tab-content <?php echo ($openTab == ImportPageController::L2_TAB_UPLOAD ? '' : 'no-display'); ?>">
|
||||
<div id="dupli-import-upload-file" class="dupli-import-upload-box"></div>
|
||||
<div class="no-display">
|
||||
<div id="dupli-import-upload-file-content" class="center-xy">
|
||||
<i class="fa fa-download fa-2x"></i>
|
||||
<span class="dup-drag-drop-message">
|
||||
<?php esc_html_e("Drag & Drop Backup File Here", 'duplicator-pro'); ?>
|
||||
</span>
|
||||
<input
|
||||
id="dup-import-dd-btn"
|
||||
type="button"
|
||||
class="button secondary hollow button-default dup-import-button margin-0"
|
||||
name="dupli-files"
|
||||
value="<?php esc_attr_e("Select File...", 'duplicator-pro'); ?>">
|
||||
</div>
|
||||
</div>
|
||||
<div id="dupli-import-upload-file-footer">
|
||||
<i
|
||||
class="fa-solid fa-question-circle fa-sm dark-gray-color"
|
||||
data-tooltip-title="<?php esc_html_e("Upload Chunk Size", 'duplicator-pro'); ?>"
|
||||
data-tooltip="<?php echo esc_attr($toolTipContent); ?>"></i> <?php echo wp_kses($footerChunkInfo, ['b' => []]); ?> |
|
||||
<span
|
||||
class="pointer link-style"
|
||||
data-tooltip-title="<?php esc_html_e("Improve Upload Speed", 'duplicator-pro'); ?>"
|
||||
data-tooltip="<?php echo esc_attr($hlpUpload); ?>">
|
||||
<i><?php esc_html_e('Slow Upload', 'duplicator-pro'); ?></i> <i class="fa-solid fa-question-circle fa-sm dark-gray-color"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
id="dupli-import-remote-file-tab"
|
||||
class="tab-content <?php echo ($openTab == ImportPageController::L2_TAB_REMOTE_URL ? '' : 'no-display'); ?>">
|
||||
<div class="dupli-import-upload-box">
|
||||
<div class="center-xy">
|
||||
<i class="fa fa-download fa-2x"></i>
|
||||
<span class="dup-drag-drop-message">
|
||||
<?php esc_html_e("Import From Link", 'duplicator-pro'); ?>
|
||||
</span>
|
||||
<input
|
||||
type="text"
|
||||
id="dupli-import-remote-url"
|
||||
class="inline-display margin-bottom-0"
|
||||
placeholder="<?php esc_attr_e('Enter Full URL to Archive', 'duplicator-pro'); ?>">
|
||||
<button id="dupli-import-remote-upload" type="button" class="button primary button-default dup-import-button margin-bottom-0">
|
||||
<?php esc_html_e("Upload", 'duplicator-pro'); ?>
|
||||
</button> <br />
|
||||
<small>
|
||||
<?php
|
||||
printf(
|
||||
esc_html_x(
|
||||
'For additional help visit the %1$sonline faq%2$s.',
|
||||
'%1$s and %2$s are <a> tags',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<a href="' . esc_url(DUPLICATOR_DUPLICATOR_DOCS_URL . 'how-to-handle-import-install-upload-launch-issues')
|
||||
. '" target="_blank">',
|
||||
'</a>'
|
||||
);
|
||||
?>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
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 ($tplData['adminMessageViewModeSwtich'] && !$blur) {
|
||||
$tplMng->render('admin_pages/import/step1/message-view-mode-switch');
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<div class="dupli-import-header" >
|
||||
<h2 class="title">
|
||||
<b>
|
||||
<?php printf(esc_html__("Step %s of 2: Upload Backup", 'duplicator-pro'), '<span class="red">1</span>'); ?>
|
||||
</b>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div class="dup-import-header-content-wrapper <?php echo ($blur ? 'dup-mock-blur' : ''); ?>" >
|
||||
<?php $tplMng->render('admin_pages/import/step1/add-file-area'); ?>
|
||||
<?php $tplMng->render('admin_pages/import/step1/packages-list'); ?>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
?><div class="notice notice-success is-dismissible dupli-admin-notice">
|
||||
<p>
|
||||
<?php
|
||||
printf(
|
||||
esc_html_x(
|
||||
'The mode has %1$sswitched to advanced%2$s because more backups have been detected in the import folder.',
|
||||
'%1$s and %2$s are opening and closing bold tags (<b> and </b>)',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<b>',
|
||||
'</b>'
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
?>
|
||||
<tr class="dupli-import-no-package-found">
|
||||
<td colspan="4" >
|
||||
<div class="dupli-import-no-package-found-msg">
|
||||
<b><?php esc_html_e("No archive files found!", 'duplicator-pro'); ?></b><br/><br/>
|
||||
<?php esc_html_e("Please upload a Duplicator archive.zip/daf in the area above.", 'duplicator-pro'); ?><br/>
|
||||
<?php esc_html_e("This will start the import process to overwrite the current site.", 'duplicator-pro'); ?>
|
||||
<br/><br/>
|
||||
<a href="<?php echo esc_url(DUPLICATOR_DUPLICATOR_DOCS_URL . 'import-install'); ?>" target="_blank">
|
||||
<?php esc_html_e('How does this work?', 'duplicator-pro'); ?>
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Libs\Snap\SnapString;
|
||||
use Duplicator\Package\Import\PackageImporter;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
/** @var PackageImporter $importObj */
|
||||
$importObj = $tplData['importObj'];
|
||||
|
||||
if ($importObj instanceof PackageImporter) {
|
||||
$name = $importObj->getName();
|
||||
$size = $importObj->getSize();
|
||||
$created = $importObj->getCreated();
|
||||
$archivePath = $importObj->getFullPath();
|
||||
$installPakageUrl = $importObj->getInstallerPageLink();
|
||||
$isImportable = $importObj->isImportable();
|
||||
$funcsEnalbed = true;
|
||||
} else {
|
||||
$name = '';
|
||||
$size = 0;
|
||||
$created = '';
|
||||
$archivePath = '';
|
||||
$installPakageUrl = '';
|
||||
$isImportable = false;
|
||||
$funcsEnalbed = false;
|
||||
}
|
||||
|
||||
$rowClasses = ['dupli-import-package'];
|
||||
if ($isImportable) {
|
||||
$rowClasses[] = 'is-importable';
|
||||
}
|
||||
?>
|
||||
<tr <?php echo strlen($tplData['idRow']) ? 'id="' . esc_attr($tplData['idRow']) . '" ' : ''; ?>
|
||||
class="<?php echo esc_attr(implode(' ', $rowClasses)) ?>"
|
||||
data-path="<?php echo esc_attr($archivePath); ?>">
|
||||
<td class="name">
|
||||
<span class="text"><b><?php echo esc_html($name); ?></b></span>
|
||||
<div class="dupli-import-package-detail no-display">
|
||||
<?php
|
||||
if ($funcsEnalbed) {
|
||||
$importObj->getHtmlDetails();
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</td>
|
||||
<td class="size">
|
||||
<span title="<?php printf(esc_attr__('Total %d bytes', 'duplicator-pro'), (int) $size); ?>">
|
||||
<?php echo esc_html(SnapString::byteSize($size)); ?>
|
||||
</span>
|
||||
</td>
|
||||
<td class="created">
|
||||
<?php echo esc_html($created); ?>
|
||||
</td>
|
||||
<td class="funcs">
|
||||
<div class="actions <?php echo $funcsEnalbed ? '' : 'no-display'; ?>">
|
||||
<button type="button" class="button secondary hollow margin-bottom-0 small dupli-import-action-package-detail-toggle">
|
||||
<i class="fa fa-caret-down"></i> <?php esc_html_e('Details', 'duplicator-pro'); ?>
|
||||
</button>
|
||||
<span class="separator"></span>
|
||||
<button type="button" class="dupli-import-action-remove button secondary hollow small margin-bottom-0 ">
|
||||
<i class="fa fa-ban"></i> <?php esc_html_e('Remove', 'duplicator-pro'); ?>
|
||||
</button>
|
||||
<span class="separator"></span>
|
||||
<button type="button" class="dupli-import-action-install button primary small margin-bottom-0"
|
||||
data-install-url="<?php echo esc_url($installPakageUrl); ?>"
|
||||
<?php echo $isImportable ? '' : 'disabled'; ?>>
|
||||
<i class="fa fa-bolt fa-sm"></i> <?php esc_html_e('Continue', 'duplicator-pro'); ?>
|
||||
</button>
|
||||
</div>
|
||||
<div class="invalid no-display">
|
||||
<?php esc_html_e('Backup Invalid', 'duplicator-pro'); ?>
|
||||
</div>
|
||||
<div class="dupli-loader no-display">
|
||||
<div class="dupli-meter-wrapper">
|
||||
<div class="dupli-meter green">
|
||||
<span style="width: 0%"></span>
|
||||
</div>
|
||||
<span class="text">0%</span>
|
||||
</div>
|
||||
<a href="" class="dupli-import-action-cancel-upload button secondary hollow small margin-bottom-0 button-cancel">
|
||||
<i class="fa fa-ban"></i> <?php esc_html_e('Cancel', 'duplicator-pro'); ?>
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Controllers\ImportPageController;
|
||||
use Duplicator\Package\Import\PackageImporter;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
switch ($tplData['viewMode']) {
|
||||
case ImportPageController::VIEW_MODE_ADVANCED:
|
||||
$viewModeClass = 'view-list-item';
|
||||
break;
|
||||
case ImportPageController::VIEW_MODE_BASIC:
|
||||
default:
|
||||
$viewModeClass = 'view-single-item';
|
||||
break;
|
||||
}
|
||||
|
||||
?>
|
||||
<div id="dupli-import-available-packages" class="<?php echo esc_attr($viewModeClass); ?>" >
|
||||
<table class="dup-import-avail-packs packages-list">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="name"><?php esc_html_e("Backups", 'duplicator-pro'); ?></th>
|
||||
<th class="size"><?php esc_html_e("Size", 'duplicator-pro'); ?></th>
|
||||
<th class="created"><?php esc_html_e("Created", 'duplicator-pro'); ?></th>
|
||||
<th class="funcs"><?php esc_html_e("Status", 'duplicator-pro'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php
|
||||
$importObjs = PackageImporter::getArchiveObjects();
|
||||
if (count($importObjs) === 0) {
|
||||
$tplMng->render('admin_pages/import/step1/package-row-no-found');
|
||||
} else {
|
||||
foreach ($importObjs as $importObj) {
|
||||
$tplMng->render(
|
||||
'admin_pages/import/step1/package-row',
|
||||
[
|
||||
'importObj' => $importObj,
|
||||
'idRow' => '',
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="no-display" >
|
||||
<table id="dupli-import-available-packages-templates">
|
||||
<?php
|
||||
$tplMng->render(
|
||||
'admin_pages/import/step1/package-row',
|
||||
[
|
||||
'importObj' => null,
|
||||
'idRow' => 'dupli-import-row-template',
|
||||
]
|
||||
);
|
||||
$tplMng->render('admin_pages/import/step1/package-row-no-found');
|
||||
?>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Controllers\SettingsPageController;
|
||||
use Duplicator\Core\CapMng;
|
||||
use Duplicator\Core\Controllers\ControllersManager;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
$importSettingsUrl = $ctrlMng->getMenuLink(
|
||||
ControllersManager::SETTINGS_SUBMENU_SLUG,
|
||||
SettingsPageController::L2_SLUG_IMPORT
|
||||
);
|
||||
|
||||
?>
|
||||
<div id="dupli-import-vews-and-opt-wrapper" >
|
||||
<ul class="dupli-toggle-sub-menu">
|
||||
<li>
|
||||
<span class="dupli-toggle" >
|
||||
<span class="button" >
|
||||
<i class="fas fa-bars fa-lg"></i><span class="screen-reader-text">Options</span>
|
||||
</span>
|
||||
</span>
|
||||
<ul>
|
||||
<li class="title"><?php esc_html_e('VIEWS', 'duplicator-pro'); ?></li>
|
||||
<li>
|
||||
<span class="link-style no-decoration dupli-import-view-list <?php echo $tplData['viewMode'] == 'list' ? 'active' : ''; ?>">
|
||||
<?php esc_html_e('Advanced mode', 'duplicator-pro'); ?>
|
||||
<span class="description"><?php esc_html_e('View multiple Backups', 'duplicator-pro') ?></span>
|
||||
</span>
|
||||
</li>
|
||||
<li>
|
||||
<span class="link-style no-decoration dupli-import-view-single <?php echo $tplData['viewMode'] == 'single' ? 'active' : ''; ?>">
|
||||
<?php esc_html_e('Basic mode', 'duplicator-pro') ?>
|
||||
<span class="description"><?php esc_html_e('View last uploaded Backup', 'duplicator-pro'); ?></span>
|
||||
</span>
|
||||
</li>
|
||||
<li class="title separator"><?php esc_html_e('TOOLS', 'duplicator-pro'); ?></li>
|
||||
<?php if (CapMng::can(CapMng::CAP_SETTINGS, false)) { ?>
|
||||
<li>
|
||||
<a class="no-decoration" href="<?php echo esc_url($importSettingsUrl); ?>" target="_blank">
|
||||
<?php esc_html_e('Import Settings', 'duplicator-pro'); ?>
|
||||
</a>
|
||||
<i class="fas fa-external-link-alt fa-small" ></i>
|
||||
</li>
|
||||
<?php } ?>
|
||||
<li>
|
||||
<span class="link-style no-decoration dupli-open-help-link">
|
||||
<a href="<?php echo esc_url(DUPLICATOR_DUPLICATOR_DOCS_URL . 'import-install'); ?>" target="_blank">
|
||||
<?php esc_html_e('Quick Start', 'duplicator-pro'); ?>
|
||||
</a>
|
||||
<i class="fas fa-external-link-alt fa-small" ></i>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
use Duplicator\Controllers\PackagesPageController;
|
||||
use Duplicator\Core\CapMng;
|
||||
use Duplicator\Package\AbstractPackage;
|
||||
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 \Duplicator\Package\DupPackage $package
|
||||
*/
|
||||
|
||||
$package = $tplData['package'];
|
||||
/** @var string */
|
||||
$innerPage = $tplData['currentInnerPage'];
|
||||
$enable_transfer_tab = (
|
||||
$package->getLocalPackageFilePath(AbstractPackage::FILE_TYPE_INSTALLER) !== false &&
|
||||
$package->getLocalPackageFilePath(AbstractPackage::FILE_TYPE_ARCHIVE) !== false
|
||||
);
|
||||
|
||||
$packagesListUrl = PackagesPageController::getInstance()->getMenuLink();
|
||||
$packgeDefailsUrl = PackagesPageController::getInstance()->getPackageDetailsUrl($package->getId());
|
||||
$packgeTransferUrl = PackagesPageController::getInstance()->getPackageTransferUrl($package->getId());
|
||||
?>
|
||||
<h2 class="nav-tab-wrapper">
|
||||
<a
|
||||
href="<?php echo esc_url($packgeDefailsUrl); ?>"
|
||||
class="nav-tab <?php echo ($innerPage == PackagesPageController::LIST_INNER_PAGE_DETAILS) ? 'nav-tab-active' : '' ?>">
|
||||
<?php esc_html_e('Details', 'duplicator-pro'); ?>
|
||||
</a>
|
||||
<?php if (CapMng::can(CapMng::CAP_CREATE, false)) { ?>
|
||||
<a
|
||||
href="<?php echo esc_url($packgeTransferUrl); ?>"
|
||||
class="nav-tab <?php echo ($innerPage == PackagesPageController::LIST_INNER_PAGE_TRANSFER) ? 'nav-tab-active' : '' ?>"
|
||||
<?php if ($enable_transfer_tab === false) { ?>
|
||||
onclick="DupliJs.Pack.TransferDisabled(); return false;"
|
||||
<?php } ?>>
|
||||
<?php esc_html_e('Transfer', 'duplicator-pro'); ?>
|
||||
</a>
|
||||
<?php } ?>
|
||||
</h2>
|
||||
<div class="dup-details-packages-list">
|
||||
<a href="<?php echo esc_url($packagesListUrl); ?>">[<?php esc_html_e('Backups', 'duplicator-pro'); ?>]</a>
|
||||
</div>
|
||||
|
||||
<?php if ($package->getStatus() == AbstractPackage::STATUS_ERROR) { ?>
|
||||
<div id='dupli-error' class="error">
|
||||
<p>
|
||||
<b>
|
||||
<?php
|
||||
printf(
|
||||
esc_html_x(
|
||||
'Error encountered building Backup, please review %1$sBackup log%2$s for details.',
|
||||
'1 and 2 are opening and closing anchor tags',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<a target="_blank" href="' . esc_url($package->getLogUrl()) . '">',
|
||||
'</a>'
|
||||
);
|
||||
?>
|
||||
</b>
|
||||
<br />
|
||||
<?php
|
||||
printf(
|
||||
esc_html_x(
|
||||
'For more help read the %1$sFAQ pages%2$s or submit a %3$shelp ticket%4$s.',
|
||||
'1 and 3 are opening, 2 and 4 are closing anchor/link tags',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<a target="_blank" href="' . esc_url(DUPLICATOR_TECH_FAQ_URL) . '">',
|
||||
'</a>',
|
||||
'<a target="_blank" href="' . esc_url(DUPLICATOR_BLOG_URL . 'my-account/support/') . '">',
|
||||
'</a>'
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
$alertTransferDisabled = new UiDialog();
|
||||
$alertTransferDisabled->title = __('Transfer Error', 'duplicator-pro');
|
||||
$alertTransferDisabled->message = __('No Backup in default location so transfer is disabled.', 'duplicator-pro');
|
||||
$alertTransferDisabled->initAlert();
|
||||
?>
|
||||
<script>
|
||||
DupliJs.Pack.TransferDisabled = function() {
|
||||
<?php $alertTransferDisabled->showAlert(); ?>
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,125 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Controllers\PackagesPageController;
|
||||
use Duplicator\Core\CapMng;
|
||||
use Duplicator\Core\Controllers\SubMenuItem;
|
||||
use Duplicator\Package\AbstractPackage;
|
||||
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 string $pageTitle
|
||||
*/
|
||||
$pageTitle = $tplData['pageTitle'];
|
||||
/** @var \Duplicator\Package\DupPackage $package */
|
||||
$package = $tplData['package'];
|
||||
/** @var string */
|
||||
$templateSecondaryPart = ($tplData['templateSecondaryPart'] ?? '');
|
||||
/** @var array<string,mixed> */
|
||||
$templateSecondaryArgs = ($tplData['templateSecondaryArgs'] ?? []);
|
||||
/** @var string */
|
||||
$innerPage = $tplData['currentInnerPage'];
|
||||
|
||||
|
||||
$items = [];
|
||||
$item = new SubMenuItem(
|
||||
PackagesPageController::LIST_INNER_PAGE_LIST,
|
||||
__('Backups', 'duplicator-pro'),
|
||||
'',
|
||||
true
|
||||
);
|
||||
$item->link = PackagesPageController::getInstance()->getMenuLink();
|
||||
$item->active = ($innerPage == PackagesPageController::LIST_INNER_PAGE_LIST);
|
||||
$items[] = $item;
|
||||
|
||||
$item = new SubMenuItem(
|
||||
PackagesPageController::LIST_INNER_PAGE_DETAILS,
|
||||
__('Details', 'duplicator-pro'),
|
||||
'',
|
||||
true
|
||||
);
|
||||
$item->link = PackagesPageController::getInstance()->getPackageDetailsUrl($package->getId());
|
||||
$item->active = ($innerPage == PackagesPageController::LIST_INNER_PAGE_DETAILS);
|
||||
$items[] = $item;
|
||||
|
||||
$item = new SubMenuItem(
|
||||
PackagesPageController::LIST_INNER_PAGE_TRANSFER,
|
||||
__('Transfer', 'duplicator-pro'),
|
||||
'',
|
||||
CapMng::can(CapMng::CAP_CREATE, false)
|
||||
);
|
||||
$item->link = PackagesPageController::getInstance()->getPackageTransferUrl($package->getId());
|
||||
$item->active = ($innerPage == PackagesPageController::LIST_INNER_PAGE_TRANSFER);
|
||||
$items[] = $item;
|
||||
?>
|
||||
|
||||
<div class="dup-body-header">
|
||||
<?php
|
||||
$tplMng->render('parts/tabs_menu_l2', ['menuItemsL2' => $items]);
|
||||
|
||||
if (strlen($templateSecondaryPart) > 0) {
|
||||
$tplMng->render($templateSecondaryPart, $templateSecondaryArgs);
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<hr class="wp-header-end margin-top-0">
|
||||
|
||||
<h1>
|
||||
<?php echo esc_html($pageTitle); ?>
|
||||
</h1>
|
||||
<?php if ($package->getStatus() == AbstractPackage::STATUS_ERROR) { ?>
|
||||
<div id='dupli-error' class="error">
|
||||
<p>
|
||||
<b>
|
||||
<?php
|
||||
printf(
|
||||
esc_html_x(
|
||||
'Error encountered building Backup, please review %1$sBackup log%2$s for details.',
|
||||
'1 and 2 are opening and closing anchor tags',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<a target="_blank" href="' . esc_url($package->getLogUrl()) . '">',
|
||||
'</a>'
|
||||
);
|
||||
?>
|
||||
</b>
|
||||
<br />
|
||||
<?php
|
||||
printf(
|
||||
esc_html_x(
|
||||
'For more help read the %1$sFAQ pages%2$s or submit a %3$shelp ticket%4$s.',
|
||||
'1 and 3 are opening, 2 and 4 are closing anchor/link tags',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<a target="_blank" href="' . esc_url(DUPLICATOR_TECH_FAQ_URL) . '">',
|
||||
'</a>',
|
||||
'<a target="_blank" href="' . esc_url(DUPLICATOR_BLOG_URL . 'my-account/support/') . '">',
|
||||
'</a>'
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
$alertTransferDisabled = new UiDialog();
|
||||
$alertTransferDisabled->title = __('Transfer Error', 'duplicator-pro');
|
||||
$alertTransferDisabled->message = __('No Backup in default location so transfer is disabled.', 'duplicator-pro');
|
||||
$alertTransferDisabled->initAlert();
|
||||
?>
|
||||
<script>
|
||||
DupliJs.Pack.TransferDisabled = function() {
|
||||
<?php $alertTransferDisabled->showAlert(); ?>
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
?>
|
||||
<br/><br/>
|
||||
<div id='dupli-error' class="error">
|
||||
<p>
|
||||
<?php echo sprintf(
|
||||
esc_html__(
|
||||
"Unable to find Backup id %d. The Backup does not exist or was deleted.",
|
||||
'duplicator-pro'
|
||||
),
|
||||
esc_html($tplData['packageId'])
|
||||
); ?>
|
||||
<br/>
|
||||
</p>
|
||||
</div>
|
||||
@@ -0,0 +1,454 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
use Duplicator\Controllers\StoragePageController;
|
||||
use Duplicator\Core\CapMng;
|
||||
use Duplicator\Libs\Snap\SnapString;
|
||||
use Duplicator\Models\Storages\AbstractStorageEntity;
|
||||
use Duplicator\Models\Storages\StoragesUtil;
|
||||
use Duplicator\Package\AbstractPackage;
|
||||
use Duplicator\Views\UI\UiDialog;
|
||||
use Duplicator\Views\UI\UiViewState;
|
||||
|
||||
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'];
|
||||
/** @var \Duplicator\Package\DupPackage */
|
||||
$package = $tplData['package'];
|
||||
$storage_list = AbstractStorageEntity::getAll(0, 0, [StoragesUtil::class, 'sortByPriority']);
|
||||
|
||||
$newStorageEditUrl = StoragePageController::getEditUrl();
|
||||
|
||||
$transfer_occurring = (
|
||||
($package->getStatus() >= AbstractPackage::STATUS_STORAGE_PROCESSING) &&
|
||||
($package->getStatus() < AbstractPackage::STATUS_COMPLETE)
|
||||
);
|
||||
|
||||
$view_state = UiViewState::getArray();
|
||||
$ui_css_transfer_log = (isset($view_state['dup-transfer-transfer-log']) && $view_state['dup-transfer-transfer-log']) ? 'display:block' : 'display:none';
|
||||
|
||||
$installer_name = $package->Installer->getInstallerName();
|
||||
$archive_name = $package->Archive->getFileName();
|
||||
|
||||
?>
|
||||
<div class="transfer-panel <?php echo ($blur ? 'dup-mock-blur' : ''); ?>">
|
||||
<div class="transfer-hdr">
|
||||
<h2 class="title">
|
||||
<i class="fas fa-exchange-alt"></i> <?php esc_html_e('Manual Transfer', 'duplicator-pro'); ?>
|
||||
<button id="dup-trans-ovr" type="button" class="dup-btn-borderless"
|
||||
title="<?php esc_html_e('Show file details', 'duplicator-pro'); ?>"
|
||||
onclick="DupliJs.Pack.Transfer.toggleOverview()">
|
||||
<i class="fas fa-chevron-left fa-fw fa-sm"></i> <?php esc_html_e('Details', 'duplicator-pro') ?>
|
||||
</button>
|
||||
</h2>
|
||||
<hr />
|
||||
</div>
|
||||
|
||||
<!-- ===================
|
||||
OVERVIEW -->
|
||||
<div id="step1-ovr">
|
||||
<h3><?php esc_html_e('File Overview', 'duplicator-pro'); ?></h3>
|
||||
<small>
|
||||
<?php esc_html_e('These files will be transferred to the selected storage locations. Links are sensitive. Keep them safe!', 'duplicator-pro'); ?>
|
||||
</small>
|
||||
<label>
|
||||
<i class="far fa-file-archive fa-fw"></i>
|
||||
<b><?php esc_html_e('Backup File', 'duplicator-pro'); ?></b>
|
||||
<?php echo ' (' . esc_html(SnapString::byteSize($package->Archive->Size)) . ')'; ?><br />
|
||||
<div class="horizontal-input-row">
|
||||
<input class="margin-right-1" type="text" value="<?php echo esc_attr($archive_name) ?>" readonly="readonly" />
|
||||
<span onclick="jQuery(this).parent().find('input').select();">
|
||||
<span class="copy-button" data-dup-copy-value="<?php echo esc_attr($archive_name); ?>">
|
||||
<i class='far fa-copy dup-cursor-pointer'></i> <?php esc_html_e('Copy Name', 'duplicator-pro'); ?>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<label>
|
||||
<i class="fa fa-bolt fa-fw"></i>
|
||||
<b><?php esc_html_e('Backup Installer', 'duplicator-pro'); ?></b>
|
||||
<?php echo ' (' . esc_html(SnapString::byteSize($package->Installer->Size)) . ')'; ?><br />
|
||||
<div class="horizontal-input-row">
|
||||
<input class="margin-right-1" type="text" value="<?php echo esc_attr($installer_name) ?>" readonly="readonly" />
|
||||
<span onclick="jQuery(this).parent().find('input').select();">
|
||||
<span class="copy-button" data-dup-copy-value="<?php echo esc_attr($installer_name); ?>">
|
||||
<i class='far fa-copy dup-cursor-pointer'></i> <?php esc_html_e('Copy Name', 'duplicator-pro'); ?>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<!-- ===================
|
||||
STEP 1 -->
|
||||
<div id="step2-section">
|
||||
<div style="margin:0px 0 0px 0">
|
||||
<h3><?php esc_html_e('Step 1: Choose Location', 'duplicator-pro') ?></h3>
|
||||
<input style="display:none" type="radio" name="location" id="location-storage" checked="checked" onclick="DupliJs.Pack.Transfer.ToggleLocation()" />
|
||||
<label style="display:none" for="location-storage"><?php esc_html_e('Storage', 'duplicator-pro'); ?></label>
|
||||
<input style="display:none" type="radio" name="location" id="location-quick" onclick="DupliJs.Pack.Transfer.ToggleLocation()" />
|
||||
<label style="display:none" for="location-quick"><?php esc_html_e('Quick FTP Connect', 'duplicator-pro'); ?></label>
|
||||
</div>
|
||||
|
||||
<!-- STEP 1: STORAGE -->
|
||||
<div id="location-storage-opts">
|
||||
<?php $tplMng->render(
|
||||
'parts/storage/select_list',
|
||||
['filteredStorageIds' => [StoragesUtil::getDefaultStorageId()]]
|
||||
); ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===================
|
||||
STEP 2 -->
|
||||
<div id="step3-section">
|
||||
<h3>
|
||||
<?php esc_html_e('Step 2: Transfer Files', 'duplicator-pro') ?>
|
||||
<button style="<?php echo ($transfer_occurring ? 'none' : 'default'); ?>"
|
||||
id="dupli-transfer-btn" type="button"
|
||||
class="button primary small"
|
||||
onclick="DupliJs.Pack.Transfer.StartTransfer();">
|
||||
<?php esc_attr_e('Start Transfer', 'duplicator-pro') ?> <i class="fas fa-upload"></i>
|
||||
|
||||
</button>
|
||||
</h3>
|
||||
|
||||
<div style="width:700px; text-align: center; margin-left: auto; margin-right: auto" class="dupli-active-status-area">
|
||||
<div style="display:none; font-size:20px; font-weight:bold" id="dupli-progress-bar-percent"></div>
|
||||
<div style="font-size:14px" id="dupli-progress-bar-text"><?php esc_html_e('Processing', 'duplicator-pro') ?></div>
|
||||
<div id="dupli-progress-bar-percent-help">
|
||||
<small><?php esc_html_e('Full Backup percentage shown on Backups screen', 'duplicator-pro'); ?></small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dupli-progress-bar-container">
|
||||
<div id="dupli-progress-bar-area" class="dupli-active-status-area">
|
||||
<div class="dupli-meter-wrapper">
|
||||
<div class="dupli-meter green dupli-fullsize">
|
||||
<span></span>
|
||||
</div>
|
||||
<span class="text"></span>
|
||||
</div>
|
||||
<button disabled id="dupli-stop-transfer-btn" type="button" class="button primary dupli-btn-stop" value=""
|
||||
onclick="DupliJs.Pack.Transfer.StopBuild();">
|
||||
<i class="fa fa-times fa-sm"></i> <?php esc_html_e('Stop Transfer', 'duplicator-pro'); ?>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ===============================
|
||||
TRANSFER LOG -->
|
||||
<div class="dup-box">
|
||||
<div class="dup-box-title">
|
||||
<i class="fas fa-file-contract fa-fw fa-sm"></i>
|
||||
<?php esc_html_e('Transfer Log', 'duplicator-pro') ?>
|
||||
<button class="dup-box-arrow">
|
||||
<span class="screen-reader-text">
|
||||
<?php esc_html_e('Toggle panel:', 'duplicator-pro') ?> <?php esc_html_e('Transfer Log', 'duplicator-pro') ?>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="dup-box-panel" id="dup-transfer-transfer-log" style="<?php echo esc_attr($ui_css_transfer_log) ?>">
|
||||
<table class="widefat package-tbl dup-table-list small">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style='width:150px'><?php esc_html_e('Started', 'duplicator-pro') ?></th>
|
||||
<th style='width:150px'><?php esc_html_e('Stopped', 'duplicator-pro') ?></th>
|
||||
<th style="white-space: nowrap"><?php esc_html_e('Status', 'duplicator-pro') ?></th>
|
||||
<th style="white-space: nowrap"><?php esc_html_e('Type', 'duplicator-pro') ?></th>
|
||||
<th style="width: 60%; white-space: nowrap"><?php esc_html_e('Description', 'duplicator-pro') ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="5" id="dup-pack-details-trans-log-count"></td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<?php
|
||||
$alert1 = new UiDialog();
|
||||
$alert1->title = __('Storage Warning!', 'duplicator-pro');
|
||||
$alert1->message = __('At least one storage location must be selected.', 'duplicator-pro');
|
||||
$alert1->initAlert();
|
||||
|
||||
$alert2 = new UiDialog();
|
||||
$alert2->title = __('Transfer Failure!', 'duplicator-pro');
|
||||
$alert2->message = __('Transfer failure when calling duplicator_manual_transfer_storage.', 'duplicator-pro');
|
||||
$alert2->initAlert();
|
||||
|
||||
$alert3 = new UiDialog();
|
||||
$alert3->title = __('Build Error', 'duplicator-pro');
|
||||
$alert3->message = __('Failed to stop build', 'duplicator-pro');
|
||||
$alert3->initAlert();
|
||||
|
||||
$alert4 = new UiDialog();
|
||||
$alert4->title = $alert3->title;
|
||||
$alert4->message = __('Failed to stop build due to AJAX error.', 'duplicator-pro');
|
||||
$alert4->initAlert();
|
||||
|
||||
$alert5 = new UiDialog();
|
||||
$alert5->title = __('An error occurred', 'duplicator-pro');
|
||||
$alert5->message = ''; // javascript inserted message
|
||||
$alert5->initAlert();
|
||||
|
||||
$alert6 = new UiDialog();
|
||||
$alert6->title = __('INFO!', 'duplicator-pro');
|
||||
$alert6->message = ''; // javascript inserted message
|
||||
$alert6->initAlert();
|
||||
?>
|
||||
<script>
|
||||
DupliJs.Pack.Transfer = {};
|
||||
jQuery(document).ready(function($) {
|
||||
|
||||
var transferRequestedTimestamp = 0;
|
||||
var activePackageId = -1;
|
||||
|
||||
DupliJs.Pack.Transfer.toggleOverview = function() {
|
||||
$('div#step1-ovr').toggle();
|
||||
var $i = $('#dup-trans-ovr i');
|
||||
|
||||
if ($($i).hasClass('fa-chevron-left')) {
|
||||
$($i).removeClass('fa-chevron-left').addClass('fa-chevron-down');
|
||||
} else {
|
||||
$($i).removeClass('fa-chevron-down').addClass('fa-chevron-left');
|
||||
}
|
||||
}
|
||||
|
||||
DupliJs.Pack.Transfer.GetTimeStamp = function() {
|
||||
return Math.floor(Date.now() / 1000);
|
||||
}
|
||||
|
||||
/* METHOD: Starts the data transfer */
|
||||
DupliJs.Pack.Transfer.StartTransfer = function() {
|
||||
|
||||
if (jQuery('#location-storage-opts input[type=checkbox]:checked').length == 0) {
|
||||
<?php $alert1->showAlert(); ?>
|
||||
} else {
|
||||
$(".dupli-active-status-area").show(500);
|
||||
var selected_storage_ids = $.map($(':checkbox[name=_storage_ids\\[\\]]:checked'), function(n, i) {
|
||||
return n.value;
|
||||
});
|
||||
|
||||
console.log("sending to selected storages " + selected_storage_ids);
|
||||
|
||||
transferRequestedTimestamp = DupliJs.Pack.Transfer.GetTimeStamp();
|
||||
|
||||
$("#dupli-progress-bar-text").text("<?php echo esc_html__('Initiating transfer. Please wait.', 'duplicator-pro') ?>");
|
||||
$("#dupli-progress-bar-percent").text('');
|
||||
DupliJs.Pack.Transfer.SetUIState(true);
|
||||
|
||||
var data = {
|
||||
action: 'duplicator_manual_transfer_storage',
|
||||
package_id: <?php echo (int) $package->getId(); ?>,
|
||||
storage_ids: selected_storage_ids,
|
||||
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_manual_transfer_storage')); ?>'
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: ajaxurl,
|
||||
cache: false,
|
||||
timeout: 10000000,
|
||||
data: data,
|
||||
success: function(parsedData) {
|
||||
if (!parsedData.success) {
|
||||
if (parsedData.data && parsedData.data.message && parsedData.data.message !== '') {
|
||||
<?php $alert5->showAlert(); ?>
|
||||
$("#<?php echo esc_js($alert5->getID()); ?>_message").html(parsedData.data.message);
|
||||
}
|
||||
transferRequestedTimestamp = 0;
|
||||
DupliJs.Pack.Transfer.SetUIState(false);
|
||||
DupliJs.Pack.Transfer.GetPackageState();
|
||||
}
|
||||
},
|
||||
error: function(respData) {
|
||||
<?php $alert2->showAlert(); ?>
|
||||
transferRequestedTimestamp = 0;
|
||||
DupliJs.Pack.Transfer.SetUIState(false);
|
||||
console.log(respData);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/* METHOD: Starts the data transfer */
|
||||
DupliJs.Pack.Transfer.StopBuild = function() {
|
||||
$("#dupli-stop-transfer-btn").prop("disabled", true);
|
||||
|
||||
DupliJs.Util.ajaxWrapper({
|
||||
action: 'duplicator_package_stop_build',
|
||||
package_id: activePackageId,
|
||||
nonce: '<?php echo esc_js(wp_create_nonce("duplicator_package_stop_build")); ?>'
|
||||
},
|
||||
function(result, data, funcData, textStatus, jqXHR) {
|
||||
if (!funcData.success) {
|
||||
<?php $alert3->showAlert(); ?>
|
||||
$("#dupli-stop-transfer-btn").prop("disabled", false);
|
||||
}
|
||||
DupliJs.addAdminMessage(
|
||||
"<?php esc_html_e('Backups transfer cancellation was initiated.', 'duplicator-pro'); ?>",
|
||||
'notice', {
|
||||
hideDelay: 3000
|
||||
}
|
||||
);
|
||||
console.log(funcData.message);
|
||||
return '';
|
||||
},
|
||||
function(result, data, funcData, textStatus, jqXHR) {
|
||||
<?php $alert4->showAlert(); ?>
|
||||
$("#dupli-stop-transfer-btn").prop("disabled", false);
|
||||
return '';
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/* METHOD: Progress bar display state*/
|
||||
DupliJs.Pack.Transfer.SetUIState = function(activeProcessing) {
|
||||
if (activeProcessing) {
|
||||
$(".dupli-active-status-area").show(500);
|
||||
$("#dupli-transfer-btn").hide();
|
||||
$("#location-storage input").prop("disabled", true);
|
||||
//$("#location-storage-opts input").prop("disabled", true);
|
||||
} else {
|
||||
$("#dupli-stop-transfer-btn").prop("disabled", true);
|
||||
// Only allow to revert after enough time has past since the last transfer request
|
||||
currentTimestamp = DupliJs.Pack.Transfer.GetTimeStamp();
|
||||
if ((currentTimestamp - transferRequestedTimestamp) > 10) {
|
||||
$("#location-storage input").prop("disabled", false);
|
||||
//$("#location-storage-opts input").prop("disabled", false);
|
||||
$("#dupli-transfer-btn").show();
|
||||
$(".dupli-active-status-area").hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* METHOD: Retreive Backup state */
|
||||
DupliJs.Pack.Transfer.GetPackageState = function() {
|
||||
var package_id = <?php echo (int) $package->getId(); ?>;
|
||||
DupliJs.Util.ajaxWrapper({
|
||||
action: 'duplicator_packages_details_transfer_get_package_vm',
|
||||
package_id: package_id,
|
||||
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_packages_details_transfer_get_package_vm')); ?>'
|
||||
},
|
||||
function(result, data, funcData, textStatus, jqXHR) {
|
||||
var vm = funcData.vm;
|
||||
|
||||
// vm - view model for this screen
|
||||
// vm.active_package_id: Active Backup id (-1 for none)
|
||||
// vm.percent_text: Percent through the current transfer
|
||||
// vm.text: Text to display
|
||||
// vm.transfer_logs: array of transfer request vms (start, stop, status, message)
|
||||
|
||||
if (activePackageId != vm.active_package_id) {
|
||||
// Once we have an active Backup ID allow the stop button to be clicked
|
||||
$("#dupli-stop-transfer-btn").prop("disabled", false);
|
||||
}
|
||||
|
||||
activePackageId = vm.active_package_id;
|
||||
if (vm.active_package_id == -1) {
|
||||
// No backups are running
|
||||
DupliJs.Pack.Transfer.SetUIState(false);
|
||||
|
||||
} else if (vm.active_package_id == package_id) {
|
||||
|
||||
// This Backup is running
|
||||
if (vm.percent_text != '') {
|
||||
$("#dupli-progress-bar-percent").text(vm.percent_text);
|
||||
} else {
|
||||
$("#dupli-progress-bar-percent").text('');
|
||||
}
|
||||
|
||||
$("#dupli-progress-bar-text").html(vm.text);
|
||||
DupliJs.Pack.Transfer.SetUIState(true);
|
||||
} else {
|
||||
|
||||
// A package other than this one is running
|
||||
$("#dupli-progress-bar-text").html(vm.text);
|
||||
DupliJs.Pack.Transfer.SetUIState(true);
|
||||
}
|
||||
DupliJs.Pack.Transfer.UpdateTransferLog(vm);
|
||||
},
|
||||
function(result, data, funcData, textStatus, jqXHR) {
|
||||
if (data.message != '') {
|
||||
<?php $alert6->showAlert(); ?>
|
||||
$("#<?php echo esc_js($alert6->getID()); ?>_message").html(data.message);
|
||||
}
|
||||
DupliJs.Pack.Transfer.SetUIState(false);
|
||||
console.log(data);
|
||||
}, {
|
||||
showProgress: false
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/* METHOD: Updates the transfer log with the information from the view model */
|
||||
DupliJs.Pack.Transfer.UpdateTransferLog = function(vm) {
|
||||
$("#dup-transfer-transfer-log table tbody").empty();
|
||||
var row_style, row_html;
|
||||
for (var i = 0; i < vm.transfer_logs.length; i++) {
|
||||
|
||||
var transfer_log = vm.transfer_logs[i];
|
||||
console.log(transfer_log);
|
||||
|
||||
row_style = (i % 2) ? ' alternate' : '';
|
||||
switch (transfer_log.status_text) {
|
||||
case 'Pending':
|
||||
row_style += ' status-pending';
|
||||
break;
|
||||
case 'Running':
|
||||
row_style += ' status-running';
|
||||
break;
|
||||
case 'Failed':
|
||||
row_style += ' status-failed';
|
||||
break;
|
||||
default:
|
||||
row_style += ' status-normal';
|
||||
break;
|
||||
}
|
||||
|
||||
row_html =
|
||||
`<tr class="package-row ${row_style}">
|
||||
<td>${transfer_log.started}</td>
|
||||
<td>${transfer_log.stopped}</td>
|
||||
<td>${transfer_log.status_text}</td>
|
||||
<td>${transfer_log.storage_type_text}</td>
|
||||
<td>${transfer_log.message}</td>
|
||||
</tr>`;
|
||||
|
||||
$("#dup-transfer-transfer-log table tbody").append(row_html);
|
||||
$('#dup-pack-details-trans-log-count').html('<?php esc_html_e('Log Items:', 'duplicator-pro') ?> ' + (i + 1));
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
var row_html = '<tr><td colspan="5" style="text-align:center">' +
|
||||
'<?php esc_html_e('- No transactions found for this Backup -', 'duplicator-pro'); ?></td></tr>';
|
||||
$("#dup-transfer-transfer-log table tbody").append(row_html);
|
||||
}
|
||||
};
|
||||
|
||||
//INIT
|
||||
DupliJs.Pack.Transfer.GetPackageState();
|
||||
setInterval(DupliJs.Pack.Transfer.GetPackageState, 8000);
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
defined('ABSPATH') || exit;
|
||||
|
||||
use Duplicator\Controllers\PackagesPageController;
|
||||
use Duplicator\Core\Views\TplMng;
|
||||
use Duplicator\Core\Views\Notifications;
|
||||
use Duplicator\Models\GlobalEntity;
|
||||
use Duplicator\Models\SystemGlobalEntity;
|
||||
use Duplicator\Package\AbstractPackage;
|
||||
use Duplicator\Package\DupPackage;
|
||||
use Duplicator\Package\PackageUtils;
|
||||
use Duplicator\Views\PackageListTable;
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var bool $blur
|
||||
*/
|
||||
|
||||
$tplMng = TplMng::getInstance();
|
||||
$system_global = SystemGlobalEntity::getInstance();
|
||||
|
||||
// Filter out failed backups (status < 0) from the main backup list
|
||||
$statusConditions = [
|
||||
[
|
||||
'op' => '>=',
|
||||
'status' => 0,
|
||||
],
|
||||
];
|
||||
|
||||
$totalElements = PackageUtils::getNumPackages([DupPackage::getBackupType()], $statusConditions);
|
||||
$statusActive = DupPackage::isPackageRunning();
|
||||
$activePackage = DupPackage::getNextActive();
|
||||
$isTransfer = $activePackage === null ? false : $activePackage->getStatus() == AbstractPackage::STATUS_STORAGE_PROCESSING;
|
||||
|
||||
$pager = new PackageListTable();
|
||||
$perPage = $pager->get_per_page();
|
||||
$currentPage = $statusActive && !$isTransfer ? 1 : $pager->get_pagenum();
|
||||
$offset = ($currentPage - 1) * $perPage;
|
||||
|
||||
$global = GlobalEntity::getInstance();
|
||||
|
||||
do_action('duplicator_before_packages_table_action');
|
||||
?>
|
||||
|
||||
<form
|
||||
id="form-duplicator"
|
||||
method="post"
|
||||
class="<?php echo esc_attr($tplData['blur'] ? 'dup-mock-blur' : ''); ?>">
|
||||
<?php PackagesPageController::getInstance()
|
||||
->getActionByKey(PackagesPageController::ACTION_STOP_BUILD)->getActionNonceFileds(); ?>
|
||||
<input type="hidden" id="stop-backup-id" name="stop-backup-id" />
|
||||
<?php $tplMng->render('admin_pages/packages/toolbar'); ?>
|
||||
|
||||
<table class="widefat dup-table-list dup-packtbl striped" aria-label="Backup List">
|
||||
<?php
|
||||
$tplMng->render(
|
||||
'admin_pages/packages/packages_table_head',
|
||||
['totalElements' => $totalElements]
|
||||
);
|
||||
|
||||
if ($totalElements == 0) {
|
||||
$tplMng->render('admin_pages/packages/no_elements_row');
|
||||
} else {
|
||||
DupPackage::dbSelectByStatusCallback(
|
||||
function (DupPackage $package): void {
|
||||
TplMng::getInstance()->render(
|
||||
'admin_pages/packages/package_row',
|
||||
['package' => $package]
|
||||
);
|
||||
},
|
||||
$statusConditions,
|
||||
$perPage,
|
||||
$offset,
|
||||
'`id` DESC',
|
||||
[
|
||||
PackageUtils::DEFAULT_BACKUP_TYPE,
|
||||
]
|
||||
);
|
||||
}
|
||||
$tplMng->render(
|
||||
'admin_pages/packages/packages_table_foot',
|
||||
['totalElements' => $totalElements]
|
||||
); ?>
|
||||
</table>
|
||||
</form>
|
||||
|
||||
<?php if ($totalElements > $perPage) { ?>
|
||||
<form id="form-duplicator-nav" method="post">
|
||||
<div class="dup-paged-nav tablenav">
|
||||
<?php if ($statusActive > 0) : ?>
|
||||
<div id="dupli-paged-progress" style="padding-right: 10px">
|
||||
<i class="fas fa-circle-notch fa-spin fa-lg fa-fw"></i>
|
||||
<i><?php esc_html_e('Paging disabled during build...', 'duplicator-pro'); ?></i>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div id="dupli-paged-buttons">
|
||||
<?php $pager->display_pagination($totalElements, $perPage); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</form>
|
||||
<?php } else { ?>
|
||||
<div style="float:right; padding:10px 5px">
|
||||
<?php echo esc_html(sprintf(_n('%s item', '%s items', $totalElements, 'duplicator-pro'), $totalElements)); ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
$tplMng->render(
|
||||
'admin_pages/packages/packages_scripts',
|
||||
[
|
||||
'perPage' => $perPage,
|
||||
'offset' => $offset,
|
||||
'currentPage' => $currentPage,
|
||||
'stattiBackupType' => DupPackage::getBackupType(),
|
||||
]
|
||||
);
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator Backup row in table Backups list
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
?>
|
||||
<tr class="dupli-nopackages">
|
||||
<td colspan="11" class="dup-list-nopackages">
|
||||
<br />
|
||||
<i class="fa fa-archive fa-sm"></i>
|
||||
<?php esc_html_e("No Backups Found", 'duplicator-pro'); ?><br />
|
||||
<i><?php esc_html_e("Click 'Add New' to Backup Site", 'duplicator-pro'); ?></i>
|
||||
<div class="dup-quick-start">
|
||||
<b><?php esc_html_e("New to Duplicator?", 'duplicator-pro'); ?></b><br />
|
||||
<a
|
||||
class="dup-quick-start-link"
|
||||
href="<?php echo esc_url(DUPLICATOR_BLOG_URL . 'knowledge-base-article-categories/quick-start/'); ?>"
|
||||
target="_blank">
|
||||
<?php esc_html_e("Visit the 'Quick Start' guide!", 'duplicator-pro'); ?>
|
||||
</a>
|
||||
</div>
|
||||
<div style="height:75px"> </div>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator Backup row in table Backups list
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Controllers\PackagesPageController;
|
||||
use Duplicator\Core\CapMng;
|
||||
use Duplicator\Package\DupPackage;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
*/
|
||||
|
||||
if ($tplMng->getDataValueBoolRequired('blur')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$disableCreate = DupPackage::isPackageRunning() || DupPackage::isPackageCancelling();
|
||||
|
||||
if (CapMng::can(CapMng::CAP_CREATE, false)) {
|
||||
$tipContent = __(
|
||||
'Create a new backup. If a backup is currently running then this button will be disabled.',
|
||||
'duplicator-pro'
|
||||
);
|
||||
?>
|
||||
<span
|
||||
class="dup-new-package-wrapper"
|
||||
data-tooltip="<?php echo esc_attr($tipContent); ?>">
|
||||
<a
|
||||
href="<?php echo esc_url(PackagesPageController::getInstance()->getPackageBuildS1Url()); ?>"
|
||||
id="dupli-create-new"
|
||||
class="button primary tiny font-bold margin-bottom-0 <?php echo $disableCreate ? 'disabled' : ''; ?>">
|
||||
<b><?php esc_html_e('Add New', 'duplicator-pro'); ?></b>
|
||||
</a>
|
||||
</span>
|
||||
<?php
|
||||
}
|
||||
do_action('duplicator_backups_page_header_after');
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
use Duplicator\Package\AbstractPackage;
|
||||
use Duplicator\Package\DupPackage;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
*/
|
||||
$package = $tplMng->getDataValueObjRequired('package', DupPackage::class);
|
||||
$pendingCancelIds = $tplMng->getDataValueArray('pending_cancelled_package_ids');
|
||||
|
||||
// If its in the pending cancels consider it stopped
|
||||
if (in_array($package->getId(), $pendingCancelIds)) {
|
||||
$status = AbstractPackage::STATUS_PENDING_CANCEL;
|
||||
} else {
|
||||
$status = $package->getStatus();
|
||||
}
|
||||
|
||||
if ($package->getStatus() >= AbstractPackage::STATUS_COMPLETE) {
|
||||
$tplMng->render('admin_pages/packages/package_row_complete', ['status' => $status]);
|
||||
} else {
|
||||
$tplMng->render('admin_pages/packages/package_row_incomplete', ['status' => $status]);
|
||||
}
|
||||
$tplMng->render('admin_pages/packages/package_row_building', ['status' => $status]);
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
use Duplicator\Core\CapMng;
|
||||
use Duplicator\Package\AbstractPackage;
|
||||
use Duplicator\Package\DupPackage;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var ?DupPackage $package
|
||||
*/
|
||||
$package = $tplData['package'];
|
||||
|
||||
/** @var int */
|
||||
$status = $tplData['status'];
|
||||
|
||||
if ($status <= AbstractPackage::STATUS_PRE_PROCESS || $status >= AbstractPackage::STATUS_COMPLETE) {
|
||||
return;
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<?php
|
||||
$progress = $package->getProgress();
|
||||
$packageId = (int) $package->getId();
|
||||
?>
|
||||
<tr class="dup-row-progress" data-package-id="<?php echo (int) $packageId; ?>">
|
||||
<td colspan="11">
|
||||
<div class="wp-filter dup-build-msg">
|
||||
<!-- PROGRESS -->
|
||||
<div class="dupli-progress-status-message">
|
||||
<div class="status-hdr">
|
||||
<span class="phase-name-<?php echo (int) $packageId; ?>">
|
||||
<?php echo esc_html($progress['phaseName']); ?>
|
||||
</span>
|
||||
<i class="fa fa-gear fa-sm fa-spin"></i>
|
||||
<span class="status-progress-<?php echo (int) $packageId; ?>">
|
||||
<?php
|
||||
if ($progress['percent'] > 0) {
|
||||
echo (float) round($progress['percent'], 1) . '%';
|
||||
}
|
||||
?>
|
||||
</span>
|
||||
<span class="status-<?php echo (int) $packageId; ?> no-display">
|
||||
<?php echo (int) $status; ?>
|
||||
</span>
|
||||
</div>
|
||||
<small class="xsmall phase-message-<?php echo (int) $packageId; ?>">
|
||||
<?php echo esc_html($progress['message']); ?>
|
||||
</small>
|
||||
</div>
|
||||
<div class="dup-progress-bar-area">
|
||||
<div class="dupli-meter-wrapper">
|
||||
<div class="dupli-meter green dupli-fullsize">
|
||||
<span></span>
|
||||
</div>
|
||||
<span class="text"></span>
|
||||
</div>
|
||||
</div>
|
||||
<?php if (CapMng::can(CapMng::CAP_CREATE, false)) { ?>
|
||||
<button
|
||||
onclick="DupliJs.Pack.StopBuild(<?php echo (int) $package->getId(); ?>); return false;"
|
||||
class="button hollow secondary small dup-build-stop-btn display-inline">
|
||||
<i class="fa fa-times fa-sm"></i>
|
||||
<?php
|
||||
if ($status >= AbstractPackage::STATUS_STORAGE_PROCESSING) {
|
||||
esc_html_e('Stop Transfer', 'duplicator-pro');
|
||||
} elseif ($status > AbstractPackage::STATUS_PRE_PROCESS) {
|
||||
esc_html_e('Stop Build', 'duplicator-pro');
|
||||
} else {
|
||||
esc_html_e('Cancel Pending', 'duplicator-pro');
|
||||
}
|
||||
?>
|
||||
</button>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
use Duplicator\Controllers\PackagesPageController;
|
||||
use Duplicator\Libs\Snap\SnapString;
|
||||
use Duplicator\Package\AbstractPackage;
|
||||
use Duplicator\Package\PackageUtils;
|
||||
use Duplicator\Package\Recovery\RecoveryPackage;
|
||||
use Duplicator\Views\UserUIOptions;
|
||||
use Duplicator\Models\GlobalEntity;
|
||||
use Duplicator\Package\DupPackage;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var ?DupPackage $package
|
||||
*/
|
||||
$package = $tplData['package'];
|
||||
|
||||
/** @var int */
|
||||
$status = $tplData['status'];
|
||||
|
||||
if ($status < AbstractPackage::STATUS_COMPLETE) {
|
||||
return;
|
||||
}
|
||||
|
||||
$global = GlobalEntity::getInstance();
|
||||
$isRecoverable = RecoveryPackage::isPackageIdRecoverable($package->getId());
|
||||
$isRecoverPoint = (RecoveryPackage::getRecoverPackageId() === $package->getId());
|
||||
$pack_name = $package->getName();
|
||||
$pack_archive_size = $package->Archive->Size;
|
||||
$pack_dbonly = $package->isDBOnly();
|
||||
$brand = $package->Brand;
|
||||
|
||||
//Links
|
||||
$uniqueid = $package->getNameHash();
|
||||
$archive_exists = ($package->getLocalPackageFilePath(AbstractPackage::FILE_TYPE_ARCHIVE) != false);
|
||||
$installer_exists = ($package->getLocalPackageFilePath(AbstractPackage::FILE_TYPE_INSTALLER) != false);
|
||||
$progress_error = '';
|
||||
|
||||
//ROW CSS
|
||||
$rowClasses = [''];
|
||||
$rowClasses[] = 'dup-row';
|
||||
$rowClasses[] = 'dup-row-complete';
|
||||
$rowClasses[] = ($isRecoverPoint) ? 'dup-recovery-package' : '';
|
||||
$rowCSS = trim(implode(' ', $rowClasses));
|
||||
|
||||
|
||||
//ArchiveInfo
|
||||
$archive_name = $package->Archive->getFileName();
|
||||
$archiveDownloadURL = $package->getLocalPackageFileURL(AbstractPackage::FILE_TYPE_ARCHIVE);
|
||||
$installerDownloadURL = $package->getLocalPackageFileURL(AbstractPackage::FILE_TYPE_INSTALLER);
|
||||
$installerFullName = $package->Installer->getInstallerName();
|
||||
$isBackupAvailable = ($package->haveRemoteStorage() || $package->haveLocalStorage());
|
||||
|
||||
//Lang Values
|
||||
$txt_DatabaseOnly = __('Database Only', 'duplicator-pro');
|
||||
$txt_BackupNotAvailable = __('Backup doesn\'t exist', 'duplicator-pro');
|
||||
|
||||
switch ($package->getExecutionType()) {
|
||||
case DupPackage::EXEC_TYPE_MANUAL:
|
||||
$package_type_string = __('Manual', 'duplicator-pro');
|
||||
break;
|
||||
case DupPackage::EXEC_TYPE_SCHEDULED:
|
||||
$package_type_string = __('Schedule', 'duplicator-pro');
|
||||
break;
|
||||
case DupPackage::EXEC_TYPE_RUN_NOW:
|
||||
$lang_schedule = __('Schedule', 'duplicator-pro');
|
||||
$lang_title = __('This Backup was started manually from the schedules page.', 'duplicator-pro');
|
||||
$package_type_string = "{$lang_schedule}<span><sup> <i class='fas fa-cog fa-sm pointer' title='{$lang_title}'></i> </sup><span>";
|
||||
break;
|
||||
default:
|
||||
$package_type_string = __('Unknown', 'duplicator-pro');
|
||||
break;
|
||||
}
|
||||
|
||||
$packageDetailsURL = PackagesPageController::getInstance()->getPackageDetailsURL($package->getId());
|
||||
$createdFormat = UserUIOptions::getInstance()->get(UserUIOptions::VAL_CREATED_DATE_FORMAT);
|
||||
|
||||
?>
|
||||
<tr
|
||||
id="dup-row-pack-id-<?php echo (int) $package->getId(); ?>"
|
||||
data-package-id="<?php echo (int) $package->getId(); ?>"
|
||||
class="<?php echo esc_attr($rowCSS); ?>">
|
||||
<td class="dup-check-column dup-cell-chk">
|
||||
<label for="<?php echo (int) $package->getId(); ?>">
|
||||
<input
|
||||
name="delete_confirm"
|
||||
type="checkbox"
|
||||
id="<?php echo (int) $package->getId(); ?>"
|
||||
data-archive-name="<?php echo esc_attr($archive_name); ?>"
|
||||
data-installer-name="<?php echo esc_attr($installerFullName); ?>" />
|
||||
</label>
|
||||
</td>
|
||||
<td class="dup-name-column dup-cell-name">
|
||||
<?php echo esc_html($pack_name); ?>
|
||||
</td>
|
||||
<td class="dup-note-column">
|
||||
<?php echo esc_html($package->notes); ?>
|
||||
</td>
|
||||
<td class="dup-storages-column">
|
||||
</td>
|
||||
<td class="dup-flags-column">
|
||||
<?php $tplMng->render('admin_pages/packages/row_parts/falgs_cell'); ?>
|
||||
</td>
|
||||
<td class="dup-size-column">
|
||||
<?php echo esc_html(SnapString::byteSize($pack_archive_size)); ?>
|
||||
</td>
|
||||
<td class="dup-created-column">
|
||||
<?php echo esc_html(PackageUtils::formatLocalDateTime($package->getCreated(), $createdFormat)); ?>
|
||||
</td>
|
||||
<td class="dup-age-column">
|
||||
<?php echo esc_html($package->getPackageLife('human')); ?>
|
||||
</td>
|
||||
<td class="dup-cell-btns dup-download-column" <?php echo $isBackupAvailable ? '' : 'data-tooltip="' . esc_attr($txt_BackupNotAvailable) . '"'; ?>>
|
||||
<?php $tplMng->render('admin_pages/packages/row_parts/download_buttons'); ?>
|
||||
</td>
|
||||
<td class="dup-cell-btns dup-restore-column" <?php echo $isBackupAvailable ? '' : 'data-tooltip="' . esc_attr($txt_BackupNotAvailable) . '"'; ?>>
|
||||
<?php $tplMng->render('admin_pages/packages/row_parts/restore_backup_button'); ?>
|
||||
</td>
|
||||
<td class="dup-cell-btns dup-cell-toggle-btn dup-toggle-details dup-details-column">
|
||||
<span class="full-cell-button link-style">
|
||||
<i class="fa-solid fa-plus"></i>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="dup-row-pack-id-<?php echo (int) $package->getId(); ?>-details" class="dup-row-details no-display">
|
||||
<?php $tplMng->render('admin_pages/packages/row_parts/details_package'); ?>
|
||||
</tr>
|
||||
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
use Duplicator\Controllers\PackagesPageController;
|
||||
use Duplicator\Package\AbstractPackage;
|
||||
use Duplicator\Package\PackageUtils;
|
||||
use Duplicator\Package\Recovery\RecoveryPackage;
|
||||
use Duplicator\Views\UserUIOptions;
|
||||
use Duplicator\Models\GlobalEntity;
|
||||
use Duplicator\Package\DupPackage;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var ?DupPackage $package
|
||||
*/
|
||||
$package = $tplData['package'];
|
||||
$global = GlobalEntity::getInstance();
|
||||
|
||||
/** @var int */
|
||||
$status = $tplData['status'];
|
||||
|
||||
if ($status >= AbstractPackage::STATUS_COMPLETE) {
|
||||
return;
|
||||
}
|
||||
|
||||
$isRecoverable = RecoveryPackage::isPackageIdRecoverable($package->getId());
|
||||
$isRecoverPoint = (RecoveryPackage::getRecoverPackageId() === $package->getId());
|
||||
$pack_name = $package->getName();
|
||||
$pack_archive_size = $package->Archive->Size;
|
||||
$pack_namehash = $package->getNameHash();
|
||||
$pack_dbonly = $package->isDBOnly();
|
||||
$brand = $package->Brand;
|
||||
|
||||
//Links
|
||||
$uniqueid = $package->getNameHash();
|
||||
$archive_exists = ($package->getLocalPackageFilePath(AbstractPackage::FILE_TYPE_ARCHIVE) != false);
|
||||
$installer_exists = ($package->getLocalPackageFilePath(AbstractPackage::FILE_TYPE_INSTALLER) != false);
|
||||
$progress_error = '';
|
||||
|
||||
//ROW CSS
|
||||
$rowClasses = [''];
|
||||
$rowClasses[] = 'dup-row';
|
||||
$rowClasses[] = 'dup-row-incomplete';
|
||||
$rowClasses[] = ($isRecoverPoint) ? 'dup-recovery-package' : '';
|
||||
$rowCSS = trim(implode(' ', $rowClasses));
|
||||
|
||||
//ArchiveInfo
|
||||
$archive_name = $package->Archive->getFileName();
|
||||
$archiveDownloadURL = $package->getLocalPackageFileURL(AbstractPackage::FILE_TYPE_ARCHIVE);
|
||||
$installerDownloadURL = $package->getLocalPackageFileURL(AbstractPackage::FILE_TYPE_INSTALLER);
|
||||
$installerFullName = $package->Installer->getInstallerName();
|
||||
|
||||
$createdFormat = UserUIOptions::getInstance()->get(UserUIOptions::VAL_CREATED_DATE_FORMAT);
|
||||
|
||||
//Lang Values
|
||||
$txt_DatabaseOnly = __('Database Only', 'duplicator-pro');
|
||||
|
||||
$cellErrCSS = '';
|
||||
|
||||
if ($status < AbstractPackage::STATUS_COPIEDPACKAGE) {
|
||||
// In the process of building
|
||||
$size = 0;
|
||||
$tmpSearch = glob(DUPLICATOR_SSDIR_PATH_TMP . "/{$pack_namehash}_*");
|
||||
|
||||
if (is_array($tmpSearch)) {
|
||||
$result = @array_map('filesize', $tmpSearch);
|
||||
$size = array_sum($result);
|
||||
}
|
||||
$pack_archive_size = $size;
|
||||
}
|
||||
|
||||
if ($status < 0) {
|
||||
//FAILURES AND CANCELLATIONS
|
||||
switch ($status) {
|
||||
case AbstractPackage::STATUS_ERROR:
|
||||
$cellErrCSS = 'dup-cell-err';
|
||||
break;
|
||||
case AbstractPackage::STATUS_BUILD_CANCELLED:
|
||||
case AbstractPackage::STATUS_STORAGE_CANCELLED:
|
||||
$cellErrCSS = 'dup-cell-cancelled';
|
||||
break;
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
<tr
|
||||
id="dup-row-pack-id-<?php echo (int) $package->getId(); ?>"
|
||||
data-package-id="<?php echo (int) $package->getId(); ?>"
|
||||
data-status="<?php echo (int) $status; ?>"
|
||||
class="<?php echo esc_attr($rowCSS); ?>">
|
||||
<td class="dup-check-column dup-cell-chk">
|
||||
<label for="<?php echo (int) $package->getId(); ?>">
|
||||
<input name="delete_confirm"
|
||||
type="checkbox" id="<?php echo (int) $package->getId(); ?>"
|
||||
<?php echo ($status >= AbstractPackage::STATUS_PRE_PROCESS) ? 'disabled="disabled"' : ''; ?> />
|
||||
</label>
|
||||
</td>
|
||||
<td class="dup-name-column dup-cell-name">
|
||||
<?php echo esc_html($pack_name); ?>
|
||||
</td>
|
||||
<td class="dup-note-column">
|
||||
</td>
|
||||
<td class="dup-storages-column">
|
||||
</td>
|
||||
<td class="dup-flags-column">
|
||||
<?php $tplMng->render('admin_pages/packages/row_parts/falgs_cell'); ?>
|
||||
</td>
|
||||
<td class="dup-size-column">
|
||||
<?php if ($status >= AbstractPackage::STATUS_PRE_PROCESS) {
|
||||
echo esc_html($package->getBuildSize());
|
||||
} else {
|
||||
esc_html_e('N/A', 'duplicator-pro');
|
||||
} ?>
|
||||
</td>
|
||||
<td class="dup-created-column">
|
||||
<?php echo esc_html(PackageUtils::formatLocalDateTime($package->getCreated(), $createdFormat)); ?>
|
||||
</td>
|
||||
<td class="dup-age-column">
|
||||
<?php echo esc_html($package->getPackageLife('human')); ?>
|
||||
</td>
|
||||
<td class="dup-cell-incomplete <?php echo esc_attr($cellErrCSS); ?> no-select" colspan="3">
|
||||
<?php if ($status >= AbstractPackage::STATUS_PRE_PROCESS) { ?>
|
||||
<i><?php esc_html_e('Creating Backup ...', 'duplicator-pro'); ?></i>
|
||||
<?php } else {
|
||||
$tplMng->render(
|
||||
'admin_pages/packages/row_parts/package_progress_error',
|
||||
[
|
||||
'package' => $package,
|
||||
'status' => $status,
|
||||
]
|
||||
);
|
||||
} ?>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -0,0 +1,677 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator Backup row in table Backups list
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
use Duplicator\Controllers\PackagesPageController;
|
||||
use Duplicator\Controllers\StoragePageController;
|
||||
use Duplicator\Controllers\ToolsPageController;
|
||||
use Duplicator\Core\Controllers\ControllersManager;
|
||||
use Duplicator\Libs\Snap\SnapJson;
|
||||
use Duplicator\Views\UI\UiDialog;
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
$perPage = $tplMng->getDataValueInt('perPage', 10);
|
||||
$offset = $tplMng->getDataValueInt('offset', 0);
|
||||
$currentPage = $tplMng->getDataValueInt('currentPage', 1);
|
||||
$statiiType = $tplMng->getDataValueStringRequired('stattiBackupType');
|
||||
|
||||
$tplMng->render('admin_pages/tools/recovery/widget/recovery-widget-scripts');
|
||||
$tplMng->render('admin_pages/packages/remote_download/scripts');
|
||||
|
||||
$transferBaseUrl = PackagesPageController::getInstance()->getPackageTransferUrl();
|
||||
$reloadPackagesURL = $ctrlMng->getCurrentLink(
|
||||
['paged' => $currentPage]
|
||||
);
|
||||
|
||||
/* ------------------------------------------
|
||||
* ALERT: Remote > Storage items */
|
||||
$remoteDlg = new UiDialog();
|
||||
$remoteDlg->width = 750;
|
||||
$remoteDlg->height = 475;
|
||||
$remoteDlg->title = __('Storage Locations', 'duplicator-pro');
|
||||
$remoteDlg->message = __('Loading. Please Wait...', 'duplicator-pro');
|
||||
$remoteDlg->boxClass = 'dup-packs-remote-store-dlg';
|
||||
$remoteDlg->initAlert();
|
||||
|
||||
/* ------------------------------------------
|
||||
* ALERT: Bulk action > no selection */
|
||||
$alert1 = new UiDialog();
|
||||
$alert1->title = __('Bulk Action Required', 'duplicator-pro');
|
||||
$alert1->templatePath = 'parts/dialogs/contents/bulk-action-not-selected';
|
||||
$alert1->initAlert();
|
||||
|
||||
/* ------------------------------------------
|
||||
* ALERT: Bulk action > no backup selected */
|
||||
$alert2 = new UiDialog();
|
||||
$alert2->title = __('Selection Required', 'duplicator-pro');
|
||||
$alert2->wrapperClassButtons = 'dupli-dlg-nopackage-sel-bulk-action-btns';
|
||||
$alert2->templatePath = 'parts/dialogs/contents/bulk-action-delete-not-selected';
|
||||
$alert2->initAlert();
|
||||
|
||||
/* ------------------------------------------
|
||||
* ALERT: Process > Error undefined */
|
||||
$alert4 = new UiDialog();
|
||||
$alert4->title = __('ERROR!', 'duplicator-pro');
|
||||
$alert4->message = __('Got an error or a warning: undefined', 'duplicator-pro');
|
||||
$alert4->initAlert();
|
||||
|
||||
/* ------------------------------------------
|
||||
* ALERT: Process > Error no details */
|
||||
$alert5 = new UiDialog();
|
||||
$alert5->title = $alert4->title;
|
||||
$alert5->message = __('Failed to get details.', 'duplicator-pro');
|
||||
$alert5->initAlert();
|
||||
|
||||
/* ------------------------------------------
|
||||
* CONFIRM: Delete Backups? */
|
||||
$confirm1 = new UiDialog();
|
||||
$confirm1->height = 280;
|
||||
$confirm1->title = __('Delete Backups?', 'duplicator-pro');
|
||||
$confirm1->wrapperClassButtons = 'dupli-dlg-detete-packages-btns';
|
||||
$confirm1->message = __('Are you sure you want to delete the selected Backup(s)?', 'duplicator-pro');
|
||||
$confirm1->message .= '<br/><br/>';
|
||||
$confirm1->message .= '<small><i>' . __(
|
||||
'Note: This action removes only Backups located on this server. If a remote Backup was created then it will not be removed or affected.',
|
||||
'duplicator-pro'
|
||||
) . '</i></small>';
|
||||
$confirm1->progressText = __('Removing Backups, Please Wait...', 'duplicator-pro');
|
||||
$confirm1->jsCallback = 'DupliJs.Pack.Delete()';
|
||||
$confirm1->initConfirm();
|
||||
|
||||
/* ------------------------------------------
|
||||
* ALERT: Recovery > toolbar button */
|
||||
$toolBarRecoveryButtonInfo = new UiDialog();
|
||||
$toolBarRecoveryButtonInfo->showButtons = false;
|
||||
$toolBarRecoveryButtonInfo->height = 600;
|
||||
$toolBarRecoveryButtonInfo->width = 600;
|
||||
$toolBarRecoveryButtonInfo->title = __('Disaster Recovery', 'duplicator-pro');
|
||||
$toolBarRecoveryButtonInfo->templatePath = 'admin_pages/packages/recovery_info/info';
|
||||
$toolBarRecoveryButtonInfo->initAlert();
|
||||
|
||||
/* ------------------------------------------
|
||||
* ALERT: Recovery */
|
||||
$availableRecoveryBox = new UiDialog();
|
||||
$availableRecoveryBox->title = __('Disaster Recovery Available', 'duplicator-pro');
|
||||
$availableRecoveryBox->boxClass = 'dup-recovery-box-info';
|
||||
$availableRecoveryBox->showButtons = false;
|
||||
$availableRecoveryBox->width = 600;
|
||||
$availableRecoveryBox->height = 400;
|
||||
$availableRecoveryBox->message = '';
|
||||
$availableRecoveryBox->initAlert();
|
||||
|
||||
$unavailableRecoveryBox = new UiDialog();
|
||||
$unavailableRecoveryBox->title = __('Disaster Recovery Unavailable', 'duplicator-pro');
|
||||
$unavailableRecoveryBox->boxClass = 'dup-recovery-box-info';
|
||||
$unavailableRecoveryBox->showButtons = false;
|
||||
$unavailableRecoveryBox->width = 600;
|
||||
$unavailableRecoveryBox->height = 700;
|
||||
$unavailableRecoveryBox->message = '';
|
||||
$unavailableRecoveryBox->initAlert();
|
||||
|
||||
/* ------------------------------------------
|
||||
* ALERT: Package overeview > Help */
|
||||
$linkInfoDlg = new UiDialog();
|
||||
$linkInfoDlg->width = 700;
|
||||
$linkInfoDlg->height = 550;
|
||||
$linkInfoDlg->title = __('Duplicator Pro Tutorial', 'duplicator-pro');
|
||||
$linkInfoDlg->templatePath = 'admin_pages/packages/packages_overview_help';
|
||||
$linkInfoDlg->initAlert();
|
||||
|
||||
$baseStorageEditURL = StoragePageController::getInstance()->getMenuLink(
|
||||
null,
|
||||
null,
|
||||
[
|
||||
ControllersManager::QUERY_STRING_INNER_PAGE => StoragePageController::INNER_PAGE_EDIT,
|
||||
]
|
||||
);
|
||||
?>
|
||||
<script>
|
||||
jQuery(document).ready(function($) {
|
||||
|
||||
DupliJs.Pack.RestorePackageId = null;
|
||||
DupliJs.PackagesTable = $('.dup-packtbl');
|
||||
|
||||
/**
|
||||
* Click event to expands each row and show Backup details
|
||||
*
|
||||
* @returns void
|
||||
*/
|
||||
$('th#dup-header-chkall').on('click', function() {
|
||||
var $this = $(this);
|
||||
var $icon = $this.find('i');
|
||||
if ($icon.hasClass('fa-plus')) {
|
||||
$icon.removeClass('fa-plus').addClass('fa-minus');
|
||||
$("tr.dup-row-complete").each(function() {
|
||||
$(this).find('.dup-cell-toggle-btn i').removeClass('fa-plus').addClass('fa-minus');
|
||||
$(this).next('tr').removeClass('no-display');
|
||||
});
|
||||
} else {
|
||||
$icon.removeClass('fa-minus').addClass('fa-plus');
|
||||
$("tr.dup-row-complete").each(function() {
|
||||
$(this).find('.dup-cell-toggle-btn i').removeClass('fa-minus').addClass('fa-plus');
|
||||
$(this).next('tr').addClass('no-display');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Click event to expands each row and show Backup details
|
||||
*
|
||||
* @returns void
|
||||
*/
|
||||
$('td.dup-cell-toggle-btn').on('click', function(e) {
|
||||
var $this = $(this);
|
||||
var $icon = $this.find('i');
|
||||
if ($icon.hasClass('fa-plus')) {
|
||||
$icon.removeClass('fa-plus').addClass('fa-minus');
|
||||
$(this).closest('tr').next('tr').removeClass('no-display');
|
||||
} else {
|
||||
$icon.removeClass('fa-minus').addClass('fa-plus');
|
||||
$(this).closest('tr').next('tr').addClass('no-display');
|
||||
}
|
||||
});
|
||||
|
||||
$('.dupli-quick-fix-notice').on('click', '.dupli-quick-fix', function() {
|
||||
var $this = $(this),
|
||||
params = JSON.parse($this.attr('data-param')),
|
||||
toggle = $this.attr('data-toggle'),
|
||||
id = $this.attr('data-id'),
|
||||
fix = $(toggle),
|
||||
button = {
|
||||
loading: function() {
|
||||
$this.prop('disabled', true)
|
||||
.addClass('disabled')
|
||||
.html('<i class="fas fa-circle-notch fa-spin fa-fw"></i> <?php esc_html_e('Please Wait...', 'duplicator-pro') ?>');
|
||||
},
|
||||
reset: function() {
|
||||
$this.prop('disabled', false)
|
||||
.removeClass('disabled')
|
||||
.html("<i class='fa fa-wrench' aria-hidden='true'></i> <?php esc_html_e('Resolve This', 'duplicator-pro') ?>");
|
||||
}
|
||||
},
|
||||
error = {
|
||||
message: function(text) {
|
||||
fix.append(
|
||||
" <span style='color:#cc0000' id='" +
|
||||
toggle.replace('#', '') +
|
||||
"-error'><i class='fa fa-exclamation-triangle'></i> " + text + "</span>"
|
||||
);
|
||||
},
|
||||
remove: function() {
|
||||
if ($(toggle + "-error"))
|
||||
$(toggle + "-error").remove();
|
||||
}
|
||||
};
|
||||
|
||||
error.remove();
|
||||
button.loading();
|
||||
|
||||
DupliJs.Util.ajaxWrapper({
|
||||
action: 'duplicator_quick_fix',
|
||||
setup: params,
|
||||
id: id,
|
||||
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_quick_fix')); ?>'
|
||||
},
|
||||
function(result, data, funcData, textStatus, jqXHR) {
|
||||
if (funcData.success) {
|
||||
fix.remove();
|
||||
|
||||
// If there is no fixes and notifications - remove container
|
||||
if (typeof funcData.recommended_fixes != 'undefined') {
|
||||
if (funcData.recommended_fixes == 0) {
|
||||
$('.dupli-quick-fix-notice').remove();
|
||||
}
|
||||
}
|
||||
|
||||
DupliJs.addAdminMessage(
|
||||
"<?php esc_html_e('Successfully applied quick fix!', 'duplicator-pro'); ?>",
|
||||
'success', {
|
||||
hideDelay: 5000
|
||||
}
|
||||
);
|
||||
} else {
|
||||
button.reset();
|
||||
error.message(funcData.message);
|
||||
}
|
||||
return '';
|
||||
},
|
||||
function(result, data, funcData, textStatus, jqXHR) {
|
||||
button.reset();
|
||||
error.message('<?php esc_html_e('Unexpected Error!', 'duplicator-pro') ?>');
|
||||
console.log(data);
|
||||
return '';
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$('.dupli-toolbar-recovery-info').click(function() {
|
||||
if ($(this).hasClass('dup-recovery-unset')) {
|
||||
<?php $toolBarRecoveryButtonInfo->showAlert(); ?>
|
||||
} else {
|
||||
let openUrl = <?php echo json_encode($ctrlMng->getMenuLink($ctrlMng::TOOLS_SUBMENU_SLUG, ToolsPageController::L2_SLUG_RECOVERY)); ?>;
|
||||
window.open(openUrl, "_self");
|
||||
}
|
||||
});
|
||||
|
||||
//DOWNLOAD MENU
|
||||
$('button.dup-dnload-btn').click(function(e) {
|
||||
var $menu = $(this).parent().find('nav.dup-dnload-menu-items');
|
||||
|
||||
if ($menu.is(':visible')) {
|
||||
$menu.addClass('no-display');
|
||||
} else {
|
||||
$('nav.dup-dnload-menu-items').addClass('no-display');
|
||||
$menu.removeClass('no-display');
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
$(document).click(function(e) {
|
||||
var className = e.target.className;
|
||||
if (className != 'dupli-menu-x') {
|
||||
$('nav.dup-dnload-menu-items').addClass('no-display');
|
||||
}
|
||||
});
|
||||
|
||||
$("nav.dup-dnload-menu-items button").each(function() {
|
||||
$(this).addClass('dupli-menu-x');
|
||||
});
|
||||
$("nav.dup-dnload-menu-items button span").each(function() {
|
||||
$(this).addClass('dupli-menu-x');
|
||||
});
|
||||
|
||||
/* Creats a comma seperate list of all selected Backup ids */
|
||||
DupliJs.Pack.GetDeleteList = function() {
|
||||
var arr = [];
|
||||
$("input[name=delete_confirm]:checked").each(function() {
|
||||
arr.push(this.id);
|
||||
});
|
||||
return arr;
|
||||
}
|
||||
|
||||
DupliJs.Pack.BackupRestore = function() {
|
||||
DupliJs.Util.ajaxWrapper({
|
||||
action: 'duplicator_restore_backup_prepare',
|
||||
packageId: DupliJs.Pack.RestorePackageId,
|
||||
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_restore_backup_prepare')); ?>'
|
||||
},
|
||||
function(result, data, funcData, textStatus, jqXHR) {
|
||||
window.location.href = data.funcData;
|
||||
},
|
||||
function(result, data, funcData, textStatus, jqXHR) {
|
||||
alert('FAIL');
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
/* Provides the correct confirmation items when deleting Backups */
|
||||
DupliJs.Pack.ConfirmDelete = function() {
|
||||
$('#dupli-dlg-confirm-delete-btns input').removeAttr('disabled');
|
||||
if ($("#dup-pack-bulk-actions").val() != "delete") {
|
||||
<?php $alert1->showAlert(); ?>
|
||||
return;
|
||||
}
|
||||
|
||||
var list = DupliJs.Pack.GetDeleteList();
|
||||
if (list.length == 0) {
|
||||
<?php $alert2->showAlert(); ?>
|
||||
return;
|
||||
}
|
||||
<?php $confirm1->showConfirm(); ?>
|
||||
}
|
||||
|
||||
/* Removes all selected Backup sets with ajax call */
|
||||
DupliJs.Pack.Delete = function() {
|
||||
var packageIds = DupliJs.Pack.GetDeleteList();
|
||||
var pageCount = $('#current-page-selector').val();
|
||||
var pageItems = $('input[name="delete_confirm"]');
|
||||
|
||||
DupliJs.Util.ajaxWrapper({
|
||||
action: 'duplicator_package_delete',
|
||||
package_ids: packageIds,
|
||||
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_package_delete')); ?>'
|
||||
},
|
||||
function(result, data, funcData, textStatus, jqXHR) {
|
||||
//Increment back a page-set if no items are left
|
||||
if ($('#form-duplicator-nav').length) {
|
||||
if (pageItems.length == packageIds.length)
|
||||
$('#current-page-selector').val(pageCount - 1);
|
||||
$('#form-duplicator-nav').submit();
|
||||
} else {
|
||||
window.location.reload();
|
||||
}
|
||||
return '';
|
||||
},
|
||||
function(result, data, funcData, textStatus, jqXHR) {
|
||||
DupliJs.addAdminMessage(okMsgContent, 'notice');
|
||||
return '';
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/* Toogles the Bulk Action Check boxes */
|
||||
DupliJs.Pack.SetDeleteAll = function() {
|
||||
var state = $('input#dup-chk-all').is(':checked') ? 1 : 0;
|
||||
$("input[name=delete_confirm]").each(function() {
|
||||
this.checked = (state) ? true : false;
|
||||
});
|
||||
}
|
||||
|
||||
/* Stops the build from running */
|
||||
DupliJs.Pack.StopBuild = function(packageID) {
|
||||
$('#stop-backup-id').val(packageID);
|
||||
$('#form-duplicator').submit();
|
||||
|
||||
$('.dup-build-stop-btn').html('<?php esc_html_e("Cancelling...", 'duplicator-pro'); ?>');
|
||||
$('.dup-build-stop-btn').prop('disabled', true);
|
||||
}
|
||||
|
||||
/* Redirects to the Backups detail screen using the Backup id */
|
||||
DupliJs.Pack.OpenPackTransfer = function(id) {
|
||||
window.location.href = '<?php echo esc_url_raw(SnapJson::jsonEncode($transferBaseUrl)) ?>' + '&id=' + id;
|
||||
}
|
||||
|
||||
/* Shows remote storage location dialogs */
|
||||
DupliJs.Pack.ShowRemote = function(package_id, name) {
|
||||
<?php $remoteDlg->showAlert(); ?>
|
||||
|
||||
DupliJs.Util.ajaxWrapper({
|
||||
action: 'duplicator_get_storage_details',
|
||||
package_id: package_id,
|
||||
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_get_storage_details')); ?>'
|
||||
},
|
||||
function(result, data, funcData, textStatus, jqXHR) {
|
||||
if (!funcData.success) {
|
||||
var text = "<?php esc_html_e('Got an error or a warning', 'duplicator-pro'); ?>: " + funcData.message;
|
||||
$('#TB_window .dupli-dlg-alert-txt').html(text);
|
||||
return false;
|
||||
}
|
||||
|
||||
var info = '<div class="dup-dlg-store-remote">';
|
||||
for (storage_provider_key in funcData.storage_providers) {
|
||||
var store = funcData.storage_providers[storage_provider_key];
|
||||
info += store.infoHTML;
|
||||
}
|
||||
info += '</div>';
|
||||
info += "<small><a href='" + funcData.logURL + "' class='dup-dlg-store-log-link' target='_blank'>" +
|
||||
'<?php echo esc_html__('[Backup Build Log]', 'duplicator-pro'); ?>' + "</a></small>";
|
||||
$('#TB_window .dupli-dlg-alert-txt').html(info);
|
||||
},
|
||||
function(data) {
|
||||
<?php $alert5->showAlert(); ?>
|
||||
console.log(data);
|
||||
return '';
|
||||
}
|
||||
);
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
$('.dup-restore-backup').click(function(event) {
|
||||
event.preventDefault();
|
||||
|
||||
let packageId = $(this).data('package-id');
|
||||
if ($(this).data('needs-download') == true) {
|
||||
DupliJs.Pack.ShowRemoteDownloadOptions(packageId, 'restore');
|
||||
} else {
|
||||
DupliJs.Pack.ShowRestoreModal(packageId);
|
||||
}
|
||||
});
|
||||
|
||||
$('.dup-remote-download').click(function(event) {
|
||||
event.preventDefault();
|
||||
let packageId = $(this).data('package-id');
|
||||
DupliJs.Pack.ShowRemoteDownloadOptions(packageId, 'download');
|
||||
});
|
||||
|
||||
DupliJs.Pack.ShowRestoreModal = function(packageId) {
|
||||
DupliJs.Util.ajaxWrapper({
|
||||
action: 'duplicator_backup_redirect',
|
||||
packageId: packageId,
|
||||
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_backup_redirect')); ?>'
|
||||
},
|
||||
function(result, data, funcData, textStatus, jqXHR) {
|
||||
if (funcData.success) {
|
||||
let box = new DuplicatorModalBox({
|
||||
url: data.funcData.redirect_url,
|
||||
openCallback: function(iframe, modalObj) {
|
||||
let body = $(iframe.contentWindow.document.body);
|
||||
// For old Backups
|
||||
body.find("#content").css('background-color', 'white');
|
||||
|
||||
body.on("click", "#s1-deploy-btn", function() {
|
||||
modalObj.disableClose();
|
||||
});
|
||||
}
|
||||
});
|
||||
box.open();
|
||||
//window.location.href = data.funcData.redirect_url;
|
||||
} else {
|
||||
DupliJs.addAdminMessage(funcData.message, 'error');
|
||||
}
|
||||
return '';
|
||||
},
|
||||
function(data) {
|
||||
<?php $alert5->showAlert(); ?>
|
||||
console.log(data);
|
||||
return '';
|
||||
}
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
<?php if (isset($tplData['triggerRestore']) && $tplData['triggerRestore'] !== -1) : ?>
|
||||
setTimeout(function() {
|
||||
DupliJs.Pack.ShowRestoreModal(<?php echo (int) $tplData['triggerRestore']; ?>);
|
||||
}, 500);
|
||||
<?php endif; ?>
|
||||
|
||||
/* Virtual states that UI uses for easier tracking of the three general states a Backup can be in*/
|
||||
DupliJs.Pack.ProcessingStats = {
|
||||
PendingCancellation: -3,
|
||||
Pending: 0,
|
||||
Building: 1,
|
||||
Storing: 2,
|
||||
Finished: 3,
|
||||
}
|
||||
|
||||
DupliJs.Pack.setIntervalID = -1;
|
||||
|
||||
DupliJs.Pack.SetUpdateInterval = function(period) {
|
||||
if (DupliJs.Pack.setIntervalID != -1) {
|
||||
clearInterval(DupliJs.Pack.setIntervalID);
|
||||
DupliJs.Pack.setIntervalID = -1
|
||||
}
|
||||
DupliJs.Pack.setIntervalID = setInterval(DupliJs.Pack.UpdateUnfinishedPackages, period * 1000);
|
||||
}
|
||||
|
||||
DupliJs.Pack.UpdateUnfinishedPackages = function() {
|
||||
let packagesTables = $('.dup-packtbl');
|
||||
|
||||
var data = {
|
||||
action: 'duplicator_get_package_statii',
|
||||
nonce: '<?php echo esc_js(wp_create_nonce("duplicator_get_package_statii")); ?>',
|
||||
offset: <?php echo (int) $offset; ?>,
|
||||
limit: <?php echo (int) $perPage; ?>,
|
||||
backupType: '<?php echo esc_js($statiiType); ?>',
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: ajaxurl,
|
||||
timeout: 10000000,
|
||||
data: data,
|
||||
complete: function() {},
|
||||
success: function(result) {
|
||||
let packagesTable = $('.dup-packtbl');
|
||||
let currentFirstPackageId = -1;
|
||||
let statiiFistPackageId = -1;
|
||||
if (packagesTables.find('.dup-row').length) {
|
||||
currentFirstPackageId = packagesTables.find('.dup-row').first().data('package-id');
|
||||
}
|
||||
|
||||
let statusInfo = result.data.funcData;
|
||||
if (statusInfo.length) {
|
||||
statiiFistPackageId = statusInfo[0].ID;
|
||||
}
|
||||
|
||||
if (currentFirstPackageId != statiiFistPackageId) {
|
||||
window.location = <?php echo wp_json_encode($reloadPackagesURL); ?>;
|
||||
}
|
||||
|
||||
let activePackagePresent = false;
|
||||
|
||||
for (package_info_key in statusInfo) {
|
||||
let package_info = statusInfo[package_info_key];
|
||||
let statusNode = packagesTable.find('.status-' + package_info.ID);
|
||||
let sizeNode = packagesTable.find('#dup-row-pack-id-' + package_info.ID + ' .dup-size-column');
|
||||
let packageNode = packagesTable.find('#dup-row-pack-id-' + package_info.ID);
|
||||
let currentStatus = parseInt(packageNode.data('status'));
|
||||
|
||||
if ((currentStatus >= 0 && currentStatus < 100) || currentStatus == -3) {
|
||||
activePackagePresent = true;
|
||||
}
|
||||
|
||||
let currentProcessingState;
|
||||
if (currentStatus == -3) {
|
||||
currentProcessingState = DupliJs.Pack.ProcessingStats.PendingCancellation;
|
||||
} else if (currentStatus == 0) {
|
||||
currentProcessingState = DupliJs.Pack.ProcessingStats.Pending;
|
||||
} else if ((currentStatus >= 0) && (currentStatus < 75)) {
|
||||
currentProcessingState = DupliJs.Pack.ProcessingStats.Building;
|
||||
} else if ((currentStatus >= 75) && (currentStatus < 100)) {
|
||||
currentProcessingState = DupliJs.Pack.ProcessingStats.Storing;
|
||||
} else {
|
||||
// Has to be negative(error) or 100 - both mean complete
|
||||
currentProcessingState = DupliJs.Pack.ProcessingStats.Finished;
|
||||
}
|
||||
if (currentProcessingState == DupliJs.Pack.ProcessingStats.Pending) {
|
||||
if (package_info.status != 0) {
|
||||
window.location = window.location.href;
|
||||
}
|
||||
} else if (currentProcessingState == DupliJs.Pack.ProcessingStats.Building ||
|
||||
currentProcessingState == DupliJs.Pack.ProcessingStats.Storing) {
|
||||
// Check for completion
|
||||
if (package_info.status == 100 || package_info.status < 0) {
|
||||
if (DupliJs.Pack.IsRemoteDownloadModalOpen() && package_info.status == 100) {
|
||||
// do a dynamic form submission to start the restore/download
|
||||
$('.status-progress-' + package_info.ID).text(100);
|
||||
DupliJs.Pack.afterRemoteDownloadAction();
|
||||
} else {
|
||||
// Backup completed or error - reload to show final state
|
||||
window.location = window.location.href;
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
// Update progress - unified logic for all phases
|
||||
packageNode.data('status', package_info.status);
|
||||
|
||||
// Show percentage only if > 0
|
||||
var progressSpan = $('.status-progress-' + package_info.ID);
|
||||
if (package_info.status_progress > 0) {
|
||||
progressSpan.text(package_info.status_progress + '%');
|
||||
} else {
|
||||
progressSpan.text('');
|
||||
}
|
||||
|
||||
sizeNode.fadeOut(100, function() {
|
||||
$(this).text(package_info.size).fadeIn(1000);
|
||||
});
|
||||
$('.phase-name-' + package_info.ID).text(package_info.phase_name);
|
||||
$('.phase-message-' + package_info.ID).html(package_info.status_progress_text);
|
||||
}
|
||||
} else if (currentProcessingState == DupliJs.Pack.ProcessingStats.PendingCancellation) {
|
||||
if ((package_info.status == -2) || (package_info.status == -4)) {
|
||||
// refresh when its gone to cancelled
|
||||
window.location = window.location.href;
|
||||
}
|
||||
} else if (currentProcessingState == DupliJs.Pack.ProcessingStats.Finished) {
|
||||
// IF something caused the Backup to come out of finished refresh everything (has to be out of finished or error state)
|
||||
if ((package_info.status != 100) && (package_info.status > 0)) {
|
||||
// wait one miutes to prevent a realod loop
|
||||
setTimeout(function() {
|
||||
window.location = window.location.href;
|
||||
}, 60000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (activePackagePresent) {
|
||||
$('#dupli-create-new').addClass('disabled');
|
||||
packagesTable.find(".dup-restore-backup").prop('disabled', true);
|
||||
packagesTable.find(".dup-dnload-btn").prop('disabled', true);
|
||||
packagesTable.find(".dup-remote-download").prop('disabled', true);
|
||||
DupliJs.Pack.SetUpdateInterval(5);
|
||||
} else {
|
||||
$('#dupli-create-new').removeClass('disabled');
|
||||
packagesTable.find(".dup-restore-backup.can-enabled").prop('disabled', false);
|
||||
packagesTable.find(".dup-dnload-btn.can-enabled").prop('disabled', false);
|
||||
packagesTable.find(".dup-remote-download.can-enabled").prop('disabled', false);
|
||||
// Kick refresh down to 60 seconds if nothing is being actively worked on
|
||||
DupliJs.Pack.SetUpdateInterval(60);
|
||||
}
|
||||
},
|
||||
error: function(data) {
|
||||
DupliJs.Pack.SetUpdateInterval(60);
|
||||
console.log(data);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
//Init
|
||||
DupliJs.UI.Clock(DupliJs._WordPressInitTime);
|
||||
DupliJs.Pack.SetUpdateInterval(5); // Start with frequent polling, will be adjusted by first response
|
||||
DupliJs.Pack.UpdateUnfinishedPackages();
|
||||
|
||||
$('.dupli-btn-open-recovery-box').click(function(event) {
|
||||
event.preventDefault();
|
||||
|
||||
let packageId = $(this).data('package-id');
|
||||
|
||||
DupliJs.Util.ajaxWrapper({
|
||||
action: 'duplicator_get_recovery_box_content',
|
||||
packageId: packageId,
|
||||
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_get_recovery_box_content')); ?>'
|
||||
},
|
||||
function(result, data, funcData, textStatus, jqXHR) {
|
||||
if (funcData.success) {
|
||||
let boxContent = funcData.content;
|
||||
if (funcData.isRecoverable) {
|
||||
<?php
|
||||
$availableRecoveryBox->updateMessage('boxContent');
|
||||
$availableRecoveryBox->showAlert();
|
||||
?>
|
||||
$('.dupli-recovery-download-launcher').off().click(function() {
|
||||
DupliJs.Pack.downloadLauncher();
|
||||
});
|
||||
} else {
|
||||
<?php
|
||||
$unavailableRecoveryBox->updateMessage('boxContent');
|
||||
$unavailableRecoveryBox->showAlert();
|
||||
?>
|
||||
}
|
||||
} else {
|
||||
DupliJs.addAdminMessage(funcData.message, 'error');
|
||||
}
|
||||
return '';
|
||||
}
|
||||
);
|
||||
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator Backup row in table Backups list
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Models\GlobalEntity;
|
||||
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
|
||||
*/
|
||||
|
||||
$global = GlobalEntity::getInstance();
|
||||
$maxDefaultPackages = StoragesUtil::getDefaultStorage()->getMaxPackages();
|
||||
$toolTipContent = sprintf(
|
||||
esc_attr__(
|
||||
'The number of Backups to keep is set at [%d]. To change this setting go to
|
||||
Duplicator Pro > Storage > Default > Max Backups and change the value, otherwise this note can be ignored.',
|
||||
'duplicator-pro'
|
||||
),
|
||||
$maxDefaultPackages
|
||||
);
|
||||
?>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th colspan="11">
|
||||
<div class="dup-pack-status-info">
|
||||
<?php if ($maxDefaultPackages < $tplData['totalElements'] && $maxDefaultPackages != 0) { ?>
|
||||
<?php echo esc_html__("Note: max backups retention enabled", 'duplicator-pro'); ?>
|
||||
<i
|
||||
class="fa-solid fa-question-circle fa-sm dark-gray-color"
|
||||
data-tooltip-title="<?php esc_attr_e("Storage Backups", 'duplicator-pro'); ?>"
|
||||
data-tooltip="<?php echo esc_attr($toolTipContent); ?>">
|
||||
</i>
|
||||
<?php } else { ?>
|
||||
|
||||
<?php } ?>
|
||||
</div>
|
||||
</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator Backup row in table Backups list
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
$tooltipStatusContent = $tplMng->render('admin_pages/packages/packages_table_head_status_icons', [], false);
|
||||
$tooltopCreatedContent = __(
|
||||
'Backup date and time expressed in UTC (Coordinated Universal Time).
|
||||
The displayed date corresponds to the server\'s international time, independent of local time zones.',
|
||||
'duplicator-pro'
|
||||
);
|
||||
?>
|
||||
<h2 class="screen-reader-text"><?php esc_html_e('Backups list', 'duplicator-pro') ?></h2>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="dup-check-column" style="width:10px;">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="dup-chk-all"
|
||||
title="<?php esc_attr_e("Select all Backups", 'duplicator-pro') ?>"
|
||||
onclick="DupliJs.Pack.SetDeleteAll()"
|
||||
>
|
||||
</th>
|
||||
<th class="dup-name-column" >
|
||||
<?php esc_html_e("Name", 'duplicator-pro') ?>
|
||||
</th>
|
||||
<th class="dup-note-column">
|
||||
<?php esc_html_e("Note", 'duplicator-pro') ?>
|
||||
</th>
|
||||
<th class="dup-storages-column">
|
||||
<?php esc_html_e("Storages", 'duplicator-pro') ?>
|
||||
</th>
|
||||
<th class="dup-flags-column">
|
||||
<?php esc_html_e("Status", 'duplicator-pro') ?>
|
||||
<i
|
||||
class="fa-solid fa-circle-info"
|
||||
data-tooltip-title="<?php esc_attr_e("Status Icons", 'duplicator-pro'); ?>"
|
||||
data-tooltip="<?php echo esc_attr($tooltipStatusContent); ?>"
|
||||
></i>
|
||||
</th>
|
||||
<th class="dup-size-column">
|
||||
<?php esc_html_e("Size", 'duplicator-pro') ?>
|
||||
</th>
|
||||
<th class="dup-created-column">
|
||||
<?php esc_html_e("Created", 'duplicator-pro') ?>
|
||||
<i
|
||||
class="fa-solid fa-circle-info"
|
||||
data-tooltip-title="<?php esc_attr_e('Backup Date/Time', 'duplicator-pro'); ?>"
|
||||
data-tooltip="<?php echo esc_attr($tooltopCreatedContent); ?>"
|
||||
></i>
|
||||
</th>
|
||||
<th class="dup-age-column">
|
||||
<?php esc_html_e("Age", 'duplicator-pro') ?>
|
||||
</th>
|
||||
<th class="dup-download-column" style="width:75px;"></th>
|
||||
<th class="dup-restore-column" style="width:25px;"></th>
|
||||
<th id="dup-header-chkall" class="dup-details-column" >
|
||||
<?php if ($tplData['totalElements'] > 0) { ?>
|
||||
<span class="link-style" title="<?php esc_attr_e('Expand/Collapse All', 'duplicator-pro'); ?>" >
|
||||
<i class="fa-solid fa-plus"></i>
|
||||
</span>
|
||||
<?php } ?>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator Backup row in table Backups list
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Views\ViewHelper;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
?>
|
||||
<ul class="dup-status-icons-list no-bullet" >
|
||||
<li>
|
||||
<span class="icon-wrapper" ><i class="fa-solid fa-hand" ></i></span>
|
||||
<?php esc_html_e('Manual Backup', 'duplicator-pro'); ?>
|
||||
</li>
|
||||
<li>
|
||||
<span class="icon-wrapper" ><i class="fa-solid fa-clock" ></i></span>
|
||||
<?php esc_attr_e('Schedule Backup', 'duplicator-pro') ?>
|
||||
</li>
|
||||
<li>
|
||||
<span class="icon-wrapper" ><i class="fa-solid fa-hard-drive"></i></span>
|
||||
<?php
|
||||
echo wp_kses(
|
||||
__('The Backup is in a Local Storage <b>[clickable]</b>', 'duplicator-pro'),
|
||||
ViewHelper::GEN_KSES_TAGS
|
||||
);
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<span class="icon-wrapper" ><i class="fa-solid fa-cloud"></i></span>
|
||||
<?php
|
||||
echo wp_kses(
|
||||
__('The Backup is in a Remote Storage <b>[clickable]</b>', 'duplicator-pro'),
|
||||
ViewHelper::GEN_KSES_TAGS
|
||||
);
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<span class="icon-wrapper" ><i class="fa-solid fa-database"></i></span>
|
||||
<?php esc_attr_e('Database Only Backup', 'duplicator-pro') ?>
|
||||
</li>
|
||||
<li>
|
||||
<span class="icon-wrapper" ><i class="fa-solid fa-images"></i></span>
|
||||
<?php esc_attr_e('Media Only Backup', 'duplicator-pro') ?>
|
||||
</li>
|
||||
<li>
|
||||
<span class="icon-wrapper" ><?php ViewHelper::disasterIcon(true, 'link-style no-decoration'); ?></span>
|
||||
<?php
|
||||
echo wp_kses(
|
||||
__('This Backup is available for Disaster Recovery <b>[clickable]</b>', 'duplicator-pro'),
|
||||
ViewHelper::GEN_KSES_TAGS
|
||||
);
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<span class="icon-wrapper" ><?php ViewHelper::disasterIcon(true, 'green'); ?></span>
|
||||
<?php
|
||||
echo wp_kses(
|
||||
__('Disaster Recovery URL is set on this Backup <b>[clickable]</b>', 'duplicator-pro'),
|
||||
ViewHelper::GEN_KSES_TAGS
|
||||
);
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<span class="icon-wrapper" ><i class="fa-solid fa-clock-rotate-left maroon"></i></span>
|
||||
<?php esc_attr_e('This Backup is created after the Last Restored Backup', 'duplicator-pro') ?>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator Backup row in table Backups list
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Controllers\RecoveryController;
|
||||
use Duplicator\Package\Recovery\RecoveryPackage;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
?>
|
||||
<div class="dupli-toolbar-recovery-info margin-bottom-1">
|
||||
<?php
|
||||
if (RecoveryPackage::getRecoverPackageId() === false) {
|
||||
$tplMng->render('admin_pages/packages/recovery_info/no_recovery_set');
|
||||
} else {
|
||||
RecoveryController::renderRecoveryWidged(
|
||||
[
|
||||
'selector' => false,
|
||||
'subtitle' => '',
|
||||
'copyLink' => true,
|
||||
'copyButton' => true,
|
||||
'launch' => true,
|
||||
'download' => true,
|
||||
'info' => true,
|
||||
]
|
||||
);
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator Backup row in table Backups list
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Views\ViewHelper;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
?>
|
||||
<h3 class="dup-title maroon">
|
||||
<?php ViewHelper::disasterIcon(); ?> <?php esc_html_e('Disaster Recovery - None Set', 'duplicator-pro'); ?>
|
||||
</h3>
|
||||
<?php
|
||||
esc_html_e(
|
||||
'The recovery point can quickly restore a site to a prior state for any reason. To activate a recovery point follow these steps:',
|
||||
'duplicator-pro'
|
||||
);
|
||||
?>
|
||||
<ol>
|
||||
<li>
|
||||
<?php
|
||||
printf(
|
||||
esc_html__('Select a Recovery Backup with the icon %s displayed*.', 'duplicator-pro'),
|
||||
wp_kses(
|
||||
ViewHelper::disasterIcon(false),
|
||||
['i' => ['class' => []]]
|
||||
)
|
||||
);
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<?php
|
||||
printf(
|
||||
esc_html_x(
|
||||
'Open details area %1$s and click the "Recover Backup ..." button.',
|
||||
'%1$s represents an icon',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<i class="fas fa-chevron-left fa-sm fa-fw"></i>'
|
||||
);
|
||||
?>
|
||||
</li>
|
||||
<li>
|
||||
<?php esc_html_e('Follow the prompts and choose the action to perform.', 'duplicator-pro'); ?>
|
||||
</li>
|
||||
</ol>
|
||||
<hr/>
|
||||
<p>
|
||||
<b><?php esc_html_e('Additional Details:', 'duplicator-pro'); ?></b>
|
||||
<?php
|
||||
esc_html_e(
|
||||
'Once a recovery point is set you can save the "Recovery Key" URL in a safe place for restoration later in the event your site goes down, gets
|
||||
hacked or basically any reason you need to restore a site. In the event you still have access to your site you can also launch the recover
|
||||
wizard from the details menu.',
|
||||
'duplicator-pro'
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
<small>
|
||||
<i>
|
||||
<?php
|
||||
printf(
|
||||
esc_html__(
|
||||
'*Note: If you do not see a Recovery Backup %s icon in the Backups List.
|
||||
Then be sure to build a full Backup that does not exclude any of the core WordPress files or database tables.
|
||||
These core files and tables are required to build a valid recovery point.',
|
||||
'duplicator-pro'
|
||||
),
|
||||
wp_kses(
|
||||
ViewHelper::disasterIcon(false),
|
||||
['i' => ['class' => []]]
|
||||
)
|
||||
);
|
||||
?>
|
||||
</i>
|
||||
</small>
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator Backup row in table Backups list
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Package\Recovery\RecoveryPackage;
|
||||
use Duplicator\Views\ViewHelper;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var \Duplicator\Package\DupPackage $package
|
||||
*/
|
||||
|
||||
$package = $tplData['package'];
|
||||
$isRecoverable = RecoveryPackage::isPackageIdRecoverable($package->getId());
|
||||
|
||||
if ($isRecoverable) {
|
||||
$tplMng->render('admin_pages/packages/recovery_info/row_recovery_box_available');
|
||||
} else {
|
||||
$tplMng->render('admin_pages/packages/recovery_info/row_recovery_box_unavailable');
|
||||
}
|
||||
?>
|
||||
<hr class="margin-top-1 margin-bottom-1">
|
||||
<small><i>
|
||||
<?php
|
||||
echo wp_kses(
|
||||
sprintf(
|
||||
_x(
|
||||
'%1$sDisaster Recovery%2$s makes it quick and easy to restore your site during an emergency.
|
||||
You don’t need WordPress to be working for this.
|
||||
Just keep the Disaster Recovery Link in a safe spot and use it when needed, or use the Launcher to restore your backup.',
|
||||
'%1$s and %2$s represents the opening and closing HTML tags for an anchor or link',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<a href="' . esc_url(DUPLICATOR_DUPLICATOR_DOCS_URL . 'tools-recovery') . '" target="_blank">',
|
||||
'</a>'
|
||||
),
|
||||
ViewHelper::GEN_KSES_TAGS
|
||||
);
|
||||
?>
|
||||
<br>
|
||||
<?php
|
||||
echo wp_kses(
|
||||
sprintf(
|
||||
_x(
|
||||
'If your backup isn’t eligible for Disaster Recovery, you can still use the %1$sRestore Backup button.%2$s',
|
||||
'%1$s and %2$s represents the opening and closing HTML tags for an anchor or link',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<a href="' . esc_url(DUPLICATOR_DUPLICATOR_DOCS_URL . 'restoring-your-backup') . '" target="_blank">',
|
||||
'</a>'
|
||||
),
|
||||
ViewHelper::GEN_KSES_TAGS
|
||||
);
|
||||
?>
|
||||
</i></small>
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator Backup row in table Backups list
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Controllers\PackagesPageController;
|
||||
use Duplicator\Controllers\RecoveryController;
|
||||
use Duplicator\Core\Controllers\ControllersManager;
|
||||
use Duplicator\Core\Views\TplMng;
|
||||
use Duplicator\Package\Recovery\RecoveryPackage;
|
||||
use Duplicator\Views\ViewHelper;
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var ControllersManager $ctrlMng
|
||||
* @var TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var \Duplicator\Package\DupPackage $package
|
||||
*/
|
||||
$package = $tplData['package'];
|
||||
$isRecoverPoint = (RecoveryPackage::getRecoverPackageId() === $package->getId());
|
||||
|
||||
$colorClass = ($isRecoverPoint ? 'green' : '');
|
||||
?>
|
||||
<h3 class="dup-title margin-top-0">
|
||||
<?php ViewHelper::disasterIcon(true, $colorClass); ?>
|
||||
<?php
|
||||
if ($isRecoverPoint) {
|
||||
esc_html_e('Disaster Recovery - Is Set on this Backup', 'duplicator-pro');
|
||||
} else {
|
||||
esc_html_e('Disaster Recovery - Is Available for this Backup', 'duplicator-pro');
|
||||
}
|
||||
?>
|
||||
</h3>
|
||||
|
||||
<?php $tplMng->render('parts/recovery/package_info_mini'); ?>
|
||||
<hr class="margin-top-1 margin-bottom-1">
|
||||
|
||||
<?php if ($isRecoverPoint) {
|
||||
RecoveryController::renderRecoveryWidged([
|
||||
'details' => false,
|
||||
'selector' => false,
|
||||
'subtitle' => '',
|
||||
'copyLink' => false,
|
||||
'copyButton' => true,
|
||||
'launch' => false,
|
||||
'download' => true,
|
||||
'info' => true,
|
||||
]);
|
||||
} else { ?>
|
||||
<form method="post" action="<?php PackagesPageController::getInstance()->getPageUrl(); ?>">
|
||||
<?php PackagesPageController::getInstance()->getActionByKey(PackagesPageController::ACTION_SET_RECOVERY_POINT)->getActionNonceFileds(); ?>
|
||||
<input type="hidden" name="recovery_package" value="<?php echo (int) $package->getId(); ?>">
|
||||
<div class="dupli-recovery-widget-wrapper">
|
||||
<div class="dupli-recovery-point-actions">
|
||||
<div class="dupli-recovery-buttons">
|
||||
<button
|
||||
class="button primary dupli-btn-set-recovery margin-0"
|
||||
type="submit">
|
||||
<span><?php ViewHelper::disasterIcon(); ?>
|
||||
<?php esc_html_e("Set Disaster Recovery", 'duplicator-pro'); ?></span>
|
||||
<i
|
||||
class="fa-solid fa-question-circle fa-sm dark-gray-color dup-base-color white"
|
||||
data-tooltip-title="<?php esc_attr_e("Activate Recovery", 'duplicator-pro'); ?>"
|
||||
data-tooltip="<?php esc_attr_e("This action will set this Backup as the active Disaster Recovery Backup.", 'duplicator-pro'); ?>"
|
||||
aria-expanded="false">
|
||||
</i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<?php }
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator Backup row in table Backups list
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Package\Recovery\RecoveryStatus;
|
||||
use Duplicator\Views\ViewHelper;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var \Duplicator\Package\DupPackage $package
|
||||
*/
|
||||
$package = $tplData['package'];
|
||||
|
||||
$tooltipContent = __('A Backup Recovery Point status is not required to be enabled and in some cases is desirable.', 'duplicator-pro') . ' ' .
|
||||
__('For example you may want to backup only your database.', 'duplicator-pro') . ' ' .
|
||||
__(
|
||||
'In this case you can still run a database only install, however the ability to use the recovery point installer will be unavailable.',
|
||||
'duplicator-pro'
|
||||
);
|
||||
?>
|
||||
|
||||
<h3 class="dup-title margin-top-0">
|
||||
<?php ViewHelper::disasterIcon(true, 'maroon'); ?>
|
||||
<?php esc_html_e('Disaster Recovery - Isn\'t Available for this Backup', 'duplicator-pro'); ?>
|
||||
<sup>
|
||||
<i class="fas fa-question-circle fa-xs"
|
||||
data-tooltip-title="<?php esc_attr_e('Recovery', 'duplicator-pro'); ?>"
|
||||
data-tooltip="<?php echo esc_attr($tooltipContent); ?>">
|
||||
</i>
|
||||
</sup>
|
||||
</h3>
|
||||
|
||||
<?php $tplMng->render('parts/recovery/package_info_mini'); ?>
|
||||
<hr class="margin-top-1 margin-bottom-1">
|
||||
|
||||
<?php
|
||||
$recoverStatus = new RecoveryStatus($package);
|
||||
$tplMng->render('parts/recovery/exclude_data_box', ['recoverStatus' => $recoverStatus]);
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
?>
|
||||
<div id="dup-remote-package-download-wrapper">
|
||||
<div class="dup-download-progress">
|
||||
<p><?php esc_html_e('No download is currently in progress.', 'duplicator-pro'); ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
jQuery(document).ready(function ($) {
|
||||
let content = $('tr.dup-row-progress').find('td').html();
|
||||
if (content && content.length > 0) {
|
||||
$('.dup-download-progress').html(content);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
use Duplicator\Controllers\PackagesPageController;
|
||||
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[] $storages
|
||||
*/
|
||||
$storages = $tplData['storages'];
|
||||
/** @var int */
|
||||
$packageId = $tplData['packageId'];
|
||||
/** @var string */
|
||||
$packageName = $tplData['packageName'];
|
||||
/** @var bool */
|
||||
$isStorageFull = $tplData['isStorageFull'];
|
||||
|
||||
?>
|
||||
<div id="dup-remote-package-download">
|
||||
<form method="POST" action="">
|
||||
<input type="hidden" name="package_id" value="<?php echo (int) $packageId; ?>">
|
||||
<input type="hidden" name="download" value="1">
|
||||
<input type="hidden" name="action" value="<?php echo esc_attr(PackagesPageController::ACTION_START_DOWNLOAD); ?>">
|
||||
<?php PackagesPageController::getInstance()->getActionByKey(PackagesPageController::ACTION_START_DOWNLOAD)->getActionNonceFileds(); ?>
|
||||
<input type="hidden" name="afterDownloadAction" value="">
|
||||
<p>
|
||||
<?php
|
||||
printf(
|
||||
wp_kses(
|
||||
__('The <b>%s</b> backup isn\'t in a local storage, it\'s possible to download it on local server.', 'duplicator-pro'),
|
||||
[
|
||||
'b' => [],
|
||||
]
|
||||
),
|
||||
esc_html($packageName)
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
<?php
|
||||
$tplMng->render('admin_pages/packages/remote_download/remote_storages_list');
|
||||
if ($isStorageFull) {
|
||||
?>
|
||||
<p>
|
||||
<small>
|
||||
<i class="maroon">
|
||||
<?php
|
||||
esc_html_e(
|
||||
'The maximum number of backups for the default local storage has been reached.
|
||||
The oldest backup will be deleted automatically, after the download finishes.
|
||||
Alternatively you can delete a backup to make room for the download.',
|
||||
'duplicator-pro'
|
||||
);
|
||||
?>
|
||||
</i>
|
||||
</small>
|
||||
</p>
|
||||
<?php } ?>
|
||||
<hr class="margin-top-1 margin-bottom-1" >
|
||||
<div class="dup-buttons-container">
|
||||
<button id="dup-remote-package-cancel-btn" class="button gray hollow">
|
||||
<?php esc_html_e('Cancel', 'duplicator-pro'); ?>
|
||||
</button>
|
||||
<button
|
||||
id="dup-remote-package-download-btn"
|
||||
class="button primary"
|
||||
type="submit"
|
||||
>
|
||||
<?php esc_html_e('Download', 'duplicator-pro'); ?>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<script>
|
||||
jQuery(document).ready(function ($) {
|
||||
$('input[name="storage_ids[]"]').click(function(event) {
|
||||
$('#dup-remote-package-download-btn').prop('disabled', false);
|
||||
});
|
||||
|
||||
$('#dup-remote-package-cancel-btn').click(function(event) {
|
||||
event.preventDefault();
|
||||
tb_remove();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
use Duplicator\Controllers\PackagesPageController;
|
||||
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[] $storages
|
||||
*/
|
||||
$storages = $tplData['storages'];
|
||||
/** @var int */
|
||||
$packageId = $tplData['packageId'];
|
||||
/** @var string */
|
||||
$packageName = $tplData['packageName'];
|
||||
/** @var bool */
|
||||
$isStorageFull = $tplData['isStorageFull'];
|
||||
|
||||
?>
|
||||
<div id="dup-remote-package-download">
|
||||
<form method="POST" action="">
|
||||
<input type="hidden" name="package_id" value="<?php echo (int) $packageId; ?>">
|
||||
<input type="hidden" name="download" value="1">
|
||||
<input type="hidden" name="action" value="<?php echo esc_attr(PackagesPageController::ACTION_START_DOWNLOAD); ?>">
|
||||
<?php PackagesPageController::getInstance()->getActionByKey(PackagesPageController::ACTION_START_DOWNLOAD)->getActionNonceFileds(); ?>
|
||||
<input type="hidden" name="afterDownloadAction" value="<?php echo esc_attr(PackagesPageController::ACTION_START_RESTORE); ?>">
|
||||
<p>
|
||||
<?php
|
||||
printf(
|
||||
wp_kses(
|
||||
__('To restore the <b>%s</b> backup, it is necessary to download it locally before proceeding with the restoration.', 'duplicator-pro'),
|
||||
[
|
||||
'b' => [],
|
||||
]
|
||||
),
|
||||
esc_html($packageName)
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
<?php
|
||||
$tplMng->render('admin_pages/packages/remote_download/remote_storages_list');
|
||||
if ($isStorageFull) {
|
||||
?>
|
||||
<p>
|
||||
<small>
|
||||
<i class="maroon">
|
||||
<?php
|
||||
esc_html_e(
|
||||
'The maximum number of backups for the default local storage has been reached.
|
||||
The oldest backup will be deleted automatically, after the download finishes.
|
||||
Alternatively you can delete a backup to make room for the download.',
|
||||
'duplicator-pro'
|
||||
);
|
||||
?>
|
||||
</i>
|
||||
</small>
|
||||
</p>
|
||||
<?php } ?>
|
||||
<hr class="margin-top-1 margin-bottom-1" >
|
||||
<div class="dup-buttons-container">
|
||||
<button id="dup-remote-package-cancel-btn" class="button button-secondary">
|
||||
<?php esc_html_e('Cancel', 'duplicator-pro'); ?>
|
||||
</button>
|
||||
<button
|
||||
id="dup-remote-package-download-btn"
|
||||
class="button primary"
|
||||
type="submit"
|
||||
>
|
||||
<?php esc_html_e('Download', 'duplicator-pro'); ?>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<script>
|
||||
jQuery(document).ready(function ($) {
|
||||
$('input[name="storage_ids[]"]').click(function(event) {
|
||||
$('#dup-remote-package-download-btn').prop('disabled', false);
|
||||
});
|
||||
|
||||
$('#dup-remote-package-cancel-btn').click(function(event) {
|
||||
event.preventDefault();
|
||||
tb_remove();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
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[] $storages
|
||||
*/
|
||||
$storages = $tplData['storages'];
|
||||
?>
|
||||
<p>
|
||||
<?php esc_html_e('Select the remote storage from which to download the Backup:', 'duplicator-pro'); ?>
|
||||
</p>
|
||||
<div class="dup-remote-storage-options">
|
||||
<?php
|
||||
for ($i = 0; $i < count($storages); $i++) {
|
||||
$storage = $storages[$i];
|
||||
?>
|
||||
<div class="storage-option horizontal-input-row">
|
||||
<input
|
||||
type="radio"
|
||||
id="storage-option-<?php echo (int) $storage->getId(); ?>"
|
||||
name="storage_ids[]"
|
||||
value="<?php echo (int) $storage->getId(); ?>"
|
||||
<?php checked($i === 0); ?>
|
||||
>
|
||||
<label for="storage-option-<?php echo (int) $storage->getId(); ?>">
|
||||
<?php echo wp_kses(
|
||||
$storage->getSTypeIcon(),
|
||||
[
|
||||
'i' => [
|
||||
'class' => [],
|
||||
],
|
||||
'img' => [
|
||||
'src' => [],
|
||||
'class' => [],
|
||||
'alt' => [],
|
||||
],
|
||||
]
|
||||
); ?>
|
||||
<b><?php echo esc_html($storage->getName()); ?></b>
|
||||
<?php echo wp_kses(
|
||||
'(' . $storage->getHtmlLocationLink() . ')',
|
||||
[
|
||||
'a' => [
|
||||
'href' => [],
|
||||
'target' => [],
|
||||
],
|
||||
'span' => [],
|
||||
]
|
||||
);?>
|
||||
</label>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
@@ -0,0 +1,164 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator Pro remote download scripts
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2024, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Controllers\PackagesPageController;
|
||||
use Duplicator\Models\Storages\AbstractStorageEntity;
|
||||
use Duplicator\Views\UI\UiDialog;
|
||||
use Duplicator\Models\GlobalEntity;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
$afterDownloadAction = $tplData['afterDownloadAction'] ?? '';
|
||||
$remoteDownloadPackageId = isset($tplData['remoteDownloadPackageId']) ? (int) $tplData['remoteDownloadPackageId'] : -1;
|
||||
$downloadStarted = $remoteDownloadPackageId > 0;
|
||||
$afterDownloadActionNonce = strlen($afterDownloadAction) > 0 ? PackagesPageController::getInstance()->getActionByKey($afterDownloadAction)->getNonce() : '';
|
||||
|
||||
$alreadyDownloadDlg = new UiDialog();
|
||||
$alreadyDownloadDlg->width = 550;
|
||||
$alreadyDownloadDlg->height = 200;
|
||||
$alreadyDownloadDlg->showButtons = true;
|
||||
$alreadyDownloadDlg->title = __('Backup is already being downloaded', 'duplicator-pro');
|
||||
$alreadyDownloadDlg->message = __('The backup is currently being downloaded. Please wait for the download to finish.', 'duplicator-pro');
|
||||
$alreadyDownloadDlg->boxClass = 'duplication-remote-download-options-dlg';
|
||||
$alreadyDownloadDlg->initAlert();
|
||||
|
||||
$remoteDownloadOptionsDlg = new UiDialog();
|
||||
$remoteDownloadOptionsDlg->width = 750;
|
||||
$remoteDownloadOptionsDlg->height = 395;
|
||||
$remoteDownloadOptionsDlg->showButtons = false;
|
||||
$remoteDownloadOptionsDlg->title = __('Download From Remote Storage', 'duplicator-pro');
|
||||
$remoteDownloadOptionsDlg->message = __('Loading Please Wait...', 'duplicator-pro');
|
||||
$remoteDownloadOptionsDlg->boxClass = 'duplicatior-remote-download-options-dlg';
|
||||
$remoteDownloadOptionsDlg->initAlert();
|
||||
|
||||
$downloadProgressDlg = new UiDialog();
|
||||
$downloadProgressDlg->height = 475;
|
||||
$downloadProgressDlg->width = 750;
|
||||
$downloadProgressDlg->showButtons = false;
|
||||
$downloadProgressDlg->title = __('Downloading Backup...', 'duplicator-pro');
|
||||
$downloadProgressDlg->templatePath = 'admin_pages/packages/remote_download/download_progress';
|
||||
$downloadProgressDlg->boxClass = 'dupli-download-progress-dlg';
|
||||
$downloadProgressDlg->initAlert();
|
||||
|
||||
$removeBackupRecordConfirm = new UiDialog();
|
||||
$removeBackupRecordConfirm->title = __('Remove Backup Record?', 'duplicator-pro');
|
||||
$removeBackupRecordConfirm->message = __('The backup does not exist in any storage. Would you like to remove the backup record?', 'duplicator-pro');
|
||||
$removeBackupRecordConfirm->progressText = __('Removing Backup Record, Please Wait...', 'duplicator-pro');
|
||||
$removeBackupRecordConfirm->jsCallback = 'DupliJs.Pack.DeleteBackupRecord(this)';
|
||||
$removeBackupRecordConfirm->progressOn = false;
|
||||
$removeBackupRecordConfirm->okText = __('Yes', 'duplicator-pro');
|
||||
$removeBackupRecordConfirm->cancelText = __('No', 'duplicator-pro');
|
||||
$removeBackupRecordConfirm->closeOnConfirm = true;
|
||||
$removeBackupRecordConfirm->initConfirm();
|
||||
?>
|
||||
|
||||
<script>
|
||||
jQuery(document).ready(function($) {
|
||||
let remoteDownloadModal = $('.<?php echo esc_html($remoteDownloadOptionsDlg->boxClass); ?>');
|
||||
let remoteDownloadInProgress = <?php echo wp_json_encode($downloadStarted); ?>;
|
||||
let remoteDownloadModalOpen = false;
|
||||
|
||||
if (remoteDownloadInProgress) {
|
||||
setTimeout(function() {
|
||||
<?php $downloadProgressDlg->showAlert(); ?>
|
||||
remoteDownloadModalOpen = true;
|
||||
}, 500);
|
||||
}
|
||||
|
||||
$(document).on('thickbox:removed', function() {
|
||||
if (!remoteDownloadInProgress && !remoteDownloadModalOpen) {
|
||||
return;
|
||||
}
|
||||
|
||||
remoteDownloadModalOpen = false;
|
||||
});
|
||||
|
||||
DupliJs.Pack.DeleteBackupRecord = function(e) {
|
||||
var id = $(e).attr('data-id');
|
||||
$("tr[data-package-id=" + id + "] input[type=checkbox]").prop('checked', true);
|
||||
DupliJs.Pack.Delete()
|
||||
}
|
||||
|
||||
DupliJs.Pack.IsRemoteDownloadModalOpen = function() {
|
||||
return remoteDownloadModalOpen;
|
||||
}
|
||||
|
||||
DupliJs.Pack.afterRemoteDownloadAction = function() {
|
||||
let packageId = <?php echo wp_json_encode($remoteDownloadPackageId); ?>;
|
||||
let action = <?php echo wp_json_encode($afterDownloadAction); ?>;
|
||||
let nonceVal = <?php echo wp_json_encode($afterDownloadActionNonce); ?>;
|
||||
|
||||
if (action.length === 0 || nonceVal.length === 0 || packageId <= 0) {
|
||||
location.reload();
|
||||
} else {
|
||||
DupliJs.Util.dynamicFormSubmit('', 'post', {
|
||||
packageId: packageId,
|
||||
action: action,
|
||||
_wpnonce: nonceVal
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show remote download options in modal window
|
||||
*
|
||||
* @param {number} packageId
|
||||
* @param {string} remoteAction
|
||||
*
|
||||
* @return {boolean}
|
||||
*/
|
||||
DupliJs.Pack.ShowRemoteDownloadOptions = function(
|
||||
packageId,
|
||||
remoteAction,
|
||||
) {
|
||||
DupliJs.Util.ajaxWrapper({
|
||||
action: 'duplicator_get_remote_restore_download_options',
|
||||
packageId: packageId,
|
||||
remoteAction: remoteAction,
|
||||
nonce: "<?php echo esc_js(wp_create_nonce('duplicator_get_remote_restore_download_options')); ?>"
|
||||
},
|
||||
function(result, data, funcData, textStatus, jqXHR) {
|
||||
if (funcData.alreadyInUse) {
|
||||
<?php $alreadyDownloadDlg->showAlert(); ?>
|
||||
} else if (!funcData.packageExists) {
|
||||
<?php if (GlobalEntity::getInstance()->getPurgeBackupRecords() === AbstractStorageEntity::BACKUP_RECORDS_REMOVE_ALL) {
|
||||
$removeBackupRecordConfirm->showConfirm();
|
||||
} else { ?>
|
||||
DupliJs.addAdminMessage(funcData.message, 'error');
|
||||
<?php } ?>
|
||||
$("#<?php echo esc_js($removeBackupRecordConfirm->getID()); ?>-confirm").attr('data-id', packageId);
|
||||
$("tr[data-package-id='" + packageId + "'] button[data-needs-download]").prop('disabled', true);
|
||||
$("#dup-row-pack-id-" + packageId + " .remote-storage-flag").remove();
|
||||
} else {
|
||||
<?php $remoteDownloadOptionsDlg->showAlert(); ?>
|
||||
remoteDownloadModal.html(data.funcData.content);
|
||||
}
|
||||
return '';
|
||||
},
|
||||
function(result, data, funcData, textStatus, jqXHR) {
|
||||
DupliJs.addAdminMessage(data.message, 'error');
|
||||
console.log(data);
|
||||
return '';
|
||||
}, {
|
||||
timeout: 300000
|
||||
} //Fetching validity of multiple storages can take a while
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,220 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator Backup row in table Backups list
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Controllers\ImportPageController;
|
||||
use Duplicator\Controllers\SettingsPageController;
|
||||
use Duplicator\Controllers\StoragePageController;
|
||||
use Duplicator\Core\CapMng;
|
||||
use Duplicator\Models\GlobalEntity;
|
||||
use Duplicator\Package\AbstractPackage;
|
||||
use Duplicator\Package\DupPackage;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var ?DupPackage $package
|
||||
*/
|
||||
|
||||
$package = $tplMng->getDataValueObjRequired('package', AbstractPackage::class);
|
||||
$archive_exists = ($package->getLocalPackageFilePath(AbstractPackage::FILE_TYPE_ARCHIVE) != false);
|
||||
$installer_exists = ($package->getLocalPackageFilePath(AbstractPackage::FILE_TYPE_INSTALLER) != false);
|
||||
$archiveDownloadURL = $package->getLocalPackageFileURL(AbstractPackage::FILE_TYPE_ARCHIVE);
|
||||
$installerDownloadURL = $package->getLocalPackageFileURL(AbstractPackage::FILE_TYPE_INSTALLER);
|
||||
$defaultStorageUrl = StoragePageController::getEditDefaultUrl();
|
||||
$global = GlobalEntity::getInstance();
|
||||
|
||||
$txt_RequiresRemote = sprintf(
|
||||
_x(
|
||||
'This option requires the Backup to use the built-in default %1$sstorage location %2$s%3$s',
|
||||
'1 and 3 are opening and closing anchor/link tags, 2 is an icon',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<a href="' . esc_url($defaultStorageUrl) . '" target="_blank">',
|
||||
'<i class="far fa-hdd fa-fw fa-sm"></i>',
|
||||
'</a>'
|
||||
);
|
||||
|
||||
?>
|
||||
<div class="dup-ovr-ctrls-hdrs clearfix">
|
||||
<h3 class="font-bold margin-bottom-0">
|
||||
<i class="fas fa-link fa-fw"></i> <?php esc_html_e('Install Resources', 'duplicator-pro'); ?>
|
||||
</h3>
|
||||
<small class="xsmall dark-gray-color">
|
||||
<i><?php esc_html_e('Links are sensitive. Keep them safe!', 'duplicator-pro'); ?></i>
|
||||
</small>
|
||||
|
||||
<?php if (CapMng::can(CapMng::CAP_STORAGE, false)) { ?>
|
||||
<small class="float-right">
|
||||
<a
|
||||
class="dup-ovr-ref-links-more"
|
||||
href="javascript:void(0)"
|
||||
onclick="DupliJs.Pack.ShowRemote(<?php echo (int) $package->getId(); ?>, '<?php echo esc_js($package->getNameHash()); ?>');">
|
||||
<i class="fas fa-server fa-xs"></i> <?php esc_html_e('Storages', 'duplicator-pro'); ?>
|
||||
</a>
|
||||
</small>
|
||||
<?php } ?>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- =======================
|
||||
ARCHIVE FILE: -->
|
||||
<div class="dup-ovr-copy-flex-box">
|
||||
<div class="flex-item">
|
||||
<i class="far fa-file-archive fa-fw"></i>
|
||||
<b class="black-color">
|
||||
<?php esc_html_e('Backup File', 'duplicator-pro'); ?>
|
||||
</b>
|
||||
<sup>
|
||||
<?php
|
||||
$archiveFileToolTipTitle = sprintf(
|
||||
esc_html_x(
|
||||
'This link is used with the %1$sImport Link Install%2$s feature.
|
||||
Use the Copy Link button to copy this URL Backup File link to import on another WordPress site.',
|
||||
'1 and 2 are opening and closing anchor tags',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<a href="' . esc_url(ImportPageController::getInstance()->getMenuLink()) . '">',
|
||||
'</a>'
|
||||
);
|
||||
?>
|
||||
<i class="fas fa-question-circle fa-xs fa-fw dup-archive-help"
|
||||
data-tooltip-title="<?php esc_attr_e("Backup File", 'duplicator-pro'); ?>"
|
||||
data-tooltip="<?php echo esc_attr($archiveFileToolTipTitle); ?>"></i>
|
||||
</sup>
|
||||
</div>
|
||||
<div class="flex-item"></div>
|
||||
</div>
|
||||
<div class="dup-ovr-copy-flex-box dup-box-file">
|
||||
<?php if ($archive_exists) : ?>
|
||||
<div class="flex-item">
|
||||
<input type="text" class="dup-ovr-ref-links margin-bottom-0" readonly="readonly"
|
||||
value="<?php echo esc_attr($archiveDownloadURL); ?>"
|
||||
title="<?php echo esc_attr($archiveDownloadURL); ?>"
|
||||
onfocus="jQuery(this).select();" />
|
||||
<span class="fas fa-arrow-alt-circle-down dup-ovr-ref-links-icon"
|
||||
title="<?php esc_attr_e('Archive Import Link (URL)', 'duplicator-pro'); ?>"></span>
|
||||
</div>
|
||||
<div class="flex-item">
|
||||
<span onclick="jQuery(this).parent().parent().find('.dup-ovr-ref-links').select();">
|
||||
<span data-dup-copy-value="<?php echo esc_attr($archiveDownloadURL); ?>"
|
||||
class="button hollow small gray dup-ovr-ref-copy no-select">
|
||||
<i class='far fa-copy dup-cursor-pointer'></i>
|
||||
<?php esc_html_e('Copy Link', 'duplicator-pro'); ?>
|
||||
</span>
|
||||
</span>
|
||||
<span class="dup-ovr-ref-dwnld button hollow small gray "
|
||||
aria-label="<?php esc_html_e("Download Archive", 'duplicator-pro') ?>"
|
||||
onclick="DupliJs.Pack.DownloadFile('<?php echo esc_attr($archiveDownloadURL); ?>',
|
||||
'<?php echo esc_attr($package->getArchiveFilename()); ?>');">
|
||||
<i class="fas fa-download"></i> <?php esc_html_e('Download', 'duplicator-pro'); ?>
|
||||
</span>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div class="flex-item maroon">
|
||||
<?php
|
||||
echo wp_kses(
|
||||
$txt_RequiresRemote,
|
||||
[
|
||||
'a' => [
|
||||
'href' => [],
|
||||
'target' => [],
|
||||
],
|
||||
'i' => [
|
||||
'class' => [],
|
||||
],
|
||||
]
|
||||
);
|
||||
?>.
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<!-- =======================
|
||||
ARCHIVE INSTALLER: -->
|
||||
<?php
|
||||
switch ($global->installer_name_mode) {
|
||||
case GlobalEntity::INSTALLER_NAME_MODE_SIMPLE:
|
||||
$settingsPackageUrl = SettingsPageController::getInstance()->getMenuLink(SettingsPageController::L2_SLUG_PACKAGE);
|
||||
$lockIcon = 'fa-lock-open';
|
||||
$installerToolTipTitle = sprintf(
|
||||
__(
|
||||
'Using standard installer name. To improve security, switch to hashed change in %1$sSettings%2$s',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<a href="' . esc_url($settingsPackageUrl) . '" >',
|
||||
'</a>'
|
||||
);
|
||||
break;
|
||||
|
||||
case GlobalEntity::INSTALLER_NAME_MODE_WITH_HASH:
|
||||
default:
|
||||
$lockIcon = 'fa-lock';
|
||||
$installerToolTipTitle = __('Using more secure, hashed installer name.', 'duplicator-pro');
|
||||
break;
|
||||
}
|
||||
$installerName = $package->Installer->getDownloadName();
|
||||
?>
|
||||
|
||||
<i class="fas fa-bolt fa-fw"></i>
|
||||
<b class="black-color">
|
||||
<?php esc_html_e('Backup Installer', 'duplicator-pro'); ?>
|
||||
</b>
|
||||
<sup>
|
||||
<i class="fas <?php echo esc_attr($lockIcon); ?> dup-cursor-pointer fa-fw fa-xs dup-installer-help"
|
||||
style="padding-left:3px"
|
||||
data-tooltip="<?php echo esc_html($installerToolTipTitle); ?>"></i>
|
||||
</sup>
|
||||
<div class="dup-ovr-copy-flex-box dup-box-installer">
|
||||
<?php if ($installer_exists) : ?>
|
||||
<div class="flex-item">
|
||||
<input type="text" class="dup-ovr-ref-links margin-bottom-0" readonly="readonly"
|
||||
value="<?php echo esc_attr($installerName); ?>"
|
||||
title="<?php echo esc_attr($installerName); ?>"
|
||||
onfocus="jQuery(this).select();">
|
||||
<small class="dup-info-msg01 xsmall dark-gray-color">
|
||||
<i><?php esc_html_e('These links contain highly sensitive data. Share with extra caution!', 'duplicator-pro'); ?></i>
|
||||
</small>
|
||||
</div>
|
||||
<div class="flex-item">
|
||||
<span onclick="jQuery(this).parent().parent().find('.dup-ovr-ref-links').select();">
|
||||
<span data-dup-copy-value="<?php echo esc_attr($installerName); ?>"
|
||||
class="dup-ovr-ref-copy no-select button hollow small gray">
|
||||
<i class='far fa-copy dup-cursor-pointer'></i>
|
||||
<?php esc_html_e('Copy Name', 'duplicator-pro'); ?>
|
||||
</span>
|
||||
</span>
|
||||
<span class="dup-ovr-ref-dwnld button hollow small gray "
|
||||
aria-label="<?php esc_html_e("Download Installer", 'duplicator-pro') ?>"
|
||||
onclick="DupliJs.Pack.DownloadFile('<?php echo esc_attr($installerDownloadURL); ?>');">
|
||||
<i class="fas fa-download"></i> <?php esc_html_e('Download', 'duplicator-pro'); ?>
|
||||
</span>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div class="flex-item maroon">
|
||||
<?php
|
||||
echo wp_kses(
|
||||
$txt_RequiresRemote,
|
||||
[
|
||||
'a' => [
|
||||
'href' => [],
|
||||
'target' => [],
|
||||
],
|
||||
'i' => [
|
||||
'class' => [],
|
||||
],
|
||||
]
|
||||
);
|
||||
?>.
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
use Duplicator\Controllers\PackagesPageController;
|
||||
use Duplicator\Core\CapMng;
|
||||
use Duplicator\Package\AbstractPackage;
|
||||
use Duplicator\Package\DupPackage;
|
||||
use Duplicator\Package\Recovery\RecoveryPackage;
|
||||
use Duplicator\Views\ViewHelper;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var ?DupPackage $package
|
||||
*/
|
||||
|
||||
$package = $tplData['package'];
|
||||
|
||||
$pack_dbonly = $package->isDBOnly();
|
||||
$pack_format = strtolower($package->Archive->Format);
|
||||
$packageDetailsURL = PackagesPageController::getInstance()->getPackageDetailsURL($package->getId());
|
||||
$txt_DBOnly = __('DB Only', 'duplicator-pro');
|
||||
$archive_exists = ($package->getLocalPackageFilePath(AbstractPackage::FILE_TYPE_ARCHIVE) != false);
|
||||
$isRecoverable = RecoveryPackage::isPackageIdRecoverable($package->getId());
|
||||
|
||||
?>
|
||||
<td colspan="11">
|
||||
<div class="dup-package-row-details-wrapper">
|
||||
<div class="dup-ovr-hdr">
|
||||
<h3 class="font-bold">
|
||||
<i class="fas fa-archive"></i>
|
||||
<?php esc_html_e('Backup Overview', 'duplicator-pro'); ?>
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
<div class="dup-ovr-bar-flex-box">
|
||||
<div>
|
||||
<label><?php esc_html_e('WordPress', 'duplicator-pro'); ?></label>
|
||||
<?php echo esc_html($package->VersionWP); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label><?php esc_html_e('Duplicator', 'duplicator-pro'); ?></label>
|
||||
<?php echo esc_html($package->getVersion()); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label><?php esc_html_e('Format', 'duplicator-pro'); ?></label>
|
||||
<?php echo esc_html(strtoupper($pack_format)); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label><?php esc_html_e('Files', 'duplicator-pro'); ?></label>
|
||||
<?php echo ($pack_dbonly)
|
||||
? '<i>' . esc_html($txt_DBOnly) . '</i>'
|
||||
: number_format($package->Archive->FileCount); ?>
|
||||
</div>
|
||||
<div>
|
||||
<label><?php esc_html_e('Folders', 'duplicator-pro'); ?></label>
|
||||
<?php echo ($pack_dbonly)
|
||||
? '<i>' . esc_html($txt_DBOnly) . '</i>'
|
||||
: number_format($package->Archive->DirCount) ?>
|
||||
</div>
|
||||
<div>
|
||||
<label><?php esc_html_e('Tables', 'duplicator-pro'); ?></label>
|
||||
<?php
|
||||
printf(
|
||||
esc_html_x(
|
||||
'%1$d of %2$d',
|
||||
'Example: 7 of 10',
|
||||
'duplicator-pro'
|
||||
),
|
||||
(int) $package->Database->info->tablesFinalCount,
|
||||
(int) $package->Database->info->tablesBaseCount
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="dup-ovr-ctrls-flex-box">
|
||||
<div class="flex-item">
|
||||
<?php
|
||||
if (CapMng::can(CapMng::CAP_EXPORT, false)) {
|
||||
$tplMng->render('admin_pages/packages/row_parts/details_download_block');
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
|
||||
<div class="flex-item dup-ovr-opts">
|
||||
<div class="dup-ovr-ctrls-hdrs">
|
||||
<h3 class="font-bold margin-bottom-0">
|
||||
<?php esc_html_e('Options', 'duplicator-pro'); ?>
|
||||
</h3>
|
||||
<small class="xsmall dark-gray-color">
|
||||
<i><?php esc_html_e('Backup actions.', 'duplicator-pro'); ?></i>
|
||||
</small>
|
||||
</div>
|
||||
<ul class="no-bullet">
|
||||
<li>
|
||||
<a
|
||||
aria-label="<?php esc_attr_e("Go to Backup details screen", 'duplicator-pro') ?>"
|
||||
class="button hollow secondary expanded dup-details"
|
||||
href="<?php echo esc_url($packageDetailsURL); ?>">
|
||||
<span><i class="fas fa-search"></i> <?php esc_html_e("View Details", 'duplicator-pro') ?></span>
|
||||
</a>
|
||||
</li>
|
||||
<?php if (CapMng::can(CapMng::CAP_STORAGE, false)) { ?>
|
||||
<li>
|
||||
<?php if ($archive_exists) : ?>
|
||||
<button class="button hollow secondary expanded dup-transfer"
|
||||
aria-label="<?php esc_attr_e('Go to Backup transfer screen', 'duplicator-pro') ?>"
|
||||
onclick="DupliJs.Pack.OpenPackTransfer(<?php echo (int) $package->getId(); ?>); return false;">
|
||||
<span><i class="fa fa-exchange-alt fa-fw"></i> <?php esc_html_e("Transfer Backup", 'duplicator-pro') ?></span>
|
||||
</button>
|
||||
<?php else : ?>
|
||||
<span title="<?php esc_attr_e('Transfer Backups requires the use of built-in default storage!', 'duplicator-pro') ?>">
|
||||
<button class="button hollow secondary expanded disabled">
|
||||
<span><i class="fa fa-exchange-alt fa-fw"></i> <?php esc_html_e("Transfer Backup", 'duplicator-pro') ?></span>
|
||||
</button>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</li>
|
||||
<?php } ?>
|
||||
|
||||
<?php if (CapMng::can(CapMng::CAP_BACKUP_RESTORE, false)) { ?>
|
||||
<li>
|
||||
<button
|
||||
aria-label="<?php esc_attr_e("Recover this Backup", 'duplicator-pro') ?>"
|
||||
class="button hollow secondary expanded dupli-btn-open-recovery-box <?php echo ($isRecoverable) ? '' : 'maroon' ?>"
|
||||
data-package-id="<?php echo (int) $package->getId(); ?>">
|
||||
<?php ViewHelper::disasterIcon(true); ?>
|
||||
<?php esc_html_e("Disaster Recovery", 'duplicator-pro'); ?>
|
||||
</button>
|
||||
</li>
|
||||
<?php } ?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
use Duplicator\Core\CapMng;
|
||||
use Duplicator\Package\AbstractPackage;
|
||||
use Duplicator\Package\DupPackage;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var ?DupPackage $package
|
||||
*/
|
||||
|
||||
$package = $tplData['package'];
|
||||
$archive_exists = ($package->getLocalPackageFilePath(AbstractPackage::FILE_TYPE_ARCHIVE) != false);
|
||||
$installer_exists = ($package->getLocalPackageFilePath(AbstractPackage::FILE_TYPE_INSTALLER) != false);
|
||||
$archiveDownloadURL = $package->getLocalPackageFileURL(AbstractPackage::FILE_TYPE_ARCHIVE);
|
||||
$installerDownloadURL = $package->getLocalPackageFileURL(AbstractPackage::FILE_TYPE_INSTALLER);
|
||||
$pack_format = strtolower($package->Archive->Format);
|
||||
|
||||
if (!CapMng::can(CapMng::CAP_EXPORT, false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$isRunning = DupPackage::isPackageRunning();
|
||||
$canEnabled = ($package->haveRemoteStorage() || $package->haveLocalStorage());
|
||||
|
||||
if ($archive_exists) : ?>
|
||||
<nav class="dup-dnload-menu">
|
||||
<button
|
||||
class="dup-dnload-btn full-cell-button link-style no-select can-enabled"
|
||||
type="button"
|
||||
aria-haspopup="true"
|
||||
data-tooltip="<?php esc_attr_e('Download Backup.', 'duplicator-pro') ?>"
|
||||
<?php disabled(!$canEnabled || $isRunning); ?>>
|
||||
<i class="fa fa-download"></i>
|
||||
<span><?php esc_html_e("Download", 'duplicator-pro'); ?></span>
|
||||
</button>
|
||||
|
||||
<nav class="dup-dnload-menu-items no-display">
|
||||
<button
|
||||
aria-label="<?php esc_html_e("Download Installer and Archive", 'duplicator-pro') ?>"
|
||||
title="<?php echo ($installer_exists ? '' : esc_html__("Unable to locate both Backup files!", 'duplicator-pro')); ?>"
|
||||
onclick="DupliJs.Pack.DownloadFile('<?php echo esc_attr($archiveDownloadURL); ?>',
|
||||
'<?php echo esc_attr($package->getArchiveFilename()); ?>');
|
||||
setTimeout(function () {DupliJs.Pack.DownloadFile('<?php echo esc_attr($installerDownloadURL); ?>');}, 700);
|
||||
jQuery(this).parent().addClass('no-display');
|
||||
return false;"
|
||||
class="dup-dnload-both">
|
||||
<i class="fa fa-fw <?php echo ($installer_exists ? 'fa-download' : 'fa-exclamation-triangle') ?>"></i>
|
||||
<?php esc_html_e("Both Files", 'duplicator-pro') ?>
|
||||
</button>
|
||||
<button
|
||||
aria-label="<?php esc_html_e("Download Installer", 'duplicator-pro') ?>"
|
||||
title="<?php echo ($installer_exists) ? '' : esc_html__("Unable to locate installer Backup file!", 'duplicator-pro'); ?>"
|
||||
onclick="DupliJs.Pack.DownloadFile('<?php echo esc_attr($installerDownloadURL); ?>');
|
||||
jQuery(this).parent().addClass('no-display');
|
||||
return false;"
|
||||
class="dup-dnload-installer">
|
||||
<i class="fa fa-fw <?php echo ($installer_exists ? 'fa-bolt' : 'fa-exclamation-triangle') ?>"></i>
|
||||
<?php esc_html_e("Installer", 'duplicator-pro') ?>
|
||||
</button>
|
||||
<button
|
||||
aria-label="<?php esc_html_e("Download Archive", 'duplicator-pro') ?>"
|
||||
onclick="DupliJs.Pack.DownloadFile('<?php echo esc_attr($archiveDownloadURL); ?>',
|
||||
'<?php echo esc_attr($package->getArchiveFilename()); ?>');
|
||||
jQuery(this).parent().addClass('no-display');
|
||||
return false;"
|
||||
|
||||
class="dup-dnload-archive">
|
||||
<i class="fa-fw far fa-file-archive"></i>
|
||||
<?php echo esc_html__('Archive', 'duplicator-pro') . ' (' . esc_html($pack_format) . ')'; ?>
|
||||
</button>
|
||||
</nav>
|
||||
</nav>
|
||||
<?php else :
|
||||
?>
|
||||
<button
|
||||
type="button"
|
||||
class="full-cell-button link-style dup-remote-download <?php echo ($canEnabled ? 'can-enabled' : ''); ?>"
|
||||
data-package-id="<?php echo (int) $package->getId(); ?>"
|
||||
data-needs-download="<?php echo $package->haveLocalStorage() ? "false" : "true"; ?>"
|
||||
aria-label="<?php esc_attr_e("Download Backup", 'duplicator-pro') ?>"
|
||||
data-tooltip="<?php esc_attr_e("Download Backup.", 'duplicator-pro') ?>"
|
||||
<?php disabled(!$canEnabled || $isRunning); ?>>
|
||||
<i class="fas fa-download fa-fw"></i> <?php esc_html_e("Download", 'duplicator-pro'); ?>
|
||||
</button>
|
||||
<?php endif; ?>
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
use Duplicator\Core\CapMng;
|
||||
use Duplicator\Package\DupPackage;
|
||||
use Duplicator\Views\ViewHelper;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var ?DupPackage $package
|
||||
*/
|
||||
|
||||
$package = $tplData['package'];
|
||||
|
||||
?>
|
||||
<div class="dup-package-flags">
|
||||
<?php if ($package->hasFlag(DupPackage::FLAG_MANUAL) || $package->hasFlag(DupPackage::FLAG_SCHEDULE_RUN_NOW)) { ?>
|
||||
<span class="icon-wrapper" title="<?php esc_attr_e('Manual Backup', 'duplicator-pro') ?>">
|
||||
<i class="fa-solid fa-hand"></i>
|
||||
</span>
|
||||
<?php } ?>
|
||||
<?php if ($package->hasFlag(DupPackage::FLAG_SCHEDULE)) { ?>
|
||||
<span class="icon-wrapper" title="<?php esc_attr_e('Schedule Backup', 'duplicator-pro') ?>">
|
||||
<i class="fa-solid fa-clock"></i>
|
||||
</span>
|
||||
<?php } ?>
|
||||
<?php if ($package->hasFlag(DupPackage::FLAG_HAVE_LOCAL)) { ?>
|
||||
<span
|
||||
class="icon-wrapper cursor-pointer"
|
||||
title="<?php esc_attr_e('The Backup is in Local Storage', 'duplicator-pro') ?>"
|
||||
onclick="DupliJs.Pack.ShowRemote(<?php echo (int) $package->getId(); ?>, '<?php echo esc_js($package->getNameHash()); ?>');">
|
||||
<i class="fa-solid fa-hard-drive"></i>
|
||||
</span>
|
||||
<?php } ?>
|
||||
<?php if ($package->hasFlag(DupPackage::FLAG_HAVE_REMOTE)) { ?>
|
||||
<span
|
||||
class="icon-wrapper cursor-pointer remote-storage-flag"
|
||||
title="<?php esc_attr_e('The Backup is in Remote Storage', 'duplicator-pro') ?>"
|
||||
onclick="DupliJs.Pack.ShowRemote(<?php echo (int) $package->getId(); ?>, '<?php echo esc_js($package->getNameHash()); ?>');">
|
||||
<i class="fa-solid fa-cloud"></i>
|
||||
</span>
|
||||
<?php } ?>
|
||||
<?php if ($package->hasFlag(DupPackage::FLAG_DB_ONLY)) { ?>
|
||||
<span class="icon-wrapper" title="<?php esc_attr_e('Database Only Backup', 'duplicator-pro') ?>">
|
||||
<i class="fa-solid fa-database"></i>
|
||||
</span>
|
||||
<?php } ?>
|
||||
<?php if ($package->hasFlag(DupPackage::FLAG_MEDIA_ONLY)) { ?>
|
||||
<span class="icon-wrapper" title="<?php esc_attr_e('Media Only Backup', 'duplicator-pro') ?>">
|
||||
<i class="fa-solid fa-images"></i>
|
||||
</span>
|
||||
<?php } ?>
|
||||
<?php if (CapMng::can(CapMng::CAP_BACKUP_RESTORE, false)) { ?>
|
||||
<?php if ($package->hasFlag(DupPackage::FLAG_DISASTER_AVAIABLE) || $package->hasFlag(DupPackage::FLAG_DISASTER_SET)) {
|
||||
if ($package->hasFlag(DupPackage::FLAG_DISASTER_SET)) {
|
||||
$title = __("Disaster Recovery URL is set on this Backup", 'duplicator-pro');
|
||||
$colorClass = 'green';
|
||||
} else {
|
||||
$colorClass = '';
|
||||
$title = __('This Backup is available for Disaster Recovery', 'duplicator-pro');
|
||||
}
|
||||
?>
|
||||
<span
|
||||
class="dupli-btn-open-recovery-box icon-wrapper link-style no-decoration"
|
||||
aria-label="<?php echo esc_attr($title); ?>"
|
||||
title="<?php echo esc_attr($title); ?>"
|
||||
data-package-id="<?php echo (int) $package->getId(); ?>">
|
||||
<?php ViewHelper::disasterIcon(true, $colorClass); ?>
|
||||
</span>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<?php if ($package->hasFlag(DupPackage::FLAG_CREATED_AFTER_RESTORE)) { ?>
|
||||
<span class="icon-wrapper" title="<?php esc_attr_e('This Backup is created after the Last Restored Backup', 'duplicator-pro') ?>">
|
||||
<i class="fa-solid fa-clock-rotate-left maroon"></i>
|
||||
</span>
|
||||
<?php } ?>
|
||||
</div>
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
use Duplicator\Controllers\PackagesPageController;
|
||||
use Duplicator\Package\AbstractPackage;
|
||||
use Duplicator\Package\DupPackage;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var ?DupPackage $package
|
||||
*/
|
||||
$package = $tplData['package'];
|
||||
/** @var int */
|
||||
$status = $tplData['status'];
|
||||
?>
|
||||
<div class="progress-error text-center">
|
||||
<?php
|
||||
switch ($status) {
|
||||
case AbstractPackage::STATUS_ERROR:
|
||||
$packageDetailsURL = PackagesPageController::getInstance()->getPackageDetailsURL($package->getId());
|
||||
?>
|
||||
<a type="button" class="dup-cell-err-btn" href="<?php echo esc_url($packageDetailsURL) ?>">
|
||||
<i class="fa fa-exclamation-triangle fa-xs"></i>
|
||||
<?php esc_html_e('Error Processing', 'duplicator-pro') ?>
|
||||
</a>
|
||||
<?php
|
||||
break;
|
||||
case AbstractPackage::STATUS_BUILD_CANCELLED:
|
||||
?>
|
||||
<i class="fas fa-info-circle fa-sm"></i>
|
||||
<?php esc_html_e('Build Cancelled', 'duplicator-pro') ?>
|
||||
<?php
|
||||
break;
|
||||
case AbstractPackage::STATUS_PENDING_CANCEL:
|
||||
?>
|
||||
<i class="fas fa-info-circle fa-sm"></i>
|
||||
<?php esc_html_e('Cancelling Build', 'duplicator-pro') ?>
|
||||
<?php
|
||||
break;
|
||||
case AbstractPackage::STATUS_STORAGE_CANCELLED:
|
||||
?>
|
||||
<i class="fas fa-info-circle fa-sm"></i>
|
||||
<?php esc_html_e('Storage Cancelled', 'duplicator-pro') ?>
|
||||
<?php
|
||||
break;
|
||||
case AbstractPackage::STATUS_REQUIREMENTS_FAILED:
|
||||
$logFileExists = file_exists($package->getSafeLogFilepath());
|
||||
|
||||
if ($logFileExists) {
|
||||
$baseUrl = rtrim($package->StoreURL, '/');
|
||||
$logsDir = DUPLICATOR_LOGS_DIR_NAME;
|
||||
$fileName = $package->getLogFilename();
|
||||
$logLink = "{$baseUrl}/{$logsDir}/{$fileName}";
|
||||
?>
|
||||
<a href="<?php echo esc_url($logLink) ?>" target="_blank">
|
||||
<i class="fas fa-info-circle"></i> <?php esc_html_e('Requirements Failed', 'duplicator-pro') ?>
|
||||
</a>
|
||||
<?php
|
||||
} else {
|
||||
?>
|
||||
<i class="fas fa-info-circle"></i> <?php esc_html_e('Requirements Failed', 'duplicator-pro') ?>
|
||||
<?php
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
use Duplicator\Core\CapMng;
|
||||
use Duplicator\Package\DupPackage;
|
||||
use Duplicator\Views\ViewHelper;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var ?DupPackage $package
|
||||
*/
|
||||
|
||||
$package = $tplData['package'];
|
||||
|
||||
if (!CapMng::can(CapMng::CAP_BACKUP_RESTORE, false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$isRunning = DupPackage::isPackageRunning();
|
||||
$canEnabled = ($package->haveRemoteStorage() || $package->haveLocalStorage());
|
||||
?>
|
||||
<button
|
||||
type="button"
|
||||
class="full-cell-button dup-restore-backup link-style <?php echo ($canEnabled ? 'can-enabled' : ''); ?>"
|
||||
data-package-id="<?php echo (int) $package->getId(); ?>"
|
||||
data-needs-download="<?php echo $package->haveLocalStorage() ? "false" : "true"; ?>"
|
||||
aria-label="<?php esc_attr_e("Restore backup", 'duplicator-pro') ?>"
|
||||
title="<?php esc_attr_e("Restore backup.", 'duplicator-pro') ?>"
|
||||
<?php disabled(!$canEnabled || $isRunning); ?>>
|
||||
<?php ViewHelper::restoreIcon(); ?> <?php esc_html_e("Restore", 'duplicator-pro'); ?>
|
||||
</button>
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
use Duplicator\Libs\Snap\SnapWP;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
?>
|
||||
<br>
|
||||
<b><?php esc_html_e('Please Retry:', 'duplicator-pro'); ?></b><br>
|
||||
<?php esc_html_e('Unable to perform a full scan and read JSON file, please try the following actions.', 'duplicator-pro'); ?><br>
|
||||
<?php esc_html_e('1. Go back and create a root path directory filter to validate the site is scan-able.', 'duplicator-pro'); ?><br>
|
||||
<?php esc_html_e('2. Continue to add/remove filters to isolate which path is causing issues.', 'duplicator-pro'); ?><br>
|
||||
<?php esc_html_e('3. This message will go away once the correct filters are applied.', 'duplicator-pro'); ?><br>
|
||||
<br>
|
||||
<b><?php esc_html_e('Common Issues:', 'duplicator-pro'); ?></b><br>
|
||||
<?php
|
||||
esc_html_e(
|
||||
'- On some budget hosts scanning over 30k files can lead to timeout/gateway issues.
|
||||
Consider scanning only your main WordPress site and avoid trying to backup other external directories.',
|
||||
'duplicator-pro'
|
||||
);
|
||||
?><br>
|
||||
<?php
|
||||
esc_html_e(
|
||||
'- Symbolic link recursion can cause timeouts. Ask your server admin if any are present in the scan path.
|
||||
If they are add the full path as a filter and try running the scan again.',
|
||||
'duplicator-pro'
|
||||
); ?><br>
|
||||
<br>
|
||||
<b><?php esc_html_e('Details:', 'duplicator-pro'); ?></b><br>
|
||||
<?php esc_html_e('JSON Service:', 'duplicator-pro'); ?> /wp-admin/admin-ajax.php?action=duplicator_package_scan<br>
|
||||
<?php esc_html_e('Scan Path:', 'duplicator-pro'); ?> [<?php echo esc_html(SnapWP::getHomePath(true)); ?>]<br><br>
|
||||
|
||||
<b><?php esc_html_e('More Information:', 'duplicator-pro'); ?></b><br>
|
||||
<?php
|
||||
printf(
|
||||
esc_html__(
|
||||
'Please see the online FAQ titled %1$s"How to resolve scanner warnings/errors and timeout issues?"%2$s',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<a href="' . esc_url(DUPLICATOR_DUPLICATOR_DOCS_URL . 'how-to-resolve-scanner-warnings-errors-and-timeout-issues') . '" target="_blank">',
|
||||
'</a>'
|
||||
);
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
?>
|
||||
<div id="addonsites-block" class="scan-item">
|
||||
<div class='title' onclick="DupliJs.Pack.toggleScanItem(this);">
|
||||
<div class="text"><i class="fa fa-caret-right"></i> <?php esc_html_e('Addon Sites', 'duplicator-pro');?></div>
|
||||
<div id="data-arc-status-addonsites"></div>
|
||||
</div>
|
||||
<div class="info">
|
||||
<div style="margin-bottom:10px;">
|
||||
<?php esc_html_e(
|
||||
'An "Addon Site" is a separate WordPress site(s) residing in subdirectories within this site.
|
||||
If you confirm these to be separate sites, then it is recommended that you exclude them by checking
|
||||
the corresponding boxes below and clicking the \'Add Filters & Rescan\' button. To backup the other
|
||||
sites install the plugin on the sites needing to be backed-up.',
|
||||
'duplicator-pro'
|
||||
); ?>
|
||||
</div>
|
||||
<script id="hb-addon-sites" type="text/x-handlebars-template">
|
||||
<div class="container">
|
||||
<div class="hdrs">
|
||||
<span style="font-weight:bold">
|
||||
<?php esc_html_e('Quick Filters', 'duplicator-pro'); ?>
|
||||
</span>
|
||||
</div>
|
||||
<div class="data">
|
||||
{{#if ARC.FilterInfo.Dirs.AddonSites.length}}
|
||||
{{#each ARC.FilterInfo.Dirs.AddonSites as |path|}}
|
||||
<div class="directory horizontal-input-row">
|
||||
<input type="checkbox" name="dir_paths[]" value="{{path}}" id="as_dir_{{@index}}"/>
|
||||
<label for="as_dir_{{@index}}" title="{{path}}">
|
||||
{{path}}
|
||||
</label>
|
||||
</div>
|
||||
{{/each}}
|
||||
{{else}}
|
||||
<div class="data-padded">
|
||||
<?php esc_html_e('No add on sites found.', 'duplicator-pro'); ?>
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="apply-btn">
|
||||
<div class="apply-warn">
|
||||
<?php esc_html_e('*Checking a directory will exclude all items in that path recursively.', 'duplicator-pro'); ?>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
class="button gray hollow tiny dupli-quick-filter-btn"
|
||||
disabled="disabled"
|
||||
onclick="DupliJs.Pack.applyFilters(this, 'addon')"
|
||||
>
|
||||
<i class="fa fa-filter fa-sm"></i> <?php esc_html_e('Add Filters & Rescan', 'duplicator-pro');?>
|
||||
</button>
|
||||
</div>
|
||||
</script>
|
||||
<div id="hb-addon-sites-result" class="hb-files-style"></div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,172 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Libs\Snap\SnapString;
|
||||
use Duplicator\Package\Archive\PackageArchive;
|
||||
use Duplicator\Models\GlobalEntity;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var \Duplicator\Package\DupPackage $package
|
||||
*/
|
||||
$package = $tplData['package'];
|
||||
$global = GlobalEntity::getInstance();
|
||||
$totalSizeMax = ($global->getBuildMode() == PackageArchive::BUILD_MODE_ZIP_ARCHIVE)
|
||||
? DUPLICATOR_SCAN_SITE_ZIP_ARCHIVE_WARNING_SIZE
|
||||
: DUPLICATOR_SCAN_SITE_WARNING_SIZE;
|
||||
?>
|
||||
<div class="scan-item">
|
||||
<div class='title' onclick="DupliJs.Pack.toggleScanItem(this);">
|
||||
<div class="text"><i class="fa fa-caret-right"></i> <?php esc_html_e('Size Checks', 'duplicator-pro'); ?></div>
|
||||
<div id="data-arc-status-size"></div>
|
||||
</div>
|
||||
<div class="info" id="scan-item-file-size">
|
||||
<b><?php esc_html_e('Size', 'duplicator-pro'); ?>:</b> <span id="data-arc-size2"></span> |
|
||||
<b><?php esc_html_e('Files', 'duplicator-pro'); ?>:</b> <span id="data-arc-files"></span> |
|
||||
<b><?php esc_html_e('Directories ', 'duplicator-pro'); ?>:</b> <span id="data-arc-dirs"></span> |
|
||||
<b><?php esc_html_e('Total', 'duplicator-pro'); ?>:</b> <span id="data-arc-fullcount"></span>
|
||||
<br />
|
||||
<?php echo wp_kses(
|
||||
__('Compressing larger sites on <i>some budget hosts</i> may cause timeouts.', 'duplicator-pro'),
|
||||
['i' => []]
|
||||
); ?>
|
||||
<i>
|
||||
<a href="javascipt:void(0)" onclick="jQuery('#size-more-details').toggle(100); return false;">
|
||||
[<?php esc_html_e('more details...', 'duplicator-pro'); ?>]
|
||||
</a>
|
||||
</i>
|
||||
<div id="size-more-details">
|
||||
<b><?php esc_html_e('Overview', 'duplicator-pro'); ?>:</b><br />
|
||||
<?php echo wp_kses(
|
||||
sprintf(
|
||||
__(
|
||||
'This notice is triggered at <b>%s</b> and can be ignored on most hosts.
|
||||
If the build process hangs or is unable to complete then this host has strict processing limits.
|
||||
Below are some options you can take to overcome constraints setup on this host.',
|
||||
'duplicator-pro'
|
||||
),
|
||||
SnapString::byteSize($totalSizeMax)
|
||||
),
|
||||
['b' => []]
|
||||
); ?>
|
||||
<br /><br />
|
||||
<b><?php esc_html_e('Timeout Options', 'duplicator-pro'); ?>: </b><br />
|
||||
<ul>
|
||||
<li><?php esc_html_e('Apply the "Quick Filters" below or click the back button to apply on previous page.', 'duplicator-pro'); ?> </li>
|
||||
<li>
|
||||
<?php esc_html_e('See the FAQ link to adjust this hosts timeout limits: ', 'duplicator-pro'); ?>
|
||||
<a href="<?php echo esc_html(DUPLICATOR_DUPLICATOR_DOCS_URL); ?>how-to-handle-server-timeout-issues" target="_blank">
|
||||
<?php esc_html_e('What can I try for Timeout Issues?', 'duplicator-pro'); ?>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="hb-files-large-result" class="dup-tree-section hb-files-style">
|
||||
<div class="container">
|
||||
<div class="hdrs">
|
||||
<span style="font-weight:bold">
|
||||
<?php esc_html_e('Quick Filters', 'duplicator-pro'); ?>
|
||||
<sup>
|
||||
<i
|
||||
class="fa-solid fa-question-circle fa-sm dark-gray-color"
|
||||
data-tooltip-title="<?php esc_attr_e("Large Files", 'duplicator-pro'); ?>"
|
||||
data-tooltip="<?php
|
||||
echo wp_kses(
|
||||
sprintf(
|
||||
__(
|
||||
'Files over %1$s are listed below. Larger files such as movies or zipped content
|
||||
can cause timeout issues on some budget hosts. If you are having issues creating
|
||||
a Backup try excluding the directory paths below or go back to Step 1 and add them.
|
||||
<br><br><b>Right click on tree node to open the bulk actions menu</b>',
|
||||
'duplicator-pro'
|
||||
),
|
||||
SnapString::byteSize(DUPLICATOR_SCAN_WARN_FILE_SIZE)
|
||||
),
|
||||
[
|
||||
'br' => [],
|
||||
'b' => [],
|
||||
]
|
||||
); ?>">
|
||||
</i>
|
||||
</sup>
|
||||
</span>
|
||||
<div class='hdrs-up-down'>
|
||||
<i
|
||||
class="fa fa-caret-up fa-lg dup-nav-toggle"
|
||||
onclick="DupliJs.Pack.toggleAllDirPath(this, 'hide')"
|
||||
title="<?php esc_attr_e("Hide All", 'duplicator-pro'); ?>">
|
||||
</i>
|
||||
<i
|
||||
class="fa fa-caret-down fa-lg dup-nav-toggle"
|
||||
onclick="DupliJs.Pack.toggleAllDirPath(this, 'show')"
|
||||
title="<?php esc_attr_e("Show All", 'duplicator-pro'); ?>">
|
||||
</i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tree-nav-bar">
|
||||
<div class="container">
|
||||
<button
|
||||
type="button"
|
||||
id="hb-files-large-tree-full-load"
|
||||
class="tree-full-load-button dup-tree-show-all button gray hollow small margin-bottom-0">
|
||||
<?php esc_html_e('Show All', 'duplicator-pro') ?>
|
||||
</button>
|
||||
<span class="size"><?php esc_html_e('Size', 'duplicator-pro') ?></span>
|
||||
<span class="nodes"><?php esc_html_e('Nodes', 'duplicator-pro') ?></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="data">
|
||||
<div id="hb-files-large-jstree" class="dup-tree-main-wrapper"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="apply-btn">
|
||||
<div class="apply-warn">
|
||||
<?php esc_html_e('*Checking a directory will exclude all items in that path recursively.', 'duplicator-pro'); ?>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
class="button gray hollow tiny dupli-quick-filter-btn"
|
||||
disabled="disabled" onclick="DupliJs.Pack.applyFilters(this, 'large')">
|
||||
<i class="fa fa-filter fa-sm"></i> <?php esc_html_e('Add Filters & Rescan', 'duplicator-pro'); ?>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="button gray hollow tiny"
|
||||
onclick="DupliJs.Pack.showPathsDlg('large')"
|
||||
title="<?php esc_attr_e('Copy Paths to Clipboard', 'duplicator-pro'); ?>">
|
||||
<i class="fa far fa-clipboard" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- =======================
|
||||
DIALOG: PATHS COPY & PASTE -->
|
||||
<div id="dup-archive-paths" style="display:none">
|
||||
<b><i class="fa fa-folder"></i> <?php esc_html_e('Directories', 'duplicator-pro'); ?></b>
|
||||
<div class="copy-butto float-right">
|
||||
<button type="button" class="button secondary hollow tiny" onclick="DupliJs.Pack.copyText(this, '.arc-paths-dlg textarea.path-dirs')">
|
||||
<i class="fa far fa-clipboard"></i> <?php esc_html_e('Click to Copy', 'duplicator-pro'); ?>
|
||||
</button>
|
||||
</div>
|
||||
<textarea class="path-dirs"></textarea>
|
||||
<b><i class="fa fa-files fa-sm"></i> <?php esc_html_e('Files', 'duplicator-pro'); ?></b>
|
||||
<div class="copy-button float-right">
|
||||
<button type="button" class="button secondary hollow tiny" onclick="DupliJs.Pack.copyText(this, '.arc-paths-dlg textarea.path-files')">
|
||||
<i class="fa far fa-clipboard"></i> <?php esc_html_e('Click to Copy', 'duplicator-pro'); ?>
|
||||
</button>
|
||||
</div>
|
||||
<textarea class="path-files"></textarea>
|
||||
<small><?php esc_html_e('Copy the paths above and apply them as needed on Step 1 > Archive > Files section.', 'duplicator-pro'); ?></small>
|
||||
</div>
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
?>
|
||||
<div class="scan-item ">
|
||||
<div class='title' onclick="DupliJs.Pack.toggleScanItem(this);">
|
||||
<div class="text"><i class="fa fa-caret-right"></i> <?php esc_html_e('Database only', 'duplicator-pro'); ?></div>
|
||||
<div id="only-db-scan-status"><div class="badge badge-warn"><?php esc_html_e("Notice", 'duplicator-pro'); ?></div></div>
|
||||
</div>
|
||||
<div class="info">
|
||||
<?php esc_html_e("Only the database and a copy of the installer.php will be included in the Backup file.", 'duplicator-pro'); ?>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
?>
|
||||
<div class="scan-item ">
|
||||
<div class='title' onclick="DupliJs.Pack.toggleScanItem(this);">
|
||||
<div class="text"><i class="fa fa-caret-right"></i> <?php esc_html_e('File checks skipped', 'duplicator-pro'); ?></div>
|
||||
<div id="skip-archive-scan-status"><div class="badge badge-warn"><?php esc_html_e("Notice", 'duplicator-pro'); ?></div></div>
|
||||
</div>
|
||||
<div class="info">
|
||||
<?php esc_html_e("All file checks are skipped. This could cause problems during extraction if problematic files are included.", 'duplicator-pro'); ?>
|
||||
<br><br>
|
||||
<b><?php esc_html_e("To enable, uncheck Backups > Advanced Settings > Scan File Checks > \"Skip\" to enable.", 'duplicator-pro'); ?></b>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Models\GlobalEntity;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var \Duplicator\Package\DupPackage $package
|
||||
*/
|
||||
|
||||
$package = $tplData['package'];
|
||||
$global = GlobalEntity::getInstance();
|
||||
?>
|
||||
|
||||
<!-- ================================================================
|
||||
ARCHIVE
|
||||
================================================================ -->
|
||||
<div class="details-title">
|
||||
<i class="far fa-file-archive fa-sm fa-fw"></i> <?php esc_html_e('Archive', 'duplicator-pro'); ?>
|
||||
<sup class="dup-small-ext-type">
|
||||
<?php if ($package->Installer->isSecure()) : ?>
|
||||
<i class="fas fa-lock fa-fw fa-sm" title="<?php esc_html_e('Requires Password to Extract', 'duplicator-pro'); ?>"></i>
|
||||
<?php endif; ?>
|
||||
<?php echo esc_html($global->getArchiveExtensionType()); ?>
|
||||
</sup>
|
||||
</div>
|
||||
<div class="scan-header scan-item-first">
|
||||
<i class="fas fa-folder-open fa-sm"></i>
|
||||
<?php esc_html_e("Files", 'duplicator-pro'); ?>
|
||||
<div class="scan-header-details">
|
||||
<div class="dup-scan-filter-status">
|
||||
<?php if ($package->isDBOnly()) { ?>
|
||||
<i class="fa fa-filter fa-sm"></i> <?php esc_html_e('Database Only', 'duplicator-pro'); ?>
|
||||
<?php } elseif ($package->Archive->FilterOn) { ?>
|
||||
<i class="fa fa-filter fa-sm"></i> <?php esc_html_e('Enabled', 'duplicator-pro'); ?>
|
||||
<?php } ?>
|
||||
</div>
|
||||
|
||||
<div id="data-arc-size1"></div>
|
||||
<i class="fa fa-question-circle data-size-help"
|
||||
data-tooltip-title="<?php esc_attr_e("File Size:", 'duplicator-pro'); ?>"
|
||||
data-tooltip="<?php
|
||||
esc_html_e(
|
||||
'The files size represents only the included files before compression is applied.
|
||||
It does not include the size of the database script and in most cases the Backup size
|
||||
once completed will be smaller than this number unless shell execution zip with no compression is enabled.',
|
||||
'duplicator-pro'
|
||||
); ?>"></i>
|
||||
<div class="dup-data-size-uncompressed"><?php esc_html_e("uncompressed", 'duplicator-pro'); ?></div>
|
||||
</div>
|
||||
</div>
|
||||
<?php if ($package->isDBOnly()) {
|
||||
$tplMng->render('admin_pages/packages/scan/items/archive/files_db_only');
|
||||
} elseif ($global->skip_archive_scan) {
|
||||
$tplMng->render('admin_pages/packages/scan/items/archive/files_skip_scan');
|
||||
} else {
|
||||
// SIZE CHECKS
|
||||
$tplMng->render('admin_pages/packages/scan/items/archive/files');
|
||||
// ADDON SITES
|
||||
$tplMng->render('admin_pages/packages/scan/items/archive/addons');
|
||||
// UNREADABLE FILES
|
||||
$tplMng->render('admin_pages/packages/scan/items/archive/unreadable');
|
||||
} ?>
|
||||
<?php if (is_multisite()) {
|
||||
$tplMng->render('admin_pages/packages/scan/items/archive/multisite');
|
||||
} ?>
|
||||
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
?>
|
||||
<div id="network-filters-scan-item" class="scan-item">
|
||||
<div class='title' onclick="DupliJs.Pack.toggleScanItem(this);">
|
||||
<div class="text"><i class="fa fa-caret-right"></i> <?php esc_html_e('Network Site Filters', 'duplicator-pro');?></div>
|
||||
<div id="data-arc-status-network"></div>
|
||||
</div>
|
||||
<div class="info">
|
||||
<script id="hb-filter-network-sites" type="text/x-handlebars-template">
|
||||
<div class="container">
|
||||
<div class="data">
|
||||
{{#if ARC.Status.HasFilteredSites}}
|
||||
<p class="red">
|
||||
<?php esc_html_e(
|
||||
"Some sites have been excluded from the network.
|
||||
With this backup it will not be possible to restore the network but only perform subsite to standalone conversions.",
|
||||
'duplicator-pro'
|
||||
); ?>
|
||||
</p>
|
||||
<b><?php esc_html_e('EXCLUDED SITES', 'duplicator-pro'); ?></b>
|
||||
<ol>
|
||||
{{#each ARC.FilteredSites as |site|}}
|
||||
<li>{{site.blogname}} </li>
|
||||
{{/each}}
|
||||
</ol>
|
||||
{{else}}
|
||||
<?php esc_html_e("No network sites has been excluded from the Backup.", 'duplicator-pro'); ?>
|
||||
{{/if}}
|
||||
{{#if ARC.Status.HasNotImportableSites}}
|
||||
<p class="red">
|
||||
<?php esc_html_e(
|
||||
"Tables and/or paths have been manually excluded from some sites so the Backup will not be
|
||||
compatible with the Drag and Drop import. An install using the installer.php can still be performed, however.",
|
||||
'duplicator-pro'
|
||||
); ?>
|
||||
</p>
|
||||
{{#each ARC.Subsites as |site|}}
|
||||
{{#compare site.filteredTables.length '||' site.filteredPaths.length}}
|
||||
<p><b>{{site.blogname}}</b></p>
|
||||
<div class="subsite-filter-info">
|
||||
{{#compare site.filteredTables.length '>' 0}}
|
||||
<?php esc_html_e('Tables:', 'duplicator-pro'); ?>
|
||||
<ol>
|
||||
{{#each site.filteredTables as |filteredTable|}}
|
||||
<li>{{filteredTable}}</li>
|
||||
{{/each}}
|
||||
</ol>
|
||||
{{/compare}}
|
||||
{{#compare site.filteredPaths.length '>' 0}}
|
||||
<?php esc_html_e('Paths:', 'duplicator-pro'); ?>
|
||||
<ol>
|
||||
{{#each site.filteredPaths as |filteredPath|}}
|
||||
<li>{{filteredPath}}</li>
|
||||
{{/each}}
|
||||
</ol>
|
||||
{{/compare}}
|
||||
</div>
|
||||
{{/compare}}
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
<div id="hb-filter-network-sites-result"></div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
?>
|
||||
<div id="scan-unreadable-items" class="scan-item">
|
||||
<div class='title' onclick="DupliJs.Pack.toggleScanItem(this);">
|
||||
<div class="text"><i class="fa fa-caret-right"></i> <?php esc_html_e('Read Checks', 'duplicator-pro');?></div>
|
||||
<div id="data-arc-status-unreadablefiles"></div>
|
||||
</div>
|
||||
<div class="info">
|
||||
<?php
|
||||
echo wp_kses(
|
||||
__(
|
||||
'PHP is unable to read the following items and they will <u>not</u> be included in the Backup.
|
||||
Please work with your host to adjust the permissions or resolve the symbolic-link(s) shown in the lists below.
|
||||
If these items are not needed then this notice can be ignored.',
|
||||
'duplicator-pro'
|
||||
),
|
||||
['u' => []]
|
||||
);
|
||||
?>
|
||||
<script id="unreadable-files" type="text/x-handlebars-template">
|
||||
<div class="container">
|
||||
<div class="data-padded">
|
||||
<b><?php esc_html_e('Unreadable Items:', 'duplicator-pro');?></b> <br/>
|
||||
<div class="directory">
|
||||
{{#if ARC.UnreadableItems}}
|
||||
{{#each ARC.UnreadableItems as |uitem|}}
|
||||
<i class="fa fa-lock fa-sm"></i> {{uitem}} <br/>
|
||||
{{/each}}
|
||||
{{else}}
|
||||
<i>
|
||||
<?php esc_html_e('No unreadable items found.', 'duplicator-pro'); ?>
|
||||
<br>
|
||||
</i>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<b><?php esc_html_e('Recursive Links:', 'duplicator-pro');?></b> <br/>
|
||||
<div class="directory">
|
||||
{{#if ARC.RecursiveLinks}}
|
||||
{{#each ARC.RecursiveLinks as |link|}}
|
||||
<i class="fa fa-lock fa-sm"></i> {{link}} <br/>
|
||||
{{/each}}
|
||||
{{else}}
|
||||
<i>
|
||||
<?php esc_html_e('No recursive sym-links found.', 'duplicator-pro'); ?>
|
||||
<br>
|
||||
</i>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<b><?php esc_html_e('Open Basedir Restricted Items:', 'duplicator-pro');?></b> <br/>
|
||||
<div class="directory">
|
||||
{{#if ARC.PathsOutOpenbaseDir}}
|
||||
{{#each ARC.PathsOutOpenbaseDir as |openBaseDiritem|}}
|
||||
<i class="fa fa-lock fa-sm"></i> {{openBaseDiritem}} <br/>
|
||||
{{/each}}
|
||||
{{else}}
|
||||
<i>
|
||||
<?php esc_html_e('No open_basedir restricted items found.', 'duplicator-pro'); ?>
|
||||
<br>
|
||||
</i>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
<div id="unreadable-files-result" class="hb-files-style"></div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
?>
|
||||
|
||||
<div class="scan-item">
|
||||
<div class="title" onclick="DupliJs.Pack.toggleScanItem(this);">
|
||||
<div class="text"><i class="fa fa-caret-right"></i> <?php esc_html_e('Database excluded', 'duplicator-pro');?></div>
|
||||
<div id="data-db-status-size1"></div>
|
||||
</div>
|
||||
<div class="info">
|
||||
<?php esc_html_e(
|
||||
'The database is excluded from the Backup build process.
|
||||
To include it make sure to check the "Database" Backup component checkbox at Step 1 of the build process.',
|
||||
'duplicator-pro'
|
||||
); ?>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Libs\WpUtils\WpDbUtils;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var \Duplicator\Package\DupPackage $package
|
||||
*/
|
||||
|
||||
$package = $tplData['package'];
|
||||
?>
|
||||
<!-- ================================================================
|
||||
DATABASE
|
||||
================================================================ -->
|
||||
<div class="scan-header">
|
||||
<i class="fas fa-database fa-fw fa-sm"></i>
|
||||
<?php esc_html_e("Database", 'duplicator-pro'); ?>
|
||||
<div class="scan-header-details">
|
||||
<small style="font-weight:normal; font-size:12px">
|
||||
<?php if ($package->Database->Compatible) { ?>
|
||||
<i style="color:maroon"><?php esc_html_e('Compatibility Mode Enabled', 'duplicator-pro'); ?></i>
|
||||
<?php } ?>
|
||||
</small>
|
||||
<div class="dup-scan-filter-status">
|
||||
<?php if ($package->Database->FilterOn) { ?>
|
||||
<i class="fa fa-filter fa-sm"></i>
|
||||
<?php esc_html_e('Enabled', 'duplicator-pro'); ?>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<div id="data-db-size1"></div>
|
||||
<i class="fa fa-question-circle data-size-help"
|
||||
data-tooltip-title="<?php esc_attr_e("Database Size:", 'duplicator-pro'); ?>"
|
||||
data-tooltip="<?php
|
||||
esc_html_e(
|
||||
'The database size represents only the included tables. The process for gathering the size uses the query SHOW TABLE STATUS.
|
||||
The overall size of the database file can impact the final size of the Backup.',
|
||||
'duplicator-pro'
|
||||
); ?>"></i>
|
||||
<div class="dup-data-size-uncompressed"><?php esc_html_e("uncompressed", 'duplicator-pro'); ?></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="dup-scan-db">
|
||||
<?php if ($package->isDBExcluded()) {
|
||||
$tplMng->render('admin_pages/packages/scan/items/database/excluded');
|
||||
} else {
|
||||
$tplMng->render('admin_pages/packages/scan/items/database/tables');
|
||||
|
||||
if (WpDbUtils::getBuildMode() == WpDbUtils::BUILD_MODE_MYSQLDUMP) {
|
||||
$tplMng->render('admin_pages/packages/scan/items/database/mysqldump');
|
||||
}
|
||||
|
||||
if (count($tplData['procedures']) > 0 || count($tplData['functions']) > 0) {
|
||||
$tplMng->render('admin_pages/packages/scan/items/database/procedures');
|
||||
}
|
||||
|
||||
if (count($tplData['triggers'])) {
|
||||
$tplMng->render('admin_pages/packages/scan/items/database/triggers');
|
||||
}
|
||||
} ?>
|
||||
</div>
|
||||
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Controllers\SettingsPageController;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
$settingsPackageUrl = SettingsPageController::getInstance()->getMenuLink(SettingsPageController::L2_SLUG_PACKAGE);
|
||||
?>
|
||||
<div class="scan-item" id="mysqldump-limit-result"></div>
|
||||
<script id="hb-mysqldump-limit-result" type="text/x-handlebars-template">
|
||||
<div class="title" onclick="DupliJs.Pack.toggleScanItem(this);">
|
||||
<div class="text">
|
||||
<i class="fa fa-caret-right"></i> <?php esc_html_e('Mysqldump memory check', 'duplicator-pro'); ?>
|
||||
</div>
|
||||
<div id="data-db-status-mysqldump-limit">
|
||||
{{#if DB.Status.mysqlDumpMemoryCheck}}
|
||||
<div class="badge badge-pass"><?php esc_html_e('Good', 'duplicator-pro'); ?></div>
|
||||
{{else}}
|
||||
<div class="badge badge-warn"><?php esc_html_e('Notice', 'duplicator-pro'); ?></div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
{{#if DB.Status.mysqlDumpMemoryCheck}}
|
||||
<div class="info">
|
||||
<p class="green">
|
||||
<?php esc_html_e('The database size is within the allowed mysqldump size limit.', 'duplicator-pro'); ?>
|
||||
</p>
|
||||
<?php
|
||||
echo wp_kses(
|
||||
sprintf(
|
||||
_x(
|
||||
'If you encounter any issues with mysqldump please change the setting SQL Mode to PHP Code.
|
||||
You can do that by opening %1$sDuplicator Pro > Settings > Backups.%2$s',
|
||||
'1$s and 2$s represent opening and closing anchor tags',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<a href="' . esc_url($settingsPackageUrl) . '" target="_blank">',
|
||||
'</a>'
|
||||
),
|
||||
[
|
||||
'a' => [
|
||||
'href' => [],
|
||||
'target' => [],
|
||||
],
|
||||
]
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="info" style="display:block;">
|
||||
<p class="red">
|
||||
<?php esc_html_e('The database size exceeds the allowed mysqldump size limit.', 'duplicator-pro'); ?>
|
||||
</p>
|
||||
<?php
|
||||
esc_html_e(
|
||||
'The database size is larger than the PHP memory_limit value.
|
||||
This can lead into issues when building a Backup, during which the system can run out of memory.
|
||||
To fix this issue please consider doing one of the below mentioned recommendations.',
|
||||
'duplicator-pro'
|
||||
);
|
||||
?>
|
||||
<hr size="1" />
|
||||
<p>
|
||||
<b><?php esc_html_e('RECOMMENDATIONS:', 'duplicator-pro'); ?></b>
|
||||
</p>
|
||||
<ul class="dupli-simple-style-disc" >
|
||||
<li>
|
||||
<?php echo wp_kses(
|
||||
sprintf(
|
||||
_x(
|
||||
'Please change the setting SQL Mode to PHP Code.
|
||||
You can do that by opening %1$sDuplicator Pro > Settings > Backups.%2$s',
|
||||
'%1$s and %2$s represent opening and closing anchor tags',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<a href="' . esc_url($settingsPackageUrl) . '" target="_blank">',
|
||||
'</a>'
|
||||
),
|
||||
[
|
||||
'a' => [
|
||||
'href' => [],
|
||||
'target' => [],
|
||||
],
|
||||
]
|
||||
); ?>
|
||||
</li>
|
||||
<li>
|
||||
<?php echo wp_kses(
|
||||
sprintf(
|
||||
_x(
|
||||
'If you want to build the backup with mysqldump, increase the PHP <b>memory_limit</b>
|
||||
value in your php.ini file to at least %1$s.',
|
||||
'%1$s represents the memory limit value (e.g. 256MB)',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<b><span id="data-db-size3">{{DB.Status.requiredMysqlDumpLimit}}</span></b>'
|
||||
),
|
||||
[
|
||||
'b' => [],
|
||||
'span' => ['id' => []],
|
||||
]
|
||||
); ?>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
{{/if}}
|
||||
</script>
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
?>
|
||||
|
||||
<div class="scan-item">
|
||||
<div class='title' onclick="DupliJs.Pack.toggleScanItem(this);">
|
||||
<div class="text"><i class="fa fa-caret-right"></i> <?php esc_html_e('Object Access', 'duplicator-pro');?></div>
|
||||
<div id="data-arc-status-showcreatefunc"></div>
|
||||
</div>
|
||||
<div class="info">
|
||||
<script id="hb-showcreatefunc-result" type="text/x-handlebars-template">
|
||||
<div class="container">
|
||||
<div class="data">
|
||||
{{#if ARC.Status.showCreateFunc}}
|
||||
<?php esc_html_e(
|
||||
"The database user for this WordPress site has sufficient permissions to write stored procedures
|
||||
and functions to the sql file of the archive. [The commands SHOW CREATE PROCEDURE/FUNCTION will work.]",
|
||||
'duplicator-pro'
|
||||
); ?>
|
||||
{{else}}
|
||||
<span style="color: red;">
|
||||
<?php
|
||||
esc_html_e(
|
||||
"The database user for this WordPress site does NOT have sufficient permissions to write stored
|
||||
procedures to the sql file of the archive. [The command SHOW CREATE FUNCTION will NOT work.]",
|
||||
'duplicator-pro'
|
||||
);
|
||||
?>
|
||||
</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
<div id="showcreatefunc-package-result"></div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
use Duplicator\Controllers\SettingsPageController;
|
||||
use Duplicator\Libs\Snap\SnapString;
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var \Duplicator\Package\DupPackage $package
|
||||
*/
|
||||
$package = $tplData['package'];
|
||||
$settingsPackageUrl = SettingsPageController::getInstance()->getMenuLink(SettingsPageController::L2_SLUG_PACKAGE);
|
||||
|
||||
/** @var wpdb $wpdb */
|
||||
global $wpdb;
|
||||
?>
|
||||
<div class="scan-item">
|
||||
<div class='title' onclick="DupliJs.Pack.toggleScanItem(this);">
|
||||
<div class="text"><i class="fa fa-caret-right"></i> <?php esc_html_e('Overview', 'duplicator-pro'); ?></div>
|
||||
<div id="data-db-status-size1"></div>
|
||||
</div>
|
||||
<div class="info">
|
||||
<b> <?php esc_html_e('TOTAL SIZE', 'duplicator-pro'); ?> ⇛ </b>
|
||||
<b><?php esc_html_e('Size', 'duplicator-pro'); ?>:</b> <span id="data-db-size2"></span> |
|
||||
<b><?php esc_html_e('Tables', 'duplicator-pro'); ?>:</b> <span id="data-db-tablecount"></span> |
|
||||
<b><?php esc_html_e('Records', 'duplicator-pro'); ?>:</b> <span id="data-db-rows"></span> <br />
|
||||
<?php echo wp_kses(
|
||||
sprintf(
|
||||
__(
|
||||
'Total size and row count are approximate values. The thresholds that trigger warnings are
|
||||
<i>%1$s OR %2$s records</i> total for the entire database. Large databases take time to process
|
||||
and can cause issues with server timeout and memory settings on some budget hosts. If your server
|
||||
supports popen or exec and mysqldump you can try to enable Shell Execution from the settings menu.',
|
||||
'duplicator-pro'
|
||||
),
|
||||
SnapString::byteSize(DUPLICATOR_SCAN_DB_ALL_SIZE),
|
||||
number_format(DUPLICATOR_SCAN_DB_ALL_ROWS)
|
||||
),
|
||||
['i' => []]
|
||||
); ?>
|
||||
<br />
|
||||
<br />
|
||||
<hr size="1" />
|
||||
<b><?php esc_html_e('TABLE DETAILS:', 'duplicator-pro'); ?></b><br />
|
||||
<?php
|
||||
echo wp_kses(
|
||||
sprintf(
|
||||
__(
|
||||
'The notices for tables are <i>%1$s, %2$s records or names with upper-case characters</i>.
|
||||
Individual tables will not trigger a notice message, but can help narrow down issues if they occur later on.',
|
||||
'duplicator-pro'
|
||||
),
|
||||
SnapString::byteSize(DUPLICATOR_SCAN_DB_TBL_SIZE),
|
||||
number_format(DUPLICATOR_SCAN_DB_TBL_ROWS)
|
||||
),
|
||||
['i' => []]
|
||||
);
|
||||
?>
|
||||
<p>
|
||||
<b><?php echo esc_html(sprintf(__('Exclude all tables without prefix "%s"', 'duplicator-pro'), $tplData['prefix'])); ?>:</b>
|
||||
<i class="maroon">
|
||||
<?php echo ($tplData['prefixFilter'] ?
|
||||
esc_html_e('Enabled', 'duplicator-pro') :
|
||||
esc_html_e('Disabled', 'duplicator-pro')
|
||||
); ?>
|
||||
</i><br>
|
||||
<?php if (is_multisite()) { ?>
|
||||
<b><?php esc_html_e('Exclude not existing subsite filter', 'duplicator-pro'); ?>:</b>
|
||||
<i class="red">
|
||||
<?php echo ($tplData['prefixSubFilter'] ?
|
||||
esc_html_e('Enabled', 'duplicator-pro') :
|
||||
esc_html_e('Disabled', 'duplicator-pro')
|
||||
); ?>
|
||||
</i>
|
||||
<?php } ?>
|
||||
</p>
|
||||
<div id="dup-scan-db-info">
|
||||
<div id="data-db-tablelist"></div>
|
||||
</div>
|
||||
<br />
|
||||
<hr size="1" />
|
||||
<b><?php esc_html_e('RECOMMENDATIONS:', 'duplicator-pro'); ?></b><br />
|
||||
<i>
|
||||
<?php esc_html_e(
|
||||
'The following recommendations are not needed unless you are having issues building or installing the Backup.',
|
||||
'duplicator-pro'
|
||||
); ?>
|
||||
</i>
|
||||
<br />
|
||||
<div style="padding:5px">
|
||||
<?php echo wp_kses(
|
||||
sprintf(
|
||||
_x(
|
||||
'1. Run a %1$srepair and optimization%2$s on the table to improve the overall size and performance.',
|
||||
'1$s and 2$s represent opening and closing anchor tags',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<a href="' . admin_url('maint/repair.php') . '" target="_blank">',
|
||||
'</a>'
|
||||
),
|
||||
[
|
||||
'a' => [
|
||||
'href' => [],
|
||||
'target' => [],
|
||||
],
|
||||
]
|
||||
); ?>
|
||||
<br /><br />
|
||||
<?php esc_html_e(
|
||||
'2. Remove post revisions and stale data from tables. Tables such as logs, statistical or other non-critical data should be cleared.',
|
||||
'duplicator-pro'
|
||||
); ?>
|
||||
<br /><br />
|
||||
<?php echo wp_kses(
|
||||
sprintf(
|
||||
_x(
|
||||
'3. %1$sEnable mysqldump%2$s if this host supports the option.',
|
||||
'1$s and 2$s represent opening and closing anchor tags',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<a href="' . esc_url($settingsPackageUrl) . '" target="_blank">',
|
||||
'</a>'
|
||||
),
|
||||
[
|
||||
'a' => [
|
||||
'href' => [],
|
||||
'target' => [],
|
||||
],
|
||||
]
|
||||
); ?>
|
||||
<br /><br />
|
||||
<?php echo wp_kses(
|
||||
sprintf(
|
||||
_x(
|
||||
'4. Restoring mixed-case tables can cause problems on some servers. If you experience a
|
||||
problem installing the backup change the %1$s system variable on the destination site\'s MySQL Server.',
|
||||
'1$s represents an anchor tag with the variable name',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<a href="http://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_lower_case_table_names" target="_blank">
|
||||
lower_case_table_names</a>'
|
||||
),
|
||||
[
|
||||
'a' => [
|
||||
'href' => [],
|
||||
'target' => [],
|
||||
],
|
||||
]
|
||||
); ?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
?>
|
||||
|
||||
<div class="scan-item">
|
||||
<div class='title' onclick="DupliJs.Pack.toggleScanItem(this);">
|
||||
<div class="text"><i class="fa fa-caret-right"></i> <?php esc_html_e('Triggers', 'duplicator-pro');?></div>
|
||||
<div id="data-arc-status-triggers"></div>
|
||||
</div>
|
||||
<div class="info">
|
||||
<script id="hb-triggers-result" type="text/x-handlebars-template">
|
||||
<div class="container">
|
||||
<div class="data">
|
||||
<span class="red">
|
||||
<?php
|
||||
esc_html_e(
|
||||
"The database contains triggers which will have to be manually imported at install time.
|
||||
No action needs to be performed at this time. During the install process you will be
|
||||
presented with the proper trigger SQL statements that you can optionally run.",
|
||||
'duplicator-pro'
|
||||
); ?>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
<div id="triggers-result"></div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
use Duplicator\Core\Views\TplMng;
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
*/
|
||||
?>
|
||||
<div class="details-title">
|
||||
<i class="fas fa-tasks fa-sm fa-fw"></i> <?php esc_html_e("Setup", 'duplicator-pro'); ?>
|
||||
<div class="dup-more-details">
|
||||
<a href="site-health.php" target="_blank" title="<?php esc_attr_e('Site Health', 'duplicator-pro'); ?>">
|
||||
<i class="fas fa-file-medical-alt"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
TplMng::getInstance()->render('admin_pages/packages/scan/items/setup/system');
|
||||
TplMng::getInstance()->render('admin_pages/packages/scan/items/setup/wordpress');
|
||||
TplMng::getInstance()->render('admin_pages/packages/scan/items/setup/restore');
|
||||
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
?>
|
||||
<div id="migration-status-scan-item" class="scan-item">
|
||||
<div class='title' onclick="DupliJs.Pack.toggleScanItem(this);">
|
||||
<div class="text"><i class="fa fa-caret-right"></i> <?php esc_html_e('Import Status', 'duplicator-pro');?></div>
|
||||
<div id="data-arc-status-migratepackage"></div>
|
||||
</div>
|
||||
<div class="info">
|
||||
<script id="hb-migrate-package-result" type="text/x-handlebars-template">
|
||||
<div class="container">
|
||||
<div class="data">
|
||||
{{#if ARC.Status.PackageIsNotImportable}}
|
||||
<hr>
|
||||
<p>
|
||||
<span class="maroon">
|
||||
<?php esc_html_e("This Backup is not compatible with", 'duplicator-pro'); ?>
|
||||
<i data-tooltip-title="<?php esc_attr_e("Drag and Drop Import", 'duplicator-pro'); ?>"
|
||||
data-tooltip="<?php esc_attr_e('The Drag and Drop import method is a way to migrate Backups.
|
||||
You can find it under Duplicator Pro > Import.', 'duplicator-pro'); ?>">
|
||||
<u><?php esc_html_e("Drag and Drop import", 'duplicator-pro'); ?></u>.
|
||||
</i>
|
||||
<?php esc_html_e("However it can still be used to perform a database migration.", 'duplicator-pro'); ?>
|
||||
</span>
|
||||
|
||||
{{#if ARC.Status.IsDBOnly}}
|
||||
<?php
|
||||
esc_attr_e(
|
||||
"Database only Backups can only be installed via the installer.php file.
|
||||
The Drag and Drop interface only processes Backups that have all WordPress core directories and all database tables.",
|
||||
'duplicator-pro'
|
||||
);
|
||||
?>
|
||||
{{else}}
|
||||
<?php esc_attr_e(
|
||||
"To make the Backup compatible with Drag and Drop import don't filter any tables or core directories.",
|
||||
'duplicator-pro'
|
||||
); ?>
|
||||
{{/if}}
|
||||
</p>
|
||||
{{#if ARC.Status.HasFilteredCoreFolders}}
|
||||
<p>
|
||||
<b><?php esc_attr_e("FILTERED CORE DIRS:", 'duplicator-pro'); ?></b>
|
||||
</p>
|
||||
<ol>
|
||||
{{#each ARC.FilteredCoreDirs as |dir|}}
|
||||
<li>{{dir}} </li>
|
||||
{{/each}}
|
||||
</ol>
|
||||
{{/if}}
|
||||
{{#if ARC.Status.HasFilteredSiteTables}}
|
||||
<b><?php esc_attr_e("FILTERED SITE TABLES:", 'duplicator-pro'); ?></b>
|
||||
<div class="dup-scan-files-migrae-status">
|
||||
<ol>
|
||||
{{#each DB.FilteredTables as |table|}}
|
||||
<li>{{table}} </li>
|
||||
{{/each}}
|
||||
</ol>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{else}}
|
||||
<?php esc_html_e("The Backup you are about to create is compatible with Drag and Drop import.", 'duplicator-pro'); ?>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
<div id="migrate-package-result"></div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,184 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
use Duplicator\Addons\ProBase\License\License;
|
||||
use Duplicator\Core\Constants;
|
||||
use Duplicator\Libs\Snap\SnapOpenBasedir;
|
||||
use Duplicator\Libs\Snap\SnapServer;
|
||||
use Duplicator\Libs\Snap\SnapUtil;
|
||||
use Duplicator\Models\DynamicGlobalEntity;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
$webServers = implode(', ', Constants::SERVER_LIST);
|
||||
$serverSoftware = SnapUtil::sanitizeTextInput(INPUT_SERVER, 'SERVER_SOFTWARE', 'unknown');
|
||||
$fopenEnabled = SnapServer::isURLFopenEnabled() ? '1' : '0';
|
||||
$isCurlEnabled = SnapUtil::isCurlEnabled() ? __('True', 'duplicator-pro') : __('False', 'duplicator-pro');
|
||||
$openBaseDir = SnapOpenBasedir::isEnabled() ? esc_html__('on', 'duplicator-pro') : esc_html__('off', 'duplicator-pro');
|
||||
$maxExecutionTime = set_time_limit(0) === true ? 0 : @ini_get('max_execution_time');
|
||||
$memoryLimit = @ini_get('memory_limit');
|
||||
$architecture = SnapUtil::getArchitectureString();
|
||||
?>
|
||||
|
||||
<div class="scan-item scan-item-first">
|
||||
<div class='title' onclick="DupliJs.Pack.toggleScanItem(this);">
|
||||
<div class="text"><i class="fa fa-caret-right"></i> <?php esc_html_e('System', 'duplicator-pro'); ?></div>
|
||||
<div id="data-srv-php-all"></div>
|
||||
</div>
|
||||
<div class="info">
|
||||
<div class="scan-system-divider"><i class="fa fa-list"></i> <?php esc_html_e('General Checks', 'duplicator-pro'); ?></div>
|
||||
<?php if (License::can(License::CAPABILITY_BRAND)) : ?>
|
||||
<span id="data-srv-brand-check"></span>
|
||||
<b><?php esc_html_e('Brand', 'duplicator-pro'); ?>: </b>
|
||||
<span id="data-srv-brand-name"><?php esc_html_e('Default', 'duplicator-pro'); ?></span>
|
||||
<br />
|
||||
<div class="scan-system-subnote" id="data-srv-brand-note">
|
||||
<?php esc_html_e('The default content used when a brand is not defined.', 'duplicator-pro'); ?>
|
||||
</div>
|
||||
<hr size="1" />
|
||||
<?php endif; ?>
|
||||
<span id="data-srv-php-websrv"></span>
|
||||
<b><?php esc_html_e('Web Server', 'duplicator-pro') ?>:</b>
|
||||
<?php echo esc_html($serverSoftware); ?><br />
|
||||
<div class="scan-system-subnote">
|
||||
<?php esc_html_e("Supported Web Servers:", 'duplicator-pro'); ?> <?php echo esc_html($webServers); ?>
|
||||
</div>
|
||||
<hr size="1" />
|
||||
<span id="data-srv-php-mysqli"></span> <b><?php esc_html_e('MySQLi', 'duplicator-pro'); ?></b><br />
|
||||
<div class="scan-system-subnote">
|
||||
<?php esc_html_e(
|
||||
'Creating the Backup does not require the mysqli module. However the installer file requires
|
||||
that the PHP module mysqli be installed on the server it is deployed on.',
|
||||
'duplicator-pro'
|
||||
); ?>
|
||||
<i><a href="http://php.net/manual/en/mysqli.installation.php" target="_blank">[<?php esc_html_e('details', 'duplicator-pro'); ?>]</a></i>
|
||||
</div>
|
||||
<div class="scan-system-divider margin-top-1"><i class="fa fa-list"></i> <?php esc_html_e('PHP Checks', 'duplicator-pro'); ?></div>
|
||||
<span id="data-srv-php-version"></span> <b><?php esc_html_e('PHP Version: ', 'duplicator-pro'); ?> </b> <?php echo PHP_VERSION; ?> <br />
|
||||
<div class="scan-system-subnote">
|
||||
<?php
|
||||
echo esc_html(
|
||||
sprintf(
|
||||
__(
|
||||
'The minimum PHP version supported by Duplicator is %1$s, however it is highly
|
||||
recommended to use PHP %2$s or higher for improved stability.',
|
||||
'duplicator-pro'
|
||||
),
|
||||
DUPLICATOR_PRO_PHP_MINIMUM_VERSION,
|
||||
DUPLICATOR_PRO_PHP_SUGGESTED_VERSION
|
||||
)
|
||||
); ?>
|
||||
</div>
|
||||
<hr size="1" />
|
||||
<span id="data-srv-php-openbase"></span>
|
||||
<b><?php esc_html_e('PHP Open Base Dir', 'duplicator-pro'); ?>:</b> <?php echo esc_html($openBaseDir); ?>
|
||||
<br />
|
||||
<div class="scan-system-subnote">
|
||||
<?php esc_html_e(
|
||||
'When [open_basedir] is enabled, issues may arise if there are symbolic links pointing outside the open_basedir restrictions.
|
||||
To view a list of unreadable files, please consult the Read Checks section.
|
||||
If you encounter problems while building a Backup,
|
||||
consider working with your server admin or hosting provider to disable this setting in the php.ini file.',
|
||||
'duplicator-pro'
|
||||
); ?>
|
||||
|
||||
<i>
|
||||
<a href="http://php.net/manual/en/ini.core.php#ini.open-basedir" target="_blank">[<?php esc_html_e('details', 'duplicator-pro'); ?>]</a>
|
||||
</i>
|
||||
<br />
|
||||
</div>
|
||||
|
||||
<hr size="1" />
|
||||
<span id="data-srv-php-maxtime"></span>
|
||||
<b><?php esc_html_e('PHP Max Execution Time', 'duplicator-pro'); ?>:</b> <?php echo esc_html($maxExecutionTime); ?>
|
||||
<br />
|
||||
<div class="scan-system-subnote">
|
||||
<?php
|
||||
esc_html(
|
||||
sprintf(
|
||||
__(
|
||||
'Issues might occur for larger Backups when the [max_execution_time] value in the php.ini is too low.
|
||||
The minimum recommended timeout is "%1$s" seconds or higher.
|
||||
An attempt is made to override this value if the server allows it. A value of 0 (recommended) indicates that PHP has no time limits.',
|
||||
'duplicator-pro'
|
||||
),
|
||||
DUPLICATOR_SCAN_TIMEOUT
|
||||
)
|
||||
); ?>
|
||||
|
||||
<i>
|
||||
<a href="http://www.php.net/manual/en/info.configuration.php#ini.max-execution-time" target="_blank">
|
||||
[<?php esc_html_e('details', 'duplicator-pro'); ?>]
|
||||
</a>
|
||||
</i>
|
||||
</div>
|
||||
|
||||
<hr size="1" />
|
||||
<span id="data-srv-php-minmemory"></span>
|
||||
<b><?php esc_html_e('PHP Memory Limit', 'duplicator-pro'); ?>:</b> <?php echo esc_html($memoryLimit); ?>
|
||||
<br />
|
||||
<div class="scan-system-subnote">
|
||||
<?php
|
||||
echo wp_kses(
|
||||
sprintf(
|
||||
_x(
|
||||
'Issues might occur for larger Backups when the [memory_limit] value in the php.ini is too low.
|
||||
The minimum recommended memory limit is "%1$s" or higher. An attempt is made to override this value if the server allows it.
|
||||
To manually increase the memory limit have a look at this %2$s[FAQ item]%3$s',
|
||||
'1: memory limit, 2: link start, 3: link end',
|
||||
'duplicator-pro'
|
||||
),
|
||||
DUPLICATOR_MIN_MEMORY_LIMIT,
|
||||
"<i><a href='" . DUPLICATOR_DUPLICATOR_DOCS_URL . "how-to-manage-server-resources-cpu-memory-disk' target='_blank'>",
|
||||
"</a></i>"
|
||||
),
|
||||
[
|
||||
'a' => [
|
||||
'href' => [],
|
||||
'target' => [],
|
||||
],
|
||||
'i' => [],
|
||||
]
|
||||
); ?>
|
||||
</div>
|
||||
|
||||
<hr size="1" />
|
||||
<span id="data-srv-php-arch64bit"></span>
|
||||
<b><?php esc_html_e('PHP 64 Bit Architecture', 'duplicator-pro'); ?>:</b> <?php echo esc_html($architecture); ?><br />
|
||||
<div class="scan-system-subnote">
|
||||
<?php
|
||||
echo wp_kses(
|
||||
sprintf(
|
||||
_x(
|
||||
'Servers that run a PHP 32-bit architecture are not capable of creating Backups larger than 2GB.
|
||||
If you need to create a Backup that is larger than 2GB in size talk with your host or server admin
|
||||
to change your version of PHP to 64-bit. %1$s[FAQ item]%2$s',
|
||||
'1: link start, 2: link end',
|
||||
'duplicator-pro'
|
||||
),
|
||||
"<i><a href='" . DUPLICATOR_DUPLICATOR_DOCS_URL . "how-to-resolve-file-io-related-build-issues' target='_blank'>",
|
||||
"</a></i>"
|
||||
),
|
||||
[
|
||||
'a' => [
|
||||
'href' => [],
|
||||
'target' => [],
|
||||
],
|
||||
'i' => [],
|
||||
]
|
||||
); ?>
|
||||
</div>
|
||||
<br />
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,136 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
use Duplicator\Addons\ProBase\License\License;
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
?>
|
||||
<div class="scan-item">
|
||||
<div class='title' onclick="DupliJs.Pack.toggleScanItem(this);">
|
||||
<div class="text"><i class="fa fa-caret-right"></i> <?php esc_html_e('WordPress', 'duplicator-pro'); ?></div>
|
||||
<div id="data-srv-wp-all"></div>
|
||||
</div>
|
||||
<div class="info">
|
||||
<span id="data-srv-wp-version"></span>
|
||||
<b><?php esc_html_e('WordPress Version', 'duplicator-pro'); ?>:</b> <?php echo esc_html(get_bloginfo('version')); ?> <br />
|
||||
<hr size="1" /><span id="data-srv-wp-core"></span> <b> <?php esc_html_e('Core Files', 'duplicator-pro'); ?></b> <br />
|
||||
<?php if (count($tplData['filteredCoreDirs']) > 0) : ?>
|
||||
<div id="data-srv-wp-core-missing-dirs">
|
||||
<?php echo wp_kses(
|
||||
__(
|
||||
"The core WordPress directories below will <u>not</u> be included in the archive.
|
||||
These paths are required for WordPress to function!",
|
||||
'duplicator-pro'
|
||||
),
|
||||
['u' => []]
|
||||
); ?>
|
||||
<br />
|
||||
<?php foreach ($tplData['filteredCoreDirs'] as $coreDir) : ?>
|
||||
<b class="margin-left-1"><i class="fa fa-exclamation-circle scan-warn margin-right-1"></i><?php echo esc_html($coreDir); ?></b><br />
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (count($tplData['filteredCoreFiles']) > 0) : ?>
|
||||
<div id="data-srv-wp-core-missing-dirs">
|
||||
<?php echo wp_kses(
|
||||
__(
|
||||
"The core WordPress files below will <u>not</u> be included in the archive.
|
||||
These files are required for WordPress to function!",
|
||||
'duplicator-pro'
|
||||
),
|
||||
['u' => []]
|
||||
); ?>
|
||||
<br />
|
||||
<?php foreach ($tplData['filteredCoreFiles'] as $coreFile) : ?>
|
||||
<b class="margin-left-1"><i class="fa fa-exclamation-circle scan-warn margin-right-1"></i><?php echo esc_html($coreFile); ?></b>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (count($tplData['filteredCoreDirs']) > 0 || count($tplData['filteredCoreFiles']) > 0) : ?>
|
||||
<div class="scan-system-subnote">
|
||||
<?php esc_html_e(
|
||||
'Note: Please change the file and directory filters if you wish to include the WordPress core files
|
||||
otherwise the data will have to be manually copied to the new location for the site to function properly.',
|
||||
'duplicator-pro'
|
||||
); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if (empty($tplData['filteredCoreDirs']) && empty($tplData['filteredCoreFiles'])) : ?>
|
||||
<div class="scan-system-subnote">
|
||||
<?php esc_html_e(
|
||||
"If the scanner is unable to locate the wp-config.php file in the root directory,
|
||||
then you will need to manually copy it to its new location.
|
||||
This check will also look for core WordPress paths that should be included in the archive for WordPress to work correctly.",
|
||||
'duplicator-pro'
|
||||
); ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
<?php if (!is_multisite()) { ?>
|
||||
<hr size="1" />
|
||||
<span>
|
||||
<div class="dup-scan-good"><i class="fa fa-check"></i></div>
|
||||
</span>
|
||||
<b> <?php esc_html_e('Multisite: N/A', 'duplicator-pro'); ?></b> <br />
|
||||
<div class="scan-system-subnote">
|
||||
<?php esc_html_e('Multisite was not detected on this site. It is currently configured as a standard WordPress site.', 'duplicator-pro'); ?>
|
||||
<i><a href='https://codex.wordpress.org/Create_A_Network' target='_blank'> [<?php esc_html_e('details', 'duplicator-pro'); ?>]</a></i>
|
||||
</div>
|
||||
<?php } elseif (License::can(License::CAPABILITY_MULTISITE_PLUS)) { ?>
|
||||
<hr size="1" />
|
||||
<span>
|
||||
<div class="dup-scan-good"><i class="fa fa-check"></i></div>
|
||||
</span>
|
||||
<b> <?php esc_html_e('Multisite: Detected', 'duplicator-pro'); ?></b> <br />
|
||||
<div class="scan-system-subnote">
|
||||
<?php esc_html_e('This license level has full access to all Multisite Plus+ features.', 'duplicator-pro'); ?>
|
||||
</div>
|
||||
<?php } else { ?>
|
||||
<hr size="1" />
|
||||
<span>
|
||||
<div class="dup-scan-warn"><i class="fa fa-exclamation-triangle fa-sm"></i></div>
|
||||
</span>
|
||||
<b><?php esc_html_e('Multisite: Detected', 'duplicator-pro'); ?> </b> <br />
|
||||
<div class="scan-system-subnote">
|
||||
<?php esc_html(
|
||||
sprintf(
|
||||
__(
|
||||
'Duplicator Pro is at the %1$s license level which allows for backups and migrations of an entire Multisite network. ',
|
||||
'duplicator-pro'
|
||||
),
|
||||
License::getLicenseToString()
|
||||
)
|
||||
); ?>
|
||||
<br>
|
||||
<?php echo wp_kses(
|
||||
__(
|
||||
"To unlock all <b>Multisite Plus</b> features please upgrade the license before building a Backup.",
|
||||
'duplicator-pro'
|
||||
),
|
||||
['b' => []]
|
||||
); ?>
|
||||
<br />
|
||||
<a href="<?php echo esc_url(License::getUpsellURL()); ?>" target='_blank'>
|
||||
<?php esc_html_e('Upgrade Here', 'duplicator-pro'); ?>
|
||||
</a> |
|
||||
<a href="<?php echo esc_html(DUPLICATOR_DUPLICATOR_DOCS_URL); ?>how-does-duplicator-handle-multisite-support" target="_blank">
|
||||
<?php esc_html_e('Multisite Plus Feature Overview', 'duplicator-pro'); ?>
|
||||
</a>
|
||||
</div>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
use Duplicator\Controllers\PackagesPageController;
|
||||
use Duplicator\Core\Controllers\ControllersManager;
|
||||
|
||||
$blur = $tplData['blur'];
|
||||
$package_list_url = ControllersManager::getMenuLink(ControllersManager::PACKAGES_SUBMENU_SLUG);
|
||||
?>
|
||||
<form
|
||||
id="form-duplicator"
|
||||
class="<?php echo ($blur ? 'dup-mock-blur' : ''); ?> scan-result"
|
||||
method="post"
|
||||
action="<?php echo esc_attr($package_list_url); ?>"
|
||||
>
|
||||
<?php PackagesPageController::getInstance()->getActionByKey(PackagesPageController::ACTION_CREATE_FROM_TEMP)->getActionNonceFileds(); ?>
|
||||
<div id="dup-progress-area">
|
||||
<!-- PROGRESS BAR -->
|
||||
<div class="dup-progress-bar-area">
|
||||
<div class="dupli-title" >
|
||||
<?php esc_html_e('Scanning Site', 'duplicator-pro'); ?>
|
||||
</div>
|
||||
<div class="dupli-meter-wrapper" >
|
||||
<div class="dupli-meter green dupli-fullsize">
|
||||
<span></span>
|
||||
</div>
|
||||
<span class="text"></span>
|
||||
</div>
|
||||
<b><?php esc_html_e('Please Wait...', 'duplicator-pro'); ?></b><br/><br/>
|
||||
<i><?php esc_html_e('Keep this window open during the scan process.', 'duplicator-pro'); ?></i><br/>
|
||||
<i><?php esc_html_e('This can take several minutes.', 'duplicator-pro'); ?></i><br/>
|
||||
</div>
|
||||
|
||||
<!-- SCAN DETAILS REPORT -->
|
||||
<div id="dup-msg-success" style="display:none">
|
||||
<div style="text-align:center">
|
||||
<div class="dup-hdr-success">
|
||||
<i class="far fa-check-square fa-nr"></i> <?php esc_html_e('Scan Complete', 'duplicator-pro'); ?>
|
||||
</div>
|
||||
<div id="dup-msg-success-subtitle">
|
||||
<?php esc_html_e("Process Time:", 'duplicator-pro'); ?> <span id="data-rpt-scantime"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="details">
|
||||
<?php $tplMng->render('admin_pages/packages/scan/items/setup/main'); ?>
|
||||
<br/>
|
||||
<?php $tplMng->render('admin_pages/packages/scan/items/archive/main'); ?>
|
||||
<?php $tplMng->render('admin_pages/packages/scan/items/database/main'); ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ERROR MESSAGE -->
|
||||
<div id="dup-msg-error" style="display:none">
|
||||
<div class="dup-hdr-error"><i class="fa fa-exclamation-circle"></i> <?php esc_html_e('Scan Error', 'duplicator-pro'); ?></div>
|
||||
<i><?php esc_html_e('Please try again!', 'duplicator-pro'); ?></i><br/>
|
||||
<div style="text-align:left">
|
||||
<b><?php esc_html_e("Server Status:", 'duplicator-pro'); ?></b>
|
||||
<div id="dup-msg-error-response-status" style="display:inline-block"></div><br/>
|
||||
<b><?php esc_html_e("Error Message:", 'duplicator-pro'); ?></b>
|
||||
<div id="dup-msg-error-response-text"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- WARNING CONTINUE -->
|
||||
<div id="dupli-scan-warning-continue">
|
||||
<div class="msg2">
|
||||
<?php esc_html_e("Scan checks are not required to pass, however they could cause issues on some systems.", 'duplicator-pro'); ?>
|
||||
<br/>
|
||||
<?php esc_html_e("Please review the details for each section by clicking on the detail title.", 'duplicator-pro'); ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="dupli-confirm-area">
|
||||
<?php esc_html_e('Do you want to continue?', 'duplicator-pro'); ?>
|
||||
<br/>
|
||||
<?php esc_html_e('At least one or more checkboxes were checked in "Quick Filters".', 'duplicator-pro') ?>
|
||||
<br/>
|
||||
<i style="font-weight:normal">
|
||||
<?php esc_html_e('To apply a "Quick Filter" click the "Add Filters & Rescan" button', 'duplicator-pro') ?>
|
||||
</i><br/>
|
||||
<input
|
||||
type="checkbox"
|
||||
id="dupli-confirm-check"
|
||||
onclick="jQuery('#dup-build-button').removeAttr('disabled');"
|
||||
class="margin-bottom-0"
|
||||
>
|
||||
<?php esc_html_e('Yes. Continue without applying any file filters.', 'duplicator-pro') ?>
|
||||
</div>
|
||||
<div class="dup-button-footer" style="display:none">
|
||||
<input
|
||||
type="button"
|
||||
class="button hollow secondary small dup-go-back-to-new1"
|
||||
value="◀ <?php esc_html_e("Back", 'duplicator-pro') ?>"
|
||||
>
|
||||
<input
|
||||
type="button"
|
||||
class="button hollow secondary small"
|
||||
value="<?php esc_attr_e("Rescan", 'duplicator-pro') ?>"
|
||||
onclick="DupliJs.Pack.reRunScanner()"
|
||||
>
|
||||
<input
|
||||
type="button"
|
||||
onclick="DupliJs.Pack.startBuild();"
|
||||
class="button primary small"
|
||||
id="dup-build-button"
|
||||
value='<?php esc_attr_e("Create Backup", 'duplicator-pro') ?> ▶'
|
||||
>
|
||||
</div>
|
||||
</form>
|
||||
<?php $tplMng->render('admin_pages/packages/scan/scripts'); ?>
|
||||
@@ -0,0 +1,922 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
use Duplicator\Ajax\ServicesPackage;
|
||||
use Duplicator\Controllers\PackagesPageController;
|
||||
use Duplicator\Libs\Snap\SnapWP;
|
||||
use Duplicator\Views\UI\UiDialog;
|
||||
use Duplicator\Models\GlobalEntity;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
$alert2 = new UiDialog();
|
||||
$alert2->height = 485;
|
||||
$alert2->width = 650;
|
||||
$alert2->title = __('Copy Quick Filter Paths', 'duplicator-pro');
|
||||
$alert2->boxClass = 'arc-paths-dlg';
|
||||
$alert2->message = "";
|
||||
$alert2->initAlert();
|
||||
|
||||
$alert3 = new UiDialog();
|
||||
$alert3->title = __('WARNING!', 'duplicator-pro');
|
||||
$alert3->message = __('Manual copy of selected text required on this browser.', 'duplicator-pro');
|
||||
$alert3->initAlert();
|
||||
|
||||
$alert4 = new UiDialog();
|
||||
$alert4->title = $alert3->title;
|
||||
$alert4->message = __('Error applying filters. Please go back to Step 1 to add filter manually!', 'duplicator-pro');
|
||||
$alert4->initAlert();
|
||||
|
||||
$messageText = $tplMng->render('admin_pages/packages/scan/error_message', [], false);
|
||||
?>
|
||||
<script>
|
||||
jQuery(document).ready(function($) {
|
||||
var large_tree = $('#hb-files-large-jstree').length ? $('#hb-files-large-jstree') : null;
|
||||
|
||||
Handlebars.registerHelper('stripWPRoot', function(path) {
|
||||
return path.replace('<?php echo esc_js(SnapWP::getHomePath(true)) ?>', '');
|
||||
});
|
||||
|
||||
Handlebars.registerHelper('ifAllOr', function(v1, v2, v3, options) {
|
||||
if (v1 || v2 || v3) {
|
||||
return options.fn(this);
|
||||
}
|
||||
|
||||
return options.inverse(this);
|
||||
});
|
||||
|
||||
Handlebars.registerHelper('compare', function(v1, operator, v2, options) {
|
||||
'use strict';
|
||||
var operators = {
|
||||
'==': v1 == v2 ? true : false,
|
||||
'===': v1 === v2 ? true : false,
|
||||
'!=': v1 != v2 ? true : false,
|
||||
'!==': v1 !== v2 ? true : false,
|
||||
'>': v1 > v2 ? true : false,
|
||||
'>=': v1 >= v2 ? true : false,
|
||||
'<': v1 < v2 ? true : false,
|
||||
'<=': v1 <= v2 ? true : false,
|
||||
'||': v1 || v2 ? true : false,
|
||||
'&&': v1 && v2 ? true : false
|
||||
}
|
||||
if (operators.hasOwnProperty(operator)) {
|
||||
if (operators[operator]) {
|
||||
return options.fn(this);
|
||||
}
|
||||
return options.inverse(this);
|
||||
}
|
||||
return console.error('Error: Expression "' + operator + '" not found');
|
||||
});
|
||||
|
||||
//Opens a dialog to show scan details
|
||||
DupliJs.Pack.filesOff = function(dir) {
|
||||
var $checks = $(dir).parent('div.directory').find('div.files input[type="checkbox"]');
|
||||
$(dir).is(':checked') ?
|
||||
$.each($checks, function() {
|
||||
$(this).attr({
|
||||
disabled: true,
|
||||
checked: false,
|
||||
title: "<?php esc_html_e('Directory applied filter set.', 'duplicator-pro'); ?>"
|
||||
});
|
||||
}) :
|
||||
$.each($checks, function() {
|
||||
$(this).removeAttr('disabled checked title');
|
||||
});
|
||||
}
|
||||
|
||||
DupliJs.Pack.FilterButton = {
|
||||
loading: function(btn) {
|
||||
$(btn).html('<i class="fas fa-circle-notch fa-spin"></i> <?php esc_html_e('Initializing Please Wait...', 'duplicator-pro'); ?>');
|
||||
$(btn).prop('disabled', true);
|
||||
$('#dup-build-button').prop('disable', true);
|
||||
},
|
||||
reset: function(btn) {
|
||||
$(btn).html('<i class="fa fa-filter fa-sm"></i> <?php esc_html_e("Add Filters & Rescan", "duplicator-pro"); ?>');
|
||||
$(btn).prop('disabled', true);
|
||||
$('#dup-build-button').prop('disable', false);
|
||||
}
|
||||
};
|
||||
|
||||
//Opens a dialog to show scan details
|
||||
DupliJs.Pack.showPathsDlg = function(type) {
|
||||
var filters = DupliJs.Pack.getFiltersLists(type);
|
||||
var dirFilters = filters.dir;
|
||||
var fileFilters = filters.file;
|
||||
|
||||
var $dirs = $('#dup-archive-paths textarea.path-dirs');
|
||||
var $files = $('#dup-archive-paths textarea.path-files');
|
||||
(dirFilters.length > 0) ?
|
||||
$dirs.text(dirFilters.join(";\n")): $dirs.text("<?php esc_html_e('No directories have been selected!', 'duplicator-pro'); ?>");
|
||||
|
||||
(fileFilters.length > 0) ?
|
||||
$files.text(fileFilters.join(";\n")): $files.text("<?php esc_html_e('No files have been selected!', 'duplicator-pro'); ?>");
|
||||
|
||||
$('.arc-paths-dlg').html($('#dup-archive-paths').html());
|
||||
<?php $alert2->showAlert(); ?>
|
||||
|
||||
return;
|
||||
};
|
||||
|
||||
//Toggles a directory path to show files
|
||||
DupliJs.Pack.toggleDirPath = function(item) {
|
||||
var $dir = $(item).parents('div.directory');
|
||||
var $files = $dir.find('div.files');
|
||||
var $arrow = $dir.find('i.dup-nav');
|
||||
if ($files.is(":hidden")) {
|
||||
$arrow.addClass('fa-caret-down').removeClass('fa-caret-right');
|
||||
$files.show();
|
||||
} else {
|
||||
$arrow.addClass('fa-caret-right').removeClass('fa-caret-down');
|
||||
$files.hide(250);
|
||||
}
|
||||
}
|
||||
|
||||
//Toggles a directory path to show files
|
||||
DupliJs.Pack.toggleAllDirPath = function(chkBox, toggle) {
|
||||
(toggle == 'hide') ?
|
||||
$('#hb-files-large-jstree').jstree().close_all(): $('#hb-files-large-jstree').jstree().open_all();
|
||||
}
|
||||
|
||||
DupliJs.Pack.copyText = function(btn, query) {
|
||||
$(query).select();
|
||||
try {
|
||||
document.execCommand('copy');
|
||||
$(btn).css({
|
||||
color: '#fff',
|
||||
backgroundColor: 'green'
|
||||
});
|
||||
$(btn).text("<?php esc_html_e('Copied to Clipboard!', 'duplicator-pro'); ?>");
|
||||
} catch (err) {
|
||||
<?php $alert3->showAlert(); ?>
|
||||
}
|
||||
}
|
||||
|
||||
DupliJs.Pack.getFiltersLists = function(type) {
|
||||
var result = {
|
||||
'dir': [],
|
||||
'file': []
|
||||
};
|
||||
|
||||
switch (type) {
|
||||
case 'large':
|
||||
console.log(large_tree);
|
||||
if (large_tree) {
|
||||
$.each(large_tree.jstree("get_checked", null, true), function(index, value) {
|
||||
var original = large_tree.jstree(true).get_node(value).original;
|
||||
if (original.type.startsWith('folder')) {
|
||||
result.dir.push(original.fullPath);
|
||||
} else {
|
||||
result.file.push(original.fullPath);
|
||||
}
|
||||
});
|
||||
}
|
||||
break;
|
||||
case 'addon':
|
||||
var id = '#hb-addon-sites-result';
|
||||
if ($(id).length) {
|
||||
$(id + " input[name='dir_paths[]']:checked").each(function() {
|
||||
result.dir.push($(this).val());
|
||||
});
|
||||
$(id + " input[name='file_paths[]']:checked").each(function() {
|
||||
result.file.push($(this).val());
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
DupliJs.Pack.applyFilters = function(btn, type) {
|
||||
var filterButton = btn;
|
||||
var filters = DupliJs.Pack.getFiltersLists(type);
|
||||
var dirFilters = filters.dir;
|
||||
var fileFilters = filters.file;
|
||||
|
||||
if (dirFilters.length === 0 && fileFilters.length === 0) {
|
||||
alert('No filter selected');
|
||||
return false;
|
||||
}
|
||||
|
||||
dirFilters = dirFilters.map(function(path) {
|
||||
return path.slice(-1) !== '\/' ? path + '\/' : path;
|
||||
});
|
||||
|
||||
DupliJs.Pack.FilterButton.loading(filterButton);
|
||||
|
||||
var data = {
|
||||
action: 'duplicator_add_quick_filters',
|
||||
nonce: <?php echo json_encode(wp_create_nonce('duplicator_add_quick_filters')); ?>,
|
||||
dir_paths: dirFilters.join(";"),
|
||||
file_paths: fileFilters.join(";")
|
||||
};
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
cache: false,
|
||||
dataType: 'json',
|
||||
url: ajaxurl,
|
||||
timeout: 100000,
|
||||
data: data,
|
||||
complete: function() {},
|
||||
success: function(data) {
|
||||
DupliJs.Pack.reRunScanner(function() {
|
||||
DupliJs.Pack.FilterButton.reset(filterButton);
|
||||
DupliJs.Pack.fullLoadButtonInit();
|
||||
});
|
||||
},
|
||||
error: function(data) {
|
||||
console.log(data);
|
||||
<?php $alert4->showAlert(); ?>
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
DupliJs.Pack.treeContextMenu = function(node) {
|
||||
var items = {};
|
||||
if (node.type.startsWith('folder')) {
|
||||
items = {
|
||||
selectAll: {
|
||||
label: "<?php esc_html_e('Select all childs files and folders', 'duplicator-pro'); ?>",
|
||||
action: function(obj) {
|
||||
$(obj.reference).parent().find('> .jstree-children .warning-node > .jstree-anchor:not(.jstree-checked) .jstree-checkbox')
|
||||
.each(function() {
|
||||
var _this = $(this);
|
||||
if (_this.parents('.selected-node').length === 0) {
|
||||
_this.trigger('click');
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
selectAllFiles: {
|
||||
label: "<?php esc_html_e('Select only all childs files', 'duplicator-pro'); ?>",
|
||||
action: function(obj) {
|
||||
$(obj.reference).parent().find('> .jstree-children .file-node.warning-node > .jstree-anchor:not(.jstree-checked) .jstree-checkbox')
|
||||
.each(function() {
|
||||
var _this = $(this);
|
||||
if (_this.parents('.selected-node').length === 0) {
|
||||
_this.trigger('click');
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
unselectAll: {
|
||||
label: "<?php esc_html_e('Unselect all childs elements', 'duplicator-pro'); ?>",
|
||||
action: function(obj) {
|
||||
$(obj.reference).parent().find('> .jstree-children .jstree-node > .jstree-anchor.jstree-checked .jstree-checkbox').trigger('click');
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
return items;
|
||||
};
|
||||
|
||||
DupliJs.Pack.getTreeFolderUrlData = function(folder, excludeList) {
|
||||
if (excludeList === undefined) {
|
||||
excludeList = [];
|
||||
}
|
||||
|
||||
return {
|
||||
'nonce': <?php echo json_encode(wp_create_nonce('duplicator_get_folder_children')); ?>,
|
||||
'action': 'duplicator_get_folder_children',
|
||||
'folder': folder,
|
||||
'exclude': excludeList
|
||||
};
|
||||
};
|
||||
|
||||
DupliJs.Pack.getTreeFolderUrl = function(folder, excludeList) {
|
||||
return ajaxurl + '?' + $.param(DupliJs.Pack.getTreeFolderUrlData(folder, excludeList));
|
||||
};
|
||||
|
||||
DupliJs.Pack.fullLoadNodes = null;
|
||||
|
||||
DupliJs.Pack.fullLoadFolder = function(tree, index, sectionContainer) {
|
||||
if (Array.isArray(DupliJs.Pack.fullLoadNodes) && index < DupliJs.Pack.fullLoadNodes.length) {
|
||||
var parent = DupliJs.Pack.fullLoadNodes[index];
|
||||
if (index === 0 && sectionContainer) {
|
||||
sectionContainer.append('<div class="tree-loader" >' +
|
||||
'<div class="container-wrapper" >' +
|
||||
'<i class="fa fa-cog fa-lg fa-spin"></i> <span></span>' +
|
||||
'</div>' +
|
||||
'</div>');
|
||||
}
|
||||
sectionContainer.find('.tree-loader span').text("<?php echo esc_js(__('Loading ', 'duplicator-pro')) ?>" + parent.original.fullPath);
|
||||
} else {
|
||||
DupliJs.Pack.fullLoadNodes = null;
|
||||
if (sectionContainer) {
|
||||
sectionContainer.find('.tree-loader').remove();
|
||||
}
|
||||
return;
|
||||
}
|
||||
var excludeList = [];
|
||||
|
||||
var parentClass = parent.li_attr.class;
|
||||
if (parentClass.indexOf('root-node') !== -1 && parentClass.indexOf('no-warnings') !== -1) {
|
||||
tree.delete_node(parent.children[0]);
|
||||
} else {
|
||||
for (i = 0; i < parent.children.length; i++) {
|
||||
excludeList.push(tree.get_node(parent.children[i]).original.fullPath.replace(/^.*[\\\/]/, ''));
|
||||
}
|
||||
}
|
||||
var data = DupliJs.Pack.getTreeFolderUrlData(parent.original.fullPath, excludeList);
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
cache: false,
|
||||
data: data,
|
||||
dataType: "json",
|
||||
url: ajaxurl,
|
||||
timeout: 100000,
|
||||
//data: data,
|
||||
complete: function() {},
|
||||
success: function(data) {
|
||||
try {
|
||||
for (i = 0; i < data.length; i++) {
|
||||
tree.create_node(parent, data[i]);
|
||||
}
|
||||
DupliJs.Pack.fullLoadFolder(tree, index + 1, sectionContainer);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
console.error('JSON parse failed for response data: ' + respData);
|
||||
console.log(respData);
|
||||
<?php $alert4->showAlert(); ?>
|
||||
return false;
|
||||
}
|
||||
},
|
||||
error: function(data) {
|
||||
console.log(data);
|
||||
<?php $alert4->showAlert(); ?>
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
function resetTreeLoadButton() {
|
||||
$('.tree-full-load-button')
|
||||
.removeClass('isLoaded dup-tree-hide-all')
|
||||
.addClass('dup-tree-show-all')
|
||||
.text("<?php echo esc_js(__('show all', 'duplicator-pro')); ?>")
|
||||
}
|
||||
|
||||
DupliJs.Pack.fullLoadButtonInit = function() {
|
||||
resetTreeLoadButton();
|
||||
$('.tree-full-load-button')
|
||||
.off()
|
||||
.click(function() {
|
||||
var sectionContainer = $(this).closest('.dup-tree-section').find('> .container');
|
||||
var cObj = $(this);
|
||||
var domTree = sectionContainer.find(".dup-tree-main-wrapper");
|
||||
var tree = domTree.jstree(true);
|
||||
|
||||
if (cObj.hasClass('dup-tree-show-all')) {
|
||||
cObj.removeClass('dup-tree-show-all')
|
||||
.addClass('dup-tree-hide-all')
|
||||
.text("<?php echo esc_js(__('show warning only', 'duplicator-pro')) ?>");
|
||||
if (!cObj.hasClass('isLoaded')) {
|
||||
cObj.addClass('isLoaded');
|
||||
DupliJs.Pack.fullLoadNodes = [];
|
||||
domTree.find(".folder-node[data-full-loaded=false]").each(function() {
|
||||
var parent = tree.get_node($(this));
|
||||
if (parent.state.loaded === false) {
|
||||
// If loaded it is false the folder has never been opened then it will be loaded by jstree if it is opened.
|
||||
return;
|
||||
}
|
||||
DupliJs.Pack.fullLoadNodes.push(parent);
|
||||
});
|
||||
|
||||
if (DupliJs.Pack.fullLoadNodes.length) {
|
||||
DupliJs.Pack.fullLoadFolder(tree, 0, sectionContainer);
|
||||
} else {
|
||||
DupliJs.Pack.fullLoadNodes = null;
|
||||
}
|
||||
} else {
|
||||
domTree.find(".root-node .jstree-node:not(.warning-childs):not(.warning-node)").each(function() {
|
||||
// don't use the tree functions show_node and hide_node are too slow.
|
||||
$(this).removeClass('jstree-hidden');
|
||||
});
|
||||
}
|
||||
} else {
|
||||
cObj.removeClass('dup-tree-hide-all').addClass('dup-tree-show-all')
|
||||
.text("<?php echo esc_js(__('show all', 'duplicator-pro')); ?>");
|
||||
domTree.find(".root-node .jstree-node:not(.warning-node):not(.warning-childs)").each(function() {
|
||||
// don't use the tree functions show_node and hide_node are too slow.
|
||||
$(this).addClass('jstree-hidden');
|
||||
});
|
||||
}
|
||||
|
||||
// recalculate the last child manually
|
||||
domTree.find(".jstree-children").each(function() {
|
||||
$(this).find('> li:not(.jstree-hidden)').removeClass('jstree-last').last().addClass('jstree-last');
|
||||
});
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
DupliJs.Pack.initTree = function(tree, data, filterBtn) {
|
||||
var treeObj = tree;
|
||||
var nameData = data;
|
||||
console.log('nameData', nameData);
|
||||
|
||||
treeObj.jstree('destroy');
|
||||
treeObj.jstree({
|
||||
'core': {
|
||||
"check_callback": true,
|
||||
'cache': false,
|
||||
//'data' : nameData,
|
||||
"themes": {
|
||||
"name": "snap",
|
||||
"dots": true,
|
||||
"icons": true,
|
||||
"stripes": true,
|
||||
},
|
||||
'data': {
|
||||
'url': function(node) {
|
||||
var folder = (node.id === '#') ? '' : node.original.fullPath;
|
||||
return DupliJs.Pack.getTreeFolderUrl(folder);
|
||||
},
|
||||
'data': function(node) {
|
||||
return {
|
||||
'id': node.id
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
'types': {
|
||||
"folder": {
|
||||
"icon": "jstree-icon jstree-folder",
|
||||
"li_attr": {
|
||||
"class": 'folder-node'
|
||||
}
|
||||
},
|
||||
"file": {
|
||||
"icon": "jstree-icon jstree-file",
|
||||
"li_attr": {
|
||||
"class": 'file-node'
|
||||
}
|
||||
},
|
||||
"info-text": {
|
||||
"icon": "jstree-noicon",
|
||||
"li_attr": {
|
||||
"class": 'info-node'
|
||||
}
|
||||
}
|
||||
},
|
||||
"checkbox": {
|
||||
// a boolean indicating if checkboxes should be visible (can be changed at a later time using
|
||||
// `show_checkboxes()` and `hide_checkboxes`). Defaults to `true`.
|
||||
visible: true,
|
||||
// a boolean indicating if clicking anywhere on the node should act as clicking on the checkbox. Defaults to `true`.
|
||||
three_state: false,
|
||||
// a boolean indicating if clicking anywhere on the node should act as clicking on the checkbox. Defaults to `true`.
|
||||
whole_node: false,
|
||||
keep_selected_style: false, // a boolean indicating if the selected style of a node should be kept, or removed. Defaults to `true`.
|
||||
// This setting controls how cascading and undetermined nodes are applied.
|
||||
// If 'up' is in the string - cascading up is enabled, if 'down' is in the string - cascading down is enabled,
|
||||
// if 'undetermined' is in the string - undetermined nodes will be used.
|
||||
// If `three_state` is set to `true` this setting is automatically set to 'up+down+undetermined'. Defaults to ''.
|
||||
cascade: '',
|
||||
// This setting controls if checkbox are bound to the general tree selection or
|
||||
// to an internal array maintained by the checkbox plugin. Defaults to `true`, only set to `false` if you know exactly what you are doing.
|
||||
tie_selection: false,
|
||||
cascade_to_disabled: false, // This setting controls if cascading down affects disabled checkboxes
|
||||
cascade_to_hidden: false //This setting controls if cascading down affects hidden checkboxes
|
||||
},
|
||||
"contextmenu": {
|
||||
"items": DupliJs.Pack.treeContextMenu
|
||||
},
|
||||
"plugins": [
|
||||
"checkbox",
|
||||
"contextmenu",
|
||||
"types",
|
||||
//"dnd",
|
||||
//"massload",
|
||||
//"search",
|
||||
//"sort",
|
||||
//"state",
|
||||
//"types",
|
||||
//"unique",
|
||||
//"wholerow",
|
||||
"changed",
|
||||
//"conditionalselect"
|
||||
]
|
||||
}).on('check_node.jstree', function(e, data) {
|
||||
treeObj.find('#' + data.node.id).addClass('selected-node');
|
||||
filterBtn.prop("disabled", false);
|
||||
}).on('uncheck_node.jstree', function(e, data) {
|
||||
treeObj.find('#' + data.node.id).removeClass('selected-node');
|
||||
if (treeObj.jstree("get_selected").length === 0) {
|
||||
filterBtn.prop("disabled", true);
|
||||
}
|
||||
}).on('ready.jstree', function() {
|
||||
// insert data
|
||||
tree.jstree(true).create_node(null, nameData);
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
DupliJs.Pack.initArchiveFilesData = function(data) {
|
||||
//TOTAL SIZE
|
||||
$('#data-arc-size1').text(data.ARC.Size || errMsg);
|
||||
$('#data-arc-size2').text(data.ARC.Size || errMsg);
|
||||
$('#data-arc-files').text(data.ARC.FileCount || errMsg);
|
||||
$('#data-arc-dirs').text(data.ARC.DirCount || errMsg);
|
||||
$('#data-arc-fullcount').text(data.ARC.FullCount || errMsg);
|
||||
|
||||
//LARGE FILES
|
||||
if ($("#hb-files-large-result").length) {
|
||||
DupliJs.Pack.initTree(
|
||||
large_tree,
|
||||
data.ARC.FilterInfo.TreeSize,
|
||||
$("#hb-files-large-result .dupli-quick-filter-btn")
|
||||
);
|
||||
}
|
||||
|
||||
//ADDON SITES
|
||||
if ($("#hb-addon-sites").length) {
|
||||
var template = $('#hb-addon-sites').html();
|
||||
var templateScript = Handlebars.compile(template);
|
||||
var html = templateScript(data);
|
||||
$('#hb-addon-sites-result').html(html);
|
||||
}
|
||||
|
||||
//UNREADABLE FILES
|
||||
if ($("#unreadable-files").length) {
|
||||
var template = $('#unreadable-files').html();
|
||||
var templateScript = Handlebars.compile(template);
|
||||
var html = templateScript(data);
|
||||
$('#unreadable-files-result').html(html);
|
||||
}
|
||||
|
||||
|
||||
//SCANNER DETAILS: Dirs
|
||||
if ($("#hb-filter-file-list").length) {
|
||||
var template = $('#hb-filter-file-list').html();
|
||||
var templateScript = Handlebars.compile(template);
|
||||
var html = templateScript(data);
|
||||
$('div.hb-filter-file-list-result').html(html);
|
||||
}
|
||||
|
||||
//NETWORK SITES
|
||||
if ($("#hb-filter-network-sites").length) {
|
||||
var template = $('#hb-filter-network-sites').html();
|
||||
var templateScript = Handlebars.compile(template);
|
||||
var html = templateScript(data);
|
||||
$('#hb-filter-network-sites-result').html(html);
|
||||
}
|
||||
|
||||
//MIGRATE PACKAGE
|
||||
if ($("#hb-migrate-package-result").length) {
|
||||
var template = $('#hb-migrate-package-result').html();
|
||||
var templateScript = Handlebars.compile(template);
|
||||
var html = templateScript(data);
|
||||
$('#migrate-package-result').html(html);
|
||||
}
|
||||
|
||||
//Security Plugins
|
||||
if ($("#hb-dup-security-plugins").length) {
|
||||
var template = $('#hb-dup-security-plugins').html();
|
||||
var templateScript = Handlebars.compile(template);
|
||||
var html = templateScript(data);
|
||||
$('#dup-security-plugins').html(html);
|
||||
}
|
||||
|
||||
//SHOW CREATE
|
||||
if ($("#hb-showcreatefunc-result").length) {
|
||||
var template = $('#hb-showcreatefunc-result').html();
|
||||
var templateScript = Handlebars.compile(template);
|
||||
var html = templateScript(data);
|
||||
$('#showcreatefunc-package-result').html(html);
|
||||
}
|
||||
|
||||
//TRIGGERS
|
||||
if ($("#hb-triggers-result").length) {
|
||||
var template = $('#hb-triggers-result').html();
|
||||
var templateScript = Handlebars.compile(template);
|
||||
var html = templateScript(data);
|
||||
$('#triggers-result').html(html);
|
||||
}
|
||||
|
||||
//MYSQLDUMP LIMIT
|
||||
if ($("#hb-mysqldump-limit-result").length) {
|
||||
var template = $('#hb-mysqldump-limit-result').html();
|
||||
var templateScript = Handlebars.compile(template);
|
||||
var html = templateScript(data);
|
||||
$('#mysqldump-limit-result').html(html);
|
||||
}
|
||||
|
||||
DuplicatorTooltip.reload();
|
||||
};
|
||||
|
||||
DupliJs.Pack.fullLoadButtonInit();
|
||||
|
||||
$("#form-duplicator").on('change', "#hb-files-large-result input[type='checkbox'], #hb-addon-sites-result input[type='checkbox']", function() {
|
||||
if ($("#hb-addon-sites-result input[type='checkbox']:checked").length) {
|
||||
var addon_disabled_prop = false;
|
||||
} else {
|
||||
var addon_disabled_prop = true;
|
||||
}
|
||||
$("#hb-addon-sites-result .dupli-quick-filter-btn").prop("disabled", addon_disabled_prop);
|
||||
});
|
||||
|
||||
DupliJs.Pack.WebServiceStatus = {
|
||||
Pass: <?php echo json_encode(ServicesPackage::EXEC_STATUS_PASS); ?>,
|
||||
Warn: <?php echo json_encode(ServicesPackage::EXEC_STATUS_WARN); ?>, //deprecated
|
||||
Error: <?php echo json_encode(ServicesPackage::EXEC_STATUS_FAIL); ?>,
|
||||
MoreToScan: <?php echo json_encode(ServicesPackage::EXEC_STATUS_MORE_TO_SCAN); ?>,
|
||||
ScheduleRunning: <?php echo json_encode(ServicesPackage::EXEC_STATUS_SCHEDULE_RUNNING); ?>
|
||||
}
|
||||
|
||||
let errorMessage = <?php echo json_encode($messageText); ?>;
|
||||
let scanTimeoutInSec = <?php echo json_encode(GlobalEntity::getInstance()->php_max_worker_time_in_sec); ?>;
|
||||
let scanTimeout = (scanTimeoutInSec + 10) * 1000; // Add 10 seconds to the backend timeout
|
||||
|
||||
DupliJs.Pack.runScanner = function(callbackOnSuccess, firstChunk = false) {
|
||||
DupliJs.Util.ajaxWrapper({
|
||||
action: 'duplicator_package_scan',
|
||||
firstChunk: firstChunk,
|
||||
nonce: <?php echo json_encode(wp_create_nonce('duplicator_package_scan')); ?>
|
||||
},
|
||||
function(result, data, funcData, textStatus, jqXHR) {
|
||||
var status = funcData.Status || 3;
|
||||
var message = funcData.Message ||
|
||||
"Unable to read JSON from service. <br/> See: /wp-admin/admin-ajax.php?action=duplicator_package_scan";
|
||||
|
||||
if (status == DupliJs.Pack.WebServiceStatus.MoreToScan) {
|
||||
console.log('Continue with next scan chunk...');
|
||||
DupliJs.Pack.runScanner(callbackOnSuccess);
|
||||
return;
|
||||
}
|
||||
|
||||
// Scan finished, parse results
|
||||
if (status == DupliJs.Pack.WebServiceStatus.Pass) {
|
||||
DupliJs.Pack.loadScanData(funcData);
|
||||
if (typeof callbackOnSuccess === "function") {
|
||||
callbackOnSuccess(funcData);
|
||||
}
|
||||
$('.dup-button-footer').show();
|
||||
} else if (status == DupliJs.Pack.WebServiceStatus.ScheduleRunning) {
|
||||
console.log('Scan is already running...');
|
||||
window.location.href = <?php echo json_encode(PackagesPageController::getInstance()->getPackageBuildS1Url()); ?>;
|
||||
} else {
|
||||
$('.dup-progress-bar-area, #dup-build-button').hide();
|
||||
$('#dup-msg-error-response-status').html(status);
|
||||
$('#dup-msg-error-response-text').html(message + errorMessage);
|
||||
$('#dup-msg-error').show();
|
||||
$('.dup-button-footer').show();
|
||||
}
|
||||
},
|
||||
function(result, data, funcData, textStatus, jqXHR) {
|
||||
var status = data.status + ' -' + data.statusText;
|
||||
$('.dup-progress-bar-area, #dup-build-button').hide();
|
||||
$('#dup-msg-error-response-status').html(status)
|
||||
$('#dup-msg-error-response-text').html(data.message + errorMessage);
|
||||
$('#dup-msg-error, .dup-button-footer').show();
|
||||
console.log(data);
|
||||
}, {
|
||||
showProgress: false,
|
||||
timeout: scanTimeout
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
DupliJs.Pack.reRunScanner = function(callbackOnSuccess) {
|
||||
$('#dup-msg-success,#dup-msg-error,.dup-button-footer,#dupli-confirm-area').hide();
|
||||
$('#dupli-confirm-check').prop('checked', false);
|
||||
$('.dup-progress-bar-area').show();
|
||||
$('#dupli-scan-warning-continue').hide();
|
||||
resetTreeLoadButton();
|
||||
DupliJs.Pack.runScanner(callbackOnSuccess, true);
|
||||
}
|
||||
|
||||
DupliJs.Pack.loadScanData = function(data) {
|
||||
try {
|
||||
var errMsg = "unable to read";
|
||||
$('.dup-progress-bar-area').hide();
|
||||
//****************
|
||||
// BRAND
|
||||
// #data-srv-brand-check
|
||||
// #data-srv-brand-name
|
||||
// #data-srv-brand-note
|
||||
|
||||
$("#data-srv-brand-name").text(data.SRV.Brand.Name);
|
||||
if (data.SRV.Brand.LogoImageExists) {
|
||||
$("#data-srv-brand-note").html(data.SRV.Brand.Notes);
|
||||
} else {
|
||||
$("#data-srv-brand-note")
|
||||
.html(`<?php
|
||||
esc_html_e(
|
||||
"WARNING! Logo images no longer can be found inside brand. Please edit this brand and place new images.
|
||||
After that you can build your Backup with this brand.",
|
||||
"duplicator-pro"
|
||||
); ?>`);
|
||||
}
|
||||
|
||||
//****************
|
||||
//REPORT
|
||||
var base = $('#data-rpt-scanfile').attr('href');
|
||||
$('#data-rpt-scanfile').attr('href', base + '&scanfile=' + data.RPT.ScanFile);
|
||||
$('#data-rpt-scantime').text(data.RPT.ScanTime || 0);
|
||||
|
||||
DupliJs.Pack.initArchiveFilesData(data);
|
||||
DupliJs.Pack.setScanStatus(data);
|
||||
|
||||
//Addon Sites
|
||||
if (data.ARC.FilterInfo.Dirs.AddonSites !== undefined && data.ARC.FilterInfo.Dirs.AddonSites.length > 0) {
|
||||
$("#addonsites-block").show();
|
||||
}
|
||||
$('#dup-msg-success').show();
|
||||
|
||||
//****************
|
||||
//DATABASE
|
||||
var html = "";
|
||||
var DB_TableRowMax = <?php echo (int) DUPLICATOR_SCAN_DB_TBL_ROWS; ?>;
|
||||
var DB_TableSizeMax = <?php echo (int) DUPLICATOR_SCAN_DB_TBL_SIZE; ?>;
|
||||
if (data.DB.DBExcluded && data.DB.Status.Success) {
|
||||
$('#data-db-size1').text(data.DB.Size || errMsg);
|
||||
} else if (data.DB.Status.Success) {
|
||||
$('#data-db-size1').text(data.DB.Size || errMsg);
|
||||
$('#data-db-size2').text(data.DB.Size || errMsg);
|
||||
$('#data-db-rows').text(data.DB.Rows || errMsg);
|
||||
$('#data-db-tablecount').text(data.DB.TableCount || errMsg);
|
||||
//Table Details
|
||||
if (data.DB.TableList == undefined || data.DB.TableList.length == 0) {
|
||||
html = '<?php esc_html_e("Unable to report on any tables", 'duplicator-pro') ?>';
|
||||
} else {
|
||||
$.each(data.DB.TableList, function(i) {
|
||||
html += '<b>' + i + '</b><br/>';
|
||||
html += '<table><tr>';
|
||||
$.each(data.DB.TableList[i], function(key, val) {
|
||||
switch (key) {
|
||||
case 'Case':
|
||||
color = (val == 1) ? 'maroon' : 'black';
|
||||
html += '<td style="color:' + color + '"><?php echo esc_js(__('Uppercase:', 'duplicator-pro')) ?> ' + val + '</td>';
|
||||
break;
|
||||
case 'Rows':
|
||||
color = (val > DB_TableRowMax) ? 'red' : 'black';
|
||||
html += '<td style="color:' + color + '"><?php echo esc_js(__('Rows:', 'duplicator-pro')) ?> ' + val + '</td>';
|
||||
break;
|
||||
case 'USize':
|
||||
color = (parseInt(val) > DB_TableSizeMax) ? 'red' : 'black';
|
||||
html += '<td style="color:' + color + '">';
|
||||
html += '<?php echo esc_js(__('Size:', 'duplicator-pro')) ?> ' + data.DB.TableList[i]['Size'];
|
||||
html += '</td>';
|
||||
break;
|
||||
}
|
||||
});
|
||||
html += '</tr></table>';
|
||||
});
|
||||
}
|
||||
$('#data-db-tablelist').html(html);
|
||||
} else {
|
||||
html = '<?php esc_html_e("Unable to report on database stats", 'duplicator-pro') ?>';
|
||||
$('#dup-scan-db').html(html);
|
||||
}
|
||||
|
||||
var isWarn = false;
|
||||
for (key in data.ARC.Status) {
|
||||
if (!data.ARC.Status[key]) {
|
||||
isWarn = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isWarn) {
|
||||
if (!data.DB.Status.Size) {
|
||||
isWarn = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isWarn && !data.DB.Status.Rows) {
|
||||
isWarn = true;
|
||||
}
|
||||
|
||||
if (!isWarn && !data.SRV.PHP.ALL) {
|
||||
isWarn = true;
|
||||
}
|
||||
|
||||
if (!isWarn && (data.SRV.WP.version == false || data.SRV.WP.core == false)) {
|
||||
isWarn = true;
|
||||
}
|
||||
|
||||
if (isWarn) {
|
||||
$('#dupli-scan-warning-continue').show();
|
||||
} else {
|
||||
$('#dupli-scan-warning-continue').hide();
|
||||
$('#dup-build-button').prop("disabled", false);
|
||||
}
|
||||
} catch (err) {
|
||||
err += '<br/> Please try again!'
|
||||
$('#dup-msg-error-response-status').html("n/a")
|
||||
$('#dup-msg-error-response-text').html(err);
|
||||
$('#dup-msg-error, .dup-button-footer').show();
|
||||
$('#dup-build-button').hide();
|
||||
}
|
||||
}
|
||||
|
||||
//Starts the build process
|
||||
DupliJs.Pack.startBuild = function() {
|
||||
// disable to prevent double click
|
||||
$('#dup-build-button').prop('disabled', true);
|
||||
|
||||
if ($('#dupli-confirm-check').is(":checked")) {
|
||||
$('#form-duplicator').submit();
|
||||
}
|
||||
|
||||
var sizeChecks = $('#hb-files-large-jstree').length ? $('#hb-files-large-jstree').jstree(true).get_checked() : 0;
|
||||
var addonChecks = $('#hb-addon-sites-result input:checked');
|
||||
var utf8Checks = $('#hb-files-utf8-jstree').length ? $('#hb-files-utf8-jstree').jstree(true).get_checked() : 0;
|
||||
if (sizeChecks.length > 0 || addonChecks.length > 0 || utf8Checks.length > 0) {
|
||||
$('#dupli-confirm-area').show();
|
||||
} else {
|
||||
$('#form-duplicator').submit();
|
||||
}
|
||||
}
|
||||
|
||||
//Toggles each scan item to hide/show details
|
||||
DupliJs.Pack.toggleScanItem = function(item) {
|
||||
var $info = $(item).parents('div.scan-item').children('div.info');
|
||||
var $text = $(item).find('div.text i.fa');
|
||||
if ($info.is(":hidden")) {
|
||||
$text.addClass('fa-caret-down').removeClass('fa-caret-right');
|
||||
$info.show();
|
||||
} else {
|
||||
$text.addClass('fa-caret-right').removeClass('fa-caret-down');
|
||||
$info.hide(250);
|
||||
}
|
||||
}
|
||||
|
||||
//Set Good/Warn Badges and checkboxes
|
||||
DupliJs.Pack.setScanStatus = function(data) {
|
||||
let subTestSelectorMappings = {
|
||||
'#data-srv-php-websrv': data.SRV.PHP.websrv,
|
||||
'#data-srv-php-openbase': data.SRV.PHP.openbase || !data.ARC.PathsOutOpenbaseDir.length,
|
||||
'#data-srv-php-maxtime': data.SRV.PHP.maxtime,
|
||||
'#data-srv-php-minmemory': data.SRV.PHP.minMemory,
|
||||
'#data-srv-php-arch64bit': data.SRV.PHP.arch64bit,
|
||||
'#data-srv-php-mysqli': data.SRV.PHP.mysqli,
|
||||
'#data-srv-php-openssl': data.SRV.PHP.openssl,
|
||||
'#data-srv-php-allowurlfopen': data.SRV.PHP.allowurlfopen,
|
||||
'#data-srv-php-curlavailable': data.SRV.PHP.curlavailable,
|
||||
'#data-srv-php-version': data.SRV.PHP.version,
|
||||
'#data-srv-wp-version': data.SRV.WP.version,
|
||||
'#data-srv-brand-check': data.SRV.Brand.LogoImageExists,
|
||||
'#data-srv-wp-core': data.SRV.WP.core
|
||||
};
|
||||
|
||||
for (let selector in subTestSelectorMappings) {
|
||||
if (subTestSelectorMappings[selector]) {
|
||||
$(selector).html('<div class="scan-good"><i class="fa fa-check"></i></div>');
|
||||
} else {
|
||||
$(selector).html('<div class="scan-warn"><i class="fa fa-exclamation-triangle fa-sm"></i></div>');
|
||||
}
|
||||
}
|
||||
|
||||
let testSelectorMappings = {
|
||||
'#data-srv-php-all': data.SRV.PHP.ALL,
|
||||
'#data-srv-wp-all': data.SRV.WP.ALL,
|
||||
'#data-arc-status-size': data.ARC.Status.Size,
|
||||
'#data-arc-status-unreadablefiles': data.ARC.Status.UnreadableItems,
|
||||
'#data-arc-status-showcreatefunc': data.ARC.Status.showCreateFuncStatus,
|
||||
'#data-arc-status-network': data.ARC.Status.Network,
|
||||
'#data-arc-status-triggers': data.DB.Status.Triggers,
|
||||
'#data-arc-status-migratepackage': !data.ARC.Status.PackageIsNotImportable,
|
||||
'#data-arc-status-addonsites': data.ARC.Status.AddonSites,
|
||||
'#data-db-status-size1': data.DB.DBExcluded && data.DB.Status.Success ? data.DB.Status.Excluded : data.DB.Status.Size,
|
||||
}
|
||||
|
||||
const GoodText = "<?php esc_html_e('Good', 'duplicator-pro'); ?>";
|
||||
const WarnText = "<?php esc_html_e('Notice', 'duplicator-pro'); ?>";
|
||||
|
||||
for (let selector in testSelectorMappings) {
|
||||
if (testSelectorMappings[selector]) {
|
||||
$(selector).html(`<div class="badge badge-pass">${GoodText}</div>`);
|
||||
} else {
|
||||
$(selector).html(`<div class="badge badge-warn">${WarnText}</div>`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Allows user to continue with build if warnings found
|
||||
DupliJs.Pack.warningContinue = function(checkbox) {
|
||||
($(checkbox).is(':checked')) ?
|
||||
$('#dup-build-button').prop('disabled', false): $('#dup-build-button').prop('disabled', true);
|
||||
}
|
||||
|
||||
//Page Init:
|
||||
DupliJs.Pack.runScanner(null, true);
|
||||
|
||||
$('.dup-go-back-to-new1').click(function(event) {
|
||||
event.preventDefault();
|
||||
window.location.href = <?php echo json_encode(PackagesPageController::getInstance()->getPackageBuildS1Url()); ?>;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
use Duplicator\Core\Controllers\ControllersManager;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
?>
|
||||
|
||||
<form
|
||||
id="form-duplicator scan-result"
|
||||
method="post"
|
||||
action="<?php echo esc_attr(ControllersManager::getMenuLink(ControllersManager::PACKAGES_SUBMENU_SLUG)); ?>"
|
||||
>
|
||||
<!-- ERROR MESSAGE -->
|
||||
<div id="dup-msg-error">
|
||||
<div class="dup-hdr-error"><i class="fa fa-exclamation-circle"></i> <?php esc_html_e('Input fields not valid', 'duplicator-pro'); ?></div>
|
||||
<i><?php esc_html_e('Please try again!', 'duplicator-pro'); ?></i><br/>
|
||||
<div style="text-align:left">
|
||||
<b><?php esc_html_e("Server Status:", 'duplicator-pro'); ?></b>
|
||||
<div id="dup-msg-error-response-status" style="display:inline-block"></div><br/>
|
||||
<b><?php esc_html_e("Error Message:", 'duplicator-pro'); ?></b>
|
||||
<div id="dup-msg-error-response-text">
|
||||
<ul>
|
||||
<?php $tplData['validator']->getErrorsFormat("<li>%s</li>"); ?>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
type="button"
|
||||
value="◀ <?php esc_html_e("Back", 'duplicator-pro') ?>"
|
||||
class="button hollow secondary dup-go-back-to-new1"
|
||||
>
|
||||
</form>
|
||||
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
use Duplicator\Views\UserUIOptions;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
$uiOpts = UserUIOptions::getInstance();
|
||||
|
||||
$perPage = $uiOpts->get(UserUIOptions::VAL_PACKAGES_PER_PAGE);
|
||||
$dateFormat = $uiOpts->get(UserUIOptions::VAL_CREATED_DATE_FORMAT);
|
||||
$showNote = $uiOpts->get(UserUIOptions::VAL_SHOW_COL_NOTE);
|
||||
$showSize = $uiOpts->get(UserUIOptions::VAL_SHOW_COL_SIZE);
|
||||
$showCreated = $uiOpts->get(UserUIOptions::VAL_SHOW_COL_CREATED);
|
||||
$showAge = $uiOpts->get(UserUIOptions::VAL_SHOW_COL_AGE);
|
||||
?>
|
||||
<fieldset class="metabox-prefs">
|
||||
<legend>
|
||||
<?php esc_html_e('Columns', 'duplicator-pro'); ?>
|
||||
</legend>
|
||||
<label class="inline-display" >
|
||||
<input
|
||||
class="dup-hide-column-tog margin-0"
|
||||
name="dupli-note-hide"
|
||||
type="checkbox"
|
||||
id="dupli-note-hide"
|
||||
value="1"
|
||||
<?php checked($showNote); ?>
|
||||
data-target-colum="dup-note-column"
|
||||
>
|
||||
<?php esc_html_e('Note', 'duplicator-pro'); ?>
|
||||
</label>
|
||||
<label class="inline-display" >
|
||||
<input
|
||||
class="dup-hide-column-tog margin-0"
|
||||
name="dupli-size-hide"
|
||||
type="checkbox"
|
||||
id="dupli-size-hide"
|
||||
value="1" <?php checked($showSize); ?>
|
||||
data-target-colum="dup-size-column"
|
||||
>
|
||||
<?php esc_html_e('Size', 'duplicator-pro'); ?>
|
||||
</label>
|
||||
<label class="inline-display" >
|
||||
<input
|
||||
class="dup-hide-column-tog margin-0"
|
||||
name="dupli-created-hide"
|
||||
type="checkbox"
|
||||
id="dupli-created-hide"
|
||||
value="1"
|
||||
<?php checked($showCreated); ?>
|
||||
data-target-colum="dup-created-column"
|
||||
>
|
||||
<?php esc_html_e('Created', 'duplicator-pro'); ?>
|
||||
</label>
|
||||
<label class="inline-display" >
|
||||
<input
|
||||
class="dup-hide-column-tog margin-0"
|
||||
name="dupli-age-hide"
|
||||
type="checkbox"
|
||||
id="dupli-age-hide"
|
||||
value="1"
|
||||
<?php checked($showAge); ?>
|
||||
data-target-colum="dup-age-column"
|
||||
>
|
||||
<?php esc_html_e('Age', 'duplicator-pro'); ?>
|
||||
</label>
|
||||
</fieldset>
|
||||
<fieldset class="screen-options" >
|
||||
<legend>
|
||||
<?php esc_html_e('Pagination', 'duplicator-pro'); ?>
|
||||
</legend>
|
||||
<label for="dupli_opts_per_page" class="inline-display" >
|
||||
<?php esc_html_e('Backups Per Page', 'duplicator-pro'); ?>
|
||||
</label>
|
||||
<input
|
||||
type="number"
|
||||
step="1"
|
||||
min="1"
|
||||
max="999"
|
||||
class="screen-per-page inline-display margin-0 width-small"
|
||||
name="dupli-per-page"
|
||||
id="dupli-per-page"
|
||||
maxlength="3"
|
||||
value="<?php echo esc_html($perPage); ?>"
|
||||
>
|
||||
</fieldset>
|
||||
<fieldset class="screen-options">
|
||||
<legend>
|
||||
<?php esc_html_e('Created Format', 'duplicator-pro'); ?>
|
||||
</legend>
|
||||
<div class="metabox-prefs">
|
||||
<input type="hidden" name="wp_screen_options[option]" value="package_screen_options">
|
||||
<input type="hidden" name="wp_screen_options[value]" value="val">
|
||||
<div class="created-format-wrapper">
|
||||
<select name="dupli-created-format" class="width-medium" >
|
||||
<!-- YEAR -->
|
||||
<optgroup label="By Year">
|
||||
<option value="1" <?php selected($dateFormat, 1); ?> >Y-m-d H:i [2000-01-05 12:00]</option>
|
||||
<option value="2" <?php selected($dateFormat, 2); ?> >Y-m-d H:i:s [2000-01-05 12:00:01]</option>
|
||||
<option value="3" <?php selected($dateFormat, 3); ?> >y-m-d H:i [00-01-05 12:00]</option>
|
||||
<option value="4" <?php selected($dateFormat, 4); ?> >y-m-d H:i:s [00-01-05 12:00:01]</option>
|
||||
</optgroup>
|
||||
<!-- MONTH -->
|
||||
<optgroup label="By Month">
|
||||
<option value="5" <?php selected($dateFormat, 5); ?> >m-d-Y H:i [01-05-2000 12:00]</option>
|
||||
<option value="6" <?php selected($dateFormat, 6); ?> >m-d-Y H:i:s [01-05-2000 12:00:01]</option>
|
||||
<option value="7" <?php selected($dateFormat, 7); ?> >m-d-y H:i [01-05-00 12:00]</option>
|
||||
<option value="8" <?php selected($dateFormat, 8); ?> >m-d-y H:i:s [01-05-00 12:00:01]</option>
|
||||
</optgroup>
|
||||
<!-- DAY -->
|
||||
<optgroup label="By Day">
|
||||
<option value="9" <?php selected($dateFormat, 9); ?> > d-m-Y H:i [05-01-2000 12:00]</option>
|
||||
<option value="10" <?php selected($dateFormat, 10); ?> >d-m-Y H:i:s [05-01-2000 12:00:01]</option>
|
||||
<option value="11" <?php selected($dateFormat, 11); ?> >d-m-y H:i [05-01-00 12:00]</option>
|
||||
<option value="12" <?php selected($dateFormat, 12); ?> >d-m-y H:i:s [05-01-00 12:00:01]</option>
|
||||
</optgroup>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<input
|
||||
type="submit"
|
||||
name="screen-options-apply"
|
||||
id="screen-options-apply"
|
||||
class="button secondary hollow small margin-0"
|
||||
value="Apply"
|
||||
>
|
||||
<script>
|
||||
jQuery(document).ready(function($) {
|
||||
$('.dup-hide-column-tog').on('change', function() {
|
||||
let node = $(this);
|
||||
let columns = $('.' + node.data('target-colum'));
|
||||
if (node.is(':checked')) {
|
||||
columns.show();
|
||||
} else {
|
||||
columns.hide();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
use Duplicator\Addons\ProBase\License\License;
|
||||
use Duplicator\Libs\WpUtils\WpUtilsMultisite;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
if (!is_multisite()) {
|
||||
return;
|
||||
}
|
||||
?>
|
||||
<div class="filter-mu-tab-content <?php echo (License::can(License::CAPABILITY_MULTISITE_PLUS) ? '' : 'disabled'); ?>">
|
||||
<div style="max-width:900px">
|
||||
<?php if (!License::can(License::CAPABILITY_MULTISITE_PLUS)) { ?>
|
||||
<div class="dupli-panel-optional-txt alert-disabled" style="text-align: center">
|
||||
<b><?php esc_html_e("Notice:", 'duplicator-pro'); ?></b>
|
||||
<?php
|
||||
printf(
|
||||
esc_html__(
|
||||
'This option isn\'t available at the %1$s license level.',
|
||||
'duplicator-pro'
|
||||
),
|
||||
esc_html(License::getLicenseToString())
|
||||
);
|
||||
?>
|
||||
<br>
|
||||
<?php
|
||||
printf(
|
||||
esc_html_x(
|
||||
'To enable this option %1$supgrade%2$s the License.',
|
||||
'%1$s and %2$s represents the opening and closing HTML tags for an anchor or link',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<a href="' . esc_url(License::getUpsellURL()) . '" target="_blank">',
|
||||
'</a>'
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
<?php } ?>
|
||||
<?php
|
||||
echo '<b>' . esc_html__("Overview:", 'duplicator-pro') . '</b><br/>';
|
||||
esc_html_e(
|
||||
"When you want to move a full multisite network or convert a subsite to a standalone site just
|
||||
create a standard Backup like you would with a single site.
|
||||
Then browse to the installer and choose either 'Restore entire multisite network' or 'Convert subsite into a standalone site'.
|
||||
These options will be present on Step 1 of the installer when restoring a Multisite Backup.",
|
||||
'duplicator-pro'
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
<table class="mu-opts">
|
||||
<tr>
|
||||
<td>
|
||||
<b><?php esc_html_e("Included Sub-Sites", 'duplicator-pro'); ?>:</b><br />
|
||||
<select name="mu-include[]" id="mu-include" multiple="true" class="mu-selector">
|
||||
<?php
|
||||
$subsites = License::can(License::CAPABILITY_MULTISITE_PLUS) ? WpUtilsMultisite::getSubsites() : [];
|
||||
foreach ($subsites as $site) {
|
||||
echo "<option value='" . (int) $site->id . "'>" . esc_html($site->domain . $site->path) . "</option>";
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</td>
|
||||
<td>
|
||||
<button type="button" id="mu-exclude-btn" class="mu-push-btn"><i class="fa fa-chevron-right"></i></button>
|
||||
<br />
|
||||
<button type="button" id="mu-include-btn" class="mu-push-btn"><i class="fa fa-chevron-left"></i></button>
|
||||
</td>
|
||||
<td>
|
||||
<b><?php esc_html_e("Excluded Sub-Sites", 'duplicator-pro'); ?>:</b><br />
|
||||
<select name="mu-exclude[]" id="mu-exclude" multiple="true" class="mu-selector"></select>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div class="dupli-panel-optional-txt" style="text-align: left">
|
||||
<?php
|
||||
echo wp_kses(
|
||||
__(
|
||||
"<u><b>Important:</b></u> Full network restoration is an installer option only if you include <b>all</b> subsites.
|
||||
If any subsites are filtered then you may only restore individual subsites as standalones sites at install-time.",
|
||||
'duplicator-pro'
|
||||
),
|
||||
[
|
||||
'b' => [],
|
||||
'u' => [],
|
||||
]
|
||||
);
|
||||
?>
|
||||
<br />
|
||||
<br />
|
||||
<?php
|
||||
esc_html_e(
|
||||
"This section allows you to control which sub-sites of a multisite network you want to include within your Backup.
|
||||
The 'Included Sub-Sites' will also be available to choose from at install time.",
|
||||
'duplicator-pro'
|
||||
);
|
||||
?>
|
||||
<br />
|
||||
<?php
|
||||
esc_html_e(
|
||||
"By default all Backups are included. The ability to exclude sub-sites are intended to help shrink your Backup if needed.",
|
||||
'duplicator-pro'
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
use Duplicator\Package\NameFormat;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
$nameFormat = $tplData['nameFormat'];
|
||||
$notes = $tplData['notes'];
|
||||
|
||||
$helpContent = $tplMng->render('admin_pages/packages/setup/name-format-help', [], false);
|
||||
?>
|
||||
|
||||
<div>
|
||||
<label for="package-name-format" class="lbl-larger large">
|
||||
<?php esc_html_e('Backup Name Format', 'duplicator-pro') ?>:
|
||||
</label>
|
||||
<i
|
||||
class="fa-solid fa-question-circle fa-sm dark-gray-color"
|
||||
data-tooltip-title="<?php esc_attr_e("Backup name format", 'duplicator-pro'); ?>"
|
||||
data-tooltip="<?php echo esc_attr($helpContent); ?>"
|
||||
data-tooltip-width="400"
|
||||
></i>
|
||||
|
||||
<div class="dup-notes-add">
|
||||
<button
|
||||
type="button"
|
||||
onClick="jQuery('#dup-notes-area').toggle()"
|
||||
class="clear button gray xtiny margin-bottom-0"
|
||||
title="<?php esc_attr_e('Add Notes', 'duplicator-pro') ?>"
|
||||
>
|
||||
<i class="far fa-edit"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="display-flex" >
|
||||
<input
|
||||
type="text"
|
||||
id="package-name-format"
|
||||
name="package_name_format"
|
||||
class="margin-0"
|
||||
data-parsley-errors-container="#template_package_name_error_container"
|
||||
data-parsley-required="true"
|
||||
value="<?php echo esc_attr($nameFormat); ?>"
|
||||
autocomplete="off"
|
||||
>
|
||||
<select class="dup-format-name-tags width-medium margin-left-1 margin-0 secondary-color secondary-border-color" >
|
||||
<option value="" selected >
|
||||
<?php esc_html_e('Dynamic Tags', 'duplicator-pro') ?>
|
||||
</option>
|
||||
<?php foreach (NameFormat::FORMATS as $format) { ?>
|
||||
<option value="%<?php echo esc_attr($format); ?>%">
|
||||
%<?php echo esc_html($format); ?>%
|
||||
</option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
</div>
|
||||
<div id="template_package_name_error_container" class="duplicator-error-container"></div>
|
||||
|
||||
<div id="dup-notes-area">
|
||||
<label class="lbl-larger large">
|
||||
<?php esc_html_e('Notes', 'duplicator-pro') ?>:
|
||||
</label><br/>
|
||||
<textarea
|
||||
id="package-notes"
|
||||
name="package-notes"
|
||||
maxlength="300"
|
||||
><?php echo esc_html($notes); ?></textarea>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
jQuery(document).ready(function($) {
|
||||
$('.dup-format-name-tags').change(function(e) {
|
||||
e.stopPropagation();
|
||||
|
||||
if ($(this).val() === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
let input = $('#package-name-format');
|
||||
let currentValue = input.val();
|
||||
let newValue = currentValue + $(this).val();
|
||||
input.val(newValue);
|
||||
|
||||
$(this).val('');
|
||||
});
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
use Duplicator\Package\NameFormat;
|
||||
use Duplicator\Views\ViewHelper;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
?>
|
||||
<p>
|
||||
<?php esc_html_e(
|
||||
'It is possible to customize the name of the backups using a fixed part and dynamic parts through tags.
|
||||
The available tags are as follows:',
|
||||
'duplicator-pro'
|
||||
); ?>
|
||||
|
||||
<ul>
|
||||
<?php foreach (NameFormat::getTagsDescriptions() as $tag => $description) : ?>
|
||||
<li>
|
||||
<strong>%<?php echo esc_html($tag); ?>%</strong> - <?php echo esc_html($description); ?>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
<?php
|
||||
echo wp_kses(
|
||||
__(
|
||||
'Important: <b>Backup date and time expressed in UTC</b> (Coordinated Universal Time).
|
||||
The displayed date corresponds to the server\'s international time, independent of local time zones.',
|
||||
'duplicator-pro'
|
||||
),
|
||||
ViewHelper::GEN_KSES_TAGS
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<?php esc_html_e(
|
||||
'Here are some examples of name formats:',
|
||||
'duplicator-pro'
|
||||
); ?>
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<strong>%year%%month%%day%_%sitetitle%</strong> -
|
||||
<?php esc_html_e('Backup name with date and site title (\'It\'s the default)', 'duplicator-pro'); ?>
|
||||
</li>
|
||||
<li>
|
||||
<strong>%year%%month%%day%_%hour%%minute%%second%_mytext_</strong> -
|
||||
<?php esc_html_e('Backup name with date and time and fixed text', 'duplicator-pro'); ?>
|
||||
</li>
|
||||
<li>
|
||||
<strong>%year%%month%%day%_%schedulename%</strong> -
|
||||
<?php esc_html_e('Backup name with date and schedule name', 'duplicator-pro'); ?>
|
||||
</li>
|
||||
</ul>
|
||||
</p>
|
||||
@@ -0,0 +1,265 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
use Duplicator\Controllers\ToolsPageController;
|
||||
use Duplicator\Core\MigrationMng;
|
||||
use Duplicator\Libs\Snap\FunctionalityCheck;
|
||||
use Duplicator\Libs\WpUtils\WpArchiveUtils;
|
||||
use Duplicator\Libs\WpUtils\WpDbUtils;
|
||||
use Duplicator\Package\BuildRequirements;
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string,mixed> $tplData
|
||||
* @var array<string,mixed> $requirements
|
||||
*/
|
||||
$requirements = $tplData['requirements'];
|
||||
|
||||
if ($requirements['Success']) {
|
||||
return;
|
||||
}
|
||||
?>
|
||||
<div class="dup-box dup-requirements-wrapper">
|
||||
<div class="dup-box-title">
|
||||
<i class="far fa-check-circle"></i>
|
||||
<?php esc_html_e("Requirements:", 'duplicator-pro'); ?> <div class="dup-sys-fail">Fail</div>
|
||||
<button class="dup-box-arrow">
|
||||
<span class="screen-reader-text">
|
||||
<?php esc_html_e('Toggle panel:', 'duplicator-pro') ?> <?php esc_html_e('Requirements:', 'duplicator-pro') ?>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="dup-box-panel">
|
||||
<div class="dup-sys-section">
|
||||
<i><?php esc_html_e("System requirements must pass for the Duplicator to work properly. Click each link for details.", 'duplicator-pro'); ?></i>
|
||||
</div>
|
||||
|
||||
<!-- PHP SUPPORT -->
|
||||
<div class='dup-sys-req'>
|
||||
<div class='dup-sys-title'>
|
||||
<a><?php esc_html_e('PHP Support', 'duplicator-pro'); ?></a>
|
||||
<div><?php echo esc_html($requirements['PHP']['ALL']); ?></div>
|
||||
</div>
|
||||
<div class="dup-sys-info dup-info-box">
|
||||
<table class="dup-sys-info-results">
|
||||
<tr>
|
||||
<td>
|
||||
<?php esc_html_e('PHP Version', 'duplicator-pro'); ?> [<?php echo esc_html(phpversion()); ?>]
|
||||
</td>
|
||||
<td><?php echo esc_html($requirements['PHP']['VERSION']); ?></td>
|
||||
</tr>
|
||||
<?php foreach (BuildRequirements::getFunctionalitiesCheckList() as $func) { ?>
|
||||
<tr>
|
||||
<td>
|
||||
<?php
|
||||
switch ($func->getType()) {
|
||||
case FunctionalityCheck::TYPE_FUNCTION:
|
||||
esc_html_e('Function', 'duplicator-pro');
|
||||
break;
|
||||
case FunctionalityCheck::TYPE_CLASS:
|
||||
esc_html_e('Class', 'duplicator-pro');
|
||||
break;
|
||||
default:
|
||||
throw new Exception('Invalid item type');
|
||||
}
|
||||
?>
|
||||
<a href="<?php echo esc_url($func->link); ?>" target="_blank">
|
||||
<?php echo esc_html($func->getItemKey()); ?>
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<?php
|
||||
if ($func->check()) {
|
||||
echo esc_html_e('Pass', 'duplicator-pro');
|
||||
} elseif ($func->isRequired()) {
|
||||
echo esc_html_e('Fail', 'duplicator-pro');
|
||||
} else {
|
||||
echo esc_html_e('Warning', 'duplicator-pro');
|
||||
}
|
||||
if (strlen($func->troubleshoot) > 0) {
|
||||
echo ' ';
|
||||
echo wp_kses(
|
||||
$func->troubleshoot,
|
||||
[
|
||||
'a' => [
|
||||
'href' => [],
|
||||
'target' => [],
|
||||
],
|
||||
'i' => [
|
||||
'class' => [],
|
||||
'style' => [],
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
</table>
|
||||
<small>
|
||||
<?php
|
||||
printf(
|
||||
esc_html__(
|
||||
"PHP versions %s+ including the listed functions are required for the plugin to create a Backup.
|
||||
For additional information see our online technical FAQs.",
|
||||
'duplicator-pro'
|
||||
),
|
||||
esc_html(DUPLICATOR_PRO_PHP_MINIMUM_VERSION)
|
||||
);
|
||||
?>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- PERMISSIONS -->
|
||||
<div class='dup-sys-req'>
|
||||
<div class='dup-sys-title'>
|
||||
<a><?php esc_html_e('Permissions', 'duplicator-pro'); ?></a>
|
||||
<div><?php echo esc_html($requirements['IO']['ALL']); ?></div>
|
||||
</div>
|
||||
<div class="dup-sys-info dup-info-box">
|
||||
<b><?php esc_html_e("Required Paths", 'duplicator-pro'); ?></b>
|
||||
<div style="padding:3px 0px 0px 15px">
|
||||
<?php
|
||||
printf("<b>%s</b> [%s] <br/>", esc_html($requirements['IO']['WPROOT']), esc_html(WpArchiveUtils::getArchiveListPaths('home')));
|
||||
printf("<b>%s</b> [%s] <br/>", esc_html($requirements['IO']['SSDIR']), esc_html(DUPLICATOR_SSDIR_PATH));
|
||||
printf("<b>%s</b> [%s] <br/>", esc_html($requirements['IO']['SSTMP']), esc_html(DUPLICATOR_SSDIR_PATH_TMP));
|
||||
?>
|
||||
</div>
|
||||
|
||||
<small>
|
||||
<?php
|
||||
esc_html_e(
|
||||
"Permissions can be difficult to resolve on some systems. If the plugin can not read the above paths here
|
||||
are a few things to try. 1) Set the above paths to have permissions of 755 for directories and 644 for files.
|
||||
You can temporarily try 777 however, be sure you don’t leave them this way.
|
||||
2) Check the owner/group settings for both files and directories.
|
||||
The PHP script owner and the process owner are different. The script owner owns the PHP script but the process owner
|
||||
is the user the script is running as, thus determining its capabilities/privileges in the file system.
|
||||
For more details contact your host or server administrator or visit the 'Help' menu under Duplicator for additional online resources.",
|
||||
'duplicator-pro'
|
||||
);
|
||||
?>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- SERVER SUPPORT -->
|
||||
<div class='dup-sys-req'>
|
||||
<div class='dup-sys-title'>
|
||||
<a><?php esc_html_e('Server Support', 'duplicator-pro'); ?></a>
|
||||
<div><?php echo esc_html($requirements['SRV']['ALL']); ?></div>
|
||||
</div>
|
||||
<div class="dup-sys-info dup-info-box">
|
||||
<table class="dup-sys-info-results">
|
||||
<tr>
|
||||
<td><?php printf("%s [%s]", esc_html__("MySQL Version", 'duplicator-pro'), esc_html(WpDbUtils::getVersion())); ?></td>
|
||||
<td><?php echo esc_html($requirements['SRV']['MYSQL_VER']); ?></td>
|
||||
</tr>
|
||||
</table>
|
||||
<small>
|
||||
<?php esc_html_e(
|
||||
"MySQL version 5.0+ or better is required. Contact your server administrator and request MySQL Server 5.0+ be installed.",
|
||||
'duplicator-pro'
|
||||
); ?>
|
||||
</small>
|
||||
<hr>
|
||||
<table class="dup-sys-info-results">
|
||||
<tr>
|
||||
<td><a href="https://www.php.net/manual/en/mysqli.real-escape-string.php" target="_blank">mysqli_real_escape_string</a></td>
|
||||
<td><?php echo esc_html($requirements['SRV']['MYSQL_ESC']); ?></td>
|
||||
</tr>
|
||||
</table>
|
||||
<small>
|
||||
<?php esc_html_e(
|
||||
"The function mysqli_real_escape_string is not working properly.
|
||||
Please consult host support and ask them to switch to a different PHP version or configuration.",
|
||||
'duplicator-pro'
|
||||
); ?>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- INSTALLATION FILES -->
|
||||
<div class='dup-sys-req'>
|
||||
<div class='dup-sys-title'>
|
||||
<a><?php esc_html_e('Installation Files', 'duplicator-pro'); ?></a>
|
||||
<div><?php echo esc_html($requirements['RES']['INSTALL']); ?></div>
|
||||
</div>
|
||||
<div class="dup-sys-info dup-info-box">
|
||||
<?php
|
||||
if ($requirements['RES']['INSTALL'] == 'Pass') :
|
||||
esc_html_e("No reserved installation files were found from a previous install. You are clear to create a new Backup.", 'duplicator-pro');
|
||||
else :
|
||||
?>
|
||||
<form method="post" action="<?php echo esc_url(ToolsPageController::getInstance()->getCleanFilesAcrtionUrl()); ?>">
|
||||
<?php
|
||||
esc_html_e(
|
||||
"An installer file(s) was found in the WordPress root directory.
|
||||
To archive your data correctly please remove any of these files and try creating your Backup again.",
|
||||
'duplicator-pro'
|
||||
);
|
||||
?><br />
|
||||
<b><?php esc_html_e('Installer file names include', 'duplicator-pro'); ?></b>
|
||||
<ul>
|
||||
<?php foreach (MigrationMng::checkInstallerFilesList() as $filePath) { ?>
|
||||
<li>
|
||||
<?php echo esc_html($filePath); ?>
|
||||
</li>
|
||||
<?php } ?>
|
||||
</ul>
|
||||
<input
|
||||
type='submit'
|
||||
class='button action'
|
||||
value='<?php esc_attr_e('Remove Files Now', 'duplicator-pro') ?>'
|
||||
style='font-size:10px; margin-top:5px;'>
|
||||
</form>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ONLINE SUPPORT -->
|
||||
<div class="dup-sys-contact">
|
||||
<?php
|
||||
printf(
|
||||
"<i class='fa fa-question-circle'></i> %s <a href='" . esc_attr(DUPLICATOR_TECH_FAQ_URL) . "' target='_blank'>[%s]</a>",
|
||||
esc_html__("For additional help please see the ", 'duplicator-pro'),
|
||||
esc_html__("online FAQs", 'duplicator-pro')
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
//INIT
|
||||
jQuery(document).ready(function($) {
|
||||
DupliJs.Pack.ToggleSystemDetails = function(anchor) {
|
||||
$(anchor).parent().siblings('.dup-sys-info').toggle();
|
||||
}
|
||||
|
||||
//Init: Toogle for system requirment detial links
|
||||
$('.dup-sys-title a').each(function() {
|
||||
$(this).attr('href', 'javascript:void(0)');
|
||||
$(this).click(function() {
|
||||
DupliJs.Pack.ToggleSystemDetails(this);
|
||||
});
|
||||
$(this).prepend("<span class='ui-icon ui-icon-triangle-1-e dup-toggle' />");
|
||||
});
|
||||
|
||||
//Init: Color code Pass/Fail/Warn items
|
||||
$('.dup-sys-title div').each(function() {
|
||||
$(this).addClass(($(this).text() == 'Pass') ? 'dup-sys-pass' : 'dup-sys-fail');
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
use Duplicator\Views\UI\UiViewState;
|
||||
use Duplicator\Models\GlobalEntity;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
$global = GlobalEntity::getInstance();
|
||||
$boxOpened = UiViewState::getValue('dup-pack-storage-panel');
|
||||
?>
|
||||
<div class="dup-box" id="dup-pack-storage-panel-area">
|
||||
<div class="dup-box-title" id="dupli-store-title">
|
||||
<i class="fas fa-server fa-sm"></i>
|
||||
<?php esc_html_e('Storage', 'duplicator-pro') ?> <sup id="dupli-storage-title-count" class="dup-box-title-badge"></sup>
|
||||
<button class="dup-box-arrow">
|
||||
<span class="screen-reader-text">
|
||||
<?php esc_html_e('Toggle panel:', 'duplicator-pro') ?> <?php esc_html_e('Storage Options', 'duplicator-pro') ?>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div id="dup-pack-storage-panel" class="dup-box-panel <?php echo ($boxOpened ? '' : 'no-display'); ?>">
|
||||
<p>
|
||||
<?php esc_html_e('Choose the storage location(s) where the Backup and Installer files will be saved.', 'duplicator-pro') ?>
|
||||
</p>
|
||||
<?php $tplMng->render(
|
||||
'parts/storage/select_list',
|
||||
[
|
||||
'selectedStorageIds' => $global->getManualModeStorageIds(),
|
||||
'recoveryPointMsg' => true,
|
||||
]
|
||||
); ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<script>
|
||||
jQuery(function($) {
|
||||
DupliJs.Pack.UpdateStorageCount = function() {
|
||||
var store_count = $('#dup-pack-storage-panel input[name="_storage_ids[]"]:checked').length;
|
||||
$('#dupli-storage-title-count').html('(' + store_count + ')');
|
||||
(store_count == 0) ?
|
||||
$('#dupli-storage-title-count').css({
|
||||
'color': 'red',
|
||||
'font-weight': 'bold'
|
||||
}): $('#dupli-storage-title-count').css({
|
||||
'color': '#444',
|
||||
'font-weight': 'normal'
|
||||
});
|
||||
}
|
||||
|
||||
$('#dup-pack-storage-panel input[name="_storage_ids[]"]').on('change', function() {
|
||||
DupliJs.Pack.UpdateStorageCount();
|
||||
});
|
||||
});
|
||||
|
||||
//INIT
|
||||
jQuery(document).ready(function($) {
|
||||
DupliJs.Pack.UpdateStorageCount();
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
echo esc_html(
|
||||
__('When enabled the archive file will be encrypted with a password that is required to open.', 'duplicator-pro') . ' ' .
|
||||
__('The installer will also prompt for the password at install time.', 'duplicator-pro') . ' ' .
|
||||
__('Encryption is a general deterrent and should not be substituted for properly keeping your files secure.', 'duplicator-pro') . ' ' .
|
||||
__('Be sure to remove all installer files when the install process is completed.', 'duplicator-pro')
|
||||
);
|
||||
?>
|
||||
<ul>
|
||||
<li>
|
||||
<b>
|
||||
<?php esc_html_e('None:', 'duplicator-pro'); ?>
|
||||
</b>
|
||||
<?php esc_html_e(
|
||||
"No protection system activated! The installer or archive files can be accessed by any resource that knows the full URL to either file.",
|
||||
'duplicator-pro'
|
||||
); ?>
|
||||
</li>
|
||||
<li>
|
||||
<b>
|
||||
<?php esc_html_e('Installer password:', 'duplicator-pro'); ?>
|
||||
</b>
|
||||
<?php esc_html_e(
|
||||
'The archive is NOT encrypted. When the installer starts, it will prompt for a password to prevent anyone from running the installer.',
|
||||
'duplicator-pro'
|
||||
); ?>
|
||||
</li>
|
||||
<li>
|
||||
<b>
|
||||
<?php esc_html_e('Archive encryption:', 'duplicator-pro'); ?>
|
||||
</b>
|
||||
<?php
|
||||
esc_html_e(
|
||||
'The archive IS encrypted with a password, and the installer will ask for a password when started.',
|
||||
'duplicator-pro'
|
||||
);
|
||||
esc_html_e(
|
||||
'This option is the recommended maximum level of security.',
|
||||
'duplicator-pro'
|
||||
);
|
||||
?>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -0,0 +1,374 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
use Duplicator\Controllers\PackagesPageController;
|
||||
use Duplicator\Controllers\ToolsPageController;
|
||||
use Duplicator\Libs\WpUtils\WpDbUtils;
|
||||
use Duplicator\Package\PackageUtils;
|
||||
use Duplicator\Models\TemplateEntity;
|
||||
use Duplicator\Views\UI\UiDialog;
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string,mixed> $tplData
|
||||
* @var array<string,mixed> $requirements
|
||||
*/
|
||||
$requirements = $tplData['requirements'];
|
||||
/** @var bool */
|
||||
$blur = $tplData['blur'];
|
||||
|
||||
$manual_template = TemplateEntity::getManualTemplate();
|
||||
$templates = TemplateEntity::getAll();
|
||||
$default_name1 = PackageUtils::getDefaultPackageName();
|
||||
$default_name2 = PackageUtils::getDefaultPackageName(false);
|
||||
$default_notes = $manual_template->notes;
|
||||
$dbbuild_mode = WpDbUtils::getBuildMode();
|
||||
|
||||
$templatesUrl = ToolsPageController::getInstance()->getMenuLink(ToolsPageController::L2_SLUG_TEMPLATE);
|
||||
$templateEditBaseUrl = ToolsPageController::getTemplateEditURL();
|
||||
|
||||
|
||||
$tplMng->render('admin_pages/packages/setup/section-requirements');
|
||||
$form_action_url = PackagesPageController::getInstance()->getPackageBuildS2Url();
|
||||
?>
|
||||
<form
|
||||
id="dup-form-opts"
|
||||
class="<?php echo ($blur ? 'dup-mock-blur' : ''); ?>"
|
||||
method="post"
|
||||
action="<?php echo esc_attr($form_action_url); ?>"
|
||||
data-parsley-validate data-parsley-ui-enabled="true">
|
||||
<?php $tplMng->getAction(PackagesPageController::ACTION_UPDATE_TEMPLATE)->getActionNonceFileds(); ?>
|
||||
<div class="dupli-general-area">
|
||||
<?php
|
||||
$tplMng->render(
|
||||
'admin_pages/packages/setup/name-format-controls',
|
||||
[
|
||||
'nameFormat' => '',
|
||||
'notes' => '',
|
||||
]
|
||||
);
|
||||
?>
|
||||
<div>
|
||||
<label for="template_id" class="lbl-larger large">
|
||||
<?php esc_html_e('Template', 'duplicator-pro') ?>:
|
||||
</label>
|
||||
<i class="fa-solid fa-question-circle fa-sm dark-gray-color margin-bottom-0"
|
||||
data-tooltip-title="<?php esc_attr_e("Apply Template", 'duplicator-pro'); ?>"
|
||||
data-tooltip="<?php
|
||||
esc_attr_e(
|
||||
'An optional template configuration that can be applied to this backup setup.
|
||||
An [Unassigned] template will retain the settings from the last scan/build.',
|
||||
'duplicator-pro'
|
||||
); ?>">
|
||||
</i>
|
||||
|
||||
<div class="float-right">
|
||||
<a
|
||||
href="<?php echo esc_url($templatesUrl); ?>"
|
||||
class="clear button gray xtiny margin-bottom-0"
|
||||
title="<?php esc_attr_e("List All Templates", 'duplicator-pro') ?>">
|
||||
<i class="fa-regular fa-clone"></i>
|
||||
</a>
|
||||
<button
|
||||
type="button"
|
||||
onclick="DupliJs.Pack.EditTemplate()"
|
||||
class="clear button gray xtiny margin-bottom-0"
|
||||
title="<?php esc_attr_e("Edit Selected Template", 'duplicator-pro') ?>">
|
||||
<i class="fa-solid fa-pen-to-square"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<select
|
||||
data-parsley-ui-enabled="false"
|
||||
onChange="DupliJs.Pack.EnableTemplate();"
|
||||
name="template_id" id="template_id"
|
||||
aria-label="Prefill option with selected template">
|
||||
<option value="<?php echo intval($manual_template->getId()); ?>"><?php echo '[' . esc_html__('Unassigned', 'duplicator-pro') . ']' ?></option>
|
||||
<?php
|
||||
if (count($templates) == 0) {
|
||||
?>
|
||||
<option value="-1">
|
||||
<?php echo esc_html_e('No Templates', 'duplicator-pro'); ?>
|
||||
</option>
|
||||
<?php
|
||||
} else {
|
||||
foreach ($templates as $template) {
|
||||
if ($template->is_manual) {
|
||||
continue;
|
||||
}
|
||||
?>
|
||||
<option value="<?php echo (int) $template->getId(); ?>">
|
||||
<?php echo esc_html($template->name); ?>
|
||||
</option>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
$tplMng->render('admin_pages/packages/setup/section_storages');
|
||||
$tplMng->render(
|
||||
'parts/packages/filters/section_filters',
|
||||
[
|
||||
'isTemplateEdit' => false,
|
||||
'template' => null,
|
||||
]
|
||||
);
|
||||
$tplMng->render('parts/packages/filters/section_installer');
|
||||
?>
|
||||
|
||||
<div class="dup-button-footer">
|
||||
<input
|
||||
type="button"
|
||||
value="<?php esc_attr_e("Reset", 'duplicator-pro') ?>"
|
||||
class="button hollow secondary small" <?php echo ($requirements['Success']) ? '' : 'disabled="disabled"'; ?>
|
||||
onClick="DupliJs.Pack.ResetSettings()">
|
||||
<input
|
||||
id="button-next"
|
||||
type="submit"
|
||||
value="<?php esc_attr_e("Next", 'duplicator-pro') ?> ▶"
|
||||
class="button primary small" <?php echo ($requirements['Success']) ? '' : 'disabled="disabled"'; ?>>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- CACHE PROTECTION: If the back-button is used from the scanner page then we need to
|
||||
refresh page in-case any filters where set while on the scanner page -->
|
||||
<form id="cache_detection">
|
||||
<input type="hidden" id="cache_state" name="cache_state" value="" />
|
||||
</form>
|
||||
<?php
|
||||
$confirm1 = new UiDialog();
|
||||
$confirm1->title = __('Would you like to continue', 'duplicator-pro');
|
||||
$confirm1->message = __('This will clear all of the current backup settings.', 'duplicator-pro');
|
||||
$confirm1->progressText = __('Please Wait...', 'duplicator-pro');
|
||||
$confirm1->jsCallback = 'DupliJs.Pack.ResetSettingsRun()';
|
||||
$confirm1->initConfirm();
|
||||
?>
|
||||
<script>
|
||||
jQuery(function($) {
|
||||
var packageTemplates = <?php TemplateEntity::getTemplatesFrontendListData(); ?>
|
||||
|
||||
DupliJs.Pack.BeforeSubmit = function(e) {
|
||||
$('#mu-exclude option').each(function() {
|
||||
$(this).prop('selected', true);
|
||||
});
|
||||
|
||||
DupliJs.Pack.FillExcludeTablesList();
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
$('#dup-form-opts').submit(function() {
|
||||
return DupliJs.Pack.BeforeSubmit();
|
||||
})
|
||||
|
||||
// Template-specific Functions
|
||||
DupliJs.Pack.GetTemplateById = function(templateId) {
|
||||
for (var i = 0; i < packageTemplates.length; i++) {
|
||||
var currentTemplate = packageTemplates[i];
|
||||
if (currentTemplate.id == templateId) {
|
||||
return currentTemplate;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
$.fn.selectOption = function(val) {
|
||||
this.val(val)
|
||||
.find('option')
|
||||
.prop('selected', false)
|
||||
.parent()
|
||||
.find('option[value="' + val + '"]')
|
||||
.prop('selected', true)
|
||||
.parent()
|
||||
.trigger('change');
|
||||
return this;
|
||||
};
|
||||
|
||||
DupliJs.Pack.PopulateCurrentTemplate = function() {
|
||||
var selectedId = $('#template_id').val();
|
||||
var selectedTemplate = DupliJs.Pack.GetTemplateById(selectedId);
|
||||
if (selectedTemplate != null) {
|
||||
let formatInput = $('#package-name-format');
|
||||
formatInput.val(selectedTemplate.package_name_format)
|
||||
if (selectedTemplate.is_manual) {
|
||||
name = '<?php echo esc_js(PackageUtils::getDefaultPackageName()); ?>';
|
||||
}
|
||||
|
||||
$("#package-notes").val(selectedTemplate.notes);
|
||||
|
||||
$("#files-filter-on").prop("checked", selectedTemplate.archive_filter_on);
|
||||
$("#filter-names").prop("checked", selectedTemplate.archive_filter_names);
|
||||
|
||||
//Add trailing slash to directories to differentiate between files and directories
|
||||
let filterDirs = selectedTemplate.archive_filter_dirs.split(';').join(";\n");
|
||||
let filterFiles = selectedTemplate.archive_filter_files.split(';').join(";\n")
|
||||
let separator = filterDirs.length > 0 && filterFiles.length > 0 ? ";\n" : '';
|
||||
|
||||
$("#filter-paths").val(filterDirs + separator + filterFiles);
|
||||
$("#filter-exts").val(selectedTemplate.archive_filter_exts);
|
||||
$("#dbfilter-on").prop("checked", selectedTemplate.database_filter_on);
|
||||
$("#db-prefix-filter").prop("checked", selectedTemplate.databasePrefixFilter);
|
||||
$("#db-prefix-sub-filter").prop("checked", selectedTemplate.databasePrefixSubFilter);
|
||||
|
||||
$(".dup-components-checkbox").each(function(i, component) {
|
||||
$(component).prop("checked", false);
|
||||
});
|
||||
|
||||
selectedTemplate.components.forEach(function(component) {
|
||||
$("#" + component).prop("checked", true);
|
||||
});
|
||||
|
||||
DupliJs.Pack.ToggleDBOnly()
|
||||
DupliJs.Pack.SetComponentsSelect();
|
||||
|
||||
if (typeof selectedTemplate.filter_sites != 'undefined' && selectedTemplate.filter_sites.length > 0) {
|
||||
for (var i = 0; i < selectedTemplate.filter_sites.length; i++) {
|
||||
var site_id = selectedTemplate.filter_sites[i];
|
||||
var exclude_option = $('#mu-include').find("option[value=" + site_id + "]").first();
|
||||
console.log(exclude_option.html());
|
||||
$("#mu-exclude").append(exclude_option.clone());
|
||||
exclude_option.remove();
|
||||
}
|
||||
}
|
||||
|
||||
//-- cPanel
|
||||
$("#cpnl-enable").prop("checked", selectedTemplate.installer_opts_cpnl_enable);
|
||||
$("#cpnl-host").val(selectedTemplate.installer_opts_cpnl_host);
|
||||
$("#cpnl-user").val(selectedTemplate.installer_opts_cpnl_user);
|
||||
|
||||
$('.secure-on-input-wrapper input').prop("checked", false);
|
||||
$('.secure-on-input-wrapper input[value=' + selectedTemplate.installer_opts_secure_on + ']:enabled').prop("checked", true);
|
||||
$("#skipscan").prop("checked", selectedTemplate.installer_opts_skip_scan);
|
||||
$("#secure-pass").val(selectedTemplate.installerPassowrd);
|
||||
$("#cpnl-dbaction").selectOption(selectedTemplate.installer_opts_cpnl_db_action);
|
||||
$("#cpnl-dbhost").val(selectedTemplate.installer_opts_cpnl_db_host);
|
||||
$("#cpnl-dbname").val(selectedTemplate.installer_opts_cpnl_db_name);
|
||||
$("#cpnl-dbuser").val(selectedTemplate.installer_opts_cpnl_db_user);
|
||||
|
||||
//-- Brand
|
||||
let installer_opts_brand = selectedTemplate.installer_opts_brand;
|
||||
installer_opts_brand_id = [];
|
||||
x = 0;
|
||||
|
||||
// most tricky thing - setup proper brand on emplate change
|
||||
if (typeof selectedTemplate.installer_opts_brand != 'undefined') {
|
||||
if (selectedTemplate.installer_opts_brand <= 0) {
|
||||
installer_opts_brand = -1;
|
||||
} else if (selectedTemplate.installer_opts_brand > 0) {
|
||||
installer_opts_brand = Number(selectedTemplate.installer_opts_brand);
|
||||
}
|
||||
}
|
||||
|
||||
// find, fix deleted brands and setup default
|
||||
for (var i = 0; i < packageTemplates.length; i++) {
|
||||
if (
|
||||
typeof packageTemplates[i].installer_opts_brand != 'undefined' &&
|
||||
null != packageTemplates[i].installer_opts_brand &&
|
||||
packageTemplates[i].installer_opts_brand != 0
|
||||
) {
|
||||
installer_opts_brand_id[x] = Number(packageTemplates[i].installer_opts_brand);
|
||||
x++;
|
||||
}
|
||||
}
|
||||
|
||||
$("#brand").selectOption(installer_opts_brand);
|
||||
|
||||
//-- Database
|
||||
if (selectedTemplate.database_filter_tables.length) {
|
||||
let databaseFilterTables = selectedTemplate.database_filter_tables.split(",");
|
||||
let tablesToExclude = $("#dup-db-tables-exclude");
|
||||
|
||||
tablesToExclude.find(".dup-pseudo-checkbox").each(function() {
|
||||
let node = $(this);
|
||||
if (databaseFilterTables.includes(node.data('value'))) {
|
||||
node.addClass('checked');
|
||||
} else {
|
||||
node.removeClass('checked');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$("#dbhost").val(selectedTemplate.installer_opts_db_host);
|
||||
$("#dbname").val(selectedTemplate.installer_opts_db_name);
|
||||
$("#dbuser").val(selectedTemplate.installer_opts_db_user);
|
||||
|
||||
} else {
|
||||
console.log("Template ID doesn't exist?? " + selectedId);
|
||||
}
|
||||
|
||||
//Default to Installer cPanel tab if used
|
||||
$('#cpnl-enable').is(":checked") ? $('#dupli-cpnl-tab-lbl').trigger("click") : $('#dupli-bsc-tab-lbl').trigger("click");
|
||||
};
|
||||
|
||||
|
||||
DupliJs.Pack.ResetSettings = function() {
|
||||
<?php $confirm1->showConfirm(); ?>
|
||||
};
|
||||
|
||||
DupliJs.Pack.ResetSettingsRun = function() {
|
||||
$('#dup-form-opts')[0].reset();
|
||||
setTimeout(function() {
|
||||
tb_remove();
|
||||
}, 800);
|
||||
}
|
||||
|
||||
DupliJs.Pack.EditTemplate = function() {
|
||||
var manualTemplateID = <?php echo (int) $manual_template->getId(); ?>;
|
||||
var templateID = $('#template_id').val();
|
||||
var url;
|
||||
|
||||
if (templateID <= 0 || templateID == manualTemplateID) {
|
||||
url = <?php echo json_encode($templatesUrl); ?>;
|
||||
} else {
|
||||
url = <?php echo json_encode($templateEditBaseUrl); ?> + '&package_template_id=' + templateID;
|
||||
}
|
||||
window.open(url, 'edit-template');
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
//INIT
|
||||
jQuery(document).ready(function($) {
|
||||
DupliJs.Pack.checkPageCache = function() {
|
||||
var $state = $('#cache_state');
|
||||
if ($state.val() == "") {
|
||||
$state.val("fresh-load");
|
||||
} else {
|
||||
$state.val("cached");
|
||||
<?php $redirect = PackagesPageController::getInstance()->getPackageBuildS1Url(); ?>
|
||||
window.location.href = '<?php echo esc_js($redirect); ?>';
|
||||
}
|
||||
}
|
||||
|
||||
DupliJs.Pack.EnableTemplate = function() {
|
||||
$('#dupli-template-specific-area').show(0);
|
||||
DupliJs.Pack.PopulateCurrentTemplate();
|
||||
//DupliJs.Pack.ToggleInstallerPassword();
|
||||
DupliJs.EnableInstallerPassword();
|
||||
DupliJs.Pack.ToggleFileFilters();
|
||||
DupliJs.Pack.ToggleDBFilters();
|
||||
DupliJs.Pack.ToggleActiveThemes();
|
||||
DupliJs.Pack.ToggleActivePlugins();
|
||||
DupliJs.Pack.ToggleDBExcluded();
|
||||
DupliJs.Pack.ToggleNoPrefixTables(false);
|
||||
DupliJs.Pack.ToggleNoSubsiteExistsTables(false);
|
||||
}
|
||||
|
||||
DupliJs.Pack.checkPageCache();
|
||||
DupliJs.Pack.EnableTemplate();
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator Backup row in table Backups list
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Controllers\ImportPageController;
|
||||
use Duplicator\Controllers\SettingsPageController;
|
||||
use Duplicator\Controllers\ToolsPageController;
|
||||
use Duplicator\Core\CapMng;
|
||||
use Duplicator\Package\Recovery\RecoveryPackage;
|
||||
use Duplicator\Views\ViewHelper;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
$settingsUrl = esc_url($ctrlMng->getMenuLink($ctrlMng::SETTINGS_SUBMENU_SLUG, SettingsPageController::L2_SLUG_PACKAGE));
|
||||
$templateUrl = esc_url($ctrlMng->getMenuLink($ctrlMng::TOOLS_SUBMENU_SLUG, ToolsPageController::L2_SLUG_TEMPLATE));
|
||||
$recoveryUrl = esc_url($ctrlMng->getMenuLink($ctrlMng::TOOLS_SUBMENU_SLUG, ToolsPageController::L2_SLUG_RECOVERY));
|
||||
?>
|
||||
<div class="dup-toolbar">
|
||||
<label for="dup-pack-bulk-actions" class="screen-reader-text">Select bulk action</label>
|
||||
<select id="dup-pack-bulk-actions" class="small" >
|
||||
<option value="-1" selected="selected">
|
||||
<?php esc_html_e("Bulk Actions", 'duplicator-pro') ?>
|
||||
</option>
|
||||
<?php if (CapMng::can(CapMng::CAP_CREATE, false)) { ?>
|
||||
<option value="delete" title="<?php esc_attr_e("Delete selected Backup(s)", 'duplicator-pro') ?>">
|
||||
<?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.Pack.ConfirmDelete()"
|
||||
>
|
||||
|
||||
<span class="separator"></span>
|
||||
|
||||
<?php if (CapMng::can(CapMng::CAP_SETTINGS, false)) { ?>
|
||||
<a href="<?php echo esc_url($settingsUrl); ?>"
|
||||
class="button hollow secondary small dupli-toolbar-settings"
|
||||
data-tooltip-title="<?php esc_attr_e("Backup Settings", 'duplicator-pro'); ?>"
|
||||
data-tooltip="<?php esc_attr_e("Advanced settings for backups.", 'duplicator-pro'); ?>"
|
||||
>
|
||||
<i class="fas fa-sliders-h fa-fw"></i>
|
||||
</a>
|
||||
<?php } ?>
|
||||
<?php if (CapMng::can(CapMng::CAP_CREATE, false)) { ?>
|
||||
<a href="<?php echo esc_url($templateUrl); ?>"
|
||||
class="button hollow secondary small dupli-toolbar-templates"
|
||||
data-tooltip-title="<?php esc_attr_e("Templates", 'duplicator-pro'); ?>"
|
||||
data-tooltip="<?php esc_attr_e("Create Backup Templates with Preset Configurations.", 'duplicator-pro'); ?>"
|
||||
>
|
||||
<i class="far fa-clone fa-fw"></i>
|
||||
</a>
|
||||
<?php } ?>
|
||||
|
||||
<?php if (CapMng::can(CapMng::CAP_IMPORT, false)) { ?>
|
||||
<a href="<?php echo esc_url(ImportPageController::getImportPageLink()); ?>"
|
||||
id="btn-logs-dialog"
|
||||
class="button hollow secondary small dupli-toolbar-import"
|
||||
data-tooltip-title="<?php esc_attr_e("Import", 'duplicator-pro'); ?>"
|
||||
data-tooltip="<?php esc_attr_e("Import a backups from a file or link.", 'duplicator-pro'); ?>"
|
||||
>
|
||||
<i class="fas fa-arrow-alt-circle-down fa-fw"></i>
|
||||
</a>
|
||||
<?php } ?>
|
||||
<?php if (CapMng::can(CapMng::CAP_BACKUP_RESTORE, false)) { ?>
|
||||
<span
|
||||
class="dupli-toolbar-recovery-info
|
||||
button hollow secondary small <?php echo (RecoveryPackage::getRecoverPackageId() === false ? 'dup-recovery-unset' : ''); ?>"
|
||||
data-tooltip-title="<?php esc_attr_e("Disaster Recovery", 'duplicator-pro') ?>"
|
||||
data-tooltip="<?php esc_attr_e("Quickly restore this site to a specific point in time.", 'duplicator-pro') ?>"
|
||||
>
|
||||
<?php ViewHelper::disasterIcon(); ?>
|
||||
</span>
|
||||
<?php } ?>
|
||||
</div>
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator messages sections
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Controllers\SchedulePageController;
|
||||
use Duplicator\Core\Controllers\ControllersManager;
|
||||
use Duplicator\Models\ScheduleEntity;
|
||||
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
|
||||
*/
|
||||
$blur = $tplData['blur'];
|
||||
$schedule = $tplData['schedule'];
|
||||
$copyScheduleList = ScheduleEntity::getAll(
|
||||
0,
|
||||
0,
|
||||
null,
|
||||
fn(ScheduleEntity $s): bool => $s->getId() != $schedule->getId()
|
||||
);
|
||||
$schedulesListURL = ControllersManager::getMenuLink(
|
||||
ControllersManager::SCHEDULES_SUBMENU_SLUG
|
||||
);
|
||||
$scheduleCopyBaseURL = SchedulePageController::getInstance()->getCopyActionUrl($schedule->getId());
|
||||
|
||||
$countList = count($copyScheduleList);
|
||||
?>
|
||||
<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-schedule-copy-select"
|
||||
name="dupli-source-schedule-id"
|
||||
class="small"
|
||||
<?php disabled($countList, 0); ?>>
|
||||
<option value="-1" selected="selected" disabled="true">
|
||||
<?php esc_html_e('Copy From', 'duplicator-pro'); ?>
|
||||
</option>
|
||||
<?php foreach ($copyScheduleList as $copy_schedule) { ?>
|
||||
<option value="<?php echo (int) $copy_schedule->getId(); ?>">
|
||||
<?php echo esc_html($copy_schedule->name); ?>
|
||||
</option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
<input
|
||||
id="dup-schedule-copy-btn"
|
||||
type="button"
|
||||
class="button hollow secondary small action"
|
||||
value="<?php esc_html_e("Apply", 'duplicator-pro') ?>"
|
||||
disabled>
|
||||
<span class="separator"></span>
|
||||
<a
|
||||
href="<?php echo esc_url($schedulesListURL); ?>"
|
||||
class="button hollow secondary small "
|
||||
title="<?php esc_attr_e('Back to Schedules list.', 'duplicator-pro'); ?>">
|
||||
<i class="far fa-clock fa-sm"></i> <?php esc_html_e('Schedules', 'duplicator-pro'); ?>
|
||||
</a>
|
||||
</div>
|
||||
<script>
|
||||
jQuery(document).ready(function($) {
|
||||
$('#dup-schedule-copy-select').on('change', function(e) {
|
||||
let copyId = parseInt($(this).val());
|
||||
$('#dup-schedule-copy-btn').prop('disabled', (copyId <= 0));
|
||||
});
|
||||
|
||||
/*$('#dup-schedule-copy-select').change(function (evente) {
|
||||
event.preventDefault();
|
||||
alert('changed val ' + $(this).val());
|
||||
$('#dup-schedule-copy-btn').prop('disabled', ($(this).val() > 0));
|
||||
});*/
|
||||
|
||||
$('#dup-schedule-copy-btn').click(function(event) {
|
||||
event.preventDefault();
|
||||
let copyId = $('#dup-schedule-copy-select').val();
|
||||
document.location.href = <?php echo json_encode($scheduleCopyBaseURL); ?> + '&dupli-source-schedule-id=' + copyId;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<hr class="dup-toolbar-divider" />
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator Daily repeat template
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
*/
|
||||
$runEvery = $tplMng->getDataValueIntRequired('run_every');
|
||||
$frequency_note = $tplMng->getDataValueString('frequency_note', '');
|
||||
?>
|
||||
<label class="lbl-larger">
|
||||
<?php esc_html_e('Every', 'duplicator-pro'); ?>
|
||||
</label>
|
||||
<div>
|
||||
<select name="_run_every_days" class="width-tiny inline-block margin-0" data-parsley-ui-enabled="false">
|
||||
<?php for ($i = 1; $i < 30; $i++) { ?>
|
||||
<option <?php selected($i, $runEvery); ?> value="<?php echo (int) $i; ?>">
|
||||
<?php echo (int) $i; ?>
|
||||
</option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
<?php esc_html_e('days', 'duplicator-pro'); ?>
|
||||
<i
|
||||
class="fa-solid fa-question-circle fa-sm dark-gray-color"
|
||||
data-tooltip-title="<?php esc_attr_e("Frequency Note", 'duplicator-pro'); ?>"
|
||||
data-tooltip="<?php echo esc_attr($frequency_note) ?>">
|
||||
</i>
|
||||
</div>
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator Hourly repeat template
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
*/
|
||||
|
||||
$runEvery = $tplMng->getDataValueIntRequired('run_every');
|
||||
$frequency_note = $tplMng->getDataValueString('frequency_note', '');
|
||||
$hour_intervals = [
|
||||
1,
|
||||
2,
|
||||
4,
|
||||
6,
|
||||
12,
|
||||
];
|
||||
$tipContent = __('Backup will build every x hours starting at 00:00.', 'duplicator-pro') . '<br/><br/>' . $frequency_note;
|
||||
?>
|
||||
<label class="lbl-larger">
|
||||
<?php esc_html_e('Every', 'duplicator-pro'); ?>
|
||||
</label>
|
||||
<div>
|
||||
<select name="_run_every_hours" class="width-tiny inline-block margin-0" data-parsley-ui-enabled="false">
|
||||
<?php foreach ($hour_intervals as $hour_interval) { ?>
|
||||
<option <?php selected($hour_interval, $runEvery); ?> value="<?php echo (int) $hour_interval; ?>">
|
||||
<?php echo (int) $hour_interval; ?>
|
||||
</option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
<?php
|
||||
esc_html_e('hours', 'duplicator-pro');
|
||||
?>
|
||||
<i
|
||||
class="fa-solid fa-question-circle fa-sm dark-gray-color"
|
||||
data-tooltip-title="<?php esc_attr_e("Frequency Note", 'duplicator-pro'); ?>"
|
||||
data-tooltip="<?php echo esc_attr($tipContent); ?>">
|
||||
</i>
|
||||
</div>
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator Monthly repeat template
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
*/
|
||||
|
||||
$runEvery = $tplMng->getDataValueIntRequired('run_every');
|
||||
$dayOfMonth = $tplMng->getDataValueIntRequired('day_of_month');
|
||||
?>
|
||||
<label class="lbl-larger">
|
||||
<?php esc_html_e('Day', 'duplicator-pro'); ?>
|
||||
</label>
|
||||
<div>
|
||||
<select name="day_of_month" class="width-tiny inline-block margin-0">
|
||||
<?php for ($i = 1; $i <= 31; $i++) { ?>
|
||||
<option <?php selected($i, $dayOfMonth); ?> value="<?php echo (int) $i; ?>">
|
||||
<?php echo (int) $i; ?>
|
||||
</option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
<?php esc_html_e('of every', 'duplicator-pro'); ?>
|
||||
<select name="_run_every_months" data-parsley-ui-enabled="false" class="width-tiny inline-block margin-0">
|
||||
<?php for ($i = 1; $i <= 12; $i++) { ?>
|
||||
<option <?php selected($i, $runEvery); ?> value="<?php echo (int) $i; ?>">
|
||||
<?php echo (int) $i; ?>
|
||||
</option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
<?php esc_html_e('month(s)', 'duplicator-pro'); ?>
|
||||
</div>
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator Weekly repeat template
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
*/
|
||||
|
||||
$weekdays = $tplMng->getDataValueArrayRequired('weekdays');
|
||||
?>
|
||||
<label class="lbl-larger">
|
||||
<?php esc_html_e('Every', 'duplicator-pro'); ?>
|
||||
</label>
|
||||
<div>
|
||||
<!-- RSR Cron does not support counting by week - just days and months so removing (for now?)-->
|
||||
<div class="weekday-div">
|
||||
<input
|
||||
<?php checked($weekdays['mon']); ?>
|
||||
value="mon" name="weekday[]"
|
||||
type="checkbox"
|
||||
id="repeat-weekly-mon"
|
||||
data-parsley-group="weekly" required data-parsley-class-handler="#repeat-weekly-area"
|
||||
data-parsley-error-message="<?php esc_attr_e('At least one day must be checked.', 'duplicator-pro'); ?>"
|
||||
data-parsley-no-focus data-parsley-errors-container="#weekday-errors">
|
||||
<label for="repeat-weekly-mon"><?php esc_html_e('Monday', 'duplicator-pro'); ?></label>
|
||||
</div>
|
||||
<div class="weekday-div">
|
||||
<input
|
||||
<?php checked($weekdays['tue']); ?>
|
||||
value="tue" name="weekday[]"
|
||||
type="checkbox"
|
||||
id="repeat-weekly-tue">
|
||||
<label for="repeat-weekly-tue"><?php esc_html_e('Tuesday', 'duplicator-pro'); ?></label>
|
||||
</div>
|
||||
<div class="weekday-div">
|
||||
<input
|
||||
<?php checked($weekdays['wed']); ?>
|
||||
value="wed" name="weekday[]"
|
||||
type="checkbox"
|
||||
id="repeat-weekly-wed">
|
||||
<label for="repeat-weekly-wed"><?php esc_html_e('Wednesday', 'duplicator-pro'); ?></label>
|
||||
</div>
|
||||
<div class="weekday-div">
|
||||
<input
|
||||
<?php checked($weekdays['thu']); ?>
|
||||
value="thu" name="weekday[]"
|
||||
type="checkbox"
|
||||
id="repeat-weekly-thu">
|
||||
<label for="repeat-weekly-thu"><?php esc_html_e('Thursday', 'duplicator-pro'); ?></label>
|
||||
</div>
|
||||
<div class="weekday-div" style="clear:both">
|
||||
<input
|
||||
<?php checked($weekdays['fri']); ?>
|
||||
value="fri" name="weekday[]"
|
||||
type="checkbox"
|
||||
id="repeat-weekly-fri">
|
||||
<label for="repeat-weekly-fri"><?php esc_html_e('Friday', 'duplicator-pro'); ?></label>
|
||||
</div>
|
||||
<div class="weekday-div">
|
||||
<input
|
||||
<?php checked($weekdays['sat']); ?>
|
||||
value="sat" name="weekday[]"
|
||||
type="checkbox"
|
||||
id="repeat-weekly-sat">
|
||||
<label for="repeat-weekly-sat"><?php esc_html_e('Saturday', 'duplicator-pro'); ?></label>
|
||||
</div>
|
||||
<div class="weekday-div">
|
||||
<input
|
||||
<?php checked($weekdays['sun']); ?>
|
||||
value="sun" name="weekday[]"
|
||||
type="checkbox"
|
||||
id="repeat-weekly-sun">
|
||||
<label for="repeat-weekly-sun"><?php esc_html_e('Sunday', 'duplicator-pro'); ?></label>
|
||||
</div>
|
||||
<div style="padding-top:3px; clear:both;" id="weekday-errors"></div>
|
||||
</div>
|
||||
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator messages sections
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Addons\ProBase\License\License;
|
||||
use Duplicator\Models\ScheduleEntity;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
*/
|
||||
|
||||
$repeatType = $tplMng->getDataValueIntRequired('repeat_type');
|
||||
|
||||
$min_frequency = 0;
|
||||
$max_frequency = (
|
||||
License::can(License::CAPABILITY_SHEDULE_HOURLY) ?
|
||||
ScheduleEntity::REPEAT_HOURLY :
|
||||
ScheduleEntity::REPEAT_MONTHLY
|
||||
);
|
||||
|
||||
$frequencyUpgradMsg = sprintf(
|
||||
__(
|
||||
'Hourly frequency isn\'t available at the <b>%1$s</b> license level.',
|
||||
'duplicator-pro'
|
||||
),
|
||||
License::getLicenseToString()
|
||||
) .
|
||||
' <b>' .
|
||||
sprintf(
|
||||
_x(
|
||||
'To enable this option %1$supgrade%2$s the License.',
|
||||
'%1$s and %2$s represents the opening and closing HTML tags for an anchor or link',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<a href="' . esc_url(License::getUpsellURL()) . '" target="_blank">',
|
||||
'</a>'
|
||||
) .
|
||||
'</b>';
|
||||
|
||||
$frequency_note = __(
|
||||
'If you have a large site, it\'s recommended you schedule backups during lower traffic periods.
|
||||
If you\'re on a shared host then be aware that running multiple schedules too close together
|
||||
(i.e. every 10 minutes) may alert your host to a spike in system resource usage.
|
||||
Be sure that your schedules do not overlap and give them plenty of time to run.',
|
||||
'duplicator-pro'
|
||||
);
|
||||
?>
|
||||
|
||||
<div class="dup-settings-wrapper margin-bottom-1">
|
||||
<label class="lbl-larger"><?php esc_html_e("Repeats", 'duplicator-pro'); ?></label>
|
||||
<div class="margin-bottom-1">
|
||||
<select
|
||||
id="change-mode"
|
||||
name="repeat_type"
|
||||
class="width-small margin-0"
|
||||
onchange="DupliJs.Schedule.ChangeMode()"
|
||||
data-parsley-range='<?php printf('[%1$s, %2$s]', (int) $min_frequency, (int) $max_frequency); ?>'
|
||||
data-parsley-error-message="<?php echo esc_attr($frequencyUpgradMsg); ?>">
|
||||
<option
|
||||
value="<?php echo (int) ScheduleEntity::REPEAT_HOURLY; ?>"
|
||||
<?php selected($repeatType, ScheduleEntity::REPEAT_HOURLY) ?>>
|
||||
<?php esc_html_e("Hourly", 'duplicator-pro'); ?>
|
||||
</option>
|
||||
<option
|
||||
value="<?php echo (int) ScheduleEntity::REPEAT_DAILY; ?>"
|
||||
<?php selected($repeatType, ScheduleEntity::REPEAT_DAILY) ?>>
|
||||
<?php esc_html_e("Daily", 'duplicator-pro'); ?>
|
||||
</option>
|
||||
<option
|
||||
value="<?php echo (int) ScheduleEntity::REPEAT_WEEKLY; ?>"
|
||||
<?php selected($repeatType, ScheduleEntity::REPEAT_WEEKLY) ?>>
|
||||
<?php esc_html_e("Weekly", 'duplicator-pro'); ?>
|
||||
</option>
|
||||
<option
|
||||
value="<?php echo (int) ScheduleEntity::REPEAT_MONTHLY; ?>"
|
||||
<?php selected($repeatType, ScheduleEntity::REPEAT_MONTHLY) ?>>
|
||||
<?php esc_html_e("Monthly", 'duplicator-pro'); ?>
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<!-- Repeat Options -->
|
||||
<div id="repeat-hourly-area" class="repeater-area margin-bottom-1">
|
||||
<?php $tplMng->render('admin_pages/schedules/parts/repeat_hourly', ['frequency_note' => $frequency_note]); ?>
|
||||
</div>
|
||||
|
||||
<div id="repeat-daily-area" class="repeater-area margin-bottom-1">
|
||||
<?php $tplMng->render('admin_pages/schedules/parts/repeat_daily', ['frequency_note' => $frequency_note]); ?>
|
||||
</div>
|
||||
|
||||
<div id="repeat-weekly-area" class="repeater-area margin-bottom-1">
|
||||
<?php $tplMng->render('admin_pages/schedules/parts/repeat_weekly'); ?>
|
||||
</div>
|
||||
|
||||
<div id="repeat-monthly-area" class="repeater-area margin-bottom-1">
|
||||
<?php $tplMng->render('admin_pages/schedules/parts/repeat_monthly'); ?>
|
||||
</div>
|
||||
|
||||
<!-- Start Time -->
|
||||
<?php $tplMng->render('admin_pages/schedules/parts/start_time'); ?>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
jQuery(document).ready(function($) {
|
||||
DupliJs.Schedule.ChangeMode = function() {
|
||||
var mode = $("#change-mode option:selected").val();
|
||||
var animate = 400;
|
||||
$('#repeat-hourly-area, #repeat-daily-area, #repeat-weekly-area, #repeat-monthly-area').hide();
|
||||
n = $("#repeat-weekly-area input:checked").length;
|
||||
|
||||
if (n == 0) {
|
||||
// Hack so parsely will ignore weekly if it isnt selected
|
||||
$('#repeat-weekly-mon').prop("checked", true);
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case "0":
|
||||
$('#repeat-daily-area').show(animate);
|
||||
$('#start-time-label, #start-time-content').show(animate);
|
||||
break;
|
||||
case "1":
|
||||
$('#repeat-weekly-area').show(animate);
|
||||
$('#start-time-label, #start-time-content').show(animate);
|
||||
break;
|
||||
case "2":
|
||||
$('#repeat-monthly-area').show(animate);
|
||||
$('#start-time-label, #start-time-content').show(animate);
|
||||
break;
|
||||
case "3":
|
||||
$('#repeat-hourly-area').show(animate);
|
||||
$('#start-time-label, #start-time-content').hide(animate);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DupliJs.Schedule.ChangeMode();
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator Start Time template
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var \Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var \Duplicator\Core\Views\TplMng $tplMng
|
||||
*/
|
||||
|
||||
$start_hour = $tplMng->getDataValueIntRequired('start_hour');
|
||||
$start_minute = $tplMng->getDataValueIntRequired('start_minute');
|
||||
$mins = 0;
|
||||
?>
|
||||
<label class="lbl-larger" id="start-time-label">
|
||||
<?php esc_html_e('Start Time', 'duplicator-pro'); ?>
|
||||
</label>
|
||||
<div class="margin-bottom-1" id="start-time-content">
|
||||
<select name="_start_time" class="width-small inline-display margin-0">
|
||||
<?php
|
||||
// Add setting to use 24 hour vs AM/PM the interval for hours is '1'
|
||||
for ($hours = 0; $hours < 24; $hours++) {
|
||||
?>
|
||||
<option <?php selected($hours, $start_hour); ?> value="<?php echo (int) $hours; ?>">
|
||||
<?php echo esc_html(sprintf('%02d:%02d', $hours, $mins)); ?>
|
||||
</option>
|
||||
<?php } ?>
|
||||
</select>
|
||||
|
||||
<i class="dupli-edit-info">
|
||||
<?php esc_html_e("Current Server Time Stamp is", 'duplicator-pro'); ?>
|
||||
<?php echo esc_html(date_i18n('Y-m-d H:i:s')); ?>
|
||||
</i>
|
||||
</div>
|
||||
|
||||
<div class="margin-bottom-1">
|
||||
<p class="description width-xlarge">
|
||||
<?php
|
||||
printf(
|
||||
esc_html_x(
|
||||
'%1$sNote:%2$s Schedules require web site traffic in order to start a build.
|
||||
If you set a start time of 06:00 daily but do not get any traffic till 10:00 then the build will not start until 10:00.
|
||||
If you have low traffic consider setting up a cron job to periodically hit your site.',
|
||||
'%1$s and %2$s represent opening and closing bold tags',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<b>',
|
||||
'</b>'
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Duplicator Backup row in table Backups list
|
||||
*
|
||||
* @package Duplicator
|
||||
* @copyright (c) 2022, Snap Creek LLC
|
||||
*/
|
||||
|
||||
use Duplicator\Controllers\SchedulePageController;
|
||||
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_SCHEDULE, false) && !$blur) {
|
||||
$scheduleEditBaseURL = SchedulePageController::getInstance()->getEditBaseUrl();
|
||||
$tipContent = __(
|
||||
'Create a new Scheduled Backup.',
|
||||
'duplicator-pro'
|
||||
);
|
||||
?>
|
||||
<span
|
||||
class="dup-new-package-wrapper"
|
||||
data-tooltip="<?php echo esc_attr($tipContent); ?>"
|
||||
>
|
||||
<a
|
||||
href="<?php echo esc_url($scheduleEditBaseURL); ?>"
|
||||
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,240 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
use Duplicator\Controllers\SchedulePageController;
|
||||
use Duplicator\Controllers\ToolsPageController;
|
||||
use Duplicator\Core\Controllers\ControllersManager;
|
||||
use Duplicator\Models\ScheduleEntity;
|
||||
use Duplicator\Models\TemplateEntity;
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
*/
|
||||
|
||||
$blur = $tplMng->getDataValueBool('blur');
|
||||
$schedule = $tplMng->getDataValueObjRequired('schedule', ScheduleEntity::class);
|
||||
|
||||
$templatesPageUrl = ToolsPageController::getInstance()->getMenuLink(ToolsPageController::L2_SLUG_TEMPLATE);
|
||||
$editTemplateUrl = ControllersManager::getMenuLink(
|
||||
ControllersManager::TOOLS_SUBMENU_SLUG,
|
||||
ToolsPageController::L2_SLUG_TEMPLATE,
|
||||
null,
|
||||
[ControllersManager::QUERY_STRING_INNER_PAGE => 'edit']
|
||||
);
|
||||
|
||||
?>
|
||||
<form
|
||||
id="dup-schedule-form"
|
||||
class="dup-monitored-form <?php echo ($blur ? 'dup-mock-blur' : ''); ?>"
|
||||
action="<?php echo esc_url(ControllersManager::getCurrentLink()); ?>"
|
||||
method="post"
|
||||
data-parsley-ui-enabled="true">
|
||||
<?php $tplMng->render('admin_pages/schedules/parts/edit_toolbar'); ?>
|
||||
<?php $tplMng->getAction(SchedulePageController::ACTION_EDIT_SAVE)->getActionNonceFileds(); ?>
|
||||
<input type="hidden" name="schedule_id" value="<?php echo (int) $schedule->getId(); ?>">
|
||||
|
||||
<!-- ===============================
|
||||
SETTINGS -->
|
||||
<table class="form-table">
|
||||
<tr valign="top">
|
||||
<th scope="row"><label><?php esc_html_e('Schedule Name', 'duplicator-pro'); ?></label></th>
|
||||
<td>
|
||||
<input
|
||||
type="text"
|
||||
id="schedule-name"
|
||||
class="width-medium"
|
||||
name="name"
|
||||
value="<?php echo esc_attr($schedule->name); ?>"
|
||||
required data-parsley-group="standard"
|
||||
autocomplete="off">
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row">
|
||||
<label><?php esc_html_e('Backup Template', 'duplicator-pro'); ?></label>
|
||||
</th>
|
||||
<td>
|
||||
<div class="schedule-template display-flex">
|
||||
<div>
|
||||
<select id="schedule-template-selector" name="template_id" class="width-medium margin-bottom-0" required>
|
||||
<?php
|
||||
$templates = TemplateEntity::getAllWithoutManualMode();
|
||||
if (count($templates) == 0) {
|
||||
$no_templates = __('No Templates Found', 'duplicator-pro');
|
||||
printf('<option value="">%1$s</option>', esc_html($no_templates));
|
||||
} else {
|
||||
echo "<option value='' selected='true'>" . esc_html__("<Choose A Template>", 'duplicator-pro') . "</option>";
|
||||
foreach ($templates as $template) {
|
||||
?>
|
||||
<option
|
||||
<?php selected($schedule->template_id, $template->getId()); ?>
|
||||
value="<?php echo (int) $template->getId(); ?>">
|
||||
<?php echo esc_html($template->name); ?>
|
||||
</option>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
<div class="margin-bottom-1">
|
||||
<small>
|
||||
<a href="<?php echo esc_url($templatesPageUrl); ?>" target="edit-template">
|
||||
[<?php esc_attr_e("Show All Templates", 'duplicator-pro') ?>]
|
||||
</a>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<a
|
||||
id="schedule-template-edit-btn"
|
||||
href="javascript:void(0)"
|
||||
onclick="DupliJs.Schedule.EditTemplate()"
|
||||
style="display:none"
|
||||
class="pack-temp-btns button hollow secondary small margin-bottom-0"
|
||||
title="<?php esc_attr_e("Edit Selected Template", 'duplicator-pro') ?>">
|
||||
<i class="far fa-edit"></i>
|
||||
</a>
|
||||
<a
|
||||
id="schedule-template-add-btn"
|
||||
href="<?php echo esc_url($editTemplateUrl); ?>"
|
||||
class="pack-temp-btns button hollow secondary small margin-bottom-0"
|
||||
title="<?php esc_attr_e("Add New Template", 'duplicator-pro') ?>"
|
||||
target="edit-template">
|
||||
<i class="far fa-plus-square"></i>
|
||||
</a>
|
||||
<a
|
||||
id="schedule-template-sync-btn"
|
||||
href="javascript:window.location.reload()"
|
||||
class="pack-temp-btns button hollow secondary small margin-bottom-0"
|
||||
title="<?php esc_attr_e("Refresh Template List", 'duplicator-pro') ?>">
|
||||
<i class="fas fa-sync-alt"></i>
|
||||
</a>
|
||||
|
||||
<i
|
||||
class="fa-solid fa-question-circle fa-sm dark-gray-color"
|
||||
data-tooltip-title="<?php esc_attr_e("Template Details", 'duplicator-pro'); ?>"
|
||||
data-tooltip="<?php
|
||||
esc_attr_e(
|
||||
'The template specifies which files and database tables should be included in the archive.<br/><br/>
|
||||
Choose from an existing template or create a new one by clicking the "Add New Template" button.
|
||||
To edit a template, select it and then click the "Edit Selected Template" button.',
|
||||
'duplicator-pro'
|
||||
);
|
||||
?>">
|
||||
</i>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row"><label><?php esc_html_e('Storage', 'duplicator-pro'); ?></label></th>
|
||||
<td>
|
||||
<!-- ===============================
|
||||
STORAGE -->
|
||||
<?php $tplMng->render(
|
||||
'parts/storage/select_list',
|
||||
[
|
||||
'selectedStorageIds' => $schedule->storage_ids,
|
||||
'showAddNew' => false,
|
||||
'recoveryPointMsg' => true,
|
||||
]
|
||||
); ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<td colspan="2">
|
||||
<?php
|
||||
$tplMng->render(
|
||||
'admin_pages/schedules/parts/repeats_options',
|
||||
[
|
||||
'repeat_type' => $schedule->repeat_type,
|
||||
'run_every' => $schedule->run_every,
|
||||
'day_of_month' => $schedule->day_of_month,
|
||||
'weekdays' => [
|
||||
'mon' => $schedule->isDaySet('mon'),
|
||||
'tue' => $schedule->isDaySet('tue'),
|
||||
'wed' => $schedule->isDaySet('wed'),
|
||||
'thu' => $schedule->isDaySet('thu'),
|
||||
'fri' => $schedule->isDaySet('fri'),
|
||||
'sat' => $schedule->isDaySet('sat'),
|
||||
'sun' => $schedule->isDaySet('sun'),
|
||||
],
|
||||
'start_hour' => $schedule->getStartTimePiece(0),
|
||||
'start_minute' => $schedule->getStartTimePiece(1),
|
||||
]
|
||||
);
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row"><label><?php esc_html_e('Recovery Status', 'duplicator-pro'); ?></label></th>
|
||||
<td class="dup-recovery-template">
|
||||
<div class="margin-bottom-1">
|
||||
<?php
|
||||
if (($template = $schedule->getTemplate()) !== false) {
|
||||
$schedule->recoveableHtmlInfo();
|
||||
} else {
|
||||
esc_html_e('Unavailable', 'duplicator-pro');
|
||||
?>
|
||||
<i class="fa-solid fa-question-circle fa-sm dark-gray-color"
|
||||
data-tooltip-title="<?php esc_attr_e("Recovery Status", 'duplicator-pro'); ?>"
|
||||
data-tooltip="<?php esc_attr_e('Status is unavailable. Please save the schedule to view recovery status', 'duplicator-pro');
|
||||
?>"></i>
|
||||
<?php } ?>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr valign="top">
|
||||
<th scope="row"><label for="schedule-active"><?php esc_html_e('Activated', 'duplicator-pro'); ?></label></th>
|
||||
<td>
|
||||
<input name="_active" id="schedule-active" type="checkbox" <?php checked($schedule->isActive()); ?> class="margin-0">
|
||||
<label for="schedule-active"><?php esc_html_e('Enable This Schedule', 'duplicator-pro'); ?></label><br />
|
||||
<i class="dupli-edit-info"> <?php esc_html_e('When checked this schedule will run', 'duplicator-pro'); ?></i>
|
||||
</td>
|
||||
</tr>
|
||||
</table><br />
|
||||
<button
|
||||
id="dupli-save-schedule"
|
||||
class="button primary small"
|
||||
type="submit">
|
||||
<?php esc_html_e('Save Schedule', 'duplicator-pro'); ?>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
jQuery(document).ready(function($) {
|
||||
DupliJs.Schedule.EditTemplate = function() {
|
||||
var templateID = $('#schedule-template-selector').val();
|
||||
var url = <?php echo wp_json_encode($editTemplateUrl); ?> + '&package_template_id=' + templateID;
|
||||
window.open(url, 'edit-template');
|
||||
};
|
||||
|
||||
DupliJs.Schedule.ToggleTemplateEditBtn = function() {
|
||||
$('#schedule-template-edit-btn, #schedule-template-add-btn, #schedule-template-sync-btn').hide();
|
||||
if ($("#schedule-template-selector").val() > 0) {
|
||||
$('#schedule-template-edit-btn').show();
|
||||
} else {
|
||||
$('#schedule-template-add-btn, #schedule-template-sync-btn').show();
|
||||
}
|
||||
}
|
||||
|
||||
$('#dup-schedule-form').parsley({
|
||||
excluded: ':disabled'
|
||||
});
|
||||
|
||||
jQuery('#schedule-name').focus().select();
|
||||
DupliJs.Schedule.ToggleTemplateEditBtn();
|
||||
|
||||
$("#schedule-template-selector").change(function() {
|
||||
DupliJs.Schedule.ToggleTemplateEditBtn()
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,619 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
use Duplicator\Ajax\ServicesSchedule;
|
||||
use Duplicator\Controllers\PackagesPageController;
|
||||
use Duplicator\Controllers\SchedulePageController;
|
||||
use Duplicator\Controllers\SettingsPageController;
|
||||
use Duplicator\Controllers\ToolsPageController;
|
||||
use Duplicator\Core\CapMng;
|
||||
use Duplicator\Core\Controllers\ControllersManager;
|
||||
use Duplicator\Models\ScheduleEntity;
|
||||
use Duplicator\Models\Storages\AbstractStorageEntity;
|
||||
use Duplicator\Models\TemplateEntity;
|
||||
use Duplicator\Package\DupPackage;
|
||||
use Duplicator\Views\UI\UiDialog;
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
* @var bool $blur
|
||||
*/
|
||||
|
||||
$blur = $tplData['blur'];
|
||||
|
||||
$active_schedules = ScheduleEntity::getActive();
|
||||
$active_count = count($active_schedules);
|
||||
$schedules = ScheduleEntity::getAll();
|
||||
$schedule_count = ScheduleEntity::count();
|
||||
|
||||
$active_package = DupPackage::getNextActive();
|
||||
$active_schedule_id = -1;
|
||||
|
||||
if ($active_package != null) {
|
||||
$active_schedule_id = $active_package->getScheduleId();
|
||||
}
|
||||
|
||||
$packagesPageUrl = PackagesPageController::getInstance()->getMenuLink();
|
||||
|
||||
$scheduleEditBaseURL = SchedulePageController::getInstance()->getEditBaseUrl();
|
||||
$scheduleCopyBaseURL = SchedulePageController::getInstance()->getCopyActionUrl();
|
||||
$settingsScheudleUrl = ControllersManager::getMenuLink(
|
||||
ControllersManager::SETTINGS_SUBMENU_SLUG,
|
||||
SettingsPageController::L2_SLUG_SCHEDULE
|
||||
);
|
||||
$templatesPageUrl = ToolsPageController::getInstance()->getMenuLink(ToolsPageController::L2_SLUG_TEMPLATE);
|
||||
$tooltopCreatedContent = __(
|
||||
'Backup date and time expressed in UTC (Coordinated Universal Time).
|
||||
The displayed date corresponds to the server\'s international time, independent of local time zones.',
|
||||
'duplicator-pro'
|
||||
);
|
||||
|
||||
?>
|
||||
|
||||
<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="selected">
|
||||
<?php esc_html_e("Bulk Actions", 'duplicator-pro'); ?>
|
||||
</option>
|
||||
<option value="<?php echo (int) ServicesSchedule::SCHEDULE_BULK_ACTIVATE; ?>" title="Activate selected schedules(s)">
|
||||
<?php esc_html_e("Activate", 'duplicator-pro'); ?>
|
||||
</option>
|
||||
<option value="<?php echo (int) ServicesSchedule::SCHEDULE_BULK_DEACTIVATE; ?>" title="Deactivate selected schedules(s)">
|
||||
<?php esc_html_e("Deactivate", 'duplicator-pro'); ?>
|
||||
</option>
|
||||
<option value="<?php echo (int) ServicesSchedule::SCHEDULE_BULK_DELETE; ?>" title="Delete selected schedules(s)">
|
||||
<?php esc_html_e("Delete", 'duplicator-pro'); ?>
|
||||
</option>
|
||||
</select>
|
||||
<input
|
||||
type="button"
|
||||
id="dup-schedule-bulk-apply"
|
||||
class="button hollow secondary small action"
|
||||
value="<?php esc_attr_e("Apply", 'duplicator-pro') ?>"
|
||||
onclick="DupliJs.Schedule.BulkAction()">
|
||||
<span class="separator"></span>
|
||||
<?php if (CapMng::can(CapMng::CAP_SETTINGS, false)) { ?>
|
||||
<a
|
||||
href="<?php echo esc_url($settingsScheudleUrl); ?>"
|
||||
class="button hollow secondary small dup-schedule-settings"
|
||||
title="<?php esc_attr_e("Settings", 'duplicator-pro') ?>">
|
||||
<i class="fas fa-sliders-h fa-fw"></i>
|
||||
</a>
|
||||
<?php } ?>
|
||||
<a
|
||||
href="<?php echo esc_url($templatesPageUrl); ?>"
|
||||
id="btn-logs-dialog"
|
||||
class="button hollow secondary small dup-schedule-templates"
|
||||
title="<?php esc_attr_e("Templates", 'duplicator-pro') ?>">
|
||||
<i class="far fa-clone"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<form
|
||||
id="dup-schedule-form"
|
||||
class="<?php echo ($blur ? 'dup-mock-blur' : ''); ?>"
|
||||
action="<?php echo esc_url(ControllersManager::getCurrentLink()); ?>"
|
||||
method="post">
|
||||
<input type="hidden" id="dup-schedule-form-action" name="action" value="" />
|
||||
<input type="hidden" id="dup-schedule-selected-schedule" name="schedule_id" value="-1" />
|
||||
|
||||
<!-- ====================
|
||||
LIST ALL SCHEDULES -->
|
||||
<table class="widefat storage-tbl dup-table-list valign-top schedule-tbl">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style='width:10px;'><input type="checkbox" id="dupli-chk-all" title="Select all Backups" onclick="DupliJs.Schedule.SetDeleteAll(this)"></th>
|
||||
<th style='width:275px;'><?php esc_html_e('Name', 'duplicator-pro'); ?></th>
|
||||
<th><?php esc_html_e('Storage', 'duplicator-pro'); ?></th>
|
||||
<th>
|
||||
<?php esc_html_e('Runs Next', 'duplicator-pro'); ?>
|
||||
<i
|
||||
class="fa-solid fa-circle-info"
|
||||
data-tooltip-title="<?php esc_attr_e('Runs Next Date/Time', 'duplicator-pro'); ?>"
|
||||
data-tooltip="<?php echo esc_attr($tooltopCreatedContent); ?>"></i>
|
||||
</th>
|
||||
<th>
|
||||
<?php esc_html_e('Last Ran', 'duplicator-pro'); ?>
|
||||
<i
|
||||
class="fa-solid fa-circle-info"
|
||||
data-tooltip-title="<?php esc_attr_e('Last Ran Date/Time', 'duplicator-pro'); ?>"
|
||||
data-tooltip="<?php echo esc_attr($tooltopCreatedContent); ?>"></i>
|
||||
</th>
|
||||
<th><?php esc_html_e('Active', 'duplicator-pro'); ?></th>
|
||||
<th class="dup-col-recovery"><?php esc_html_e('Recovery', 'duplicator-pro'); ?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<?php if ($schedule_count <= 0) : ?>
|
||||
<tr>
|
||||
<td colspan="7" class="dup-schedules-no-schedule">
|
||||
<div class="margin-top-1 margin-bottom-1">
|
||||
<h3 class="margin-bottom-0">
|
||||
<b><i class="far fa-clock fa-sm"></i> <?php esc_html_e('No Schedules Found', 'duplicator-pro') ?></b>
|
||||
</h3>
|
||||
<a href="<?php echo esc_url($scheduleEditBaseURL); ?>">
|
||||
[<?php esc_html_e('Add New Schedule', 'duplicator-pro') ?>]
|
||||
</a>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php
|
||||
$i = 0;
|
||||
foreach ($schedules as $schedule) :
|
||||
$i++;
|
||||
$icon_display = (($schedule->getId() == $active_schedule_id) ? 'inline' : 'none');
|
||||
?>
|
||||
<tr class="schedule-row <?php echo ($i % 2) ? 'alternate' : ''; ?>">
|
||||
<td>
|
||||
<input name="selected_id[]" type="checkbox" value="<?php echo (int) $schedule->getId() ?>" class="item-chk" />
|
||||
</td>
|
||||
<td>
|
||||
<i
|
||||
id="<?php echo "icon-{" . (int) $schedule->getId() . "}-status"; ?>"
|
||||
class="fas fa-cog fa-spin schedule-status-icon"
|
||||
style="display:<?php echo esc_attr($icon_display); ?>; margin-right:4px;"
|
||||
data-tooltip="<?php esc_attr_e('This scheduled backup is currently in progress', 'duplicator-pro'); ?>">
|
||||
</i>
|
||||
<a
|
||||
id="<?php echo "text-{" . (int) $schedule->getId() . "}"; ?>"
|
||||
href="javascript:void(0);"
|
||||
onclick="DupliJs.Schedule.Edit('<?php echo (int) $schedule->getId() ?>');"
|
||||
class="name">
|
||||
<?php echo esc_html($schedule->name); ?>
|
||||
</a>
|
||||
<div class="sub-menu">
|
||||
<span class="link-style dup-schedule-quick-view" onclick="DupliJs.Schedule.QuickView('<?php echo (int) $schedule->getId() ?>');">
|
||||
<?php esc_html_e('Quick View', 'duplicator-pro'); ?>
|
||||
</span> |
|
||||
<span class="link-style dup-schedule-edit" onclick="DupliJs.Schedule.Edit('<?php echo (int) $schedule->getId() ?>');">
|
||||
<?php esc_html_e('Edit', 'duplicator-pro'); ?>
|
||||
</span> |
|
||||
<span class="link-style dup-schedule-copy" onclick="DupliJs.Schedule.Copy('<?php echo (int) $schedule->getId(); ?>');">
|
||||
<?php esc_html_e('Copy', 'duplicator-pro'); ?>
|
||||
</span> |
|
||||
<span class="link-style dup-schedule-delete" onclick="DupliJs.Schedule.Delete('<?php echo (int) $schedule->getId(); ?>');">
|
||||
<?php esc_html_e('Delete', 'duplicator-pro'); ?>
|
||||
</span>
|
||||
<?php if (CapMng::can(CapMng::CAP_CREATE, false)) : ?>
|
||||
| <span class="link-style dup-schedule-run-now" onclick="DupliJs.Schedule.RunNow('<?php echo (int) $schedule->getId(); ?>');">
|
||||
<?php esc_html_e('Run Now', 'duplicator-pro'); ?>
|
||||
</span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<?php
|
||||
if (count($schedule->storage_ids) > 0 && strlen(implode('', $schedule->storage_ids)) != 0) {
|
||||
foreach ($schedule->storage_ids as $storage_id) {
|
||||
if (($storage = AbstractStorageEntity::getById($storage_id)) === false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check storage validity
|
||||
$isValid = $storage->isValid();
|
||||
$isSupported = $storage::isSupported();
|
||||
|
||||
if (!$isSupported) {
|
||||
echo '<span style="opacity: 0.5;" data-tooltip="' . esc_attr($storage::getNotSupportedNotice()) . '">';
|
||||
echo esc_html($storage->getName());
|
||||
echo '</span><br/>';
|
||||
} elseif (!$isValid) {
|
||||
$tooltipMsg = __('This storage has invalid configuration and cannot be used.', 'duplicator-pro');
|
||||
|
||||
echo '<span style="opacity: 0.5;" data-tooltip="' . esc_attr($tooltipMsg) . '">';
|
||||
echo esc_html($storage->getName());
|
||||
echo '</span><br/>';
|
||||
} else {
|
||||
// Valid storage - display normally
|
||||
echo esc_html($storage->getName()) . '<br/>';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$txt_DeleteStorage = __('No Storage', 'duplicator-pro');
|
||||
echo "<a href='javascript:void(0)' onclick='DupliJs.Schedule.showDeleteStorageMessage()'>"
|
||||
. "<i class='fa fa-info-circle fa-fw fa-sm'></i>"
|
||||
. "<u>" . esc_html($txt_DeleteStorage) . "</u></a>";
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
<td>
|
||||
<?php echo esc_html($schedule->getNextRunTimeString()); ?>
|
||||
</td>
|
||||
<td id="schedule-<?php echo (int) $schedule->getId() ?>-last-ran-string">
|
||||
<?php echo esc_html($schedule->getLastRanString()); ?>
|
||||
</td>
|
||||
<td>
|
||||
<b>
|
||||
<?php if ($schedule->isActive()) { ?>
|
||||
<span class="green"><?php esc_html_e('Yes', 'duplicator-pro'); ?></span>
|
||||
<?php } else { ?>
|
||||
<span class="maroon"><?php esc_html_e('No', 'duplicator-pro'); ?></span>
|
||||
<?php } ?>
|
||||
</b>
|
||||
</td>
|
||||
<td class="dup-col-recovery">
|
||||
<?php $schedule->recoveableHtmlInfo(true); ?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id='detail-<?php echo (int) $schedule->getId() ?>' class='<?php echo ($i % 2) ? 'alternate' : ''; ?> schedule-detail'>
|
||||
<td colspan="7">
|
||||
<?php
|
||||
$template = TemplateEntity::getById($schedule->template_id);
|
||||
?>
|
||||
<ul class="no-bullet">
|
||||
<li>
|
||||
<b><?php esc_html_e('Backup Template:', 'duplicator-pro'); ?></b>
|
||||
<?php echo esc_html($template->name); ?>
|
||||
</li>
|
||||
<li>
|
||||
<b><?php esc_html_e('Summary:', 'duplicator-pro'); ?></b>
|
||||
<?php echo sprintf(esc_html__('Runs %1$s', 'duplicator-pro'), esc_html($schedule->getRepeatText())); ?>
|
||||
</li>
|
||||
<li>
|
||||
<b><?php esc_html_e('Last Ran:', 'duplicator-pro') ?></b>
|
||||
<?php echo esc_html($schedule->getLastRanString()); ?>
|
||||
</li>
|
||||
<li>
|
||||
<b><?php esc_html_e('Times Run:', 'duplicator-pro') ?></b>
|
||||
<?php echo (int) $schedule->times_run; ?>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<th colspan="7" style="text-align:right; white-space: nowrap; font-size:12px">
|
||||
<?php
|
||||
printf(
|
||||
esc_html_x(
|
||||
'Total: %1$s | Active: %2$s | Time: %3$s',
|
||||
'%1$s represents total schedules, %2$s represents active schedules, %3$s represents current time',
|
||||
'duplicator-pro'
|
||||
),
|
||||
(int) $schedule_count,
|
||||
(int) $active_count,
|
||||
'<span id="dupli-clock-container"></span>'
|
||||
);
|
||||
?>
|
||||
</th>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</form>
|
||||
<?php
|
||||
$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();
|
||||
|
||||
$alert2 = new UiDialog();
|
||||
$alert2->title = __('Selection Required', 'duplicator-pro');
|
||||
$alert2->wrapperClassButtons = 'dupli-dlg-noschedule-sel-bulk-action-btns';
|
||||
$alert2->message = __('Please select at least one schedule to perform the action on!', 'duplicator-pro');
|
||||
$alert2->initAlert();
|
||||
|
||||
$alert3 = new UiDialog();
|
||||
$alert3->title = __('No Storage', 'duplicator-pro');
|
||||
$alert3->message = __('All storage types associated with this schedule have been deleted. ', 'duplicator-pro');
|
||||
$alert3->message .= __('To enable this schedule please assign a valid storage type.', 'duplicator-pro');
|
||||
$alert3->message .= '<br/><br/>';
|
||||
$alert3->initAlert();
|
||||
|
||||
$confirm1 = new UiDialog();
|
||||
$confirm1->title = __('Delete Schedule?', 'duplicator-pro');
|
||||
$confirm1->wrapperClassButtons = 'dupli-dlg-delete-schedules-btns';
|
||||
$confirm1->message = __('Are you sure you want to delete the selected schedule(s)?', 'duplicator-pro');
|
||||
$confirm1->message .= '<br/>';
|
||||
$confirm1->message .= '<small><i>' . __('Note: This action removes all schedules.', 'duplicator-pro') . '</i></small>';
|
||||
$confirm1->progressText = __('Removing Schedules, Please Wait...', 'duplicator-pro');
|
||||
$confirm1->jsCallback = 'DupliJs.Schedule.BulkDelete()';
|
||||
$confirm1->initConfirm();
|
||||
|
||||
$confirm4 = new UiDialog();
|
||||
$confirm4->title = __('Activate Schedule?', 'duplicator-pro');
|
||||
$confirm4->wrapperClassButtons = 'dupli-dlg-activate-schedules-btns';
|
||||
$confirm4->message = __('Are you sure you want to activate the selected schedule(s)?', 'duplicator-pro');
|
||||
$confirm4->message .= '<br/>';
|
||||
$confirm4->message .= '<small><i>' . __('Note: This action activates all schedules.', 'duplicator-pro') . '</i></small>';
|
||||
$confirm4->progressText = __('Activating Schedules, Please Wait...', 'duplicator-pro');
|
||||
$confirm4->jsCallback = 'DupliJs.Schedule.BulkActivate()';
|
||||
$confirm4->initConfirm();
|
||||
|
||||
$confirm5 = new UiDialog();
|
||||
$confirm5->title = __('Deactivate Schedule?', 'duplicator-pro');
|
||||
$confirm5->wrapperClassButtons = 'dupli-dlg-deactivate-schedules-btns';
|
||||
$confirm5->message = __('Are you sure you want to deactivate the selected schedule(s)?', 'duplicator-pro');
|
||||
$confirm5->message .= '<br/>';
|
||||
$confirm5->message .= '<small><i>' . __('Note: This action deactivates all schedules.', 'duplicator-pro') . '</i></small>';
|
||||
$confirm5->progressText = __('Deactivating Schedules, Please Wait...', 'duplicator-pro');
|
||||
$confirm5->jsCallback = 'DupliJs.Schedule.BulkDeactivate()';
|
||||
$confirm5->initConfirm();
|
||||
|
||||
$confirm2 = new UiDialog();
|
||||
$confirm2->title = __('RUN SCHEDULE?', 'duplicator-pro');
|
||||
$confirm2->message = __('Are you sure you want to run schedule now?', 'duplicator-pro');
|
||||
$confirm2->progressText = __('Running Schedule, Please Wait...', 'duplicator-pro');
|
||||
$confirm2->jsCallback = 'DupliJs.Schedule.Run(this)';
|
||||
$confirm2->initConfirm();
|
||||
|
||||
$confirm3 = new UiDialog();
|
||||
$confirm3->title = $confirm1->title;
|
||||
$confirm3->message = __('Are you sure you want to delete this schedule?', 'duplicator-pro');
|
||||
$confirm3->progressText = $confirm1->progressText;
|
||||
$confirm3->jsCallback = 'DupliJs.Schedule.DeleteThis(this)';
|
||||
$confirm3->initConfirm();
|
||||
|
||||
$schedule_bulk_action_nonce = wp_create_nonce('duplicator_schedule_bulk_action');
|
||||
?>
|
||||
<script>
|
||||
jQuery(document).ready(function($) {
|
||||
|
||||
/*METHOD: Shows quick view summary */
|
||||
DupliJs.Schedule.QuickView = function(id) {
|
||||
$('#detail-' + id).toggle();
|
||||
};
|
||||
|
||||
/*METHOD: Run the schedule now and redirect to backups page */
|
||||
DupliJs.Schedule.RunNow = function(schedule_id) {
|
||||
<?php $confirm2->showConfirm(); ?>
|
||||
$("#<?php echo esc_js($confirm2->getID()); ?>-confirm").attr('data-id', schedule_id);
|
||||
};
|
||||
|
||||
DupliJs.Schedule.Run = function(e) {
|
||||
var schedule_id = $(e).attr('data-id');
|
||||
|
||||
$('#icon-' + schedule_id + '-status').show();
|
||||
$('#text-' + schedule_id).html("<?php esc_html_e('Queueing Now - Please Wait...', 'duplicator-pro') ?>");
|
||||
var data = {
|
||||
action: 'duplicator_run_schedule_now',
|
||||
schedule_id: schedule_id,
|
||||
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_run_schedule_now')); ?>'
|
||||
}
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: ajaxurl,
|
||||
timeout: 10000000,
|
||||
data: data
|
||||
}).done(function(respData) {
|
||||
try {
|
||||
var data = DupliJs.parseJSON(respData);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
console.error('JSON parse failed for response data: ' + respData);
|
||||
return false;
|
||||
}
|
||||
|
||||
window.location.href = <?php echo wp_json_encode($packagesPageUrl) ?>;
|
||||
});
|
||||
};
|
||||
|
||||
/*METHOD: Deletes a single schedule */
|
||||
DupliJs.Schedule.Delete = function(id) {
|
||||
<?php $confirm3->showConfirm(); ?>
|
||||
$("#<?php echo esc_js($confirm3->getID()); ?>-confirm").attr('data-id', id);
|
||||
};
|
||||
|
||||
DupliJs.Schedule.DeleteThis = function(e) {
|
||||
var id = $(e).attr('data-id');
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: ajaxurl,
|
||||
dataType: "json",
|
||||
data: {
|
||||
action: 'duplicator_schedule_bulk_action',
|
||||
perform: <?php echo (int) ServicesSchedule::SCHEDULE_BULK_DELETE; ?>,
|
||||
schedule_ids: [id],
|
||||
nonce: '<?php echo esc_js($schedule_bulk_action_nonce); ?>'
|
||||
},
|
||||
}).done(function(data) {
|
||||
$('#dup-schedule-form').submit();
|
||||
});
|
||||
};
|
||||
|
||||
// Creats a comma seperate list of all selected Backup ids
|
||||
DupliJs.Schedule.SelectedList = function() {
|
||||
var arr = [];
|
||||
|
||||
$("input[name^='selected_id[]']").each(function() {
|
||||
if ($(this).is(':checked')) {
|
||||
arr.push($(this).val());
|
||||
}
|
||||
});
|
||||
|
||||
return arr;
|
||||
};
|
||||
|
||||
// Bulk delete
|
||||
DupliJs.Schedule.BulkDelete = function() {
|
||||
var list = DupliJs.Schedule.SelectedList();
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: ajaxurl,
|
||||
dataType: "json",
|
||||
data: {
|
||||
action: 'duplicator_schedule_bulk_action',
|
||||
perform: <?php echo (int) ServicesSchedule::SCHEDULE_BULK_DELETE; ?>,
|
||||
schedule_ids: list,
|
||||
nonce: '<?php echo esc_js($schedule_bulk_action_nonce); ?>'
|
||||
},
|
||||
}).done(function(data) {
|
||||
$('#dup-schedule-form').submit();
|
||||
});
|
||||
};
|
||||
|
||||
// Bulk activate
|
||||
DupliJs.Schedule.BulkActivate = function() {
|
||||
var list = DupliJs.Schedule.SelectedList();
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: ajaxurl,
|
||||
dataType: "json",
|
||||
data: {
|
||||
action: 'duplicator_schedule_bulk_action',
|
||||
perform: <?php echo (int) ServicesSchedule::SCHEDULE_BULK_ACTIVATE; ?>,
|
||||
schedule_ids: list,
|
||||
nonce: '<?php echo esc_js($schedule_bulk_action_nonce); ?>'
|
||||
},
|
||||
}).done(function(data) {
|
||||
if (data.success) {
|
||||
$('#dup-schedule-form').submit();
|
||||
} else {
|
||||
if (data.message.length > 0) {
|
||||
$('#<?php echo esc_js($confirm4->getID()); ?>-progress').hide();
|
||||
$('#<?php echo esc_js($confirm4->getMessageID()); ?>').html(data.message);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Bulk deactivate
|
||||
DupliJs.Schedule.BulkDeactivate = function() {
|
||||
var list = DupliJs.Schedule.SelectedList();
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: ajaxurl,
|
||||
dataType: "json",
|
||||
data: {
|
||||
action: 'duplicator_schedule_bulk_action',
|
||||
perform: <?php echo (int) ServicesSchedule::SCHEDULE_BULK_DEACTIVATE; ?>,
|
||||
schedule_ids: list,
|
||||
nonce: '<?php echo esc_js($schedule_bulk_action_nonce); ?>'
|
||||
},
|
||||
}).done(function(data) {
|
||||
$('#dup-schedule-form').submit();
|
||||
});
|
||||
};
|
||||
|
||||
/*METHOD: Bulk action response */
|
||||
DupliJs.Schedule.BulkAction = function() {
|
||||
var list = DupliJs.Schedule.SelectedList();
|
||||
|
||||
if (list.length == 0) {
|
||||
<?php $alert2->showAlert(); ?>
|
||||
return;
|
||||
}
|
||||
|
||||
var action = $('#bulk_action').val(),
|
||||
checked = ($('.item-chk:checked').length > 0);
|
||||
|
||||
if (action == -1) {
|
||||
<?php $alert1->showAlert(); ?>
|
||||
return;
|
||||
}
|
||||
|
||||
if (checked) {
|
||||
switch (action) {
|
||||
case '<?php echo (int) ServicesSchedule::SCHEDULE_BULK_DELETE; ?>':
|
||||
<?php $confirm1->showConfirm(); ?>
|
||||
break;
|
||||
case '<?php echo (int) ServicesSchedule::SCHEDULE_BULK_ACTIVATE; ?>':
|
||||
<?php $confirm4->showConfirm(); ?>
|
||||
break;
|
||||
case '<?php echo (int) ServicesSchedule::SCHEDULE_BULK_DEACTIVATE; ?>':
|
||||
<?php $confirm5->showConfirm(); ?>
|
||||
break;
|
||||
default:
|
||||
<?php $alert2->showAlert(); ?>
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/*METHOD: Edit a single schedule */
|
||||
DupliJs.Schedule.Edit = function(id) {
|
||||
document.location.href = <?php echo json_encode($scheduleEditBaseURL); ?> + '&schedule_id=' + id;
|
||||
};
|
||||
|
||||
/*METHOD: Copy a schedule */
|
||||
DupliJs.Schedule.Copy = function(id) {
|
||||
document.location.href = <?php echo json_encode($scheduleCopyBaseURL); ?> + '&dupli-source-schedule-id=' + id;
|
||||
};
|
||||
|
||||
/*METHOD: Set delete all */
|
||||
DupliJs.Schedule.SetDeleteAll = function(chkbox) {
|
||||
$('.item-chk').each(function() {
|
||||
this.checked = chkbox.checked;
|
||||
});
|
||||
};
|
||||
|
||||
/*METHOD: Shows the delete storage message*/
|
||||
DupliJs.Schedule.showDeleteStorageMessage = function() {
|
||||
<?php $alert3->showAlert(); ?>
|
||||
};
|
||||
|
||||
/*METHOD: Enableds the update flag to track proccessing */
|
||||
DupliJs.Schedule.SetUpdateInterval = function(period) {
|
||||
console.log('setting interval to ' + period);
|
||||
if (DupliJs.Schedule.setIntervalID != -1) {
|
||||
clearInterval(DupliJs.Schedule.setIntervalID);
|
||||
DupliJs.Schedule.setIntervalID = -1
|
||||
}
|
||||
DupliJs.Schedule.setIntervalID = setInterval(DupliJs.Schedule.UpdateSchedules, period * 1000);
|
||||
};
|
||||
|
||||
/*METHOD: Checks the schedule status */
|
||||
DupliJs.Schedule.UpdateSchedules = function() {
|
||||
|
||||
var data = {
|
||||
action: 'duplicator_get_schedule_infos',
|
||||
nonce: '<?php echo esc_js(wp_create_nonce('duplicator_get_schedule_infos')); ?>'
|
||||
};
|
||||
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: ajaxurl,
|
||||
data: data,
|
||||
success: function(schedule_infos) {
|
||||
activeSchedulePresent = false;
|
||||
for (schedule_info_key in schedule_infos) {
|
||||
var schedule_info = schedule_infos[schedule_info_key];
|
||||
var is_running_selector = "#icon-" + schedule_info.schedule_id + "-status";
|
||||
var last_ran_selector = "#schedule-" + schedule_info.schedule_id + "-last-ran-string";
|
||||
if (schedule_info.is_running) {
|
||||
$(is_running_selector).show();
|
||||
activeSchedulePresent = true;
|
||||
} else {
|
||||
$(is_running_selector).hide();
|
||||
}
|
||||
$(last_ran_selector).text(schedule_info.last_ran_string);
|
||||
}
|
||||
|
||||
if (activeSchedulePresent) {
|
||||
DupliJs.Schedule.SetUpdateInterval(10);
|
||||
} else {
|
||||
|
||||
DupliJs.Schedule.SetUpdateInterval(60);
|
||||
}
|
||||
},
|
||||
error: function(data) {
|
||||
console.log("error");
|
||||
console.log(data);
|
||||
$(".schedule-status-icon").css('display', 'none');
|
||||
DupliJs.Schedule.SetUpdateInterval(60);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
DupliJs.UI.Clock(DupliJs._WordPressInitTime);
|
||||
DupliJs.Schedule.setIntervalID = -1;
|
||||
DupliJs.Schedule.UpdateSchedules();
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,413 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
use Duplicator\Models\GlobalEntity;
|
||||
use Duplicator\Libs\Snap\SnapIO;
|
||||
use Duplicator\Libs\Snap\SnapUtil;
|
||||
use Duplicator\Models\DynamicGlobalEntity;
|
||||
use Duplicator\Utils\LockUtil;
|
||||
use Duplicator\Libs\WpUtils\WpArchiveUtils;
|
||||
|
||||
$global = GlobalEntity::getInstance();
|
||||
$dGlobal = DynamicGlobalEntity::getInstance();
|
||||
|
||||
$max_execution_time = (int) SnapUtil::phpIniGet("max_execution_time", 0);
|
||||
$max_execution_time = $max_execution_time < 0 ? PHP_INT_MAX : $max_execution_time;
|
||||
$max_execution_time = empty($max_execution_time) ? 30 : $max_execution_time;
|
||||
$workerTimeCapRange = [
|
||||
10,
|
||||
min(180, max(30, (int) (0.7 * (float) $max_execution_time))),
|
||||
];
|
||||
$workerTimeValue = (int) max($workerTimeCapRange[0], min((int) $global->php_max_worker_time_in_sec, $workerTimeCapRange[1]));
|
||||
?>
|
||||
<div class="dup-accordion-wrapper display-separators close">
|
||||
<div class="accordion-header">
|
||||
<h3 class="title">
|
||||
<?php esc_html_e("Advanced", 'duplicator-pro'); ?>
|
||||
</h3>
|
||||
</div>
|
||||
<div class="accordion-content">
|
||||
<label class="lbl-larger">
|
||||
<?php esc_html_e("Thread Lock", 'duplicator-pro'); ?>
|
||||
</label>
|
||||
<div class="margin-bottom-1">
|
||||
<input
|
||||
type="radio"
|
||||
name="lock_mode"
|
||||
id="lock_mode_flock"
|
||||
class="margin-0"
|
||||
value="<?php echo (int) LockUtil::LOCK_MODE_FILE; ?>"
|
||||
<?php checked($global->lock_mode, LockUtil::LOCK_MODE_FILE); ?>>
|
||||
<label for="lock_mode_flock">
|
||||
<?php esc_html_e("File", 'duplicator-pro'); ?>
|
||||
</label>
|
||||
<input
|
||||
type="radio"
|
||||
name="lock_mode"
|
||||
id="lock_mode_sql"
|
||||
class="margin-0"
|
||||
value="<?php echo (int) LockUtil::LOCK_MODE_SQL; ?>"
|
||||
<?php checked($global->lock_mode, LockUtil::LOCK_MODE_SQL); ?>>
|
||||
<label for="lock_mode_sql">
|
||||
<?php esc_html_e("SQL", 'duplicator-pro'); ?>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<label class="lbl-larger">
|
||||
<?php esc_html_e("Max Worker Time", 'duplicator-pro'); ?>
|
||||
</label>
|
||||
<div class="margin-bottom-1">
|
||||
<input
|
||||
data-parsley-required
|
||||
data-parsley-errors-container="#php_max_worker_time_in_sec_error_container"
|
||||
data-parsley-range="<?php echo esc_attr(wp_json_encode($workerTimeCapRange)); ?>"
|
||||
data-parsley-type="number"
|
||||
class="width-small inline-display margin-0"
|
||||
type="text"
|
||||
name="php_max_worker_time_in_sec"
|
||||
id="php_max_worker_time_in_sec"
|
||||
value="<?php echo (int) $workerTimeValue; ?>">
|
||||
<span>
|
||||
<?php esc_html_e('Seconds', 'duplicator-pro'); ?>
|
||||
</span>
|
||||
<div id="php_max_worker_time_in_sec_error_container" class="duplicator-error-container"></div>
|
||||
<p class="description">
|
||||
<?php
|
||||
esc_html_e(
|
||||
'This setting controls how long each processing chunk can run. A lower value makes the process more reliable but slower.',
|
||||
'duplicator-pro'
|
||||
);
|
||||
?><br />
|
||||
<?php
|
||||
esc_html_e(
|
||||
"Try a low value (30 seconds or lower) if the build fails with the recommended setting.",
|
||||
'duplicator-pro'
|
||||
); ?>
|
||||
</p>
|
||||
</div>
|
||||
<label class="lbl-larger">
|
||||
<?php esc_html_e("Ajax", 'duplicator-pro'); ?>
|
||||
</label>
|
||||
<div class="margin-bottom-1">
|
||||
<input
|
||||
type="radio"
|
||||
id="ajax_protocol_1"
|
||||
name="ajax_protocol"
|
||||
class="ajax_protocol margin-0"
|
||||
value="admin"
|
||||
<?php checked($global->ajax_protocol, 'admin'); ?>>
|
||||
<label for="ajax_protocol_1">
|
||||
<?php esc_html_e("Auto", 'duplicator-pro'); ?>
|
||||
</label>
|
||||
<input
|
||||
type="radio"
|
||||
id="ajax_protocol_2"
|
||||
name="ajax_protocol"
|
||||
class="ajax_protocol margin-0"
|
||||
value="http"
|
||||
<?php checked($global->ajax_protocol == 'http'); ?>>
|
||||
<label for="ajax_protocol_2">
|
||||
<?php esc_html_e("HTTP", 'duplicator-pro'); ?>
|
||||
</label>
|
||||
<input
|
||||
type="radio"
|
||||
id="ajax_protocol_3"
|
||||
name="ajax_protocol"
|
||||
class="ajax_protocol margin-0"
|
||||
value="https"
|
||||
<?php checked($global->ajax_protocol == 'https'); ?>>
|
||||
<label for="ajax_protocol_3">
|
||||
<?php esc_html_e("HTTPS", 'duplicator-pro'); ?>
|
||||
</label>
|
||||
<input
|
||||
type="radio"
|
||||
id="ajax_protocol_4"
|
||||
name="ajax_protocol"
|
||||
class="ajax_protocol margin-0"
|
||||
value="custom"
|
||||
<?php checked($global->ajax_protocol, 'custom'); ?>>
|
||||
<label for="ajax_protocol_4">
|
||||
<?php esc_html_e("Custom URL", 'duplicator-pro'); ?>
|
||||
</label> <br />
|
||||
<input
|
||||
type="<?php echo ($global->ajax_protocol == 'custom' ? 'text' : 'hidden'); ?>"
|
||||
id="custom_ajax_url"
|
||||
name="custom_ajax_url"
|
||||
class="width-xlarge"
|
||||
placeholder="<?php esc_attr_e('Consult support before changing.', 'duplicator-pro'); ?>"
|
||||
value="<?php echo esc_url($global->custom_ajax_url); ?>">
|
||||
<span id="custom_ajax_url_error" class="alert-color">
|
||||
<?php esc_html_e("Bad URL!", 'duplicator-pro'); ?>
|
||||
</span>
|
||||
<p class="description">
|
||||
<?php esc_html_e("Used to kick off build worker. Only change if Backups get stuck at the start of a build.", 'duplicator-pro'); ?>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<label class="lbl-larger">
|
||||
<?php esc_html_e('Root path', 'duplicator-pro') ?>
|
||||
</label>
|
||||
<div class="margin-bottom-1">
|
||||
<input
|
||||
type="checkbox"
|
||||
name="homepath_as_abspath"
|
||||
id="homepath_as_abspath"
|
||||
class="margin-0"
|
||||
<?php disabled(WpArchiveUtils::isAbspathHomepathEquivalent()); ?>
|
||||
<?php checked($global->homepath_as_abspath); ?>
|
||||
value="1">
|
||||
<label for="homepath_as_abspath">
|
||||
<?php
|
||||
printf(
|
||||
esc_html_x(
|
||||
'Use ABSPATH %s as root path.',
|
||||
'%s represents the ABSPATH surrounded with bold (<b>) tags',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<b>' . esc_html(WpArchiveUtils::getArchiveListPaths('abs')) . '</b>'
|
||||
);
|
||||
?>
|
||||
<br>
|
||||
</label>
|
||||
<p class="description">
|
||||
<?php
|
||||
if (WpArchiveUtils::isAbspathHomepathEquivalent()) {
|
||||
esc_html_e('Abspath and home path are equivalent so this option is disabled', 'duplicator-pro');
|
||||
} else {
|
||||
?>
|
||||
<?php
|
||||
printf(
|
||||
esc_html_x(
|
||||
'In this installation the default root path is %s.',
|
||||
'%s represents the root path surrounded with bold (<b>) tags',
|
||||
'duplicator-pro'
|
||||
),
|
||||
'<b>' . esc_html(SnapIO::safePathUntrailingslashit(get_home_path(), true)) . '</b>'
|
||||
); ?><br>
|
||||
<?php
|
||||
esc_html_e(
|
||||
'The path of the WordPress core is different. Activate this option if you want to consider ABSPATH as root path.',
|
||||
'duplicator-pro'
|
||||
);
|
||||
}
|
||||
?>
|
||||
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<label class="lbl-larger">
|
||||
<?php esc_html_e('Scan File Checks', 'duplicator-pro'); ?>
|
||||
</label>
|
||||
<div class="margin-bottom-1">
|
||||
<input
|
||||
type="checkbox"
|
||||
name="_skip_archive_scan"
|
||||
id="_skip_archive_scan"
|
||||
class="margin-0"
|
||||
<?php checked($global->skip_archive_scan); ?>>
|
||||
<label for="_skip_archive_scan">
|
||||
<?php esc_html_e("Skip", 'duplicator-pro') ?>
|
||||
</label><br />
|
||||
<p class="description">
|
||||
<?php
|
||||
esc_html_e(
|
||||
'If enabled all files check on scan will be skipped before Backup creation.
|
||||
In some cases, this option can be beneficial if the scan process is having issues running or returning errors.',
|
||||
'duplicator-pro'
|
||||
);
|
||||
?>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<label class="lbl-larger">
|
||||
<?php esc_html_e('Client-side Kickoff', 'duplicator-pro'); ?>
|
||||
</label>
|
||||
<div class="margin-bottom-1">
|
||||
<input
|
||||
type="checkbox"
|
||||
name="_clientside_kickoff"
|
||||
id="_clientside_kickoff"
|
||||
class="margin-0"
|
||||
<?php checked($global->clientside_kickoff); ?> />
|
||||
<label for="_clientside_kickoff">
|
||||
<?php esc_html_e("Enabled", 'duplicator-pro') ?>
|
||||
</label><br />
|
||||
<p class="description">
|
||||
<?php esc_html_e('Initiate Backup build from client. Only check this if instructed to by Duplicator support.', 'duplicator-pro'); ?>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<label class="lbl-larger">
|
||||
<?php esc_html_e("Password-Protected Access", 'duplicator-pro'); ?>
|
||||
</label>
|
||||
<div class="margin-bottom-1">
|
||||
<input
|
||||
type="checkbox"
|
||||
name="_basic_auth_enabled"
|
||||
id="_basic_auth_enabled"
|
||||
value="1"
|
||||
class="margin-0"
|
||||
<?php checked($dGlobal->getValBool('basic_auth_enabled')); ?>>
|
||||
<label for="_basic_auth_enabled">
|
||||
<?php esc_html_e("Enabled", 'duplicator-pro') ?>
|
||||
</label>
|
||||
<i class="fa-solid fa-question-circle fa-sm dark-gray-color"
|
||||
data-tooltip-title="<?php esc_attr_e("HTTP Basic authentication", 'duplicator-pro'); ?>"
|
||||
data-tooltip="<?php esc_attr_e(
|
||||
"When HTTP Basic authentication is applied Duplicator needs to attach the login credentials to each request to the server.
|
||||
This is required for the build process to work properly. If you see a browser popup login window when accessing the admin area,
|
||||
then basic authentication should be enabled. If you are not sure, please consult your hosting provider.",
|
||||
'duplicator-pro'
|
||||
); ?>"></i>
|
||||
<div id="dup-basic-auth-login-wrapper">
|
||||
<input
|
||||
autocomplete="off"
|
||||
placeholder="<?php esc_attr_e('User', 'duplicator-pro'); ?>"
|
||||
type="text"
|
||||
name="basic_auth_user"
|
||||
id="basic_auth_user"
|
||||
class="margin-0"
|
||||
value="<?php echo esc_attr($dGlobal->getValString('basic_auth_user')); ?>"
|
||||
<?php disabled(!$dGlobal->getValBool('basic_auth_enabled')); ?>>
|
||||
<span class="dup-password-toggle">
|
||||
<input
|
||||
id="auth_password"
|
||||
autocomplete="off"
|
||||
placeholder="<?php esc_attr_e('Password', 'duplicator-pro'); ?>"
|
||||
type="password"
|
||||
name="basic_auth_password"
|
||||
id="basic_auth_password"
|
||||
class="margin-0"
|
||||
value="<?php echo esc_attr($dGlobal->getValString('basic_auth_password')); ?>"
|
||||
<?php disabled(!$dGlobal->getValBool('basic_auth_enabled')); ?>>
|
||||
<button type="button">
|
||||
<i class="fas fa-eye fa-sm"></i>
|
||||
</button>
|
||||
</span>
|
||||
</div>
|
||||
<p class="description">
|
||||
<?php esc_html_e(
|
||||
'Enable this function and provide username and password in case Backup creation error.
|
||||
Essential for making authorized HTTP requests in a server protected folder.',
|
||||
'duplicator-pro'
|
||||
); ?>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
(function($) {
|
||||
$('#_basic_auth_enabled').on('change', function() {
|
||||
if ($(this).is(':checked')) {
|
||||
$('#dup-basic-auth-login-wrapper input').prop('disabled', false);
|
||||
} else {
|
||||
$('#dup-basic-auth-login-wrapper input').prop('disabled', true);
|
||||
}
|
||||
});
|
||||
|
||||
var url_error = $('#custom_ajax_url_error');
|
||||
// Check URL is valid
|
||||
$.urlExists = function(url) {
|
||||
var http = new XMLHttpRequest();
|
||||
try {
|
||||
http.open('HEAD', url, false);
|
||||
http.send();
|
||||
} catch (err) {
|
||||
$('#custom_ajax_url_error').html(err.message);
|
||||
return false;
|
||||
}
|
||||
return http.status != 404;
|
||||
};
|
||||
var debounce;
|
||||
$('#custom_ajax_url').on('input keyup keydown change paste focus', function(e) {
|
||||
clearTimeout(debounce);
|
||||
var $this = $(this);
|
||||
debounce = setTimeout(function() {
|
||||
$this.css({
|
||||
'border': ''
|
||||
});
|
||||
url_error.hide();
|
||||
if (!$.urlExists($this.val())) {
|
||||
$this.css({
|
||||
'border': 'maroon 1px solid'
|
||||
});
|
||||
url_error.show();
|
||||
}
|
||||
}, 500);
|
||||
});
|
||||
|
||||
(function($this) {
|
||||
$this.css({
|
||||
'border': ''
|
||||
});
|
||||
url_error.hide();
|
||||
setTimeout(function() {
|
||||
var isCustomAjaxUrl = $('#ajax_protocol_4').is(':checked');
|
||||
if (isCustomAjaxUrl && !$.urlExists($this.val())) {
|
||||
$this.css({
|
||||
'border': 'maroon 1px solid'
|
||||
});
|
||||
url_error.show();
|
||||
}
|
||||
if (isCustomAjaxUrl) {
|
||||
$('#custom_ajax_url').attr('data-parsley-required', 'true');
|
||||
} else {
|
||||
$('#custom_ajax_url').removeAttr('data-parsley-required');
|
||||
}
|
||||
}, 0);
|
||||
}($('#custom_ajax_url')))
|
||||
|
||||
/*
|
||||
* DISPLAY OR HIDE CUSTOM_AJAX_URL
|
||||
*/
|
||||
$('.ajax_protocol').on('input click change select touchstart', function(e) {
|
||||
// Setup and collect value
|
||||
var $this = $(this),
|
||||
value = $this.val(),
|
||||
hideField = $('#custom_ajax_url'),
|
||||
hideFieldState = hideField.attr('type'),
|
||||
offset = 200;
|
||||
url_error.hide();
|
||||
if (value == 'custom') {
|
||||
// Display hidden field
|
||||
if (hideFieldState == 'hidden') {
|
||||
hideField.hide().attr('type', 'text').fadeIn(offset).attr('data-parsley-required', 'true');
|
||||
hideField.css({
|
||||
'border': ''
|
||||
});
|
||||
url_error.hide();
|
||||
if (!$.urlExists(hideField.val())) {
|
||||
hideField.css({
|
||||
'border': 'maroon 1px solid'
|
||||
});
|
||||
url_error.show();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Hide field but keep it active for POST reading
|
||||
if (hideFieldState == 'text') {
|
||||
var parsleyId = $('#custom_ajax_url').data('parsley-id');
|
||||
var errorUlId = '#parsley-id-' + parsleyId;
|
||||
if ($(errorUlId).length)
|
||||
$(errorUlId).remove();
|
||||
hideField.fadeOut(Math.round(offset / 2), function() {
|
||||
$(this).attr('type', 'hidden').show();
|
||||
}).removeAttr('data-parsley-required');;
|
||||
}
|
||||
}
|
||||
});
|
||||
}(window.jQuery || jQuery))
|
||||
</script>
|
||||
@@ -0,0 +1,191 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
use Duplicator\Libs\Shell\ShellZipUtils;
|
||||
use Duplicator\Models\GlobalEntity;
|
||||
use Duplicator\Package\Archive\PackageArchive;
|
||||
use Duplicator\Utils\ZipArchiveExtended;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
$global = GlobalEntity::getInstance();
|
||||
$isZipArchiveAvailable = ZipArchiveExtended::isPhpZipAvailable();
|
||||
$isShellZipAvailable = (ShellZipUtils::getShellExecZipPath() != null);
|
||||
?>
|
||||
|
||||
<h3 class="title">
|
||||
<?php esc_html_e("Archive", 'duplicator-pro') ?>
|
||||
</h3>
|
||||
<hr size="1" />
|
||||
|
||||
<label class="lbl-larger">
|
||||
<?php esc_html_e("Compression", 'duplicator-pro'); ?>
|
||||
</label>
|
||||
<div class="margin-bottom-1">
|
||||
<input
|
||||
type="radio"
|
||||
name="archive_compression"
|
||||
id="archive_compression_off"
|
||||
value="0"
|
||||
class="margin-0"
|
||||
<?php checked($global->archive_compression, false); ?>>
|
||||
<label for="archive_compression_off">
|
||||
<?php esc_html_e("Off", 'duplicator-pro'); ?>
|
||||
</label>
|
||||
<input
|
||||
type="radio"
|
||||
name="archive_compression"
|
||||
id="archive_compression_on"
|
||||
value="1"
|
||||
class="margin-0"
|
||||
<?php checked($global->archive_compression); ?>>
|
||||
<label for="archive_compression_on">
|
||||
<?php esc_html_e("On", 'duplicator-pro'); ?>
|
||||
</label>
|
||||
<?php $tipContent = __(
|
||||
'This setting controls archive compression. The setting apply to all Archive Engine formats.
|
||||
For ZipArchive this setting only works on PHP 7.0 or higher.',
|
||||
'duplicator-pro'
|
||||
); ?>
|
||||
<i style="margin-right:7px;" class="fa-solid fa-question-circle fa-sm dark-gray-color"
|
||||
data-tooltip-title="<?php esc_attr_e("Archive Compression", 'duplicator-pro'); ?>"
|
||||
data-tooltip="<?php echo esc_attr($tipContent); ?>">
|
||||
</i>
|
||||
</div>
|
||||
|
||||
<label class="lbl-larger">
|
||||
<?php esc_html_e("Archive Engine", 'duplicator-pro'); ?>
|
||||
</label>
|
||||
<div class="margin-bottom-1">
|
||||
<div class="engine-radio">
|
||||
<input
|
||||
onclick="DupliJs.UI.SetArchiveOptionStates();"
|
||||
type="radio"
|
||||
name="archive_build_mode" id="archive_build_mode3"
|
||||
class="margin-0"
|
||||
value="<?php echo (int) PackageArchive::BUILD_MODE_DUP_ARCHIVE; ?>"
|
||||
<?php checked($global->getBuildMode() == PackageArchive::BUILD_MODE_DUP_ARCHIVE); ?>
|
||||
<?php disabled(!$global->isBuildModeAvailable(PackageArchive::BUILD_MODE_DUP_ARCHIVE)) ?>>
|
||||
<label for="archive_build_mode3"><?php esc_html_e("DupArchive", 'duplicator-pro'); ?></label>
|
||||
</div>
|
||||
<div class="engine-radio <?php echo ($isShellZipAvailable) ? '' : 'engine-radio-disabled'; ?>">
|
||||
<input
|
||||
onclick="DupliJs.UI.SetArchiveOptionStates();"
|
||||
type="radio"
|
||||
name="archive_build_mode"
|
||||
id="archive_build_mode1"
|
||||
class="margin-0"
|
||||
value="<?php echo (int) PackageArchive::BUILD_MODE_SHELL_EXEC; ?>"
|
||||
<?php checked($global->getBuildMode() == PackageArchive::BUILD_MODE_SHELL_EXEC); ?>
|
||||
<?php disabled(!$global->isBuildModeAvailable(PackageArchive::BUILD_MODE_SHELL_EXEC)) ?>>
|
||||
<label for="archive_build_mode1"><?php esc_html_e("Shell Zip", 'duplicator-pro'); ?></label>
|
||||
</div>
|
||||
<div class="engine-radio">
|
||||
<input
|
||||
onclick="DupliJs.UI.SetArchiveOptionStates();"
|
||||
type="radio"
|
||||
name="archive_build_mode"
|
||||
id="archive_build_mode2"
|
||||
class="margin-0"
|
||||
value="<?php echo (int) PackageArchive::BUILD_MODE_ZIP_ARCHIVE; ?>"
|
||||
<?php checked($global->getBuildMode() == PackageArchive::BUILD_MODE_ZIP_ARCHIVE); ?>
|
||||
<?php disabled(!$global->isBuildModeAvailable(PackageArchive::BUILD_MODE_ZIP_ARCHIVE)) ?>>
|
||||
<label for="archive_build_mode2"><?php esc_html_e("ZipArchive", 'duplicator-pro'); ?></label>
|
||||
</div>
|
||||
|
||||
<br style="clear:both" />
|
||||
|
||||
<!-- DUPARCHIVE -->
|
||||
<div class="engine-sub-opts" id="engine-details-3" style="display:none">
|
||||
<?php
|
||||
esc_html_e('This option creates a custom Duplicator Archive Format (.daf) archive file.', 'duplicator-pro');
|
||||
echo '<br/> ';
|
||||
esc_html_e('This option is fully multi-threaded and recommended for large sites or throttled servers.', 'duplicator-pro');
|
||||
echo '<br/> ';
|
||||
printf(
|
||||
'%s <a href="' . esc_url(DUPLICATOR_DUPLICATOR_DOCS_URL . 'how-to-work-with-daf-files-and-the-duparchive-extraction-tool')
|
||||
. '" target="_blank">%s</a> ',
|
||||
esc_html__('For details on how to use and manually extract the DAF format please see the ', 'duplicator-pro'),
|
||||
esc_html__('online documentation.', 'duplicator-pro')
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<!-- SHELL EXEC -->
|
||||
<div class="engine-sub-opts" id="engine-details-1" style="display:none">
|
||||
<?php
|
||||
$tplMng->render(
|
||||
'parts/settings/shellZipMessage',
|
||||
['hasShellZip' => $isShellZipAvailable]
|
||||
);
|
||||
?>
|
||||
</div>
|
||||
|
||||
<!-- ZIP ARCHIVE -->
|
||||
<div class="engine-sub-opts" id="engine-details-2" style="display:none;">
|
||||
<div class="margin-bottom-1">
|
||||
<span><?php esc_html_e("Process Mode", 'duplicator-pro'); ?></span>
|
||||
<select name="ziparchive_mode" id="ziparchive_mode" onchange="DupliJs.UI.setZipArchiveMode();" class="inline-display width-medium margin-0">
|
||||
<option <?php selected($global->ziparchive_mode, PackageArchive::ZIP_MODE_MULTI_THREAD); ?>
|
||||
value="<?php echo (int) PackageArchive::ZIP_MODE_MULTI_THREAD ?>">
|
||||
<?php esc_html_e("Multi-Threaded", 'duplicator-pro'); ?>
|
||||
</option>
|
||||
<option <?php selected($global->ziparchive_mode == PackageArchive::ZIP_MODE_SINGLE_THREAD); ?>
|
||||
value="<?php echo (int) PackageArchive::ZIP_MODE_SINGLE_THREAD ?>">
|
||||
<?php esc_html_e("Single-Threaded", 'duplicator-pro'); ?>
|
||||
</option>
|
||||
</select>
|
||||
<i style="margin-right:7px;" class="fa-solid fa-question-circle fa-sm dark-gray-color"
|
||||
data-tooltip-title="<?php esc_attr_e("PHP ZipArchive Mode", 'duplicator-pro'); ?>"
|
||||
data-tooltip="<?php
|
||||
esc_attr_e(
|
||||
'Single-Threaded mode attempts to create the entire archive in one request.
|
||||
Multi-Threaded mode allows the archive to be chunked over multiple requests.
|
||||
Multi-Threaded mode is typically slower but much more reliable especially for larger sites.',
|
||||
'duplicator-pro'
|
||||
);
|
||||
?>"></i>
|
||||
</div>
|
||||
|
||||
<div id="dupli-ziparchive-mode-st">
|
||||
<input type="checkbox" id="ziparchive_validation" name="ziparchive_validation" class="margin-0"
|
||||
<?php checked($global->ziparchive_validation); ?>>
|
||||
<label for="ziparchive_validation">Enable file validation</label>
|
||||
</div>
|
||||
|
||||
<div id="dupli-ziparchive-mode-mt">
|
||||
<span><?php esc_html_e("Buffer Size", 'duplicator-pro'); ?></span>
|
||||
<input
|
||||
maxlength="4"
|
||||
class="inline-display width-small margin-0"
|
||||
data-parsley-required data-parsley-errors-container="#ziparchive_chunk_size_error_container"
|
||||
data-parsley-min="5" data-parsley-type="number"
|
||||
type="text" name="ziparchive_chunk_size_in_mb" id="ziparchive_chunk_size_in_mb"
|
||||
value="<?php echo (int) $global->ziparchive_chunk_size_in_mb; ?>">
|
||||
<?php esc_html_e('MB', 'duplicator-pro'); ?>
|
||||
<?php
|
||||
$toolTipContent = __(
|
||||
'Buffer size only applies to multi-threaded requests and indicates how large an archive will get before a close is registered.
|
||||
Higher values are faster but can be more unstable based on the hosts max_execution_time.',
|
||||
'duplicator-pro'
|
||||
);
|
||||
?>
|
||||
<i style="margin-right:7px" class="fa-solid fa-question-circle fa-sm dark-gray-color"
|
||||
data-tooltip-title="<?php esc_attr_e("PHP ZipArchive Buffer", 'duplicator-pro'); ?>"
|
||||
data-tooltip="<?php echo esc_attr($toolTipContent); ?>">
|
||||
</i>
|
||||
<div id="ziparchive_chunk_size_error_container" class="duplicator-error-container"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Duplicator
|
||||
*/
|
||||
|
||||
use Duplicator\Controllers\SettingsPageController;
|
||||
use Duplicator\Core\Controllers\ControllersManager;
|
||||
|
||||
defined("ABSPATH") or die("");
|
||||
|
||||
|
||||
/**
|
||||
* Variables
|
||||
*
|
||||
* @var Duplicator\Core\Controllers\ControllersManager $ctrlMng
|
||||
* @var Duplicator\Core\Views\TplMng $tplMng
|
||||
* @var array<string, mixed> $tplData
|
||||
*/
|
||||
|
||||
?>
|
||||
<form
|
||||
id="dup-settings-form" class="dup-settings-pack-basic"
|
||||
action="<?php echo esc_url(ControllersManager::getCurrentLink()); ?>"
|
||||
method="post" data-parsley-validate
|
||||
>
|
||||
<?php $tplData['actions'][SettingsPageController::ACTION_PACKAGE_BASIC_SAVE]->getActionNonceFileds(); ?>
|
||||
<div class="dup-settings-wrapper margin-bottom-1">
|
||||
<?php $tplMng->render('admin_pages/settings/backup/database_settings'); ?>
|
||||
<?php $tplMng->render('admin_pages/settings/backup/archive_settings'); ?>
|
||||
<?php $tplMng->render('admin_pages/settings/backup/processing_settings'); ?>
|
||||
<?php $tplMng->render('admin_pages/settings/backup/installer_settings'); ?>
|
||||
<?php $tplMng->render('admin_pages/settings/backup/advanced_settings'); ?>
|
||||
</div>
|
||||
<p class="submit dupli-save-submit">
|
||||
<input
|
||||
type="submit"
|
||||
name="submit"
|
||||
id="submit"
|
||||
class="button primary small"
|
||||
value="<?php esc_attr_e('Save Settings', 'duplicator-pro') ?>" style="display: inline-block;"
|
||||
>
|
||||
</p>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
jQuery(document).ready(function ($)
|
||||
{
|
||||
|
||||
DupliJs.UI.SetDBEngineMode = function ()
|
||||
{
|
||||
var isMysqlDump = $('#package_mysqldump').is(':checked');
|
||||
var isPHPMode = $('#package_phpdump').is(':checked');
|
||||
var isPHPChunkMode = $('#package_phpchunkingdump').is(':checked');
|
||||
|
||||
$('#dbengine-details-1, #dbengine-details-2').hide();
|
||||
switch (true) {
|
||||
case isMysqlDump :
|
||||
$('#dbengine-details-1').show();
|
||||
break;
|
||||
case isPHPMode :
|
||||
case isPHPChunkMode :
|
||||
$('#dbengine-details-2').show();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DupliJs.UI.setZipArchiveMode = function ()
|
||||
{
|
||||
$('#dupli-ziparchive-mode-st, #dupli-ziparchive-mode-mt').hide();
|
||||
if ($('#ziparchive_mode').val() == 0) {
|
||||
$('#dupli-ziparchive-mode-mt').show();
|
||||
} else {
|
||||
$('#dupli-ziparchive-mode-st').show();
|
||||
}
|
||||
}
|
||||
|
||||
DupliJs.UI.SetArchiveOptionStates = function ()
|
||||
{
|
||||
var php70 = <?php echo (version_compare(PHP_VERSION, '7', '>=') ? 'true' : 'false'); ?>;
|
||||
var isShellZipSelected = $('#archive_build_mode1').is(':checked');
|
||||
var isZipArchiveSelected = $('#archive_build_mode2').is(':checked');
|
||||
var isDupArchiveSelected = $('#archive_build_mode3').is(':checked');
|
||||
|
||||
if (isShellZipSelected || isDupArchiveSelected) {
|
||||
$("[name='archive_compression']").prop('disabled', false);
|
||||
$("[name='ziparchive_mode']").prop('disabled', true);
|
||||
} else {
|
||||
$("[name='ziparchive_mode']").prop('disabled', false);
|
||||
if (php70) {
|
||||
$("[name='archive_compression']").prop('disabled', false);
|
||||
} else {
|
||||
$('#archive_compression_on').prop('checked', true);
|
||||
$("[name='archive_compression']").prop('disabled', true);
|
||||
}
|
||||
}
|
||||
|
||||
$('#engine-details-1, #engine-details-2, #engine-details-3').hide();
|
||||
switch (true) {
|
||||
case isShellZipSelected :
|
||||
$('#engine-details-1').show();
|
||||
break;
|
||||
case isZipArchiveSelected :
|
||||
$('#engine-details-2').show();
|
||||
break;
|
||||
case isDupArchiveSelected :
|
||||
$('#engine-details-3').show();
|
||||
break;
|
||||
}
|
||||
DupliJs.UI.setZipArchiveMode();
|
||||
}
|
||||
|
||||
//INIT
|
||||
DupliJs.UI.SetArchiveOptionStates();
|
||||
DupliJs.UI.SetDBEngineMode();
|
||||
|
||||
DupliJs.UI.cleanupModeRadioSwitched = function() {
|
||||
if ($('#cleanup_mode_Cleanup_Off').is(":checked")){
|
||||
$('#auto_cleanup_hours').attr('readonly','readonly');
|
||||
$('#cleanup_email').attr('readonly','readonly');
|
||||
} else if ($('#cleanup_mode_Email_Notice').is(":checked")) {
|
||||
$('#auto_cleanup_hours').attr('readonly','readonly');
|
||||
$("#cleanup_email").removeAttr('readonly');
|
||||
} else if ($('#cleanup_mode_Auto_Cleanup').is(":checked")) {
|
||||
$("#auto_cleanup_hours").removeAttr('readonly');
|
||||
$("#cleanup_email").removeAttr('readonly');
|
||||
}
|
||||
}
|
||||
|
||||
$('input[type=radio][name=cleanup_mode]').change(function () {
|
||||
DupliJs.UI.cleanupModeRadioSwitched();
|
||||
});
|
||||
// We must call this also once in the beginning, after UI is loaded
|
||||
DupliJs.UI.cleanupModeRadioSwitched();
|
||||
|
||||
});
|
||||
</script>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user