$default_value ) { if ( false === get_option( $option_name, false ) ) { add_option( $option_name, $default_value ); } } } /** * Default plugin options. * * @return array */ private static function get_default_options() { return array( 'airize_providers' => array( 'chatgpt' => 1, 'gemini' => 1, 'perplexity' => 1, 'grok' => 1, ), 'airize_show_pages' => 1, 'airize_show_posts' => 1, 'airize_design_style' => 'style1', 'airize_button_text' => array( 'chatgpt' => 'ChatGPT', 'gemini' => 'Gemini', 'perplexity' => 'Perplexity', 'grok' => 'Grok', ), 'airize_prompt_text' => 'Summarize this page', 'airize_intro_text' => '', 'airize_provider_icons' => array( 'chatgpt' => '', 'gemini' => '', 'perplexity' => '', 'grok' => '', ), 'airize_custom_colors' => array( 'chatgpt' => '#10A37F', 'gemini' => '#4285F4', 'perplexity' => '#1E3A8A', 'grok' => '#000000', ), 'airize_button_size' => 'medium', 'airize_position' => 'after_content', ); } /** * Add Settings link on the Plugins page. * * @param string[] $links Action links. * @return string[] */ public function add_plugin_action_links( $links ) { $settings_link = sprintf( '%s', esc_url( admin_url( 'options-general.php?page=airize-settings' ) ), esc_html__( 'Settings', 'airize' ) ); array_unshift( $links, $settings_link ); return $links; } /** * Enqueue admin scripts on the settings page. * * @param string $hook Admin page hook suffix. * @return void */ public function admin_enqueue_scripts( $hook ) { if ( empty( $this->settings_page_hook ) || $hook !== $this->settings_page_hook ) { return; } wp_enqueue_media(); wp_enqueue_style( 'airize-style', AIRIZE_PLUGIN_URL . 'assets/style.css', array(), AIRIZE_VERSION ); wp_enqueue_style( 'wp-color-picker' ); wp_enqueue_script( 'airize-admin', AIRIZE_PLUGIN_URL . 'assets/admin.js', array( 'jquery', 'wp-color-picker' ), AIRIZE_VERSION, true ); wp_localize_script( 'airize-admin', 'airizeAdmin', array( 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( 'airize_test_links' ), 'i18n' => array( 'error' => __( 'Unable to load preview. Please try again.', 'airize' ), 'mediaTitle' => __( 'Select an icon', 'airize' ), 'mediaButton' => __( 'Use this icon', 'airize' ), ), ) ); } public function add_admin_menu() { $this->settings_page_hook = add_options_page( __( 'AIRize Settings', 'airize' ), __( 'AIRize', 'airize' ), 'manage_options', 'airize-settings', array( $this, 'admin_page' ) ); } public function register_settings() { $defaults = self::get_default_options(); register_setting( 'airize_settings', 'airize_providers', array( 'type' => 'array', 'sanitize_callback' => array( $this, 'sanitize_providers' ), 'default' => $defaults['airize_providers'], ) ); register_setting( 'airize_settings', 'airize_show_pages', array( 'type' => 'boolean', 'sanitize_callback' => array( $this, 'sanitize_checkbox' ), 'default' => $defaults['airize_show_pages'], ) ); register_setting( 'airize_settings', 'airize_show_posts', array( 'type' => 'boolean', 'sanitize_callback' => array( $this, 'sanitize_checkbox' ), 'default' => $defaults['airize_show_posts'], ) ); register_setting( 'airize_settings', 'airize_design_style', array( 'type' => 'string', 'sanitize_callback' => array( $this, 'sanitize_design_style' ), 'default' => $defaults['airize_design_style'], ) ); register_setting( 'airize_settings', 'airize_button_text', array( 'type' => 'array', 'sanitize_callback' => array( $this, 'sanitize_button_text' ), 'default' => $defaults['airize_button_text'], ) ); register_setting( 'airize_settings', 'airize_prompt_text', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => $defaults['airize_prompt_text'], ) ); register_setting( 'airize_settings', 'airize_intro_text', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => $defaults['airize_intro_text'], ) ); register_setting( 'airize_settings', 'airize_provider_icons', array( 'type' => 'array', 'sanitize_callback' => array( $this, 'sanitize_provider_icons' ), 'default' => $defaults['airize_provider_icons'], ) ); register_setting( 'airize_settings', 'airize_custom_colors', array( 'type' => 'array', 'sanitize_callback' => array( $this, 'sanitize_custom_colors' ), 'default' => $defaults['airize_custom_colors'], ) ); register_setting( 'airize_settings', 'airize_button_size', array( 'type' => 'string', 'sanitize_callback' => array( $this, 'sanitize_button_size' ), 'default' => $defaults['airize_button_size'], ) ); register_setting( 'airize_settings', 'airize_position', array( 'type' => 'string', 'sanitize_callback' => array( $this, 'sanitize_position' ), 'default' => $defaults['airize_position'], ) ); // Add settings sections add_settings_section( 'airize_providers_section', __( 'AI Provider Settings', 'airize' ), array($this, 'providers_section_callback'), 'airize-settings' ); add_settings_section( 'airize_display_section', __( 'Display Settings', 'airize' ), array($this, 'display_section_callback'), 'airize-settings' ); add_settings_section( 'airize_customization_section', __( 'Customization Settings', 'airize' ), array($this, 'customization_section_callback'), 'airize-settings' ); // Add fields add_settings_field( 'airize_providers', __( 'Enable AI Providers', 'airize' ), array($this, 'providers_field_callback'), 'airize-settings', 'airize_providers_section' ); add_settings_field( 'airize_show_pages', __( 'Show on Pages', 'airize' ), array($this, 'show_pages_field_callback'), 'airize-settings', 'airize_display_section' ); add_settings_field( 'airize_show_posts', __( 'Show on Posts', 'airize' ), array($this, 'show_posts_field_callback'), 'airize-settings', 'airize_display_section' ); add_settings_field( 'airize_design_style', __( 'Design Style', 'airize' ), array($this, 'design_style_field_callback'), 'airize-settings', 'airize_display_section' ); add_settings_field( 'airize_position', __( 'Button Position', 'airize' ), array($this, 'position_field_callback'), 'airize-settings', 'airize_display_section' ); add_settings_field( 'airize_button_text', __( 'Button Text', 'airize' ), array($this, 'button_text_field_callback'), 'airize-settings', 'airize_customization_section' ); add_settings_field( 'airize_prompt_text', __( 'Prompt Text', 'airize' ), array($this, 'prompt_text_field_callback'), 'airize-settings', 'airize_customization_section' ); add_settings_field( 'airize_intro_text', __( 'Text Before Buttons', 'airize' ), array( $this, 'intro_text_field_callback' ), 'airize-settings', 'airize_customization_section' ); add_settings_field( 'airize_provider_icons', __( 'Provider Icons', 'airize' ), array( $this, 'provider_icons_field_callback' ), 'airize-settings', 'airize_customization_section' ); add_settings_field( 'airize_button_size', __( 'Button Size', 'airize' ), array($this, 'button_size_field_callback'), 'airize-settings', 'airize_customization_section' ); add_settings_field( 'airize_custom_colors', __( 'Custom Colors', 'airize' ), array($this, 'custom_colors_field_callback'), 'airize-settings', 'airize_customization_section' ); } /** * Sanitize provider settings. * * @param mixed $value Raw value. * @return array */ public function sanitize_providers( $value ) { $defaults = self::get_default_options(); $value = is_array( $value ) ? $value : array(); $sanitized = array(); foreach ( $defaults['airize_providers'] as $provider => $enabled ) { $sanitized[ $provider ] = empty( $value[ $provider ] ) ? 0 : 1; } return $sanitized; } /** * Sanitize checkbox values to 0/1. * * @param mixed $value Raw value. * @return int */ public function sanitize_checkbox( $value ) { return empty( $value ) ? 0 : 1; } /** * Sanitize design style. * * @param mixed $value Raw value. * @return string */ public function sanitize_design_style( $value ) { $allowed = array( 'style1', 'style2', 'style3', 'style4' ); $value = is_string( $value ) ? $value : ''; if ( in_array( $value, $allowed, true ) ) { return $value; } $defaults = self::get_default_options(); return $defaults['airize_design_style']; } /** * Sanitize button size. * * @param mixed $value Raw value. * @return string */ public function sanitize_button_size( $value ) { $allowed = array( 'small', 'medium', 'large' ); $value = is_string( $value ) ? $value : ''; if ( in_array( $value, $allowed, true ) ) { return $value; } $defaults = self::get_default_options(); return $defaults['airize_button_size']; } /** * Sanitize button position. * * @param mixed $value Raw value. * @return string */ public function sanitize_position( $value ) { $allowed = array( 'before_content', 'after_content', 'both' ); $value = is_string( $value ) ? $value : ''; if ( in_array( $value, $allowed, true ) ) { return $value; } $defaults = self::get_default_options(); return $defaults['airize_position']; } /** * Sanitize custom button text values. * * @param mixed $value Raw value. * @return array */ public function sanitize_button_text( $value ) { $defaults = self::get_default_options(); $value = is_array( $value ) ? $value : array(); $sanitized = array(); foreach ( $defaults['airize_button_text'] as $provider => $label ) { $sanitized[ $provider ] = isset( $value[ $provider ] ) ? sanitize_text_field( $value[ $provider ] ) : $label; } return $sanitized; } /** * Sanitize custom colors. * * @param mixed $value Raw value. * @return array */ public function sanitize_custom_colors( $value ) { $defaults = self::get_default_options(); $value = is_array( $value ) ? $value : array(); $sanitized = array(); foreach ( $defaults['airize_custom_colors'] as $provider => $color ) { $maybe_color = isset( $value[ $provider ] ) ? sanitize_hex_color( $value[ $provider ] ) : ''; $sanitized[ $provider ] = empty( $maybe_color ) ? $color : $maybe_color; } return $sanitized; } /** * Sanitize provider icon URLs. * * @param mixed $value Raw value. * @return array */ public function sanitize_provider_icons( $value ) { $defaults = self::get_default_options(); $value = is_array( $value ) ? $value : array(); $sanitized = array(); foreach ( $defaults['airize_provider_icons'] as $provider => $default_url ) { $url = isset( $value[ $provider ] ) ? esc_url_raw( $value[ $provider ] ) : ''; if ( '' !== $url && ! wp_http_validate_url( $url ) ) { $url = ''; } $sanitized[ $provider ] = $url; } return $sanitized; } // Section callbacks public function providers_section_callback() { echo '

