1, 'enable_skip_links' => 1, 'enable_focus_indicators' => 1, 'enable_alt_text_check' => 1, 'toolbar_position' => 'top-right', 'high_contrast_mode' => 0, 'font_size_adjustment' => 0, 'keyboard_navigation' => 1, // AI Features 'ai_alt_text' => 1, 'ai_content_scan' => 1, 'ai_text_to_speech' => 1, 'ai_text_simplification' => 1, 'openai_api_key' => '', 'google_vision_api_key' => '', 'ai_service' => 'openai', // 'openai' or 'google' ]; add_option('accessimate_options', $default_options); // Create custom table for user preferences if needed $this->create_user_preferences_table(); } /** * Plugin deactivation */ public function deactivate() { // Clean up if needed (keeping options for now) } /** * Create user preferences table */ private function create_user_preferences_table() { global $wpdb; $table_name = $wpdb->prefix . 'accessimate_user_prefs'; $charset_collate = $wpdb->get_charset_collate(); $sql = "CREATE TABLE $table_name ( id mediumint(9) NOT NULL AUTO_INCREMENT, user_session varchar(100) NOT NULL, preferences text NOT NULL, created_at datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY user_session (user_session) ) $charset_collate;"; require_once ABSPATH . 'wp-admin/includes/upgrade.php'; dbDelta($sql); // Create AI suggestions table $ai_table = $wpdb->prefix . 'accessimate_ai_suggestions'; $sql_ai = "CREATE TABLE $ai_table ( id mediumint(9) NOT NULL AUTO_INCREMENT, post_id mediumint(9) NOT NULL, suggestion_type varchar(50) NOT NULL, original_content text NOT NULL, suggested_content text NOT NULL, status varchar(20) DEFAULT 'pending', created_at datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY post_id (post_id) ) $charset_collate;"; dbDelta($sql_ai); } /** * Add admin menu */ public function add_admin_menu() { add_options_page( __('AccessiMate Settings', 'accessimate'), __('AccessiMate', 'accessimate'), 'manage_options', 'accessimate', [ $this, 'admin_page' ] ); } /** * Initialize admin settings */ public function admin_init() { register_setting('accessimate_options', 'accessimate_options', [ $this, 'validate_options' ]); add_settings_section( 'accessimate_main', __('Main Settings', 'accessimate'), [ $this, 'main_section_callback' ], 'accessimate' ); add_settings_section( 'accessimate_ai', __('AI-Powered Features', 'accessimate'), [ $this, 'ai_section_callback' ], 'accessimate' ); // Toolbar settings add_settings_field( 'enable_toolbar', __('Enable Accessibility Toolbar', 'accessimate'), [ $this, 'checkbox_field' ], 'accessimate', 'accessimate_main', [ 'field' => 'enable_toolbar', 'description' => 'Show accessibility toolbar on frontend', ] ); add_settings_field( 'toolbar_position', __('Toolbar Position', 'accessimate'), [ $this, 'select_field' ], 'accessimate', 'accessimate_main', [ 'field' => 'toolbar_position', 'options' => [ 'top-left' => __('Top Left', 'accessimate'), 'top-right' => __('Top Right', 'accessimate'), 'bottom-left' => __('Bottom Left', 'accessimate'), 'bottom-right' => __('Bottom Right', 'accessimate'), ], ] ); // Feature settings add_settings_field( 'enable_skip_links', __('Enable Skip Links', 'accessimate'), [ $this, 'checkbox_field' ], 'accessimate', 'accessimate_main', [ 'field' => 'enable_skip_links', 'description' => 'Add skip to content links for keyboard users', ] ); add_settings_field( 'enable_focus_indicators', __('Enhanced Focus Indicators', 'accessimate'), [ $this, 'checkbox_field' ], 'accessimate', 'accessimate_main', [ 'field' => 'enable_focus_indicators', 'description' => 'Improve focus visibility for keyboard navigation', ] ); add_settings_field( 'enable_alt_text_check', __('Alt Text Checker', 'accessimate'), [ $this, 'checkbox_field' ], 'accessimate', 'accessimate_main', [ 'field' => 'enable_alt_text_check', 'description' => 'Highlight images without alt text (admin only)', ] ); // AI Feature Settings add_settings_field( 'ai_service', __('AI Service Provider', 'accessimate'), [ $this, 'select_field' ], 'accessimate', 'accessimate_ai', [ 'field' => 'ai_service', 'options' => [ 'openai' => __('OpenAI (GPT-4 Vision)', 'accessimate'), 'google' => __('Google Vision AI', 'accessimate'), ], ] ); add_settings_field( 'openai_api_key', __('OpenAI API Key', 'accessimate'), [ $this, 'text_field' ], 'accessimate', 'accessimate_ai', [ 'field' => 'openai_api_key', 'type' => 'password', 'description' => 'Required for OpenAI services', ] ); add_settings_field( 'google_vision_api_key', __('Google Vision API Key', 'accessimate'), [ $this, 'text_field' ], 'accessimate', 'accessimate_ai', [ 'field' => 'google_vision_api_key', 'type' => 'password', 'description' => 'Required for Google Vision services', ] ); add_settings_field( 'ai_alt_text', __('AI Alt Text Generation', 'accessimate'), [ $this, 'checkbox_field' ], 'accessimate', 'accessimate_ai', [ 'field' => 'ai_alt_text', 'description' => 'Automatically generate alt text for images', ] ); add_settings_field( 'ai_content_scan', __('AI Content Accessibility Scan', 'accessimate'), [ $this, 'checkbox_field' ], 'accessimate', 'accessimate_ai', [ 'field' => 'ai_content_scan', 'description' => 'Scan content for accessibility issues', ] ); add_settings_field( 'ai_text_to_speech', __('Text-to-Speech', 'accessimate'), [ $this, 'checkbox_field' ], 'accessimate', 'accessimate_ai', [ 'field' => 'ai_text_to_speech', 'description' => 'Enable text-to-speech functionality', ] ); add_settings_field( 'ai_text_simplification', __('AI Text Simplification', 'accessimate'), [ $this, 'checkbox_field' ], 'accessimate', 'accessimate_ai', [ 'field' => 'ai_text_simplification', 'description' => 'Provide simplified text alternatives', ] ); add_settings_field( 'reading_assistance', __('Reading Assistance Tools', 'accessimate'), [ $this, 'checkbox_field' ], 'accessimate', 'accessimate_main', [ 'field' => 'reading_assistance', 'description' => 'Enable reading assistance tools (Hide Images, Reading Mask, Reading Line)', ] ); } /** * Main settings section callback */ public function main_section_callback() { echo '

