plugin_url = plugin_dir_url(dirname(__FILE__)); $this->init(); } public function init() { // Check if frontend widget is enabled if ($this->is_widget_enabled()) { add_action('wp_enqueue_scripts', [$this, 'enqueue_frontend_scripts']); add_action('wp_footer', [$this, 'render_widget_template']); } } /** * Check if frontend widget is enabled */ private function is_widget_enabled() { return (bool) get_option('acb_frontend_widget_enabled', true); } /** * Enqueue frontend scripts and styles */ public function enqueue_frontend_scripts() { // Only load on frontend pages if (is_admin()) { return; } // Enqueue frontend widget styles wp_enqueue_style( 'acb-frontend-widget-style', esc_url($this->plugin_url . 'build/frontend-index.css'), [], '1.0.0' ); wp_enqueue_style( 'font-awesome', esc_url($this->plugin_url . 'assets/library/all.min.css'), [], '5.15.4' ); // Enqueue frontend widget script wp_enqueue_script( 'acb-frontend-widget-script', esc_url($this->plugin_url . 'build/frontend-index.js'), ['jquery', 'wp-element'], '1.0.0', true ); // Pass Firebase config and nonces to frontend $firebase_config = get_option('acb_firebase_config', []); // Sanitize Firebase config before passing to frontend $sanitized_config = $this->sanitize_firebase_config($firebase_config); wp_localize_script('acb-frontend-widget-script', 'acb_firebase_config', $sanitized_config); wp_localize_script('acb-frontend-widget-script', 'acb_firebase_nonce', wp_create_nonce('acb_firebase_nonce')); wp_localize_script('acb-frontend-widget-script', 'ajaxurl', esc_url(admin_url('admin-ajax.php'))); } /** * Sanitize Firebase config for frontend use */ private function sanitize_firebase_config($config) { if (!is_array($config)) { return []; } $sanitized = []; $allowed_keys = ['apiKey', 'authDomain', 'projectId', 'storageBucket', 'messagingSenderId', 'appId']; foreach ($allowed_keys as $key) { if (isset($config[$key])) { $sanitized[$key] = sanitize_text_field($config[$key]); } } return $sanitized; } /** * Render widget template in footer */ public function render_widget_template() { // Only render if widget is enabled if (!$this->is_widget_enabled()) { return; } // Get widget settings with proper sanitization $widget_position = sanitize_text_field(get_option('acb_widget_position', 'bottom-right')); $widget_title = sanitize_text_field(get_option('acb_widget_title', 'Chat Support')); $widget_description = sanitize_text_field(get_option('acb_widget_description', 'Need help? Chat with our team!')); // Validate position value $allowed_positions = ['bottom-right', 'bottom-left', 'top-right', 'top-left']; if (!in_array($widget_position, $allowed_positions, true)) { $widget_position = 'bottom-right'; } ?>
(bool) get_option('acb_frontend_widget_enabled', false), 'position' => sanitize_text_field(get_option('acb_widget_position', 'bottom-right')), 'title' => sanitize_text_field(get_option('acb_widget_title', 'Chat Support')), 'description' => sanitize_text_field(get_option('acb_widget_description', 'Need help? Chat with our team!')), 'show_on_pages' => sanitize_text_field(get_option('acb_widget_show_on_pages', 'all')), 'exclude_pages' => sanitize_textarea_field(get_option('acb_widget_exclude_pages', '')), ]; } /** * Save widget settings with proper validation and sanitization */ public static function save_widget_settings($settings) { // Verify nonce if this is an AJAX request if (wp_doing_ajax()) { if (!wp_verify_nonce($_POST['nonce'] ?? '', 'acb_widget_settings_nonce')) { wp_send_json_error(['message' => 'Invalid security token']); return false; } } // Check user capabilities if (!current_user_can('manage_options')) { wp_send_json_error(['message' => 'Insufficient permissions']); return false; } // Validate and sanitize input if (!is_array($settings)) { wp_send_json_error(['message' => 'Invalid settings format']); return false; } // Sanitize enabled setting $enabled = isset($settings['enabled']) ? (bool) $settings['enabled'] : false; update_option('acb_frontend_widget_enabled', $enabled); // Sanitize and validate position $position = sanitize_text_field($settings['position'] ?? 'bottom-right'); $allowed_positions = ['bottom-right', 'bottom-left', 'top-right', 'top-left']; if (!in_array($position, $allowed_positions, true)) { $position = 'bottom-right'; } update_option('acb_widget_position', $position); // Sanitize text fields $title = sanitize_text_field($settings['title'] ?? 'Chat Support'); $title = wp_unslash($title); // Remove slashes if any if (strlen($title) > 100) { // Limit title length $title = substr($title, 0, 100); } update_option('acb_widget_title', $title); $description = sanitize_textarea_field($settings['description'] ?? 'Need help? Chat with our team!'); $description = wp_unslash($description); // Remove slashes if any if (strlen($description) > 500) { // Limit description length $description = substr($description, 0, 500); } update_option('acb_widget_description', $description); // Sanitize show_on_pages $show_on_pages = sanitize_text_field($settings['show_on_pages'] ?? 'all'); $allowed_show_options = ['all', 'specific', 'exclude']; if (!in_array($show_on_pages, $allowed_show_options, true)) { $show_on_pages = 'all'; } update_option('acb_widget_show_on_pages', $show_on_pages); // Sanitize exclude_pages $exclude_pages = sanitize_textarea_field($settings['exclude_pages'] ?? ''); $exclude_pages = wp_unslash($exclude_pages); // Remove slashes if any // Validate page IDs if provided if (!empty($exclude_pages)) { $page_ids = array_map('trim', explode(',', $exclude_pages)); $valid_page_ids = []; foreach ($page_ids as $page_id) { $page_id = absint($page_id); // Ensure positive integer if ($page_id > 0) { $valid_page_ids[] = $page_id; } } $exclude_pages = implode(',', $valid_page_ids); } update_option('acb_widget_exclude_pages', $exclude_pages); // Send success response for AJAX requests if (wp_doing_ajax()) { wp_send_json_success(['message' => 'Settings saved successfully']); } return true; } /** * Check if widget should be displayed on current page */ private function should_display_widget() { $show_on_pages = get_option('acb_widget_show_on_pages', 'all'); $exclude_pages = get_option('acb_widget_exclude_pages', ''); $current_page_id = get_the_ID(); // If excluding specific pages if (!empty($exclude_pages) && $current_page_id) { $excluded_ids = array_map('absint', explode(',', $exclude_pages)); if (in_array($current_page_id, $excluded_ids, true)) { return false; } } // Additional display logic can be added here return true; } /** * AJAX handler for widget settings */ public static function ajax_save_widget_settings() { // This method would be called via AJAX // The nonce verification is handled in save_widget_settings() $settings = $_POST['settings'] ?? []; // Unslash the entire settings array $settings = wp_unslash($settings); self::save_widget_settings($settings); } }