' . esc_html__( 'Choose which AI providers to enable for content summarization.', 'airize' ) . '

'; } public function display_section_callback() { echo '

' . esc_html__( 'Configure where and how the AI buttons should appear.', 'airize' ) . '

'; } public function customization_section_callback() { echo '

' . esc_html__( 'Customize the appearance and behavior of the AI buttons.', 'airize' ) . '

'; } // Field callbacks public function providers_field_callback() { $defaults = self::get_default_options(); $options = $this->sanitize_providers( get_option( 'airize_providers', $defaults['airize_providers'] ) ); $providers = array( 'chatgpt' => __( 'ChatGPT', 'airize' ), 'gemini' => __( 'Google Gemini', 'airize' ), 'perplexity' => __( 'Perplexity', 'airize' ), 'grok' => __( 'Grok', 'airize' ), ); echo '
'; foreach ( $providers as $key => $label ) { printf( '
', esc_attr( $key ), checked( 1, (int) $options[ $key ], false ), esc_html( $label ) ); } echo '
'; } public function show_pages_field_callback() { $defaults = self::get_default_options(); $value = (int) $this->sanitize_checkbox( get_option( 'airize_show_pages', $defaults['airize_show_pages'] ) ); printf( '', checked( 1, $value, false ), esc_html__( 'Show AI buttons on pages', 'airize' ) ); } public function show_posts_field_callback() { $defaults = self::get_default_options(); $value = (int) $this->sanitize_checkbox( get_option( 'airize_show_posts', $defaults['airize_show_posts'] ) ); printf( '', checked( 1, $value, false ), esc_html__( 'Show AI buttons on posts', 'airize' ) ); } public function design_style_field_callback() { $defaults = self::get_default_options(); $value = $this->sanitize_design_style( get_option( 'airize_design_style', $defaults['airize_design_style'] ) ); $styles = array( 'style1' => __( 'Style 1: Clean & Modern', 'airize' ), 'style2' => __( 'Style 2: Rounded & Colorful', 'airize' ), 'style3' => __( 'Style 3: Minimal & Compact', 'airize' ), 'style4' => __( 'Style 4: Bold & Prominent', 'airize' ), ); echo ''; } public function position_field_callback() { $defaults = self::get_default_options(); $value = $this->sanitize_position( get_option( 'airize_position', $defaults['airize_position'] ) ); $positions = array( 'before_content' => __( 'Before Content', 'airize' ), 'after_content' => __( 'After Content', 'airize' ), 'both' => __( 'Both Before & After', 'airize' ), ); echo ''; } public function button_text_field_callback() { $defaults = self::get_default_options(); $options = $this->sanitize_button_text( get_option( 'airize_button_text', $defaults['airize_button_text'] ) ); $providers = array( 'chatgpt' => __( 'ChatGPT', 'airize' ), 'gemini' => __( 'Gemini', 'airize' ), 'perplexity' => __( 'Perplexity', 'airize' ), 'grok' => __( 'Grok', 'airize' ), ); echo '
'; foreach ( $providers as $key => $label ) { printf( '