' . esc_html__('Configure AccessiMate settings to improve your website accessibility.', 'accessimate') . '

'; } /** * AI settings section callback */ public function ai_section_callback() { echo '

' . esc_html__('Configure AI-powered accessibility features. API keys are required for external AI services.', 'accessimate') . '

'; echo '

' . esc_html__('Note: AI features may incur costs from third-party providers. Please review their pricing before enabling.', 'accessimate') . '

'; } /** * Render checkbox field * * @param array $args Field arguments. */ public function checkbox_field($args) { $options = get_option('accessimate_options'); $field = $args['field']; $checked = isset($options[ $field ]) ? checked($options[ $field ], 1, false) : ''; $description = isset($args['description']) ? $args['description'] : ''; echo ''; } /** * Render select field * * @param array $args Field arguments. */ public function select_field($args) { $options = get_option('accessimate_options'); $field = $args['field']; $current = isset($options[ $field ]) ? $options[ $field ] : ''; echo ''; } /** * Render text field * * @param array $args Field arguments. */ public function text_field($args) { $options = get_option('accessimate_options'); $field = $args['field']; $value = isset($options[ $field ]) ? esc_attr($options[ $field ]) : ''; $type = isset($args['type']) ? $args['type'] : 'text'; $description = isset($args['description']) ? $args['description'] : ''; echo ''; if ($description) { echo '

