init(); } /** * Initialize module */ private function init() { // Load dependencies $this->load_dependencies(); // Defer backup system initialization until needed to avoid database errors during startup add_action('admin_init', array($this, 'init_backup_system'), 10); // Setup hooks $this->setup_hooks(); } /** * Initialize backup system components */ public function init_backup_system() { // Only initialize if we're in admin and not already initialized if (!is_admin() || $this->backup_engine) { return; } // Initialize components $this->backup_engine = TigerStyleSEO_Backup_Engine::instance(); $this->restore_engine = TigerStyleSEO_Restore_Engine::instance(); $this->storage_manager = TigerStyleSEO_Storage_Manager::instance(); $this->logger = TigerStyleSEO_Backup_Logger::instance(); $this->validator = TigerStyleSEO_Backup_Validator::instance(); } /** * Load dependencies */ private function load_dependencies() { require_once TIGERSTYLE_HEAT_PLUGIN_DIR . 'includes/backup/class-backup-engine.php'; require_once TIGERSTYLE_HEAT_PLUGIN_DIR . 'includes/backup/class-restore-engine.php'; require_once TIGERSTYLE_HEAT_PLUGIN_DIR . 'includes/backup/class-storage-manager.php'; require_once TIGERSTYLE_HEAT_PLUGIN_DIR . 'includes/backup/class-backup-logger.php'; require_once TIGERSTYLE_HEAT_PLUGIN_DIR . 'includes/backup/class-backup-validator.php'; require_once TIGERSTYLE_HEAT_PLUGIN_DIR . 'includes/backup/class-backup-scheduler.php'; require_once TIGERSTYLE_HEAT_PLUGIN_DIR . 'includes/backup/class-compression-manager.php'; require_once TIGERSTYLE_HEAT_PLUGIN_DIR . 'includes/backup/ajax-handlers.php'; } /** * Setup WordPress hooks */ private function setup_hooks() { // AJAX handlers add_action('wp_ajax_tigerstyle_create_backup', array($this, 'ajax_create_backup')); add_action('wp_ajax_tigerstyle_restore_backup', array($this, 'ajax_restore_backup')); add_action('wp_ajax_tigerstyle_delete_backup', array($this, 'ajax_delete_backup')); add_action('wp_ajax_tigerstyle_download_backup', array($this, 'ajax_download_backup')); add_action('wp_ajax_tigerstyle_upload_backup', array($this, 'ajax_upload_backup')); add_action('wp_ajax_tigerstyle_reset_wordpress', array($this, 'ajax_reset_wordpress')); add_action('wp_ajax_tigerstyle_reset_database', array($this, 'ajax_reset_database')); add_action('wp_ajax_tigerstyle_backup_progress', array($this, 'ajax_backup_progress')); add_action('wp_ajax_tigerstyle_validate_backup', array($this, 'ajax_validate_backup')); // Scheduled backup hooks add_action('tigerstyle_backup_scheduled', array($this, 'run_scheduled_backup')); add_action('tigerstyle_backup_cleanup', array($this, 'cleanup_old_backups')); // Admin hooks add_action('admin_post_tigerstyle_backup_settings', array($this, 'save_backup_settings')); add_action('admin_notices', array($this, 'display_backup_notices')); // Cron hooks if (!wp_next_scheduled('tigerstyle_backup_cleanup')) { wp_schedule_event(time(), 'daily', 'tigerstyle_backup_cleanup'); } } /** * Render admin page */ public function render_admin_page() { if (!current_user_can('manage_options')) { wp_die(__('You do not have sufficient permissions to access this page.', 'tigerstyle-heat')); } // Handle form submissions $this->handle_form_submissions(); // Get backup list $backups = $this->get_backup_list(); $storage_stats = $this->storage_manager->get_storage_stats(); $compression_methods = $this->get_available_compression_methods(); include TIGERSTYLE_HEAT_PLUGIN_DIR . 'admin/pages/backup-restore.php'; } /** * Handle form submissions */ private function handle_form_submissions() { if (!isset($_POST['tigerstyle_backup_nonce']) || !wp_verify_nonce($_POST['tigerstyle_backup_nonce'], 'tigerstyle_backup_action')) { return; } $action = sanitize_text_field($_POST['backup_action']); switch ($action) { case 'create_backup': $this->handle_create_backup(); break; case 'restore_backup': $this->handle_restore_backup(); break; case 'delete_backup': $this->handle_delete_backup(); break; case 'save_settings': $this->handle_save_settings(); break; } } /** * Create backup via AJAX */ public function ajax_create_backup() { check_ajax_referer('tigerstyle_backup_action', 'nonce'); if (!current_user_can('manage_options')) { wp_send_json_error('Insufficient permissions'); } $backup_type = sanitize_text_field($_POST['backup_type']); $compression = sanitize_text_field($_POST['compression']); $storage_location = sanitize_text_field($_POST['storage_location']); $include_files = isset($_POST['include_files']) ? (bool)$_POST['include_files'] : true; $include_database = isset($_POST['include_database']) ? (bool)$_POST['include_database'] : true; try { $backup_id = $this->backup_engine->create_backup(array( 'type' => $backup_type, 'compression' => $compression, 'storage_location' => $storage_location, 'include_files' => $include_files, 'include_database' => $include_database, 'description' => sanitize_textarea_field($_POST['description']) )); wp_send_json_success(array( 'backup_id' => $backup_id, 'message' => __('Backup started successfully', 'tigerstyle-heat') )); } catch (Exception $e) { $this->logger->error('Backup creation failed: ' . $e->getMessage()); wp_send_json_error($e->getMessage()); } } /** * Restore backup via AJAX */ public function ajax_restore_backup() { check_ajax_referer('tigerstyle_backup_action', 'nonce'); if (!current_user_can('manage_options')) { wp_send_json_error('Insufficient permissions'); } $backup_id = sanitize_text_field($_POST['backup_id']); $restore_files = isset($_POST['restore_files']) ? (bool)$_POST['restore_files'] : true; $restore_database = isset($_POST['restore_database']) ? (bool)$_POST['restore_database'] : true; try { // Validate backup first if (!$this->validator->validate_backup($backup_id)) { throw new Exception(__('Invalid or corrupted backup file', 'tigerstyle-heat')); } $restore_id = $this->restore_engine->restore_backup(array( 'backup_id' => $backup_id, 'restore_files' => $restore_files, 'restore_database' => $restore_database )); wp_send_json_success(array( 'restore_id' => $restore_id, 'message' => __('Restore started successfully', 'tigerstyle-heat') )); } catch (Exception $e) { $this->logger->error('Restore failed: ' . $e->getMessage()); wp_send_json_error($e->getMessage()); } } /** * Reset WordPress (remove default pages/posts) */ public function ajax_reset_wordpress() { check_ajax_referer('tigerstyle_backup_action', 'nonce'); if (!current_user_can('manage_options')) { wp_send_json_error('Insufficient permissions'); } $confirmation = sanitize_text_field($_POST['confirmation']); if ($confirmation !== 'RESET_WORDPRESS') { wp_send_json_error(__('Invalid confirmation text', 'tigerstyle-heat')); } try { $this->reset_wordpress_content(); wp_send_json_success(__('WordPress content reset successfully', 'tigerstyle-heat')); } catch (Exception $e) { wp_send_json_error($e->getMessage()); } } /** * Reset database (complete database wipe) */ public function ajax_reset_database() { check_ajax_referer('tigerstyle_backup_action', 'nonce'); if (!current_user_can('manage_options')) { wp_send_json_error('Insufficient permissions'); } $confirmation_code = sanitize_text_field($_POST['confirmation_code']); $expected_code = get_transient('tigerstyle_reset_code_' . get_current_user_id()); if (!$expected_code || $confirmation_code !== $expected_code) { wp_send_json_error(__('Invalid confirmation code', 'tigerstyle-heat')); } $final_confirmation = sanitize_text_field($_POST['final_confirmation']); if ($final_confirmation !== 'YES_DELETE_EVERYTHING') { wp_send_json_error(__('Final confirmation required', 'tigerstyle-heat')); } try { $this->reset_database_completely(); delete_transient('tigerstyle_reset_code_' . get_current_user_id()); wp_send_json_success(__('Database reset successfully', 'tigerstyle-heat')); } catch (Exception $e) { wp_send_json_error($e->getMessage()); } } /** * Get backup progress */ public function ajax_backup_progress() { check_ajax_referer('tigerstyle_backup_action', 'nonce'); $operation_id = sanitize_text_field($_POST['operation_id']); $progress = get_transient('tigerstyle_backup_progress_' . $operation_id); if ($progress === false) { wp_send_json_error(__('Operation not found', 'tigerstyle-heat')); } wp_send_json_success($progress); } /** * Get list of available backups */ public function get_backup_list() { return $this->storage_manager->list_backups(); } /** * Get available compression methods */ public function get_available_compression_methods() { $methods = array(); if (class_exists('ZipArchive')) { $methods['zip'] = __('ZIP Compression', 'tigerstyle-heat'); } if (function_exists('gzopen')) { $methods['tar.gz'] = __('TAR.GZ Compression', 'tigerstyle-heat'); } if (function_exists('bzopen')) { $methods['tar.bz2'] = __('TAR.BZ2 Compression', 'tigerstyle-heat'); } if (empty($methods)) { $methods['none'] = __('No Compression (Fallback)', 'tigerstyle-heat'); } return $methods; } /** * Reset WordPress content (default pages/posts) */ private function reset_wordpress_content() { global $wpdb; // Create backup before reset $backup_id = $this->backup_engine->create_backup(array( 'type' => 'quick', 'description' => 'Auto-backup before WordPress reset', 'include_files' => false, 'include_database' => true )); // Delete default posts $default_posts = get_posts(array( 'post_type' => array('post', 'page'), 'posts_per_page' => -1, 'post_status' => 'any' )); foreach ($default_posts as $post) { wp_delete_post($post->ID, true); } // Delete default comments $wpdb->query("DELETE FROM {$wpdb->comments}"); $wpdb->query("DELETE FROM {$wpdb->commentmeta}"); // Reset comment count $wpdb->query("UPDATE {$wpdb->posts} SET comment_count = 0"); // Clear caches wp_cache_flush(); $this->logger->info('WordPress content reset completed', array( 'backup_id' => $backup_id, 'posts_deleted' => count($default_posts) )); } /** * Reset database completely */ private function reset_database_completely() { global $wpdb; // Get all tables $tables = $wpdb->get_col("SHOW TABLES"); // Disable foreign key checks $wpdb->query("SET FOREIGN_KEY_CHECKS = 0"); try { // Drop all tables foreach ($tables as $table) { $wpdb->query("DROP TABLE IF EXISTS `{$table}`"); } $this->logger->critical('Complete database reset performed', array( 'tables_dropped' => count($tables), 'user_id' => get_current_user_id() )); } finally { // Re-enable foreign key checks $wpdb->query("SET FOREIGN_KEY_CHECKS = 1"); } } /** * Generate reset confirmation code */ public function generate_reset_code() { $code = wp_generate_password(6, false, false); $code = strtoupper($code); set_transient('tigerstyle_reset_code_' . get_current_user_id(), $code, 300); // 5 minutes return $code; } /** * Display admin notices */ public function display_backup_notices() { // Check for backup failures $failed_backups = get_option('tigerstyle_failed_backups', array()); if (!empty($failed_backups)) { echo '

'; echo __('Some backup operations have failed. Please check the backup logs.', 'tigerstyle-heat'); echo '

'; } // Check storage space $storage_stats = $this->storage_manager->get_storage_stats(); if (isset($storage_stats['usage_percent']) && $storage_stats['usage_percent'] > 90) { echo '

'; echo __('Backup storage is nearly full. Consider cleaning up old backups.', 'tigerstyle-heat'); echo '

'; } } /** * Run scheduled backup */ public function run_scheduled_backup() { $settings = get_option('tigerstyle_backup_settings', array()); if (!isset($settings['schedule_enabled']) || !$settings['schedule_enabled']) { return; } try { $this->backup_engine->create_backup(array( 'type' => 'scheduled', 'compression' => $settings['compression'] ?? 'zip', 'storage_location' => $settings['storage_location'] ?? 'local', 'include_files' => $settings['include_files'] ?? true, 'include_database' => $settings['include_database'] ?? true, 'description' => 'Scheduled backup - ' . current_time('mysql') )); } catch (Exception $e) { $this->logger->error('Scheduled backup failed: ' . $e->getMessage()); } } /** * Cleanup old backups */ public function cleanup_old_backups() { $settings = get_option('tigerstyle_backup_settings', array()); $retention_days = $settings['retention_days'] ?? 30; $this->storage_manager->cleanup_old_backups($retention_days); } /** * Get backup settings */ public function get_backup_settings() { $defaults = array( 'compression' => 'zip', 'storage_location' => 'local', 'schedule_enabled' => false, 'schedule_frequency' => 'daily', 'retention_days' => 30, 'include_files' => true, 'include_database' => true, 'chunk_size' => 5, // MB 's3_bucket' => '', 's3_access_key' => '', 's3_secret_key' => '', 's3_region' => 'us-east-1', 's3_endpoint' => '', // For S3-compatible services 'email_notifications' => false, 'notification_email' => get_option('admin_email') ); return wp_parse_args(get_option('tigerstyle_backup_settings', array()), $defaults); } /** * Save backup settings */ public function save_backup_settings() { if (!isset($_POST['tigerstyle_backup_nonce']) || !wp_verify_nonce($_POST['tigerstyle_backup_nonce'], 'tigerstyle_backup_settings')) { wp_die(__('Security check failed', 'tigerstyle-heat')); } if (!current_user_can('manage_options')) { wp_die(__('Insufficient permissions', 'tigerstyle-heat')); } $settings = array( 'compression' => sanitize_text_field($_POST['compression']), 'storage_location' => sanitize_text_field($_POST['storage_location']), 'schedule_enabled' => isset($_POST['schedule_enabled']), 'schedule_frequency' => sanitize_text_field($_POST['schedule_frequency']), 'retention_days' => absint($_POST['retention_days']), 'include_files' => isset($_POST['include_files']), 'include_database' => isset($_POST['include_database']), 'chunk_size' => absint($_POST['chunk_size']), 's3_bucket' => sanitize_text_field($_POST['s3_bucket']), 's3_access_key' => sanitize_text_field($_POST['s3_access_key']), 's3_secret_key' => sanitize_text_field($_POST['s3_secret_key']), 's3_region' => sanitize_text_field($_POST['s3_region']), 's3_endpoint' => sanitize_url($_POST['s3_endpoint']), 'email_notifications' => isset($_POST['email_notifications']), 'notification_email' => sanitize_email($_POST['notification_email']) ); update_option('tigerstyle_backup_settings', $settings); // Update scheduled backup if settings changed if ($settings['schedule_enabled']) { wp_clear_scheduled_hook('tigerstyle_backup_scheduled'); wp_schedule_event(time(), $settings['schedule_frequency'], 'tigerstyle_backup_scheduled'); } else { wp_clear_scheduled_hook('tigerstyle_backup_scheduled'); } wp_redirect(add_query_arg('message', 'backup_settings_saved', wp_get_referer())); exit; } }