', esc_attr( $key ), esc_html( $label ), esc_attr( $options[ $key ] ) ); } echo '
'; } public function prompt_text_field_callback() { $defaults = self::get_default_options(); $value = sanitize_text_field( get_option( 'airize_prompt_text', $defaults['airize_prompt_text'] ) ); printf( '', esc_attr( $value ) ); echo '

' . esc_html__( 'This text will be used in the AI prompt along with the page URL and your site name.', 'airize' ) . '

'; } /** * Field: text before buttons. * * @return void */ public function intro_text_field_callback() { $defaults = self::get_default_options(); $value = sanitize_text_field( get_option( 'airize_intro_text', $defaults['airize_intro_text'] ) ); printf( '', esc_attr( $value ) ); echo '

' . esc_html__( 'Optional text shown before the AI buttons (for example: "Summarize with:").', 'airize' ) . '

'; } /** * Field: provider icons. * * @return void */ public function provider_icons_field_callback() { $defaults = self::get_default_options(); $options = $this->sanitize_provider_icons( get_option( 'airize_provider_icons', $defaults['airize_provider_icons'] ) ); $providers = array( 'chatgpt' => __( 'ChatGPT', 'airize' ), 'gemini' => __( 'Gemini', 'airize' ), 'perplexity' => __( 'Perplexity', 'airize' ), 'grok' => __( 'Grok', 'airize' ), ); echo '
'; foreach ( $providers as $key => $label ) { $field_id = 'airize_provider_icon_' . $key; $value = isset( $options[ $key ] ) ? $options[ $key ] : ''; $hidden_class = empty( $value ) ? ' is-hidden' : ''; printf( '


