diagnostics_tab = new AI_Ready_Diagnostics_Tab(); } if (class_exists('AI_Ready_LLMS_Tab')) { $this->llms_tab = new AI_Ready_LLMS_Tab(); } // Set Agent Gate module $this->agent_gate = $agent_gate; if (class_exists('AI_Ready_Admin_Notices')) { $this->notices = new AI_Ready_Admin_Notices(); } // Register hooks add_action('admin_menu', [$this, 'add_admin_menu']); add_action('admin_init', [$this, 'register_settings']); add_action('admin_init', [$this, 'handle_form_submission']); add_action('admin_enqueue_scripts', [$this, 'enqueue_admin_scripts']); } /** * Add admin menu page */ public function add_admin_menu() { add_options_page( __('AI Ready Settings', 'ai-ready-core'), __('AI Ready', 'ai-ready-core'), 'manage_options', 'ai-ready-settings', [$this, 'admin_page_callback'] ); } /** * Register plugin settings */ public function register_settings() { // Register settings for llms.txt customization register_setting( 'ai_ready_settings', 'ai_ready_site_title', [ 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '' ] ); register_setting( 'ai_ready_settings', 'ai_ready_site_summary', [ 'type' => 'string', 'sanitize_callback' => 'sanitize_textarea_field', 'default' => '' ] ); register_setting( 'ai_ready_settings', 'ai_ready_llms_sections', [ 'type' => 'array', 'sanitize_callback' => [$this, 'sanitize_llms_sections'], 'default' => [] ] ); register_setting( 'ai_ready_settings', 'ai_ready_custom_content', [ 'type' => 'string', 'sanitize_callback' => 'sanitize_textarea_field', 'default' => '' ] ); // Register Agent Gate settings if module is available if ($this->agent_gate && method_exists($this->agent_gate, 'register_settings')) { $this->agent_gate->register_settings(); } } /** * Sanitize LLMS sections array * * @param mixed $sections The sections to sanitize * @return array Sanitized sections */ public function sanitize_llms_sections($sections) { if (!is_array($sections)) { return []; } return array_map('sanitize_text_field', $sections); } /** * Enqueue admin scripts and styles */ public function enqueue_admin_scripts($hook_suffix) { // Enqueue on all admin screens to avoid missing due to hook_suffix mismatches // Get the base URL for our assets (plugin root) $plugin_url = AI_READY_CORE_PLUGIN_URL; // Enqueue our admin script from external file wp_enqueue_script( 'ai-ready-admin-tabs', $plugin_url . 'assets/js/admin.js', array('jquery'), AI_READY_CORE_VERSION, false ); // Enqueue our admin styles from external file with cache busting wp_enqueue_style( 'ai-ready-admin-styles', $plugin_url . 'assets/css/admin.css', array(), AI_READY_CORE_VERSION . '.' . time() // Add timestamp for cache busting ); // Add debug info as inline script for troubleshooting wp_add_inline_script( 'ai-ready-admin-tabs', 'console.log("[AI Ready] Scripts enqueued successfully. JS URL: " + "' . esc_js($plugin_url . 'assets/js/admin.js') . '");', 'before' ); } /** * Verify nonce and user permissions * * @param string $nonce_action The nonce action to verify * @param string $capability The capability to check (default: manage_options) * @return bool True if verification passes, false otherwise */ private function verify_security($nonce_action = 'ai_ready_settings_nonce', $capability = 'manage_options') { // Check nonce if (!isset($_POST['_wpnonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['_wpnonce'])), $nonce_action)) { return false; } // Check user capability if (!current_user_can($capability)) { return false; } return true; } /** * Handle form submissions */ public function handle_form_submission() { if (!isset($_GET['page']) || $_GET['page'] !== 'ai-ready-settings') { return; } // Check user permissions for settings access if (!current_user_can('manage_options')) { wp_die(esc_html__('You do not have sufficient permissions to access this page.', 'ai-ready-core')); } // Handle POST form submissions with proper nonce verification if (!empty($_POST)) { // Verify nonce BEFORE accessing any POST data if (!isset($_POST['_wpnonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['_wpnonce'])), 'ai_ready_settings_nonce')) { wp_die(esc_html__('Security check failed. Please try again.', 'ai-ready-core')); } // Now safe to access POST data after nonce verification $current_tab = isset($_POST['current_tab']) ? sanitize_text_field(wp_unslash($_POST['current_tab'])) : 'diagnostics'; $redirect_params = [ 'page' => 'ai-ready-settings' ]; // Always add the tab parameter unless it's diagnostics (default) if ($current_tab !== 'diagnostics') { $redirect_params['tab'] = $current_tab; } // Handle form submission if (isset($_POST['ai_ready_submit'])) { $this->save_settings(); $redirect_params['message'] = 'settings-saved'; wp_safe_redirect(add_query_arg($redirect_params, admin_url('options-general.php'))); exit; } // Handle Agent Gate reset if (isset($_POST['ai_ready_reset'])) { $this->handle_agent_gate_reset(); $redirect_params['message'] = 'settings-reset'; wp_safe_redirect(add_query_arg($redirect_params, admin_url('options-general.php'))); exit; } // Handle remove llms.txt if (isset($_POST['ai_ready_remove_llms'])) { $this->remove_llms_txt(); $redirect_params['message'] = 'llms-removed'; wp_safe_redirect(add_query_arg($redirect_params, admin_url('options-general.php'))); exit; } // Handle manual refresh if (isset($_POST['ai_ready_refresh'])) { $this->force_refresh_content(); $redirect_params['message'] = 'content-refreshed'; wp_safe_redirect(add_query_arg($redirect_params, admin_url('options-general.php'))); exit; } } // Handle GET requests separately (no POST data) $current_tab = isset($_GET['tab']) ? sanitize_text_field(wp_unslash($_GET['tab'])) : 'diagnostics'; // Handle diagnostics rescan (GET request) if (isset($_GET['rescan_diagnostics']) && current_user_can('manage_options')) { delete_transient('ai_ready_diagnostics_cache'); // Force refresh the diagnostics and update timestamp if (function_exists('ai_ready_run_diagnostics')) { ai_ready_run_diagnostics(true); // Force refresh } $this->notices->add_notice('rescan'); // Redirect back to the current tab if set $redirect_params = ['page' => 'ai-ready-settings']; if ($current_tab !== 'diagnostics') { $redirect_params['tab'] = $current_tab; } wp_safe_redirect(add_query_arg($redirect_params, admin_url('options-general.php'))); exit; } // Show notices based on message parameter if (isset($_GET['message'])) { $message = sanitize_text_field(wp_unslash($_GET['message'])); $this->notices->handle_message($message); } } /** * Handle Agent Gate reset action */ private function handle_agent_gate_reset() { // Verify nonce for security if (!check_admin_referer('ai_ready_settings_nonce')) { return; } // Use Agent Gate reset functionality if ($this->agent_gate && method_exists($this->agent_gate, 'reset_settings')) { $this->agent_gate->reset_settings(); } } /** * Save form settings */ private function save_settings() { // Verify nonce for security if (!check_admin_referer('ai_ready_settings_nonce')) { return; } // LLMS.txt settings if (isset($_POST['ai_ready_site_title'])) { update_option('ai_ready_site_title', sanitize_text_field(wp_unslash($_POST['ai_ready_site_title']))); } if (isset($_POST['ai_ready_site_summary'])) { update_option('ai_ready_site_summary', sanitize_textarea_field(wp_unslash($_POST['ai_ready_site_summary']))); } if (isset($_POST['ai_ready_custom_content'])) { update_option('ai_ready_custom_content', sanitize_textarea_field(wp_unslash($_POST['ai_ready_custom_content']))); } // Agent Gate settings - use module if available if ($this->agent_gate && method_exists($this->agent_gate, 'process_form_submission')) { $this->agent_gate->process_form_submission(); } } /** * Remove llms.txt and all related settings */ private function remove_llms_txt() { // Mark llms.txt as explicitly disabled update_option('ai_ready_llms_disabled', true); // Delete all llms.txt related options delete_option('ai_ready_site_title'); delete_option('ai_ready_site_summary'); delete_option('ai_ready_llms_sections'); delete_option('ai_ready_custom_content'); delete_option('ai_ready_last_section_refresh'); delete_option('ai_ready_llms_notes'); // Clear any cached content delete_transient('ai_ready_diagnostics_cache'); delete_transient('ai_ready_fresh_preview_content'); // Clear any stale preview content // Force refresh to clear any cached content if (function_exists('ai_ready_force_refresh_sections')) { ai_ready_force_refresh_sections(); } // Clear WordPress cache wp_cache_flush(); } /** * Force refresh of llms.txt content */ private function force_refresh_content() { // Re-enable llms.txt if it was disabled delete_option('ai_ready_llms_disabled'); // Clear cached sections to force regeneration if (function_exists('ai_ready_force_refresh_sections')) { ai_ready_force_refresh_sections(); } // Clear sitemap cache if (function_exists('ai_ready_refresh_sitemap')) { ai_ready_refresh_sitemap(); } // Clear last refresh timestamp to force regeneration delete_option('ai_ready_last_section_refresh'); // Initialize defaults to ensure options are set if (function_exists('ai_ready_init_llms_defaults')) { ai_ready_init_llms_defaults(); } // Clear diagnostics cache delete_transient('ai_ready_diagnostics_cache'); } /** * Admin page callback */ public function admin_page_callback() { // Define allowed tabs for security $allowed_tabs = ['diagnostics', 'configuration', 'agent-gate']; // Get and validate tab parameter against whitelist (no nonce needed for navigation) // phpcs:ignore WordPress.Security.NonceVerification.Recommended $tab_param = isset($_GET['tab']) ? sanitize_text_field(wp_unslash($_GET['tab'])) : 'diagnostics'; $current_tab = in_array($tab_param, $allowed_tabs, true) ? $tab_param : 'diagnostics'; ?>