' . esc_html($description) . '

'; } } public function validate_options($input) { $valid = []; // Main settings validation $valid['enable_toolbar'] = isset($input['enable_toolbar']) ? 1 : 0; $valid['enable_skip_links'] = isset($input['enable_skip_links']) ? 1 : 0; $valid['enable_focus_indicators'] = isset($input['enable_focus_indicators']) ? 1 : 0; $valid['enable_alt_text_check'] = isset($input['enable_alt_text_check']) ? 1 : 0; $valid['reading_assistance'] = isset($input['reading_assistance']) ? 1 : 0; $valid['high_contrast_mode'] = isset($input['high_contrast_mode']) ? 1 : 0; $valid['font_size_adjustment'] = isset($input['font_size_adjustment']) ? absint($input['font_size_adjustment']) : 0; $valid['keyboard_navigation'] = isset($input['keyboard_navigation']) ? 1 : 0; // Validate toolbar position $valid_positions = [ 'top-left', 'top-right', 'bottom-left', 'bottom-right' ]; $valid['toolbar_position'] = in_array($input['toolbar_position'], $valid_positions, true) ? sanitize_text_field($input['toolbar_position']) : 'top-right'; // AI settings validation $valid['ai_alt_text'] = isset($input['ai_alt_text']) ? 1 : 0; $valid['ai_content_scan'] = isset($input['ai_content_scan']) ? 1 : 0; $valid['ai_text_to_speech'] = isset($input['ai_text_to_speech']) ? 1 : 0; $valid['ai_text_simplification'] = isset($input['ai_text_simplification']) ? 1 : 0; // Validate AI service $valid_services = [ 'openai', 'google' ]; $valid['ai_service'] = in_array($input['ai_service'], $valid_services, true) ? sanitize_text_field($input['ai_service']) : 'openai'; // Validate and sanitize API keys $valid['openai_api_key'] = ! empty($input['openai_api_key']) ? sanitize_text_field(trim($input['openai_api_key'])) : ''; $valid['google_vision_api_key'] = ! empty($input['google_vision_api_key']) ? sanitize_text_field(trim($input['google_vision_api_key'])) : ''; // Validate API key formats if (! empty($valid['openai_api_key']) && ! $this->validate_openai_api_key($valid['openai_api_key'])) { add_settings_error( 'accessimate_options', 'invalid_openai_key', __('Invalid OpenAI API key format. Please check your key and try again.', 'accessimate'), 'error' ); $valid['openai_api_key'] = ''; // Clear invalid key } if (! empty($valid['google_vision_api_key']) && ! $this->validate_google_api_key($valid['google_vision_api_key'])) { add_settings_error( 'accessimate_options', 'invalid_google_key', __('Invalid Google Vision API key format. Please check your key and try again.', 'accessimate'), 'error' ); $valid['google_vision_api_key'] = ''; // Clear invalid key } return $valid; } /** * Validate OpenAI API key format * * @param string $api_key The API key to validate. * @return bool True if valid format, false otherwise. */ private function validate_openai_api_key($api_key) { // OpenAI API keys start with 'sk-' and are typically 51 characters long return preg_match('/^sk-[a-zA-Z0-9]{48}$/', $api_key); } /** * Validate Google Vision API key format * * @param string $api_key The API key to validate. * @return bool True if valid format, false otherwise. */ private function validate_google_api_key($api_key) { // Google API keys are typically 39 characters of alphanumeric and some special chars return preg_match('/^[a-zA-Z0-9_-]{39}$/', $api_key); } /** * Display admin page */ public function admin_page() { // Check user capabilities if (! current_user_can('manage_options')) { return; } ?>