', esc_attr( $field_id ), esc_html( $label ), esc_attr( $key ), esc_attr( $value ), esc_attr__( 'https://example.com/icon.png', 'airize' ), esc_html__( 'Select', 'airize' ), esc_html__( 'Remove', 'airize' ) ); printf( '

', esc_attr( $field_id ), esc_attr( $hidden_class ), esc_url( $value ) ); } echo '
'; echo '

' . esc_html__( 'Upload/select an image from the Media Library, or paste an image URL. Leave empty to show no icon.', 'airize' ) . '

'; } public function button_size_field_callback() { $defaults = self::get_default_options(); $value = $this->sanitize_button_size( get_option( 'airize_button_size', $defaults['airize_button_size'] ) ); $sizes = array( 'small' => __( 'Small', 'airize' ), 'medium' => __( 'Medium', 'airize' ), 'large' => __( 'Large', 'airize' ), ); echo ''; } public function custom_colors_field_callback() { $defaults = self::get_default_options(); $options = $this->sanitize_custom_colors( get_option( 'airize_custom_colors', $defaults['airize_custom_colors'] ) ); $providers = array( 'chatgpt' => __( 'ChatGPT', 'airize' ), 'gemini' => __( 'Gemini', 'airize' ), 'perplexity' => __( 'Perplexity', 'airize' ), 'grok' => __( 'Grok', 'airize' ), ); echo '
'; foreach ( $providers as $key => $label ) { printf( '