Lighthouse Studios' ); ?>

diagnostics_tab) { $this->diagnostics_tab->render(); $this->diagnostics_tab->init(); // Initialize diagnostics tab JavaScript } else { echo '

' . esc_html__('Diagnostics component not available.', 'ai-ready-core') . '

'; } ?>
llms_tab) { $this->llms_tab->render(); $this->llms_tab->init(); // Initialize LLMS tab JavaScript } else { echo '

' . esc_html__('LLMS.txt component not available.', 'ai-ready-core') . '

'; } ?>
' . "\n"; echo '' . "\n"; if ($this->agent_gate) { echo '' . "\n"; echo '' . "\n"; } } if ($this->agent_gate && method_exists($this->agent_gate, 'get_tab_component')) { $tab_component = $this->agent_gate->get_tab_component(); if (defined('WP_DEBUG') && WP_DEBUG) { echo '' . "\n"; } if ($tab_component) { try { $tab_component->render(); $tab_component->init(); } catch (Exception $e) { if (defined('WP_DEBUG') && WP_DEBUG) { echo '' . "\n"; } echo '

' . esc_html__('Error loading Agent Gate tab. Check debug log for details.', 'ai-ready-core') . '

'; } } else { echo '

' . esc_html__('Agent Gate tab component could not be created.', 'ai-ready-core') . '

'; } } else { echo '

' . esc_html__('Agent Gate component not available.', 'ai-ready-core') . '

'; } ?>