display_ai_status(); ?>
admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('accessimate_nonce'), 'ai_features' => [ 'text_to_speech' => isset($options['ai_text_to_speech']) ? $options['ai_text_to_speech'] : 0, 'text_simplification' => isset($options['ai_text_simplification']) ? $options['ai_text_simplification'] : 0, 'content_scan' => isset($options['ai_content_scan']) ? $options['ai_content_scan'] : 0, 'reading_assistance' => isset($options['reading_assistance']) ? $options['reading_assistance'] : 0, ], ] ); } /** * Enqueue AI-related scripts */ public function enqueue_ai_scripts() { $options = get_option('accessimate_options'); if (isset($options['ai_text_to_speech']) && $options['ai_text_to_speech']) { wp_enqueue_script( 'accessimate-speech', ACCESSIMATE_PLUGIN_URL . 'assets/js/accessimate-speech.js', [ 'jquery' ], ACCESSIMATE_VERSION, true ); } } /** * Render accessibility toolbar */ public function render_accessibility_toolbar() { $options = get_option('accessimate_options'); if (! isset($options['enable_toolbar']) || ! $options['enable_toolbar']) { return; } $position = isset($options['toolbar_position']) ? $options['toolbar_position'] : 'top-right'; ?>
__('Security check failed', 'accessimate') ]); } // Validate input if (! isset($_POST['preferences'])) { wp_send_json_error([ 'message' => __('Missing preferences data', 'accessimate') ]); } $preferences = sanitize_text_field(wp_unslash($_POST['preferences'])); $session_id = session_id(); if (empty($session_id)) { session_start(); $session_id = session_id(); } global $wpdb; $table_name = $wpdb->prefix . 'accessimate_user_prefs'; // Direct database query is necessary here as WordPress doesn't provide // a built-in API for custom user preference storage with session handling // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching $result = $wpdb->replace( $table_name, [ 'user_session' => $session_id, 'preferences' => $preferences, ], [ '%s', '%s' ] ); if (false === $result) { wp_send_json_error([ 'message' => __('Failed to save preferences', 'accessimate') ]); } wp_send_json_success([ 'message' => __('Preferences saved successfully', 'accessimate') ]); } /** * Display AI features status */ public function display_ai_status() { $options = get_option('accessimate_options'); echo '
'; // OpenAI Status echo '
'; echo '

' . esc_html__('OpenAI Service', 'accessimate') . '

'; if (! empty($options['openai_api_key'])) { echo '✓ ' . esc_html__('API Key Configured', 'accessimate') . ''; } else { echo '✗ ' . esc_html__('API Key Missing', 'accessimate') . ''; } echo '
'; // Google Vision Status echo '
'; echo '

' . esc_html__('Google Vision Service', 'accessimate') . '

'; if (! empty($options['google_vision_api_key'])) { echo '✓ ' . esc_html__('API Key Configured', 'accessimate') . ''; } else { echo '✗ ' . esc_html__('API Key Missing', 'accessimate') . ''; } echo '
'; // Active Service echo '
'; echo '

' . esc_html__('Active Service', 'accessimate') . '

'; $active_service = isset($options['ai_service']) ? $options['ai_service'] : 'openai'; echo '' . esc_html(ucfirst($active_service)) . ''; echo '
'; // Feature Status echo '
'; echo '

' . esc_html__('Enabled Features', 'accessimate') . '

'; $enabled_features = []; if (isset($options['ai_alt_text']) && $options['ai_alt_text']) { $enabled_features[] = __('Alt Text Generation', 'accessimate'); } if (isset($options['ai_content_scan']) && $options['ai_content_scan']) { $enabled_features[] = __('Content Scan', 'accessimate'); } if (isset($options['ai_text_to_speech']) && $options['ai_text_to_speech']) { $enabled_features[] = __('Text-to-Speech', 'accessimate'); } if (isset($options['ai_text_simplification']) && $options['ai_text_simplification']) { $enabled_features[] = __('Text Simplification', 'accessimate'); } if (! empty($enabled_features)) { echo ''; } else { echo '' . esc_html__('No AI features enabled', 'accessimate') . ''; } echo '
'; echo '
'; } } // Initialize the plugin new AccessiMate();