', esc_attr( $key ), esc_html( $label ), esc_attr( $options[ $key ] ), esc_attr( $defaults['airize_custom_colors'][ $key ] ) ); } echo '
'; } public function admin_page() { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'You do not have permission to access this page.', 'airize' ) ); } ?>

sanitize_checkbox( get_option( 'airize_show_pages', $defaults['airize_show_pages'] ) ); $show_posts = (int) $this->sanitize_checkbox( get_option( 'airize_show_posts', $defaults['airize_show_posts'] ) ); if ( ( 'page' === $post_type && ! $show_pages ) || ( 'post' === $post_type && ! $show_posts ) ) { return; } $providers = $this->sanitize_providers( get_option( 'airize_providers', $defaults['airize_providers'] ) ); if ( empty( array_filter( $providers ) ) ) { return; } wp_enqueue_style( 'airize-style', AIRIZE_PLUGIN_URL . 'assets/style.css', array(), AIRIZE_VERSION ); } public function add_ai_buttons( $content ) { if ( is_admin() || ! is_singular() || post_password_required() ) { return $content; } $post_type = get_post_type(); $defaults = self::get_default_options(); $show_pages = (int) $this->sanitize_checkbox( get_option( 'airize_show_pages', $defaults['airize_show_pages'] ) ); $show_posts = (int) $this->sanitize_checkbox( get_option( 'airize_show_posts', $defaults['airize_show_posts'] ) ); if ( ( 'page' === $post_type && ! $show_pages ) || ( 'post' === $post_type && ! $show_posts ) ) { return $content; } $ai_buttons = $this->generate_ai_buttons( get_permalink(), get_the_title() ); if ( empty( $ai_buttons ) ) { return $content; } $position = $this->sanitize_position( get_option( 'airize_position', $defaults['airize_position'] ) ); switch ( $position ) { case 'before_content': return $ai_buttons . $content; case 'both': return $ai_buttons . $content . $ai_buttons; case 'after_content': default: return $content . $ai_buttons; } } /** * Build an AI prompt. * * @param string $prompt_text Prompt text. * @param string $page_url Page URL. * @param string $page_title Page title. * @return string */ private function build_prompt( $prompt_text, $page_url, $page_title ) { $prompt_text = sanitize_text_field( $prompt_text ); $page_url = esc_url_raw( $page_url ); $page_title = sanitize_text_field( $page_title ); $site_name = sanitize_text_field( get_bloginfo( 'name' ) ); $parts = array_filter( array( $prompt_text, $page_title, $page_url, sprintf( 'Source: %s', $site_name ), ) ); $prompt = implode( "\n\n", $parts ); return (string) apply_filters( 'airize_prompt', $prompt, $page_url, $page_title ); } /** * Provider URL templates. * * @return array */ private function get_provider_templates() { return array( 'chatgpt' => array( 'base' => 'https://chatgpt.com/', 'param' => 'q', ), 'gemini' => array( 'base' => 'https://gemini.google.com/app', 'param' => 'q', ), 'perplexity' => array( 'base' => 'https://www.perplexity.ai/search', 'param' => 'q', ), 'grok' => array( 'base' => 'https://grok.x.ai/', 'param' => 'q', ), ); } /** * Build provider link for a prompt. * * @param string $provider Provider key. * @param string $prompt Prompt text. * @return string */ private function build_provider_link( $provider, $prompt ) { $templates = $this->get_provider_templates(); if ( empty( $templates[ $provider ] ) ) { return ''; } $base = $templates[ $provider ]['base']; $param = $templates[ $provider ]['param']; $url = add_query_arg( array( $param => $prompt ), $base ); return (string) apply_filters( 'airize_provider_url', $url, $provider, $prompt ); } /** * Generate the AI buttons block HTML. * * @param string $page_url Page URL. * @param string $page_title Page title. * @param array $overrides Optional settings overrides (used for preview). * @return string */ private function generate_ai_buttons( $page_url = '', $page_title = '', $overrides = array() ) { $defaults = self::get_default_options(); $providers = isset( $overrides['providers'] ) ? $this->sanitize_providers( $overrides['providers'] ) : $this->sanitize_providers( get_option( 'airize_providers', $defaults['airize_providers'] ) ); if ( empty( array_filter( $providers ) ) ) { return ''; } $button_texts = isset( $overrides['button_text'] ) ? $this->sanitize_button_text( $overrides['button_text'] ) : $this->sanitize_button_text( get_option( 'airize_button_text', $defaults['airize_button_text'] ) ); $custom_colors = isset( $overrides['custom_colors'] ) ? $this->sanitize_custom_colors( $overrides['custom_colors'] ) : $this->sanitize_custom_colors( get_option( 'airize_custom_colors', $defaults['airize_custom_colors'] ) ); $design_style = isset( $overrides['design_style'] ) ? $this->sanitize_design_style( $overrides['design_style'] ) : $this->sanitize_design_style( get_option( 'airize_design_style', $defaults['airize_design_style'] ) ); $button_size = isset( $overrides['button_size'] ) ? $this->sanitize_button_size( $overrides['button_size'] ) : $this->sanitize_button_size( get_option( 'airize_button_size', $defaults['airize_button_size'] ) ); $prompt_text = isset( $overrides['prompt_text'] ) ? sanitize_text_field( $overrides['prompt_text'] ) : sanitize_text_field( get_option( 'airize_prompt_text', $defaults['airize_prompt_text'] ) ); $intro_text = isset( $overrides['intro_text'] ) ? sanitize_text_field( $overrides['intro_text'] ) : sanitize_text_field( get_option( 'airize_intro_text', $defaults['airize_intro_text'] ) ); $provider_icons = isset( $overrides['provider_icons'] ) ? $this->sanitize_provider_icons( $overrides['provider_icons'] ) : $this->sanitize_provider_icons( get_option( 'airize_provider_icons', $defaults['airize_provider_icons'] ) ); if ( empty( $page_url ) ) { $page_url = home_url( '/' ); } $prompt = $this->build_prompt( $prompt_text, $page_url, $page_title ); $container_classes = array( 'airize-buttons-block', 'airize-buttons-block--align-center', 'airize-style-' . $design_style, 'airize-size-' . $button_size, ); $output = '
'; $output .= '
'; if ( ! empty( $intro_text ) ) { $output .= '' . esc_html( $intro_text ) . ''; } foreach ( $providers as $provider => $enabled ) { if ( empty( $enabled ) ) { continue; } $link = $this->build_provider_link( $provider, $prompt ); if ( empty( $link ) ) { continue; } $color = isset( $custom_colors[ $provider ] ) ? sanitize_hex_color( $custom_colors[ $provider ] ) : ''; $color = empty( $color ) ? $defaults['airize_custom_colors'][ $provider ] : $color; $color_2 = $this->adjust_hex_brightness( $color, -40 ); $text_color = $this->get_contrasting_text_color( $color ); $style_attr = sprintf( '--airize-btn-color:%1$s;--airize-btn-color-2:%2$s;--airize-btn-text:%3$s;', $color, $color_2, $text_color ); $label = isset( $button_texts[ $provider ] ) ? $button_texts[ $provider ] : ucfirst( $provider ); $icon_html = ''; if ( ! empty( $provider_icons[ $provider ] ) ) { $icon_html = ''; } $output .= sprintf( '%4$s%5$s', esc_attr( $provider ), esc_url( $link ), esc_attr( $style_attr ), $icon_html, esc_html( $label ) ); } $output .= '
'; return $output; } /** * Adjust a hex color brightness. * * @param string $hex_color Hex color. * @param int $steps Steps (-255 to 255). * @return string */ private function adjust_hex_brightness( $hex_color, $steps ) { $hex_color = sanitize_hex_color( $hex_color ); if ( empty( $hex_color ) ) { return '#000000'; } $steps = (int) $steps; $steps = max( -255, min( 255, $steps ) ); $hex = ltrim( $hex_color, '#' ); if ( 3 === strlen( $hex ) ) { $hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2]; } $red = hexdec( substr( $hex, 0, 2 ) ); $green = hexdec( substr( $hex, 2, 2 ) ); $blue = hexdec( substr( $hex, 4, 2 ) ); $red = max( 0, min( 255, $red + $steps ) ); $green = max( 0, min( 255, $green + $steps ) ); $blue = max( 0, min( 255, $blue + $steps ) ); return sprintf( '#%02x%02x%02x', $red, $green, $blue ); } /** * Get a readable text color for a background. * * @param string $hex_color Hex color. * @return string */ private function get_contrasting_text_color( $hex_color ) { $hex_color = sanitize_hex_color( $hex_color ); if ( empty( $hex_color ) ) { return '#ffffff'; } $hex = ltrim( $hex_color, '#' ); if ( 3 === strlen( $hex ) ) { $hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2]; } $red = hexdec( substr( $hex, 0, 2 ) ); $green = hexdec( substr( $hex, 2, 2 ) ); $blue = hexdec( substr( $hex, 4, 2 ) ); $yiq = ( ( $red * 299 ) + ( $green * 587 ) + ( $blue * 114 ) ) / 1000; return ( $yiq >= 128 ) ? '#000000' : '#ffffff'; } /** * AJAX: return preview HTML for the settings page. * * @return void */ public function test_ai_links() { if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( array( 'message' => __( 'Forbidden', 'airize' ) ), 403 ); } check_ajax_referer( 'airize_test_links', 'nonce' ); $overrides = array(); $defaults = self::get_default_options(); $provider_keys = array_keys( $defaults['airize_providers'] ); $preview = filter_input( INPUT_POST, 'preview', FILTER_UNSAFE_RAW, FILTER_REQUIRE_ARRAY ); if ( is_array( $preview ) ) { $preview = wp_unslash( $preview ); } else { $preview = array(); } if ( ! empty( $preview ) ) { if ( isset( $preview['providers'] ) && is_array( $preview['providers'] ) ) { $providers = array(); foreach ( $provider_keys as $provider_key ) { $value = isset( $preview['providers'][ $provider_key ] ) ? absint( $preview['providers'][ $provider_key ] ) : 0; $providers[ $provider_key ] = empty( $value ) ? 0 : 1; } $overrides['providers'] = $providers; } if ( isset( $preview['button_text'] ) && is_array( $preview['button_text'] ) ) { $button_text = array(); foreach ( $provider_keys as $provider_key ) { if ( ! isset( $preview['button_text'][ $provider_key ] ) ) { continue; } $button_text[ $provider_key ] = sanitize_text_field( $preview['button_text'][ $provider_key ] ); } $overrides['button_text'] = $button_text; } if ( isset( $preview['custom_colors'] ) && is_array( $preview['custom_colors'] ) ) { $custom_colors = array(); foreach ( $provider_keys as $provider_key ) { if ( ! isset( $preview['custom_colors'][ $provider_key ] ) ) { continue; } $custom_colors[ $provider_key ] = sanitize_hex_color( $preview['custom_colors'][ $provider_key ] ); } $overrides['custom_colors'] = $custom_colors; } if ( isset( $preview['design_style'] ) ) { $design_style = sanitize_key( $preview['design_style'] ); if ( in_array( $design_style, array( 'style1', 'style2', 'style3', 'style4' ), true ) ) { $overrides['design_style'] = $design_style; } } if ( isset( $preview['button_size'] ) ) { $button_size = sanitize_key( $preview['button_size'] ); if ( in_array( $button_size, array( 'small', 'medium', 'large' ), true ) ) { $overrides['button_size'] = $button_size; } } if ( isset( $preview['prompt_text'] ) ) { $overrides['prompt_text'] = sanitize_text_field( $preview['prompt_text'] ); } if ( isset( $preview['intro_text'] ) ) { $overrides['intro_text'] = sanitize_text_field( $preview['intro_text'] ); } if ( isset( $preview['provider_icons'] ) && is_array( $preview['provider_icons'] ) ) { $provider_icons = array(); foreach ( $provider_keys as $provider_key ) { $url = isset( $preview['provider_icons'][ $provider_key ] ) ? esc_url_raw( $preview['provider_icons'][ $provider_key ] ) : ''; if ( '' !== $url && ! wp_http_validate_url( $url ) ) { $url = ''; } $provider_icons[ $provider_key ] = $url; } $overrides['provider_icons'] = $provider_icons; } } $html = $this->generate_ai_buttons( home_url( '/' ), __( 'Example Page', 'airize' ), $overrides ); wp_send_json_success( array( 'html' => $html, ) ); } } register_activation_hook( AIRIZE_PLUGIN_FILE, array( 'AIRizePlugin', 'activate' ) ); new AIRizePlugin();