plugin = $plugin; $this->security = $plugin->get_security(); $this->load_asset_manifest(); $this->init_hooks(); } /** * Initialize WordPress hooks */ private function init_hooks() { add_action('admin_menu', [$this, 'register_admin_pages']); add_action('admin_enqueue_scripts', [$this, 'enqueue_admin_assets']); add_action('admin_init', [$this, 'handle_admin_actions']); add_action('wp_ajax_tigerstyle_life9_render_page', [$this, 'render_astro_page']); // Add admin notices add_action('admin_notices', [$this, 'display_admin_notices']); // Add plugin action links add_filter('plugin_action_links_' . TIGERSTYLE_LIFE9_BASENAME, [$this, 'add_plugin_action_links']); } /** * Load Astro asset manifest */ private function load_asset_manifest() { $manifest_path = TIGERSTYLE_LIFE9_PATH . 'admin/assets/dist/manifest.json'; if (file_exists($manifest_path)) { $manifest_content = file_get_contents($manifest_path); $this->asset_manifest = json_decode($manifest_content, true) ?: []; } } /** * Register admin menu pages */ public function register_admin_pages() { // Check user capability if (!current_user_can('manage_options')) { return; } // Main menu page add_menu_page( '🐾 Life Tracker Dashboard', // Page title 'TigerStyle Life9', // Menu title 'manage_options', // Capability 'tigerstyle-life9', // Menu slug [$this, 'render_dashboard_page'], // Callback 'dashicons-backup', // Icon (more appropriate for backups) 30 // Position ); // Life Saving page add_submenu_page( 'tigerstyle-life9', // Parent slug '💾 Save a Life', // Page title '💾 Save a Life', // Menu title 'manage_options', // Capability 'tigerstyle-life9-backup', // Menu slug [$this, 'render_backup_page'] // Callback ); // Life Revival page add_submenu_page( 'tigerstyle-life9', // Parent slug '🔄 Revive a Life', // Page title '🔄 Revive a Life', // Menu title 'manage_options', // Capability 'tigerstyle-life9-restore', // Menu slug [$this, 'render_restore_page'] // Callback ); // Life Chronicles page add_submenu_page( 'tigerstyle-life9', // Parent slug '📚 Life Chronicles', // Page title '📚 Life Chronicles', // Menu title 'manage_options', // Capability 'tigerstyle-life9-backups', // Menu slug [$this, 'render_backups_page'] // Callback ); // Territory Settings page add_submenu_page( 'tigerstyle-life9', // Parent slug '🏠 Territory Settings', // Page title '🏠 Territory Settings', // Menu title 'manage_options', // Capability 'tigerstyle-life9-settings', // Menu slug [$this, 'render_settings_page'] // Callback ); // Rename first submenu to cat-themed name global $submenu; if (isset($submenu['tigerstyle-life9'])) { $submenu['tigerstyle-life9'][0][0] = '🐾 Life Tracker'; } } /** * Enqueue admin assets * * @param string $hook_suffix Current admin page hook suffix */ public function enqueue_admin_assets($hook_suffix) { // Only load on our admin pages if (!$this->is_tigerstyle_admin_page($hook_suffix)) { return; } // Enqueue WordPress core dependencies wp_enqueue_script('jquery'); wp_enqueue_media(); // Enqueue Alpine.js wp_enqueue_script( 'alpine-js', 'https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js', [], '3.13.3', true ); // Defer Alpine.js execution add_filter('script_loader_tag', function($tag, $handle) { if ($handle === 'alpine-js') { return str_replace(' src', ' defer src', $tag); } return $tag; }, 10, 2); // Enqueue Astro-generated assets $this->enqueue_astro_assets(); // Enqueue admin styles wp_enqueue_style( 'tigerstyle-life9-admin', TIGERSTYLE_LIFE9_URL . 'admin/assets/css/admin.css', [], TIGERSTYLE_LIFE9_VERSION ); // Localize script for AJAX with cat-themed messages wp_localize_script('jquery', 'tigerStyleLife9', [ 'ajaxUrl' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('tigerstyle_life9_ajax'), 'pluginUrl' => TIGERSTYLE_LIFE9_URL, 'currentPage' => $this->get_current_page_slug($hook_suffix), 'capabilities' => [ 'backup' => current_user_can('manage_options'), 'restore' => current_user_can('manage_options'), 'settings' => current_user_can('manage_options') ], 'strings' => [ 'confirmDelete' => __('😿 Are you sure you want to permanently lose this life? This cannot be undone!', 'tigerstyle-life9'), 'confirmRestore' => __('🔄 This will revive your site to this saved life. Current state will be overwritten. Ready to pounce?', 'tigerstyle-life9'), 'processing' => __('🐾 Stalking through the process...', 'tigerstyle-life9'), 'error' => __('😿 Oops! Cat got stuck. Please try again.', 'tigerstyle-life9'), 'scanning' => __('🔍 Stalking through your files...', 'tigerstyle-life9'), 'compressing' => __('📦 Packing your territory efficiently...', 'tigerstyle-life9'), 'uploading' => __('☁️ Moving to your backup lair...', 'tigerstyle-life9'), 'completed' => __('😻 Mission accomplished! Life saved successfully.', 'tigerstyle-life9'), 'warning' => __('⚠️ Something smells fishy in your files...', 'tigerstyle-life9'), 'ninthLife' => __('🛡️ Nine lives protection activated!', 'tigerstyle-life9'), 'territoryScan' => __('🏠 Territory backup complete - domain secured!', 'tigerstyle-life9'), 'memoryPreservation' => __('🧠 Preserving digital memories...', 'tigerstyle-life9'), 'catReflexes' => __('⚡ Pouncing on database changes...', 'tigerstyle-life9') ] ]); // Add Alpine.js WordPress integration helper $this->add_alpine_wordpress_helper(); } /** * Enqueue Astro-generated assets */ private function enqueue_astro_assets() { if (empty($this->asset_manifest)) { return; } // Enqueue CSS files foreach ($this->asset_manifest as $file => $data) { if (isset($data['isEntry']) && $data['isEntry'] && isset($data['css'])) { foreach ($data['css'] as $css_file) { wp_enqueue_style( 'tigerstyle-astro-' . basename($css_file, '.css'), TIGERSTYLE_LIFE9_URL . 'admin/assets/dist/' . $css_file, [], TIGERSTYLE_LIFE9_VERSION ); } } } // Enqueue JS files foreach ($this->asset_manifest as $file => $data) { if (isset($data['isEntry']) && $data['isEntry']) { wp_enqueue_script( 'tigerstyle-astro-' . basename($file, '.js'), TIGERSTYLE_LIFE9_URL . 'admin/assets/dist/' . $file, ['jquery', 'alpine-js'], TIGERSTYLE_LIFE9_VERSION, true ); } } } /** * Add Alpine.js WordPress helper */ private function add_alpine_wordpress_helper() { ?> 'dashboard', 'tigerstyle-life9_page_tigerstyle-life9-backup' => 'backup', 'tigerstyle-life9_page_tigerstyle-life9-restore' => 'restore', 'tigerstyle-life9_page_tigerstyle-life9-backups' => 'backups', 'tigerstyle-life9_page_tigerstyle-life9-settings' => 'settings' ]; return $page_map[$hook_suffix] ?? 'dashboard'; } /** * Render dashboard page */ public function render_dashboard_page() { $this->render_page('admin-dashboard'); } /** * Render backup page */ public function render_backup_page() { $this->render_page('backup'); } /** * Render restore page */ public function render_restore_page() { $this->render_page('restore'); } /** * Render backups management page */ public function render_backups_page() { $this->render_page('backups'); } /** * Render settings page */ public function render_settings_page() { $this->render_page('settings'); } /** * Render Astro page * * @param string $page_name Page name */ private function render_page($page_name) { // Security check if (!current_user_can('manage_options')) { wp_die(__('You do not have sufficient permissions to access this page.', 'tigerstyle-life9')); } // Verify nonce for AJAX requests if (wp_doing_ajax()) { check_ajax_referer('tigerstyle_life9_ajax', '_wpnonce'); } // For now, render the Astro pages as PHP templates // In a production version, you would use a proper Astro SSR setup $astro_file = TIGERSTYLE_LIFE9_PATH . "src/astro/pages/{$page_name}.astro"; if (file_exists($astro_file)) { // Convert Astro to WordPress-compatible output $this->render_astro_as_php($astro_file, $page_name); } else { // Fallback if Astro file doesn't exist $this->render_fallback_page($page_name); } } /** * Render Astro file as PHP (simplified conversion) * * @param string $astro_file Path to Astro file * @param string $page_name Page name for context */ private function render_astro_as_php($astro_file, $page_name) { // Read the Astro file content $astro_content = file_get_contents($astro_file); // Extract the HTML content (everything after the ---) $parts = preg_split('/^---$/m', $astro_content); $html_content = isset($parts[2]) ? $parts[2] : (isset($parts[1]) ? $parts[1] : $astro_content); // Process template variables $html_content = str_replace('{{PLUGIN_URL}}', TIGERSTYLE_LIFE9_URL, $html_content); $html_content = str_replace('{{ADMIN_URL}}', admin_url(), $html_content); $html_content = str_replace('{{AJAX_URL}}', admin_url('admin-ajax.php'), $html_content); // Add WordPress admin wrapper echo '