set_basename(false, __FILE__); } else { /** * DO NOT REMOVE THIS IF, IT IS ESSENTIAL FOR THE * `function_exists` CALL ABOVE TO PROPERLY WORK. */ if (!function_exists('bdpacc_fs')) { // Create a helper function for easy SDK access. function bdpacc_fs() { global $bdpacc_fs; if (!isset($bdpacc_fs)) { // Include Freemius SDK. require_once dirname(__FILE__) . '/vendor/freemius/start.php'; $bdpacc_fs = fs_dynamic_init([ 'id' => '20125', 'slug' => 'accessimate', 'type' => 'plugin', 'public_key' => 'pk_2070f9a53475a07dc6e32a706509a', 'is_premium' => false, 'premium_suffix' => 'Pro', 'has_addons' => false, 'has_paid_plans' => true, 'is_org_compliant' => true, 'trial' => [ 'days' => 3, 'is_require_payment' => true, ], 'menu' => [ 'slug' => 'accessimate', 'first-path' => 'options-general.php?page=accessimate', 'support' => false, 'parent' => [ 'slug' => 'options-general.php', ], ], 'is_live' => true, ]); } return $bdpacc_fs; } // Init Freemius. bdpacc_fs(); // Signal that SDK was initiated. do_action('bdpacc_fs_loaded'); // Initialize the plugin new AccessiMate(); } // ... Your plugin's main file logic ... } class AccessiMate { /** * Constructor */ public function __construct() { add_action('init', [$this, 'init']); register_activation_hook(__FILE__, [$this, 'activate']); register_deactivation_hook(__FILE__, [$this, 'deactivate']); } /** * Initialize the plugin */ public function init() { // Admin hooks if (is_admin()) { add_action('admin_menu', [$this, 'add_admin_menu']); add_action('admin_init', [$this, 'admin_init']); add_action('admin_enqueue_scripts', [$this, 'enqueue_admin_scripts']); } // Frontend hooks add_action('wp_enqueue_scripts', [$this, 'enqueue_frontend_scripts']); add_action('wp_footer', [$this, 'render_accessibility_toolbar']); // AJAX hooks add_action('wp_ajax_accessimate_save_settings', [$this, 'save_user_preferences']); add_action('wp_ajax_nopriv_accessimate_save_settings', [$this, 'save_user_preferences']); add_action('wp_ajax_accessimate_generate_alt_text', [$this, 'generate_alt_text']); add_action('wp_ajax_accessimate_scan_content', [$this, 'scan_content_accessibility']); add_action('wp_ajax_accessimate_simplify_text', [$this, 'simplify_text']); // AI Features // if (ACCESSIMATE_AI_ENABLED) { // add_action('wp_enqueue_scripts', [ $this, 'enqueue_ai_scripts' ]); // add_filter('wp_get_attachment_image_attributes', [ $this, 'auto_generate_alt_text' ], 10, 3); // } } /** * Plugin activation */ public function activate() { // Set default options $default_options = [ 'enable_toolbar' => 1, 'enable_skip_links' => 1, 'keyboard' => 1, 'line-height' => 1, 'letter-spacing' => 1, 'readable-font' => 1, 'dyslexic-font' => 1, 'text-align' => 1, 'highlight-links' => 1, 'invert-colors' => 1, 'brightness' => 1, 'contrast' => 1, 'gray-scale' => 1, 'saturation' => 1, 'reading-line' => 1, 'reading-mask' => 1, 'highlight-all' => 1, 'highlight-titles' => 1, 'hide-images' => 1, 'text-to-speech' => 1, 'mute-sounds' => 1, 'stop-animations' => 1, 'toolbar_position' => 'bottom-left', 'toolbar_animation' => 'slide-left', 'toolbar_theme' => 'auto', 'bigger-text' => 1, 'cursor' => 1, ]; 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} (\n id mediumint(9) NOT NULL AUTO_INCREMENT,\n user_session varchar(100) NOT NULL,\n preferences text NOT NULL,\n created_at datetime DEFAULT CURRENT_TIMESTAMP,\n PRIMARY KEY (id),\n UNIQUE KEY user_session (user_session)\n ) {$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} (\n id mediumint(9) NOT NULL AUTO_INCREMENT,\n post_id mediumint(9) NOT NULL,\n suggestion_type varchar(50) NOT NULL,\n original_content text NOT NULL,\n suggested_content text NOT NULL,\n status varchar(20) DEFAULT 'pending',\n created_at datetime DEFAULT CURRENT_TIMESTAMP,\n PRIMARY KEY (id),\n KEY post_id (post_id)\n ) {$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' ); $settings = [ // Toolbar Settings [ 'id' => 'enable_toolbar', 'label' => __('Accessibility Toolbar', 'accessimate'), 'callback' => [$this, 'checkbox_field'], 'description' => 'Display the accessibility toolbar on the frontend.', ], [ 'id' => 'toolbar_position', 'label' => __('Toolbar Position', 'accessimate'), 'callback' => [$this, 'select_field'], 'options' => [ 'top-left' => __('Top Left', 'accessimate'), 'top-right' => __('Top Right', 'accessimate'), 'bottom-left' => __('Bottom Left', 'accessimate'), 'bottom-right' => __('Bottom Right', 'accessimate'), ], ], [ 'id' => 'toolbar_animation', 'label' => __('Toolbar Animation', 'accessimate'), 'callback' => [$this, 'select_field'], 'options' => [ 'none' => __('None', 'accessimate'), 'fade' => __('Fade', 'accessimate'), 'slide-left' => __('Slide Left', 'accessimate'), 'slide-right' => __('Slide Right', 'accessimate'), 'slide-top' => __('Slide Top', 'accessimate'), 'slide-bottom' => __('Slide Bottom', 'accessimate'), ], ], [ 'id' => 'toolbar_theme', 'label' => __('Toolbar Theme', 'accessimate'), 'callback' => [$this, 'select_field'], 'options' => [ 'auto' => __('Auto (System Preference)', 'accessimate'), 'light' => __('Light', 'accessimate'), 'dark' => __('Dark', 'accessimate'), ], ], // Feature Toggles [ 'id' => 'bigger-text', 'label' => __('Bigger Text', 'accessimate'), 'callback' => [$this, 'checkbox_field'], 'description' => 'Increase text size for better readability.', ], [ 'id' => 'cursor', 'label' => __('Cursor', 'accessimate'), 'callback' => [$this, 'checkbox_field'], 'description' => 'Improve cursor visibility for users with visual challenges.', ], [ 'id' => 'line-height', 'label' => __('Line Height', 'accessimate'), 'callback' => [$this, 'checkbox_field'], 'description' => 'Adjust line spacing to reduce text clutter.', ], [ 'id' => 'letter-spacing', 'label' => __('Letter Spacing', 'accessimate'), 'callback' => [$this, 'checkbox_field'], 'description' => 'Increase spacing between letters for clarity.', ], [ 'id' => 'readable-font', 'label' => __('Readable Font', 'accessimate'), 'callback' => [$this, 'checkbox_field'], 'description' => 'Use a clean, legible font for easier reading.', ], [ 'id' => 'dyslexic-font', 'label' => __('Dyslexic Font', 'accessimate'), 'callback' => [$this, 'checkbox_field'], 'description' => 'Enable a font designed to aid dyslexic users.', 'is_beta' => true, ], [ 'id' => 'text-align', 'label' => __('Text Align', 'accessimate'), 'callback' => [$this, 'checkbox_field'], 'description' => 'Adjust text alignment for better legibility.', ], [ 'id' => 'text-magnifier', 'label' => __('Text Magnifier', 'accessimate'), 'callback' => [$this, 'checkbox_field'], 'description' => 'Magnify text on hover or focus for better visibility.', 'is_beta' => true, ], [ 'id' => 'highlight-links', 'label' => __('Highlight Links', 'accessimate'), 'callback' => [$this, 'checkbox_field'], 'description' => 'Highlight all links on the page for visibility.', ], [ 'id' => 'invert-colors', 'label' => __('Invert Colors', 'accessimate'), 'callback' => [$this, 'checkbox_field'], 'description' => 'Invert website colors to reduce eye strain.', ], [ 'id' => 'brightness', 'label' => __('Brightness', 'accessimate'), 'callback' => [$this, 'checkbox_field'], 'description' => 'Adjust screen brightness for comfort.', ], [ 'id' => 'contrast', 'label' => __('Contrast', 'accessimate'), 'callback' => [$this, 'checkbox_field'], 'description' => 'Improve content visibility with contrast adjustment.', 'is_beta' => true, ], [ 'id' => 'grayscale', 'label' => __('Grayscale', 'accessimate'), 'callback' => [$this, 'checkbox_field'], 'description' => 'Convert content to grayscale for focus.', ], [ 'id' => 'saturation', 'label' => __('Saturation', 'accessimate'), 'callback' => [$this, 'checkbox_field'], 'description' => 'Adjust saturation to reduce visual overload.', 'is_beta' => true, ], [ 'id' => 'reading-line', 'label' => __('Reading Line', 'accessimate'), 'callback' => [$this, 'checkbox_field'], 'description' => 'Display a horizontal line to follow text.', ], [ 'id' => 'reading-mask', 'label' => __('Reading Mask', 'accessimate'), 'callback' => [$this, 'checkbox_field'], 'description' => 'Dim parts of the screen to focus on text.', ], [ 'id' => 'highlight-all', 'label' => __('Highlight All', 'accessimate'), 'callback' => [$this, 'checkbox_field'], 'description' => 'Highlight all content to assist with visual tracking.', ], [ 'id' => 'highlight-titles', 'label' => __('Highlight Titles', 'accessimate'), 'callback' => [$this, 'checkbox_field'], 'description' => 'Emphasize headings and titles for better navigation.', 'is_beta' => true, ], [ 'id' => 'hide-images', 'label' => __('Hide Images', 'accessimate'), 'callback' => [$this, 'checkbox_field'], 'description' => 'Hide images to reduce distractions.', ], [ 'id' => 'text-to-speech', 'label' => __('Text to Speech', 'accessimate'), 'callback' => [$this, 'checkbox_field'], 'description' => 'Read out text for users with visual impairments.', 'is_beta' => true, ], [ 'id' => 'mute-sounds', 'label' => __('Mute Sounds', 'accessimate'), 'callback' => [$this, 'checkbox_field'], 'description' => 'Silence all site audio for a quieter experience.', 'is_beta' => true, ], [ 'id' => 'stop-animations', 'label' => __('Stop Animations', 'accessimate'), 'callback' => [$this, 'checkbox_field'], 'description' => 'Stop moving elements to prevent distractions.', ], [ 'id' => 'keyboard', 'label' => __('Keyboard Navigation', 'accessimate'), 'callback' => [$this, 'checkbox_field'], 'description' => 'Highlight elements during keyboard navigation.', 'is_beta' => true, ], [ 'id' => 'language', 'label' => __('Toolbar Language', 'accessimate'), 'callback' => [$this, 'select_field'], 'options' => [ 'en' => __('English', 'accessimate'), 'fr' => __('French', 'accessimate'), 'es' => __('Spanish', 'accessimate'), 'de' => __('German', 'accessimate'), 'it' => __('Italian', 'accessimate'), 'pt' => __('Portuguese', 'accessimate'), 'ar' => __('Arabic', 'accessimate'), ], 'description' => __('Select the language for the accessibility toolbar.', 'accessimate'), ], ]; // Register all fields foreach ($settings as $setting) { $args = [ 'field' => $setting['id'], ]; if (isset($setting['description'])) { $args['description'] = $setting['description']; } if (isset($setting['options'])) { $args['options'] = $setting['options']; } if (isset($setting['is_beta'])) { $args['is_beta'] = $setting['is_beta']; } add_settings_field( $setting['id'], $setting['label'], $setting['callback'], 'accessimate', 'accessimate_main', $args ); } } /** * Main settings section callback */ public function main_section_callback() { echo '

' . esc_html__('Configure AccessiMate settings to improve your website accessibility.', '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'] : ''); $is_beta = (isset($args['is_beta']) ? $args['is_beta'] : false); echo ''; } /** * Render select field * * @param array $args Field arguments. */ public function select_field($args) { $options = get_option('accessimate_options'); $field = $args['field']; $current = $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['bigger-text'] = (isset($input['bigger-text']) ? 1 : 0); $valid['cursor'] = (isset($input['cursor']) ? 1 : 0); $valid['line-height'] = (isset($input['line-height']) ? 1 : 0); $valid['letter-spacing'] = (isset($input['letter-spacing']) ? 1 : 0); $valid['readable-font'] = (isset($input['readable-font']) ? 1 : 0); $valid['dyslexic-font'] = (isset($input['dyslexic-font']) ? 1 : 0); $valid['text-align'] = (isset($input['text-align']) ? 1 : 0); $valid['text-magnifier'] = (isset($input['text-magnifier']) ? 1 : 0); $valid['highlight-links'] = (isset($input['highlight-links']) ? 1 : 0); $valid['invert-colors'] = (isset($input['invert-colors']) ? 1 : 0); $valid['brightness'] = (isset($input['brightness']) ? 1 : 0); $valid['contrast'] = (isset($input['contrast']) ? 1 : 0); $valid['grayscale'] = (isset($input['grayscale']) ? 1 : 0); $valid['saturation'] = (isset($input['saturation']) ? 1 : 0); $valid['reading-line'] = (isset($input['reading-line']) ? 1 : 0); $valid['reading-mask'] = (isset($input['reading-mask']) ? 1 : 0); $valid['highlight-all'] = (isset($input['highlight-all']) ? 1 : 0); $valid['highlight-titles'] = (isset($input['highlight-titles']) ? 1 : 0); $valid['hide-images'] = (isset($input['hide-images']) ? 1 : 0); $valid['text-to-speech'] = (isset($input['text-to-speech']) ? 1 : 0); $valid['mute-sounds'] = (isset($input['mute-sounds']) ? 1 : 0); $valid['stop-animations'] = (isset($input['stop-animations']) ? 1 : 0); $valid['keyboard'] = (isset($input['keyboard']) ? 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'); // Validate toolbar theme $valid_themes = ['auto', 'light', 'dark']; $valid['toolbar_theme'] = (in_array($input['toolbar_theme'], $valid_themes, true) ? sanitize_text_field($input['toolbar_theme']) : 'auto'); // Validate toolbar animation $valid_animations = [ 'none', 'fade', 'slide-left', 'slide-right', 'slide-top', 'slide-bottom' ]; $valid['toolbar_animation'] = (in_array($input['toolbar_animation'], $valid_animations, true) ? sanitize_text_field($input['toolbar_animation']) : 'slide-top'); // Validate language $valid_languages = [ 'en', 'fr', 'es', 'de', 'it', 'pt', 'ar' ]; $valid['language'] = (in_array($input['language'], $valid_languages, true) ? sanitize_text_field($input['language']) : 'en'); return $valid; } /** * Display admin page */ public function admin_page() { // Check user capabilities if (!current_user_can('manage_options')) { return; } ?>

admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('accessimate_nonce'), 'ai_features' => [ 'text_to_speech' => $options['ai_text_to_speech'] ?? 0, 'text_simplification' => $options['ai_text_simplification'] ?? 0, 'content_scan' => $options['ai_content_scan'] ?? 0, 'reading_assistance' => $options['reading_assistance'] ?? 0, ], ]); } /** * Get all buttons or a specific button by key * * @param string|null $key Button ID to retrieve * * @return array|null Button data or null if key is not found */ private function getFeatures($key = null) { $features = [ [ 'id' => 'bigger-text', 'icon' => 'format_size', 'label' => [ 'en' => 'Bigger Text', 'fr' => 'Texte Plus Grand', ], 'default' => true, 'has_step' => true, ], [ 'id' => 'cursor', 'icon' => 'arrow_selector_tool', 'label' => [ 'en' => 'Cursor', 'fr' => 'Curseur', ], 'default' => true, 'has_step' => true, ], [ 'id' => 'line-height', 'icon' => 'format_line_spacing', 'label' => [ 'en' => 'Line Height', 'fr' => 'Hauteur de Ligne', ], 'default' => true, 'has_step' => true, ], [ 'id' => 'letter-spacing', 'icon' => 'format_letter_spacing', 'label' => [ 'en' => 'Letter Spacing', 'fr' => 'Espacement des Lettres', ], 'default' => true, 'has_step' => true, ], [ 'id' => 'readable-font', 'icon' => 'hdr_auto', 'label' => [ 'en' => 'Readable Font', 'fr' => 'Police Lisible', ], 'default' => true, ], [ 'id' => 'dyslexic-font', 'icon' => 'brand_family', 'label' => [ 'en' => 'Dyslexic Font', 'fr' => 'Police Dyslexique', ], 'default' => true, ], [ 'id' => 'text-align', 'icon' => 'format_align_left', 'label' => [ 'en' => 'Text Align', 'fr' => 'Alignement du Texte', ], 'default' => true, 'has_step' => true, ], [ 'id' => 'text-magnifier', 'icon' => 'loupe', 'label' => [ 'en' => 'Text Magnifier', 'fr' => 'Loupe de Texte', ], 'default' => true, ], [ 'id' => 'highlight-links', 'icon' => 'link', 'label' => [ 'en' => 'Highlight Links', 'fr' => 'Mettre en Évidence les Liens', ], 'default' => true, ], [ 'id' => 'invert-colors', 'icon' => 'invert_colors', 'label' => [ 'en' => 'Invert Colors', 'fr' => 'Inverser les Couleurs', ], 'default' => true, 'has_step' => true, ], [ 'id' => 'brightness', 'icon' => 'brightness_6', 'label' => [ 'en' => 'Brightness', 'fr' => 'Luminosité', ], 'default' => true, 'has_step' => true, ], [ 'id' => 'contrast', 'icon' => 'contrast', 'label' => [ 'en' => 'Contrast', 'fr' => 'Contraste', ], 'has_step' => true, 'default' => true, ], [ 'id' => 'grayscale', 'icon' => 'filter_b_and_w', 'label' => [ 'en' => 'Grayscale', 'fr' => 'Niveaux de Gris', ], 'default' => true, 'has_step' => true, ], [ 'id' => 'saturation', 'icon' => 'palette', 'label' => [ 'en' => 'Saturation', 'fr' => 'Saturation', ], 'default' => true, 'has_step' => true, ], [ 'id' => 'reading-line', 'icon' => 'insert_page_break', 'label' => [ 'en' => 'Reading Line', 'fr' => 'Ligne de Lecture', ], 'default' => true, ], [ 'id' => 'reading-mask', 'icon' => 'credit_card', 'label' => [ 'en' => 'Reading Mask', 'fr' => 'Masque de Lecture', ], 'default' => true, ], [ 'id' => 'highlight-all', 'icon' => 'highlight', 'label' => [ 'en' => 'Highlight All', 'fr' => 'Tout Mettre en Évidence', ], 'default' => true, ], [ 'id' => 'highlight-titles', 'icon' => 'title', 'label' => [ 'en' => 'Highlight Titles', 'fr' => 'Mettre en Évidence les Titres', ], 'default' => true, ], [ 'id' => 'keyboard', 'icon' => 'keyboard', 'label' => [ 'en' => 'Keyboard Navigation', 'fr' => 'Navigation au Clavier', ], 'default' => true, ], [ 'id' => 'hide-images', 'icon' => 'hide_image', 'label' => [ 'en' => 'Hide Images', 'fr' => 'Cacher les Images', ], 'default' => true, ], [ 'id' => 'text-to-speech', 'icon' => 'text_to_speech', 'label' => [ 'en' => 'Text to Speech', 'fr' => 'Texte en Parole', ], 'default' => true, ], [ 'id' => 'mute-sounds', 'icon' => 'volume_off', 'label' => [ 'en' => 'Mute Sounds', 'fr' => 'Couper les Sons', ], 'default' => true, ], [ 'id' => 'stop-animations', 'icon' => 'animation', 'label' => [ 'en' => 'Stop Animations', 'fr' => 'Arrêter les Animations', ], 'default' => true, ], [ 'id' => 'simplify-text', 'icon' => 'description', 'label' => [ 'en' => 'Simplify Text', 'fr' => 'Simplifier le Texte', ], 'default' => false, ], [ 'id' => 'scan-page', 'icon' => 'scan', 'label' => [ 'en' => 'Scan Page', 'fr' => 'Analyser la Page', ], 'default' => false, ] ]; return ($key === null ? $features : array_filter($features, fn ($feature) => $feature['id'] === $key)); } /** * Render accessibility toolbar */ public function render_accessibility_toolbar() { $options = get_option('accessimate_options'); if (!isset($options['enable_toolbar']) || !$options['enable_toolbar']) { return; } $position = $options['toolbar_position'] ?? 'bottom-right'; $language = $options['language'] ?? 'en'; $title = [ 'en' => 'Accessibility', 'fr' => 'Accessibilité', 'es' => 'Accesibilidad', 'de' => 'Barrierefreiheit', 'it' => 'Accessibilità', 'pt' => 'Acessibilidade', 'ar' => 'إمكانية الوصول', ]; ?>
__('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'), ]); } }