Make your WordPress site irresistible. Natural SEO attraction with: - robots.txt management - sitemap.xml generation - LLMs.txt support - Google integration (Analytics, Search Console, Tag Manager) - Schema.org structured data - Open Graph / Twitter Card meta tags - AMP support - Visual elements gallery - Built-in backup/restore module Includes build.sh and .distignore for WordPress-installable release ZIPs.
1442 lines
58 KiB
PHP
1442 lines
58 KiB
PHP
<?php
|
|
/**
|
|
* Backup & Restore Admin Page
|
|
*
|
|
* Enterprise-grade backup and restore interface with progress tracking,
|
|
* advanced options, and comprehensive management features.
|
|
*/
|
|
|
|
// Prevent direct access
|
|
if (!defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
// Get backup module instance
|
|
$backup_module = tigerstyle_heat()->get_module('backup_restore');
|
|
$settings = $backup_module->get_backup_settings();
|
|
$backups = $backup_module->get_backup_list();
|
|
$compression_methods = $backup_module->get_available_compression_methods();
|
|
|
|
// Get storage stats
|
|
$storage_manager = TigerStyleSEO_Storage_Manager::instance();
|
|
$storage_stats = $storage_manager->get_storage_stats();
|
|
|
|
// Get scheduler status (check if class exists first)
|
|
$schedule_status = array();
|
|
if (class_exists('TigerStyleSEO_Backup_Scheduler')) {
|
|
$scheduler = new TigerStyleSEO_Backup_Scheduler();
|
|
$schedule_status = $scheduler->get_schedule_status();
|
|
}
|
|
?>
|
|
|
|
<div class="tigerstyle-backup-restore">
|
|
<h2><?php _e('Backup & Restore', 'tigerstyle-heat'); ?></h2>
|
|
|
|
<!-- Statistics Dashboard -->
|
|
<div class="backup-dashboard">
|
|
<div class="stats-cards">
|
|
<div class="stat-card">
|
|
<h3><?php _e('Total Backups', 'tigerstyle-heat'); ?></h3>
|
|
<div class="stat-value"><?php echo esc_html($storage_stats['total_backups'] ?? 0); ?></div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<h3><?php _e('Storage Used', 'tigerstyle-heat'); ?></h3>
|
|
<div class="stat-value"><?php echo esc_html($storage_stats['total_size_formatted'] ?? '0 B'); ?></div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<h3><?php _e('Last Backup', 'tigerstyle-heat'); ?></h3>
|
|
<div class="stat-value">
|
|
<?php if (isset($storage_stats['newest_backup'])): ?>
|
|
<?php echo esc_html(mysql2date(get_option('date_format'), $storage_stats['newest_backup'])); ?>
|
|
<?php else: ?>
|
|
<?php _e('Never', 'tigerstyle-heat'); ?>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
<div class="stat-card">
|
|
<h3><?php _e('Next Scheduled', 'tigerstyle-heat'); ?></h3>
|
|
<div class="stat-value">
|
|
<?php if ($schedule_status['enabled'] && $schedule_status['next_run']): ?>
|
|
<?php echo esc_html($schedule_status['next_run']['human']); ?>
|
|
<?php else: ?>
|
|
<?php _e('Not scheduled', 'tigerstyle-heat'); ?>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Tab Navigation -->
|
|
<div class="nav-tab-wrapper backup-tabs">
|
|
<a href="#create-backup" class="nav-tab nav-tab-active"><?php _e('Create Backup', 'tigerstyle-heat'); ?></a>
|
|
<a href="#manage-backups" class="nav-tab"><?php _e('Manage Backups', 'tigerstyle-heat'); ?></a>
|
|
<a href="#restore" class="nav-tab"><?php _e('Restore', 'tigerstyle-heat'); ?></a>
|
|
<a href="#settings" class="nav-tab"><?php _e('Settings', 'tigerstyle-heat'); ?></a>
|
|
<a href="#advanced" class="nav-tab"><?php _e('Advanced', 'tigerstyle-heat'); ?></a>
|
|
<a href="#logs" class="nav-tab"><?php _e('Logs', 'tigerstyle-heat'); ?></a>
|
|
</div>
|
|
|
|
<!-- Create Backup Tab -->
|
|
<div id="create-backup" class="tab-content active">
|
|
<div class="backup-section">
|
|
<h3><?php _e('Create New Backup', 'tigerstyle-heat'); ?></h3>
|
|
|
|
<form id="create-backup-form" class="backup-form">
|
|
<?php wp_nonce_field('tigerstyle_backup_action', 'tigerstyle_backup_nonce'); ?>
|
|
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label for="backup_type"><?php _e('Backup Type', 'tigerstyle-heat'); ?></label>
|
|
<select id="backup_type" name="backup_type">
|
|
<option value="full"><?php _e('Full Backup (Files + Database)', 'tigerstyle-heat'); ?></option>
|
|
<option value="files_only"><?php _e('Files Only', 'tigerstyle-heat'); ?></option>
|
|
<option value="database_only"><?php _e('Database Only', 'tigerstyle-heat'); ?></option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="compression"><?php _e('Compression', 'tigerstyle-heat'); ?></label>
|
|
<select id="compression" name="compression">
|
|
<?php foreach ($compression_methods as $method => $name): ?>
|
|
<option value="<?php echo esc_attr($method); ?>" <?php selected($settings['compression'], $method); ?>>
|
|
<?php echo esc_html($name); ?>
|
|
</option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
<div class="form-group">
|
|
<label for="storage_location"><?php _e('Storage Location', 'tigerstyle-heat'); ?></label>
|
|
<select id="storage_location" name="storage_location">
|
|
<option value="local" <?php selected($settings['storage_location'], 'local'); ?>><?php _e('Local Storage', 'tigerstyle-heat'); ?></option>
|
|
<?php if (!empty($settings['s3_bucket'])): ?>
|
|
<option value="s3" <?php selected($settings['storage_location'], 's3'); ?>><?php _e('S3 Compatible Storage', 'tigerstyle-heat'); ?></option>
|
|
<?php endif; ?>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="form-group">
|
|
<label for="backup_description"><?php _e('Description (Optional)', 'tigerstyle-heat'); ?></label>
|
|
<input type="text" id="backup_description" name="description" placeholder="<?php esc_attr_e('Backup before site update', 'tigerstyle-heat'); ?>">
|
|
</div>
|
|
</div>
|
|
|
|
<div class="advanced-options" style="display: none;">
|
|
<h4><?php _e('Advanced Options', 'tigerstyle-heat'); ?></h4>
|
|
|
|
<label class="checkbox-label">
|
|
<input type="checkbox" name="include_uploads" checked>
|
|
<?php _e('Include wp-content/uploads directory', 'tigerstyle-heat'); ?>
|
|
</label>
|
|
|
|
<label class="checkbox-label">
|
|
<input type="checkbox" name="include_themes" checked>
|
|
<?php _e('Include themes', 'tigerstyle-heat'); ?>
|
|
</label>
|
|
|
|
<label class="checkbox-label">
|
|
<input type="checkbox" name="include_plugins" checked>
|
|
<?php _e('Include plugins', 'tigerstyle-heat'); ?>
|
|
</label>
|
|
|
|
<label class="checkbox-label">
|
|
<input type="checkbox" name="exclude_cache">
|
|
<?php _e('Exclude cache files', 'tigerstyle-heat'); ?>
|
|
</label>
|
|
</div>
|
|
|
|
<div class="form-actions">
|
|
<button type="button" class="button" id="toggle-advanced"><?php _e('Advanced Options', 'tigerstyle-heat'); ?></button>
|
|
<button type="submit" class="button-primary" id="create-backup-btn">
|
|
<span class="dashicons dashicons-backup"></span>
|
|
<?php _e('Create Backup', 'tigerstyle-heat'); ?>
|
|
</button>
|
|
</div>
|
|
</form>
|
|
|
|
<!-- Progress Display -->
|
|
<div id="backup-progress" style="display: none;">
|
|
<h4><?php _e('Backup Progress', 'tigerstyle-heat'); ?></h4>
|
|
<div class="progress-bar">
|
|
<div class="progress-fill"></div>
|
|
<div class="progress-text">0%</div>
|
|
</div>
|
|
<div class="progress-message"><?php _e('Initializing backup...', 'tigerstyle-heat'); ?></div>
|
|
<div class="progress-details">
|
|
<div class="detail-item">
|
|
<span class="label"><?php _e('Backup ID:', 'tigerstyle-heat'); ?></span>
|
|
<span class="value" id="backup-id-display">-</span>
|
|
</div>
|
|
<div class="detail-item">
|
|
<span class="label"><?php _e('Started:', 'tigerstyle-heat'); ?></span>
|
|
<span class="value" id="backup-start-time">-</span>
|
|
</div>
|
|
<div class="detail-item">
|
|
<span class="label"><?php _e('Estimated Time:', 'tigerstyle-heat'); ?></span>
|
|
<span class="value" id="backup-eta">-</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Manage Backups Tab -->
|
|
<div id="manage-backups" class="tab-content">
|
|
<div class="backup-section">
|
|
<h3><?php _e('Backup List', 'tigerstyle-heat'); ?></h3>
|
|
|
|
<div class="backup-filters">
|
|
<select id="backup-filter-storage">
|
|
<option value=""><?php _e('All Storage Locations', 'tigerstyle-heat'); ?></option>
|
|
<option value="local"><?php _e('Local Storage', 'tigerstyle-heat'); ?></option>
|
|
<option value="s3"><?php _e('S3 Compatible Storage', 'tigerstyle-heat'); ?></option>
|
|
</select>
|
|
|
|
<input type="text" id="backup-search" placeholder="<?php esc_attr_e('Search backups...', 'tigerstyle-heat'); ?>">
|
|
|
|
<button type="button" class="button" id="refresh-backups">
|
|
<span class="dashicons dashicons-update"></span>
|
|
<?php _e('Refresh', 'tigerstyle-heat'); ?>
|
|
</button>
|
|
</div>
|
|
|
|
<div class="backup-list">
|
|
<?php if (empty($backups)): ?>
|
|
<div class="no-backups">
|
|
<span class="dashicons dashicons-backup"></span>
|
|
<p><?php _e('No backups found. Create your first backup to get started.', 'tigerstyle-heat'); ?></p>
|
|
</div>
|
|
<?php else: ?>
|
|
<div class="backup-table">
|
|
<div class="backup-header">
|
|
<div class="col-backup-id"><?php _e('Backup ID', 'tigerstyle-heat'); ?></div>
|
|
<div class="col-date"><?php _e('Created', 'tigerstyle-heat'); ?></div>
|
|
<div class="col-size"><?php _e('Size', 'tigerstyle-heat'); ?></div>
|
|
<div class="col-type"><?php _e('Type', 'tigerstyle-heat'); ?></div>
|
|
<div class="col-storage"><?php _e('Storage', 'tigerstyle-heat'); ?></div>
|
|
<div class="col-actions"><?php _e('Actions', 'tigerstyle-heat'); ?></div>
|
|
</div>
|
|
|
|
<?php foreach ($backups as $backup): ?>
|
|
<div class="backup-row" data-backup-id="<?php echo esc_attr($backup['backup_id']); ?>">
|
|
<div class="col-backup-id">
|
|
<strong><?php echo esc_html(substr($backup['backup_id'], 0, 16)); ?>...</strong>
|
|
<?php if (!empty($backup['description'])): ?>
|
|
<div class="backup-description"><?php echo esc_html($backup['description']); ?></div>
|
|
<?php endif; ?>
|
|
</div>
|
|
<div class="col-date">
|
|
<?php echo esc_html($backup['created_at_formatted'] ?? ($backup['created_at'] ?? 'Unknown')); ?>
|
|
<div class="age"><?php echo esc_html($backup['age'] ?? ''); ?> <?php if (!empty($backup['age'])): ?><?php _e('ago', 'tigerstyle-heat'); ?><?php endif; ?></div>
|
|
</div>
|
|
<div class="col-size"><?php echo esc_html($backup['file_size_formatted'] ?? (isset($backup['file_size']) ? size_format($backup['file_size']) : 'Unknown')); ?></div>
|
|
<div class="col-type">
|
|
<span class="backup-type-badge"><?php echo esc_html($backup['type'] ?? 'full'); ?></span>
|
|
</div>
|
|
<div class="col-storage">
|
|
<span class="storage-badge <?php echo esc_attr($backup['storage_type'] ?? 'local'); ?>">
|
|
<?php echo esc_html(strtoupper($backup['storage_type'] ?? 'LOCAL')); ?>
|
|
</span>
|
|
</div>
|
|
<div class="col-actions">
|
|
<?php if (!empty($backup['backup_id'])): ?>
|
|
<button type="button" class="button button-small restore-backup"
|
|
data-backup-id="<?php echo esc_attr($backup['backup_id']); ?>">
|
|
<span class="dashicons dashicons-update"></span>
|
|
<?php _e('Restore', 'tigerstyle-heat'); ?>
|
|
</button>
|
|
<button type="button" class="button button-small download-backup"
|
|
data-backup-id="<?php echo esc_attr($backup['backup_id']); ?>">
|
|
<span class="dashicons dashicons-download"></span>
|
|
<?php _e('Download', 'tigerstyle-heat'); ?>
|
|
</button>
|
|
<button type="button" class="button button-small validate-backup"
|
|
data-backup-id="<?php echo esc_attr($backup['backup_id']); ?>">
|
|
<span class="dashicons dashicons-yes-alt"></span>
|
|
<?php _e('Validate', 'tigerstyle-heat'); ?>
|
|
</button>
|
|
<button type="button" class="button button-small button-link-delete delete-backup"
|
|
data-backup-id="<?php echo esc_attr($backup['backup_id']); ?>">
|
|
<span class="dashicons dashicons-trash"></span>
|
|
<?php _e('Delete', 'tigerstyle-heat'); ?>
|
|
<?php else: ?>
|
|
<span class="backup-error"><?php _e('Invalid backup data', 'tigerstyle-heat'); ?></span>
|
|
<?php endif; ?>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<?php endforeach; ?>
|
|
</div>
|
|
<?php endif; ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Restore Tab -->
|
|
<div id="restore" class="tab-content">
|
|
<div class="backup-section">
|
|
<h3><?php _e('Restore from Backup', 'tigerstyle-heat'); ?></h3>
|
|
|
|
<div class="restore-warning">
|
|
<span class="dashicons dashicons-warning"></span>
|
|
<p><?php _e('Restoring from backup will overwrite your current website. This action cannot be undone. Please create a backup before proceeding.', 'tigerstyle-heat'); ?></p>
|
|
</div>
|
|
|
|
<form id="restore-form" class="backup-form">
|
|
<?php wp_nonce_field('tigerstyle_backup_action', 'tigerstyle_restore_nonce'); ?>
|
|
|
|
<div class="form-group">
|
|
<label for="restore_backup_id"><?php _e('Select Backup to Restore', 'tigerstyle-heat'); ?></label>
|
|
<select id="restore_backup_id" name="backup_id" required>
|
|
<option value=""><?php _e('Choose a backup...', 'tigerstyle-heat'); ?></option>
|
|
<?php foreach ($backups as $backup): ?>
|
|
<option value="<?php echo esc_attr($backup['backup_id']); ?>">
|
|
<?php echo esc_html(substr($backup['backup_id'], 0, 16)); ?>... -
|
|
<?php echo esc_html(isset($backup['created_at_formatted']) ? $backup['created_at_formatted'] : $backup['created_at']); ?>
|
|
(<?php echo esc_html(isset($backup['file_size_formatted']) ? $backup['file_size_formatted'] : ($backup['file_size'] ? size_format($backup['file_size']) : 'Unknown')); ?>)
|
|
</option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="restore-options">
|
|
<h4><?php _e('Restore Options', 'tigerstyle-heat'); ?></h4>
|
|
|
|
<label class="checkbox-label">
|
|
<input type="checkbox" name="restore_files" checked>
|
|
<?php _e('Restore Files', 'tigerstyle-heat'); ?>
|
|
</label>
|
|
|
|
<label class="checkbox-label">
|
|
<input type="checkbox" name="restore_database" checked>
|
|
<?php _e('Restore Database', 'tigerstyle-heat'); ?>
|
|
</label>
|
|
|
|
<label class="checkbox-label">
|
|
<input type="checkbox" name="create_rollback" checked>
|
|
<?php _e('Create rollback backup before restore', 'tigerstyle-heat'); ?>
|
|
</label>
|
|
|
|
<label class="checkbox-label">
|
|
<input type="checkbox" name="validate_before_restore" checked>
|
|
<?php _e('Validate backup integrity before restore', 'tigerstyle-heat'); ?>
|
|
</label>
|
|
</div>
|
|
|
|
<div class="confirmation-section" style="display: none;">
|
|
<h4><?php _e('Confirmation Required', 'tigerstyle-heat'); ?></h4>
|
|
<p><?php _e('Type "CONFIRM RESTORE" to proceed with the restoration:', 'tigerstyle-heat'); ?></p>
|
|
<input type="text" id="restore_confirmation" placeholder="<?php esc_attr_e('Type confirmation here...', 'tigerstyle-heat'); ?>" required>
|
|
</div>
|
|
|
|
<div class="form-actions">
|
|
<button type="button" class="button" id="show-restore-confirmation">
|
|
<?php _e('Prepare Restore', 'tigerstyle-heat'); ?>
|
|
</button>
|
|
<button type="submit" class="button-primary" id="restore-backup-btn" style="display: none;">
|
|
<span class="dashicons dashicons-update"></span>
|
|
<?php _e('Restore Now', 'tigerstyle-heat'); ?>
|
|
</button>
|
|
</div>
|
|
</form>
|
|
|
|
<!-- Restore Progress -->
|
|
<div id="restore-progress" style="display: none;">
|
|
<h4><?php _e('Restore Progress', 'tigerstyle-heat'); ?></h4>
|
|
<div class="progress-bar">
|
|
<div class="progress-fill"></div>
|
|
<div class="progress-text">0%</div>
|
|
</div>
|
|
<div class="progress-message"><?php _e('Initializing restore...', 'tigerstyle-heat'); ?></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Settings Tab -->
|
|
<div id="settings" class="tab-content">
|
|
<div class="backup-section">
|
|
<h3><?php _e('Backup Settings', 'tigerstyle-heat'); ?></h3>
|
|
|
|
<form method="post" action="<?php echo admin_url('admin-post.php'); ?>" class="backup-settings-form">
|
|
<?php wp_nonce_field('tigerstyle_backup_settings', 'tigerstyle_backup_nonce'); ?>
|
|
<input type="hidden" name="action" value="tigerstyle_backup_settings">
|
|
|
|
<!-- General Settings -->
|
|
<div class="settings-section">
|
|
<h4><?php _e('General Settings', 'tigerstyle-heat'); ?></h4>
|
|
|
|
<table class="form-table">
|
|
<tr>
|
|
<th scope="row"><?php _e('Default Compression', 'tigerstyle-heat'); ?></th>
|
|
<td>
|
|
<select name="compression">
|
|
<?php foreach ($compression_methods as $method => $name): ?>
|
|
<option value="<?php echo esc_attr($method); ?>" <?php selected($settings['compression'], $method); ?>>
|
|
<?php echo esc_html($name); ?>
|
|
</option>
|
|
<?php endforeach; ?>
|
|
</select>
|
|
<p class="description"><?php _e('Default compression method for new backups.', 'tigerstyle-heat'); ?></p>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<th scope="row"><?php _e('Default Storage Location', 'tigerstyle-heat'); ?></th>
|
|
<td>
|
|
<select name="storage_location">
|
|
<option value="local" <?php selected($settings['storage_location'], 'local'); ?>><?php _e('Local Storage', 'tigerstyle-heat'); ?></option>
|
|
<option value="s3" <?php selected($settings['storage_location'], 's3'); ?>><?php _e('S3 Compatible Storage', 'tigerstyle-heat'); ?></option>
|
|
</select>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<th scope="row"><?php _e('Chunk Size (MB)', 'tigerstyle-heat'); ?></th>
|
|
<td>
|
|
<input type="number" name="chunk_size" value="<?php echo esc_attr($settings['chunk_size']); ?>" min="1" max="50">
|
|
<p class="description"><?php _e('Size of file chunks for processing large backups.', 'tigerstyle-heat'); ?></p>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<th scope="row"><?php _e('Backup Retention', 'tigerstyle-heat'); ?></th>
|
|
<td>
|
|
<input type="number" name="retention_days" value="<?php echo esc_attr($settings['retention_days']); ?>" min="0">
|
|
<span><?php _e('days (0 = unlimited)', 'tigerstyle-heat'); ?></span>
|
|
<p class="description"><?php _e('Automatically delete backups older than this many days.', 'tigerstyle-heat'); ?></p>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
|
|
<!-- Scheduled Backups -->
|
|
<div class="settings-section">
|
|
<h4><?php _e('Scheduled Backups', 'tigerstyle-heat'); ?></h4>
|
|
|
|
<table class="form-table">
|
|
<tr>
|
|
<th scope="row"><?php _e('Enable Scheduled Backups', 'tigerstyle-heat'); ?></th>
|
|
<td>
|
|
<label>
|
|
<input type="checkbox" name="schedule_enabled" value="1" <?php checked($settings['schedule_enabled']); ?>>
|
|
<?php _e('Automatically create backups on schedule', 'tigerstyle-heat'); ?>
|
|
</label>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr class="schedule-option">
|
|
<th scope="row"><?php _e('Backup Frequency', 'tigerstyle-heat'); ?></th>
|
|
<td>
|
|
<select name="schedule_frequency">
|
|
<option value="hourly" <?php selected($settings['schedule_frequency'], 'hourly'); ?>><?php _e('Hourly', 'tigerstyle-heat'); ?></option>
|
|
<option value="daily" <?php selected($settings['schedule_frequency'], 'daily'); ?>><?php _e('Daily', 'tigerstyle-heat'); ?></option>
|
|
<option value="weekly" <?php selected($settings['schedule_frequency'], 'weekly'); ?>><?php _e('Weekly', 'tigerstyle-heat'); ?></option>
|
|
<option value="monthly" <?php selected($settings['schedule_frequency'], 'monthly'); ?>><?php _e('Monthly', 'tigerstyle-heat'); ?></option>
|
|
</select>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr class="schedule-option">
|
|
<th scope="row"><?php _e('Backup What', 'tigerstyle-heat'); ?></th>
|
|
<td>
|
|
<label>
|
|
<input type="checkbox" name="include_files" value="1" <?php checked($settings['include_files']); ?>>
|
|
<?php _e('Include Files', 'tigerstyle-heat'); ?>
|
|
</label><br>
|
|
<label>
|
|
<input type="checkbox" name="include_database" value="1" <?php checked($settings['include_database']); ?>>
|
|
<?php _e('Include Database', 'tigerstyle-heat'); ?>
|
|
</label>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
|
|
<!-- S3 Storage Settings -->
|
|
<div class="settings-section">
|
|
<h4><?php _e('S3 Compatible Storage', 'tigerstyle-heat'); ?></h4>
|
|
|
|
<table class="form-table">
|
|
<tr>
|
|
<th scope="row"><?php _e('S3 Bucket', 'tigerstyle-heat'); ?></th>
|
|
<td>
|
|
<input type="text" name="s3_bucket" value="<?php echo esc_attr($settings['s3_bucket']); ?>" class="regular-text">
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<th scope="row"><?php _e('Access Key ID', 'tigerstyle-heat'); ?></th>
|
|
<td>
|
|
<input type="text" name="s3_access_key" value="<?php echo esc_attr($settings['s3_access_key']); ?>" class="regular-text">
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<th scope="row"><?php _e('Secret Access Key', 'tigerstyle-heat'); ?></th>
|
|
<td>
|
|
<input type="password" name="s3_secret_key" value="<?php echo esc_attr($settings['s3_secret_key']); ?>" class="regular-text">
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<th scope="row"><?php _e('Region', 'tigerstyle-heat'); ?></th>
|
|
<td>
|
|
<input type="text" name="s3_region" value="<?php echo esc_attr($settings['s3_region']); ?>" class="regular-text" placeholder="us-east-1">
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<th scope="row"><?php _e('Custom Endpoint', 'tigerstyle-heat'); ?></th>
|
|
<td>
|
|
<input type="url" name="s3_endpoint" value="<?php echo esc_attr($settings['s3_endpoint']); ?>" class="regular-text" placeholder="https://s3.example.com">
|
|
<p class="description"><?php _e('For S3-compatible services like MinIO, DigitalOcean Spaces, etc.', 'tigerstyle-heat'); ?></p>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<th scope="row"><?php _e('Test Connection', 'tigerstyle-heat'); ?></th>
|
|
<td>
|
|
<button type="button" class="button" id="test-s3-connection">
|
|
<?php _e('Test S3 Connection', 'tigerstyle-heat'); ?>
|
|
</button>
|
|
<div id="s3-test-result"></div>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
|
|
<!-- Notification Settings -->
|
|
<div class="settings-section">
|
|
<h4><?php _e('Email Notifications', 'tigerstyle-heat'); ?></h4>
|
|
|
|
<table class="form-table">
|
|
<tr>
|
|
<th scope="row"><?php _e('Enable Notifications', 'tigerstyle-heat'); ?></th>
|
|
<td>
|
|
<label>
|
|
<input type="checkbox" name="email_notifications" value="1" <?php checked($settings['email_notifications']); ?>>
|
|
<?php _e('Send email notifications for backup events', 'tigerstyle-heat'); ?>
|
|
</label>
|
|
</td>
|
|
</tr>
|
|
|
|
<tr class="notification-option">
|
|
<th scope="row"><?php _e('Notification Email', 'tigerstyle-heat'); ?></th>
|
|
<td>
|
|
<input type="email" name="notification_email" value="<?php echo esc_attr($settings['notification_email']); ?>" class="regular-text">
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
|
|
<?php submit_button(__('Save Settings', 'tigerstyle-heat')); ?>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Advanced Tab -->
|
|
<div id="advanced" class="tab-content">
|
|
<div class="backup-section">
|
|
<h3><?php _e('Advanced Operations', 'tigerstyle-heat'); ?></h3>
|
|
|
|
<!-- WordPress Reset -->
|
|
<div class="advanced-operation">
|
|
<h4><?php _e('WordPress Content Reset', 'tigerstyle-heat'); ?></h4>
|
|
<p><?php _e('Remove default WordPress posts, pages, and comments to prepare for a fresh restore.', 'tigerstyle-heat'); ?></p>
|
|
|
|
<div class="warning-box">
|
|
<span class="dashicons dashicons-warning"></span>
|
|
<p><?php _e('This will delete all posts, pages, and comments. A backup will be created automatically before reset.', 'tigerstyle-heat'); ?></p>
|
|
</div>
|
|
|
|
<form id="wordpress-reset-form">
|
|
<?php wp_nonce_field('tigerstyle_backup_action', 'tigerstyle_reset_nonce'); ?>
|
|
<p><?php _e('Type "RESET_WORDPRESS" to confirm:', 'tigerstyle-heat'); ?></p>
|
|
<input type="text" id="wordpress-reset-confirmation" placeholder="<?php esc_attr_e('Confirmation text...', 'tigerstyle-heat'); ?>" required>
|
|
<button type="submit" class="button button-delete" id="reset-wordpress-btn">
|
|
<?php _e('Reset WordPress Content', 'tigerstyle-heat'); ?>
|
|
</button>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- Database Reset -->
|
|
<div class="advanced-operation">
|
|
<h4><?php _e('Complete Database Reset', 'tigerstyle-heat'); ?></h4>
|
|
<p><?php _e('Completely wipe the database. This is irreversible and should only be used for development.', 'tigerstyle-heat'); ?></p>
|
|
|
|
<div class="danger-box">
|
|
<span class="dashicons dashicons-dismiss"></span>
|
|
<p><?php _e('DANGER: This will completely delete all database tables. Your site will be completely broken until you restore from backup.', 'tigerstyle-heat'); ?></p>
|
|
</div>
|
|
|
|
<form id="database-reset-form">
|
|
<?php wp_nonce_field('tigerstyle_backup_action', 'tigerstyle_db_reset_nonce'); ?>
|
|
|
|
<div id="reset-code-section" style="display: none;">
|
|
<p><?php _e('Confirmation code:', 'tigerstyle-heat'); ?> <strong id="reset-code-display"></strong></p>
|
|
<p><?php _e('Enter the code shown above:', 'tigerstyle-heat'); ?></p>
|
|
<input type="text" id="database-reset-code" placeholder="<?php esc_attr_e('Enter confirmation code...', 'tigerstyle-heat'); ?>" required>
|
|
|
|
<p><?php _e('Type "YES_DELETE_EVERYTHING" to proceed:', 'tigerstyle-heat'); ?></p>
|
|
<input type="text" id="database-reset-final" placeholder="<?php esc_attr_e('Final confirmation...', 'tigerstyle-heat'); ?>" required>
|
|
|
|
<button type="submit" class="button button-delete" id="reset-database-btn">
|
|
<?php _e('DELETE DATABASE COMPLETELY', 'tigerstyle-heat'); ?>
|
|
</button>
|
|
</div>
|
|
|
|
<button type="button" class="button" id="generate-reset-code">
|
|
<?php _e('Generate Reset Code', 'tigerstyle-heat'); ?>
|
|
</button>
|
|
</form>
|
|
</div>
|
|
|
|
<!-- File Upload -->
|
|
<div class="advanced-operation">
|
|
<h4><?php _e('Upload Backup File', 'tigerstyle-heat'); ?></h4>
|
|
<p><?php _e('Upload a backup file from your computer to restore.', 'tigerstyle-heat'); ?></p>
|
|
|
|
<form id="upload-backup-form" enctype="multipart/form-data">
|
|
<?php wp_nonce_field('tigerstyle_backup_action', 'tigerstyle_upload_nonce'); ?>
|
|
<input type="file" id="backup-file-upload" name="backup_file" accept=".zip,.tar,.tar.gz,.tar.bz2" required>
|
|
<button type="submit" class="button">
|
|
<span class="dashicons dashicons-upload"></span>
|
|
<?php _e('Upload Backup', 'tigerstyle-heat'); ?>
|
|
</button>
|
|
</form>
|
|
|
|
<div id="upload-progress" style="display: none;">
|
|
<div class="progress-bar">
|
|
<div class="progress-fill"></div>
|
|
<div class="progress-text">0%</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Logs Tab -->
|
|
<div id="logs" class="tab-content">
|
|
<div class="backup-section">
|
|
<h3><?php _e('Backup Logs', 'tigerstyle-heat'); ?></h3>
|
|
|
|
<div class="log-filters">
|
|
<select id="log-level-filter">
|
|
<option value=""><?php _e('All Levels', 'tigerstyle-heat'); ?></option>
|
|
<option value="debug"><?php _e('Debug', 'tigerstyle-heat'); ?></option>
|
|
<option value="info"><?php _e('Info', 'tigerstyle-heat'); ?></option>
|
|
<option value="warning"><?php _e('Warning', 'tigerstyle-heat'); ?></option>
|
|
<option value="error"><?php _e('Error', 'tigerstyle-heat'); ?></option>
|
|
<option value="critical"><?php _e('Critical', 'tigerstyle-heat'); ?></option>
|
|
</select>
|
|
|
|
<button type="button" class="button" id="refresh-logs">
|
|
<span class="dashicons dashicons-update"></span>
|
|
<?php _e('Refresh', 'tigerstyle-heat'); ?>
|
|
</button>
|
|
|
|
<button type="button" class="button" id="export-logs">
|
|
<span class="dashicons dashicons-download"></span>
|
|
<?php _e('Export Logs', 'tigerstyle-heat'); ?>
|
|
</button>
|
|
|
|
<button type="button" class="button button-link-delete" id="clear-logs">
|
|
<span class="dashicons dashicons-trash"></span>
|
|
<?php _e('Clear Old Logs', 'tigerstyle-heat'); ?>
|
|
</button>
|
|
</div>
|
|
|
|
<div id="logs-container">
|
|
<div class="log-loading">
|
|
<span class="spinner is-active"></span>
|
|
<?php _e('Loading logs...', 'tigerstyle-heat'); ?>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<style>
|
|
/* Backup & Restore Styles */
|
|
.tigerstyle-backup-restore {
|
|
max-width: 1200px;
|
|
}
|
|
|
|
.backup-dashboard {
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.stats-cards {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
gap: 15px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.stat-card {
|
|
background: #fff;
|
|
border: 1px solid #ddd;
|
|
border-radius: 4px;
|
|
padding: 15px;
|
|
text-align: center;
|
|
}
|
|
|
|
.stat-card h3 {
|
|
margin: 0 0 10px 0;
|
|
font-size: 14px;
|
|
color: #666;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.stat-value {
|
|
font-size: 24px;
|
|
font-weight: bold;
|
|
color: #2271b1;
|
|
}
|
|
|
|
.backup-tabs {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.tab-content {
|
|
display: none;
|
|
background: #fff;
|
|
border: 1px solid #ccd0d4;
|
|
border-top: none;
|
|
padding: 20px;
|
|
}
|
|
|
|
.tab-content.active {
|
|
display: block;
|
|
}
|
|
|
|
.backup-section {
|
|
margin-bottom: 30px;
|
|
}
|
|
|
|
.backup-form {
|
|
max-width: 600px;
|
|
}
|
|
|
|
.form-row {
|
|
display: grid;
|
|
grid-template-columns: 1fr 1fr;
|
|
gap: 20px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.form-group {
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.form-group label {
|
|
margin-bottom: 5px;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.form-group input,
|
|
.form-group select {
|
|
padding: 8px 12px;
|
|
border: 1px solid #ddd;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.advanced-options {
|
|
margin: 20px 0;
|
|
padding: 15px;
|
|
background: #f9f9f9;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.checkbox-label {
|
|
display: flex;
|
|
align-items: center;
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
.checkbox-label input {
|
|
margin-right: 8px;
|
|
}
|
|
|
|
.form-actions {
|
|
display: flex;
|
|
gap: 10px;
|
|
align-items: center;
|
|
}
|
|
|
|
.progress-bar {
|
|
position: relative;
|
|
width: 100%;
|
|
height: 30px;
|
|
background: #f0f0f0;
|
|
border-radius: 4px;
|
|
overflow: hidden;
|
|
margin: 10px 0;
|
|
}
|
|
|
|
.progress-fill {
|
|
height: 100%;
|
|
background: linear-gradient(90deg, #2271b1, #72aee6);
|
|
transition: width 0.3s ease;
|
|
width: 0%;
|
|
}
|
|
|
|
.progress-text {
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
font-weight: bold;
|
|
color: #333;
|
|
}
|
|
|
|
.progress-details {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
gap: 15px;
|
|
margin-top: 15px;
|
|
}
|
|
|
|
.detail-item {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
}
|
|
|
|
.detail-item .label {
|
|
font-weight: 600;
|
|
}
|
|
|
|
.backup-filters {
|
|
display: flex;
|
|
gap: 10px;
|
|
margin-bottom: 15px;
|
|
align-items: center;
|
|
}
|
|
|
|
.backup-filters input,
|
|
.backup-filters select {
|
|
padding: 6px 10px;
|
|
}
|
|
|
|
.no-backups {
|
|
text-align: center;
|
|
padding: 40px;
|
|
color: #666;
|
|
}
|
|
|
|
.no-backups .dashicons {
|
|
font-size: 48px;
|
|
margin-bottom: 10px;
|
|
opacity: 0.5;
|
|
}
|
|
|
|
.backup-table {
|
|
border: 1px solid #ddd;
|
|
border-radius: 4px;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.backup-header,
|
|
.backup-row {
|
|
display: grid;
|
|
grid-template-columns: 2fr 1.5fr 1fr 1fr 1fr 2fr;
|
|
gap: 15px;
|
|
padding: 15px;
|
|
align-items: center;
|
|
}
|
|
|
|
.backup-header {
|
|
background: #f9f9f9;
|
|
font-weight: 600;
|
|
border-bottom: 1px solid #ddd;
|
|
}
|
|
|
|
.backup-row {
|
|
border-bottom: 1px solid #eee;
|
|
}
|
|
|
|
.backup-row:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
.backup-row:hover {
|
|
background: #f9f9f9;
|
|
}
|
|
|
|
.backup-description {
|
|
font-size: 12px;
|
|
color: #666;
|
|
font-style: italic;
|
|
}
|
|
|
|
.age {
|
|
font-size: 12px;
|
|
color: #666;
|
|
}
|
|
|
|
.backup-type-badge,
|
|
.storage-badge {
|
|
padding: 4px 8px;
|
|
border-radius: 3px;
|
|
font-size: 11px;
|
|
font-weight: bold;
|
|
text-transform: uppercase;
|
|
}
|
|
|
|
.backup-type-badge {
|
|
background: #e1f5fe;
|
|
color: #0277bd;
|
|
}
|
|
|
|
.storage-badge.local {
|
|
background: #e8f5e8;
|
|
color: #2e7d32;
|
|
}
|
|
|
|
.storage-badge.s3 {
|
|
background: #fff3e0;
|
|
color: #ef6c00;
|
|
}
|
|
|
|
.col-actions {
|
|
display: flex;
|
|
gap: 5px;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.restore-warning,
|
|
.warning-box {
|
|
background: #fff2cd;
|
|
border: 1px solid #f0ad4e;
|
|
border-radius: 4px;
|
|
padding: 15px;
|
|
margin-bottom: 20px;
|
|
display: flex;
|
|
align-items: flex-start;
|
|
gap: 10px;
|
|
}
|
|
|
|
.danger-box {
|
|
background: #f8d7da;
|
|
border: 1px solid #dc3545;
|
|
border-radius: 4px;
|
|
padding: 15px;
|
|
margin-bottom: 20px;
|
|
display: flex;
|
|
align-items: flex-start;
|
|
gap: 10px;
|
|
}
|
|
|
|
.restore-options,
|
|
.confirmation-section {
|
|
margin: 20px 0;
|
|
padding: 15px;
|
|
background: #f9f9f9;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.advanced-operation {
|
|
margin-bottom: 30px;
|
|
padding: 20px;
|
|
border: 1px solid #ddd;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.advanced-operation h4 {
|
|
margin-top: 0;
|
|
}
|
|
|
|
.settings-section {
|
|
margin-bottom: 30px;
|
|
padding-bottom: 20px;
|
|
border-bottom: 1px solid #eee;
|
|
}
|
|
|
|
.settings-section:last-child {
|
|
border-bottom: none;
|
|
}
|
|
|
|
.log-filters {
|
|
display: flex;
|
|
gap: 10px;
|
|
margin-bottom: 15px;
|
|
align-items: center;
|
|
}
|
|
|
|
.log-loading {
|
|
text-align: center;
|
|
padding: 40px;
|
|
color: #666;
|
|
}
|
|
|
|
.log-entry {
|
|
padding: 10px;
|
|
border-bottom: 1px solid #eee;
|
|
font-family: monospace;
|
|
}
|
|
|
|
.log-entry.level-error,
|
|
.log-entry.level-critical {
|
|
background: #ffeaea;
|
|
border-left: 3px solid #dc3545;
|
|
}
|
|
|
|
.log-entry.level-warning {
|
|
background: #fff3cd;
|
|
border-left: 3px solid #ffc107;
|
|
}
|
|
|
|
.log-entry.level-info {
|
|
background: #d1ecf1;
|
|
border-left: 3px solid #17a2b8;
|
|
}
|
|
|
|
@media (max-width: 768px) {
|
|
.form-row {
|
|
grid-template-columns: 1fr;
|
|
}
|
|
|
|
.backup-header,
|
|
.backup-row {
|
|
grid-template-columns: 1fr;
|
|
gap: 10px;
|
|
}
|
|
|
|
.col-actions {
|
|
justify-content: flex-start;
|
|
}
|
|
}
|
|
</style>
|
|
|
|
<script>
|
|
jQuery(document).ready(function($) {
|
|
// Tab switching
|
|
$('.backup-tabs .nav-tab').on('click', function(e) {
|
|
e.preventDefault();
|
|
|
|
const target = $(this).attr('href');
|
|
|
|
$('.backup-tabs .nav-tab').removeClass('nav-tab-active');
|
|
$(this).addClass('nav-tab-active');
|
|
|
|
$('.tab-content').removeClass('active');
|
|
$(target).addClass('active');
|
|
});
|
|
|
|
// Toggle advanced options
|
|
$('#toggle-advanced').on('click', function() {
|
|
$('.advanced-options').toggle();
|
|
});
|
|
|
|
// Show/hide schedule options
|
|
$('input[name="schedule_enabled"]').on('change', function() {
|
|
$('.schedule-option').toggle(this.checked);
|
|
}).trigger('change');
|
|
|
|
// Show/hide notification options
|
|
$('input[name="email_notifications"]').on('change', function() {
|
|
$('.notification-option').toggle(this.checked);
|
|
}).trigger('change');
|
|
|
|
// Create backup form
|
|
$('#create-backup-form').on('submit', function(e) {
|
|
e.preventDefault();
|
|
createBackup();
|
|
});
|
|
|
|
// Restore preparation
|
|
$('#show-restore-confirmation').on('click', function() {
|
|
if ($('#restore_backup_id').val()) {
|
|
$('.confirmation-section').show();
|
|
$('#restore-backup-btn').show();
|
|
$(this).hide();
|
|
} else {
|
|
alert('<?php echo esc_js(__('Please select a backup to restore.', 'tigerstyle-heat')); ?>');
|
|
}
|
|
});
|
|
|
|
// Restore form
|
|
$('#restore-form').on('submit', function(e) {
|
|
e.preventDefault();
|
|
|
|
const confirmation = $('#restore_confirmation').val();
|
|
if (confirmation !== 'CONFIRM RESTORE') {
|
|
alert('<?php echo esc_js(__('Please type "CONFIRM RESTORE" to proceed.', 'tigerstyle-heat')); ?>');
|
|
return;
|
|
}
|
|
|
|
restoreBackup();
|
|
});
|
|
|
|
// WordPress reset
|
|
$('#wordpress-reset-form').on('submit', function(e) {
|
|
e.preventDefault();
|
|
|
|
const confirmation = $('#wordpress-reset-confirmation').val();
|
|
if (confirmation !== 'RESET_WORDPRESS') {
|
|
alert('<?php echo esc_js(__('Please type "RESET_WORDPRESS" to confirm.', 'tigerstyle-heat')); ?>');
|
|
return;
|
|
}
|
|
|
|
resetWordPress();
|
|
});
|
|
|
|
// Generate reset code
|
|
$('#generate-reset-code').on('click', function() {
|
|
generateResetCode();
|
|
});
|
|
|
|
// Database reset
|
|
$('#database-reset-form').on('submit', function(e) {
|
|
e.preventDefault();
|
|
resetDatabase();
|
|
});
|
|
|
|
// Test S3 connection
|
|
$('#test-s3-connection').on('click', function() {
|
|
testS3Connection();
|
|
});
|
|
|
|
// Backup actions
|
|
$(document).on('click', '.restore-backup', function() {
|
|
const backupId = $(this).data('backup-id');
|
|
$('#restore_backup_id').val(backupId);
|
|
$('.backup-tabs .nav-tab[href="#restore"]').click();
|
|
});
|
|
|
|
$(document).on('click', '.validate-backup', function() {
|
|
const backupId = $(this).data('backup-id');
|
|
validateBackup(backupId);
|
|
});
|
|
|
|
$(document).on('click', '.delete-backup', function() {
|
|
const backupId = $(this).data('backup-id');
|
|
if (confirm('<?php echo esc_js(__('Are you sure you want to delete this backup? This action cannot be undone.', 'tigerstyle-heat')); ?>')) {
|
|
deleteBackup(backupId);
|
|
}
|
|
});
|
|
|
|
// Load logs on tab switch
|
|
$('.backup-tabs .nav-tab[href="#logs"]').on('click', function() {
|
|
loadLogs();
|
|
});
|
|
|
|
// Refresh buttons
|
|
$('#refresh-backups').on('click', function() {
|
|
location.reload();
|
|
});
|
|
|
|
$('#refresh-logs').on('click', function() {
|
|
loadLogs();
|
|
});
|
|
|
|
// Functions
|
|
function createBackup() {
|
|
const formData = new FormData(document.getElementById('create-backup-form'));
|
|
|
|
$('#create-backup-btn').prop('disabled', true);
|
|
$('#backup-progress').show();
|
|
|
|
$.ajax({
|
|
url: ajaxurl,
|
|
type: 'POST',
|
|
data: {
|
|
action: 'tigerstyle_create_backup',
|
|
nonce: $('#tigerstyle_backup_nonce').val(),
|
|
backup_type: formData.get('backup_type'),
|
|
compression: formData.get('compression'),
|
|
storage_location: formData.get('storage_location'),
|
|
description: formData.get('description'),
|
|
include_files: $('input[name="backup_type"]').val() !== 'database_only',
|
|
include_database: $('input[name="backup_type"]').val() !== 'files_only'
|
|
},
|
|
success: function(response) {
|
|
if (response.success) {
|
|
$('#backup-id-display').text(response.data.backup_id);
|
|
$('#backup-start-time').text(new Date().toLocaleString());
|
|
|
|
// Start progress tracking
|
|
trackBackupProgress(response.data.backup_id);
|
|
} else {
|
|
alert('Backup failed: ' + response.data);
|
|
$('#backup-progress').hide();
|
|
$('#create-backup-btn').prop('disabled', false);
|
|
}
|
|
},
|
|
error: function() {
|
|
alert('<?php echo esc_js(__('Network error occurred.', 'tigerstyle-heat')); ?>');
|
|
$('#backup-progress').hide();
|
|
$('#create-backup-btn').prop('disabled', false);
|
|
}
|
|
});
|
|
}
|
|
|
|
function trackBackupProgress(backupId) {
|
|
const interval = setInterval(function() {
|
|
$.ajax({
|
|
url: ajaxurl,
|
|
type: 'POST',
|
|
data: {
|
|
action: 'tigerstyle_backup_progress',
|
|
nonce: $('#tigerstyle_backup_nonce').val(),
|
|
operation_id: backupId
|
|
},
|
|
success: function(response) {
|
|
if (response.success) {
|
|
const progress = response.data;
|
|
$('.progress-fill').css('width', progress.percentage + '%');
|
|
$('.progress-text').text(progress.percentage + '%');
|
|
$('.progress-message').text(progress.message);
|
|
|
|
if (progress.percentage >= 100) {
|
|
clearInterval(interval);
|
|
$('#create-backup-btn').prop('disabled', false);
|
|
setTimeout(function() {
|
|
location.reload();
|
|
}, 2000);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}, 2000);
|
|
}
|
|
|
|
function restoreBackup() {
|
|
const formData = new FormData(document.getElementById('restore-form'));
|
|
|
|
$('#restore-backup-btn').prop('disabled', true);
|
|
$('#restore-progress').show();
|
|
|
|
$.ajax({
|
|
url: ajaxurl,
|
|
type: 'POST',
|
|
data: {
|
|
action: 'tigerstyle_restore_backup',
|
|
nonce: $('#tigerstyle_restore_nonce').val(),
|
|
backup_id: formData.get('backup_id'),
|
|
restore_files: formData.get('restore_files') ? true : false,
|
|
restore_database: formData.get('restore_database') ? true : false
|
|
},
|
|
success: function(response) {
|
|
if (response.success) {
|
|
// Start progress tracking
|
|
trackRestoreProgress(response.data.restore_id);
|
|
} else {
|
|
alert('Restore failed: ' + response.data);
|
|
$('#restore-progress').hide();
|
|
$('#restore-backup-btn').prop('disabled', false);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function trackRestoreProgress(restoreId) {
|
|
const interval = setInterval(function() {
|
|
$.ajax({
|
|
url: ajaxurl,
|
|
type: 'POST',
|
|
data: {
|
|
action: 'tigerstyle_backup_progress',
|
|
nonce: $('#tigerstyle_backup_nonce').val(),
|
|
operation_id: restoreId
|
|
},
|
|
success: function(response) {
|
|
if (response.success) {
|
|
const progress = response.data;
|
|
$('#restore-progress .progress-fill').css('width', progress.percentage + '%');
|
|
$('#restore-progress .progress-text').text(progress.percentage + '%');
|
|
$('#restore-progress .progress-message').text(progress.message);
|
|
|
|
if (progress.percentage >= 100) {
|
|
clearInterval(interval);
|
|
alert('<?php echo esc_js(__('Restore completed successfully!', 'tigerstyle-heat')); ?>');
|
|
location.reload();
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}, 2000);
|
|
}
|
|
|
|
function validateBackup(backupId) {
|
|
$.ajax({
|
|
url: ajaxurl,
|
|
type: 'POST',
|
|
data: {
|
|
action: 'tigerstyle_validate_backup',
|
|
nonce: $('#tigerstyle_backup_nonce').val(),
|
|
backup_id: backupId
|
|
},
|
|
success: function(response) {
|
|
if (response.success) {
|
|
alert('<?php echo esc_js(__('Backup validation passed!', 'tigerstyle-heat')); ?>');
|
|
} else {
|
|
alert('Backup validation failed: ' + response.data);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function deleteBackup(backupId) {
|
|
$.ajax({
|
|
url: ajaxurl,
|
|
type: 'POST',
|
|
data: {
|
|
action: 'tigerstyle_delete_backup',
|
|
nonce: $('#tigerstyle_backup_nonce').val(),
|
|
backup_id: backupId
|
|
},
|
|
success: function(response) {
|
|
if (response.success) {
|
|
$('[data-backup-id="' + backupId + '"]').remove();
|
|
} else {
|
|
alert('Delete failed: ' + response.data);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function resetWordPress() {
|
|
$.ajax({
|
|
url: ajaxurl,
|
|
type: 'POST',
|
|
data: {
|
|
action: 'tigerstyle_reset_wordpress',
|
|
nonce: $('#tigerstyle_reset_nonce').val(),
|
|
confirmation: $('#wordpress-reset-confirmation').val()
|
|
},
|
|
success: function(response) {
|
|
if (response.success) {
|
|
alert('<?php echo esc_js(__('WordPress content reset completed!', 'tigerstyle-heat')); ?>');
|
|
$('#wordpress-reset-confirmation').val('');
|
|
} else {
|
|
alert('Reset failed: ' + response.data);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function generateResetCode() {
|
|
$.ajax({
|
|
url: ajaxurl,
|
|
type: 'POST',
|
|
data: {
|
|
action: 'tigerstyle_generate_reset_code',
|
|
nonce: $('#tigerstyle_db_reset_nonce').val()
|
|
},
|
|
success: function(response) {
|
|
if (response.success) {
|
|
$('#reset-code-display').text(response.data.code);
|
|
$('#reset-code-section').show();
|
|
$('#generate-reset-code').hide();
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function resetDatabase() {
|
|
$.ajax({
|
|
url: ajaxurl,
|
|
type: 'POST',
|
|
data: {
|
|
action: 'tigerstyle_reset_database',
|
|
nonce: $('#tigerstyle_db_reset_nonce').val(),
|
|
confirmation_code: $('#database-reset-code').val(),
|
|
final_confirmation: $('#database-reset-final').val()
|
|
},
|
|
success: function(response) {
|
|
if (response.success) {
|
|
alert('<?php echo esc_js(__('Database reset completed!', 'tigerstyle-heat')); ?>');
|
|
location.reload();
|
|
} else {
|
|
alert('Reset failed: ' + response.data);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function testS3Connection() {
|
|
$('#test-s3-connection').prop('disabled', true);
|
|
$('#s3-test-result').html('<span class="spinner is-active"></span>');
|
|
|
|
$.ajax({
|
|
url: ajaxurl,
|
|
type: 'POST',
|
|
data: {
|
|
action: 'tigerstyle_test_s3_connection',
|
|
nonce: $('#tigerstyle_backup_nonce').val(),
|
|
s3_bucket: $('input[name="s3_bucket"]').val(),
|
|
s3_access_key: $('input[name="s3_access_key"]').val(),
|
|
s3_secret_key: $('input[name="s3_secret_key"]').val(),
|
|
s3_region: $('input[name="s3_region"]').val(),
|
|
s3_endpoint: $('input[name="s3_endpoint"]').val()
|
|
},
|
|
success: function(response) {
|
|
$('#test-s3-connection').prop('disabled', false);
|
|
|
|
if (response.success) {
|
|
$('#s3-test-result').html('<span style="color: green;">✓ Connection successful</span>');
|
|
} else {
|
|
$('#s3-test-result').html('<span style="color: red;">✗ ' + response.data + '</span>');
|
|
}
|
|
},
|
|
error: function() {
|
|
$('#test-s3-connection').prop('disabled', false);
|
|
$('#s3-test-result').html('<span style="color: red;">✗ Network error</span>');
|
|
}
|
|
});
|
|
}
|
|
|
|
function loadLogs() {
|
|
$('#logs-container').html('<div class="log-loading"><span class="spinner is-active"></span> <?php echo esc_js(__('Loading logs...', 'tigerstyle-heat')); ?></div>');
|
|
|
|
$.ajax({
|
|
url: ajaxurl,
|
|
type: 'POST',
|
|
data: {
|
|
action: 'tigerstyle_get_backup_logs',
|
|
nonce: $('#tigerstyle_backup_nonce').val(),
|
|
level: $('#log-level-filter').val(),
|
|
limit: 100
|
|
},
|
|
success: function(response) {
|
|
if (response.success) {
|
|
displayLogs(response.data);
|
|
} else {
|
|
$('#logs-container').html('<p>Failed to load logs.</p>');
|
|
}
|
|
},
|
|
error: function() {
|
|
$('#logs-container').html('<p>Network error loading logs.</p>');
|
|
}
|
|
});
|
|
}
|
|
|
|
function displayLogs(logs) {
|
|
if (logs.length === 0) {
|
|
$('#logs-container').html('<p><?php echo esc_js(__('No logs found.', 'tigerstyle-heat')); ?></p>');
|
|
return;
|
|
}
|
|
|
|
let html = '<div class="logs-list">';
|
|
logs.forEach(function(log) {
|
|
html += '<div class="log-entry level-' + log.level + '">';
|
|
html += '<div class="log-meta">';
|
|
html += '<span class="log-time">' + log.created_at_formatted + '</span>';
|
|
html += '<span class="log-level level-' + log.level + '">' + log.level.toUpperCase() + '</span>';
|
|
html += '</div>';
|
|
html += '<div class="log-message">' + log.message + '</div>';
|
|
if (log.context && Object.keys(log.context).length > 0) {
|
|
html += '<div class="log-context"><pre>' + JSON.stringify(log.context, null, 2) + '</pre></div>';
|
|
}
|
|
html += '</div>';
|
|
});
|
|
html += '</div>';
|
|
|
|
$('#logs-container').html(html);
|
|
}
|
|
});
|
|
</script>
|