admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('wpallstars-nonce'), // Generic nonce for general actions 'update_option_nonce' => wp_create_nonce('wpallstars_update_option'), // Specific nonce for updating options via AJAX (if still needed) 'l10n' => array( // Localization strings for JS 'updating' => __('Updating...', WPALLSTARS_TEXT_DOMAIN), 'error' => __('Error', WPALLSTARS_TEXT_DOMAIN), 'success' => __('Success', WPALLSTARS_TEXT_DOMAIN), ), // Add any other data needed by wpallstars-admin.js )); // Settings Manager handles its own enqueuing via its init hook // WPALLSTARS_Settings_Manager::enqueue_settings_scripts($hook); // Removed // Other managers can still enqueue specific assets if needed // Example: // WPALLSTARS_Theme_Manager::enqueue_theme_scripts($hook); // WPALLSTARS_Free_Plugins_Manager::enqueue_free_plugins_scripts($hook); // Combine inline styles from various managers $inline_styles = ''; // Initialize // Uncomment and adjust class/method names as needed // $inline_styles .= WPALLSTARS_Pro_Plugins_Manager::get_inline_styles(); // $inline_styles .= WPALLSTARS_Hosting_Manager::get_inline_styles(); // $inline_styles .= WPALLSTARS_Tools_Manager::get_inline_styles(); if (!empty($inline_styles)) { wp_add_inline_style('wpallstars-admin', $inline_styles); } // Combine inline scripts from various managers (use with caution) $inline_scripts = ''; // Initialize // $inline_scripts .= WPALLSTARS_Theme_Manager::get_theme_scripts(); // $inline_scripts .= WPALLSTARS_Free_Plugins_Manager::get_plugin_scripts(); // $inline_scripts .= WPALLSTARS_Settings_Manager::get_settings_scripts(); // Removed if (!empty($inline_scripts)) { wp_add_inline_script('wpallstars-admin', $inline_scripts); } } /** * Register core plugin settings - REMOVED * Settings registration is now handled by WPALLSTARS_Settings_Manager::register_settings */ // public static function register_settings() { ... } /** * AJAX handler for updating options (Generic handler, specific validation can be added) * Note: This is likely NOT used for the main settings form save action anymore, * which is handled by options.php via the Settings API. * Keep it if it's used for dynamic updates elsewhere. * Handles saving *individual* setting keys within the 'wpallstars_options' array via AJAX. */ public static function update_option() { // Check nonce check_ajax_referer('wpallstars_update_option', 'nonce'); // Check user capabilities if (!current_user_can('manage_options')) { wp_send_json_error(__('You do not have permission to perform this action.', WPALLSTARS_TEXT_DOMAIN)); return; } // Get setting key and value from POST data $setting_key = isset($_POST['setting_key']) ? sanitize_key($_POST['setting_key']) : ''; // Don't sanitize value yet, do it based on the key type later $setting_value = isset($_POST['setting_value']) ? wp_unslash($_POST['setting_value']) : null; if (empty($setting_key) || is_null($setting_value)) { wp_send_json_error(__('Setting key or value is missing.', WPALLSTARS_TEXT_DOMAIN)); return; } // --- Security & Validation --- // Whitelist setting KEYS within 'wpallstars_options' that can be updated via this AJAX handler $allowed_options = array( 'admin_color_scheme', // Example: Key for admin color scheme 'enable_auto_upload', // Example: Key for auto-upload toggle 'max_image_width', // Example: Key for max image width // Add other keys registered in Settings_Manager that should be AJAX-updatable ); if (!in_array($setting_key, $allowed_options, true)) { wp_send_json_error(__('Invalid setting key specified for AJAX update.', WPALLSTARS_TEXT_DOMAIN)); return; } // Sanitize the value based on the specific setting key $sanitized_value = ''; switch ($setting_key) { case 'admin_color_scheme': // Assuming it's a class name or identifier $sanitized_value = sanitize_html_class($setting_value); // If it was intended to be a hex color, use sanitize_hex_color($setting_value); break; case 'enable_auto_upload': // Boolean toggle (common JS values are 'true'/'false' strings) $sanitized_value = rest_sanitize_boolean($setting_value); break; case 'max_image_width': // Positive integer $sanitized_value = absint($setting_value); break; // Add cases for other allowed keys default: // Should not happen due to whitelist check, but as a fallback: $sanitized_value = sanitize_text_field($setting_value); break; } // Get the existing options array $options = get_option(WPALLSTARS_Settings_Manager::$option_name, array()); // Store the old value for comparison $old_value = isset($options[$setting_key]) ? $options[$setting_key] : null; // Update the specific key in the options array $options[$setting_key] = $sanitized_value; // Save the entire options array back // update_option handles serialization and DB storage $result = update_option(WPALLSTARS_Settings_Manager::$option_name, $options); if ($result) { wp_send_json_success(__('Option updated successfully.', WPALLSTARS_TEXT_DOMAIN)); } else { // Option might not have changed, or error occurred // Check if the value is the same as the old value (update_option returns false if value hasn't changed) if ($old_value === $sanitized_value) { wp_send_json_success(__('Option unchanged.', WPALLSTARS_TEXT_DOMAIN)); } else { wp_send_json_error(__('Failed to update option.', WPALLSTARS_TEXT_DOMAIN)); } } } /** * Register the admin menu item */ public static function register_admin_menu() { add_menu_page( __('WP Allstars', WPALLSTARS_TEXT_DOMAIN), __('WP Allstars', WPALLSTARS_TEXT_DOMAIN), 'manage_options', 'wpallstars-dashboard', // Main dashboard slug array(__CLASS__, 'render_settings_page'), // Default to settings page for now 'dashicons-star-filled', 85 ); // Add actual settings submenu add_submenu_page( 'wpallstars-dashboard', // Parent slug __('Settings', WPALLSTARS_TEXT_DOMAIN), // Page title __('Settings', WPALLSTARS_TEXT_DOMAIN), // Menu title 'manage_options', // Capability 'wpallstars-settings', // Settings slug << THIS IS THE SLUG TO USE array(__CLASS__, 'render_settings_page') // Callback function ); // Add other submenus here using their respective managers or callbacks } /** * Render the settings page container and handle tab navigation. * Content for each tab is rendered by the respective manager class. */ public static function render_settings_page() { // Check user capabilities if (!current_user_can('manage_options')) { wp_die(__('You do not have sufficient permissions to access this page.', WPALLSTARS_TEXT_DOMAIN)); } // Whitelist of valid tabs $valid_tabs = array( 'general' => __('General', WPALLSTARS_TEXT_DOMAIN), 'advanced' => __('Advanced', WPALLSTARS_TEXT_DOMAIN), 'workflow' => __('Workflow', WPALLSTARS_TEXT_DOMAIN), 'theme' => __('Theme', WPALLSTARS_TEXT_DOMAIN), 'recommended' => __('Free Plugins', WPALLSTARS_TEXT_DOMAIN), 'pro' => __('Pro Plugins', WPALLSTARS_TEXT_DOMAIN), 'hosting' => __('Hosting', WPALLSTARS_TEXT_DOMAIN), 'tools' => __('Tools', WPALLSTARS_TEXT_DOMAIN), 'readme' => __('Read Me', WPALLSTARS_TEXT_DOMAIN), ); // Get current tab from URL, default to 'general' $current_tab = isset($_GET['tab']) ? sanitize_key($_GET['tab']) : 'general'; // Fallback to 'general' if the tab is not in the whitelist if (!array_key_exists($current_tab, $valid_tabs)) { $current_tab = 'general'; } ?>