init_hooks(); } private function init_hooks(): void { // Settings & Admin add_action( 'admin_init', [ $this, 'register_settings' ] ); add_action( 'admin_menu', [ $this, 'add_admin_menu' ] ); add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_admin_assets' ] ); // Frontend add_action( 'wp_footer', [ $this, 'inject_bubble_chat_script' ] ); add_shortcode( 'agentivo_chat', [ $this, 'render_shortcode' ] ); // Blocks add_action( 'init', [ $this, 'register_blocks' ] ); // Activation register_activation_hook( __FILE__, [ $this, 'activate' ] ); } /** * Helpers */ public static function get_asset_url( string $path ): string { return AGENTIVO_CHATBOTS_PLUGIN_URL . 'assets/' . ltrim( $path, '/' ); } public static function get_widget_url( string $chat_id ): string { return AGENTIVO_CHATBOTS_WIDGET_BASE_URL . sanitize_text_field( $chat_id ) . '.js'; } /** * Settings */ public function register_settings(): void { $options = [ 'agentivo_chatbots_bubble_chat_id' => [ $this, 'sanitize_chat_id' ], 'agentivo_chatbots_inline_chat_id' => [ $this, 'sanitize_chat_id' ], 'agentivo_chatbots_inline_width' => 'sanitize_text_field', 'agentivo_chatbots_inline_height' => 'sanitize_text_field', ]; foreach ( $options as $option => $callback ) { register_setting( 'agentivo_chatbots_settings', $option, [ 'type' => 'string', 'sanitize_callback' => $callback, 'default' => $option === 'agentivo_chatbots_inline_width' ? '100%' : ($option === 'agentivo_chatbots_inline_height' ? '600px' : ''), 'show_in_rest' => true, ] ); } } public function sanitize_chat_id( string $value ): string { return preg_replace( '/[^a-zA-Z0-9\-]/', '', sanitize_text_field( $value ) ); } /** * Admin UI */ public function add_admin_menu(): void { add_menu_page( __( 'Agentivo Chatbots', 'agentivo-chatbots' ), __( 'Agentivo', 'agentivo-chatbots' ), 'manage_options', 'agentivo-chatbots', [ $this, 'render_admin_page' ], 'dashicons-format-chat', 80 ); } public function enqueue_admin_assets( string $hook ): void { if ( 'toplevel_page_agentivo-chatbots' !== $hook ) return; wp_enqueue_style( 'agentivo-chatbots-admin', self::get_asset_url( 'css/admin.css' ), [], AGENTIVO_CHATBOTS_VERSION ); wp_enqueue_script( 'agentivo-chatbots-admin', self::get_asset_url( 'js/admin.js' ), [], AGENTIVO_CHATBOTS_VERSION, true ); wp_localize_script( 'agentivo-chatbots-admin', 'agentivoChatbots', [ 'copySuccess' => __( 'Shortcode copied to clipboard!', 'agentivo-chatbots' ), 'copyError' => __( 'Failed to copy. Please select and copy manually.', 'agentivo-chatbots' ), ] ); } public function render_admin_page(): void { if ( ! current_user_can( 'manage_options' ) ) return; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- settings-updated is added by WordPress core after successful save. if ( isset( $_GET['settings-updated'] ) && 'true' === $_GET['settings-updated'] ) { add_settings_error( 'agentivo_chatbots_messages', 'agentivo_chatbots_message', __( 'Settings saved successfully.', 'agentivo-chatbots' ), 'success' ); } settings_errors( 'agentivo_chatbots_messages' ); include AGENTIVO_CHATBOTS_PLUGIN_DIR . 'assets/templates/admin-page.php'; } /** * Frontend & Shortcode */ public function inject_bubble_chat_script(): void { $id = get_option( 'agentivo_chatbots_bubble_chat_id', '' ); if ( empty( $id ) ) return; wp_enqueue_script( 'agentivo-bubble-chat-' . md5( $id ), self::get_widget_url( $id ), [], AGENTIVO_CHATBOTS_VERSION, [ 'strategy' => 'async', 'in_footer' => true ] ); } public function render_shortcode( array $atts ): string { $atts = shortcode_atts( [ 'id' => get_option( 'agentivo_chatbots_inline_chat_id', '' ), 'width' => get_option( 'agentivo_chatbots_inline_width', '100%' ), 'height' => get_option( 'agentivo_chatbots_inline_height', '600px' ), ], $atts, 'agentivo_chat' ); if ( empty( $atts['id'] ) ) return '

' . esc_html__( 'Please configure the inline chat ID.', 'agentivo-chatbots' ) . '

'; wp_enqueue_script( 'agentivo-inline-chat-' . md5( $atts['id'] ), self::get_widget_url( $atts['id'] ), [], AGENTIVO_CHATBOTS_VERSION, [ 'strategy' => 'async', 'in_footer' => true ] ); return sprintf( '
', esc_attr( $atts['width'] ), esc_attr( $atts['height'] ) ); } /** * Blocks */ public function register_blocks(): void { register_block_type( 'agentivo/chat', [ 'editor_script' => 'agentivo-chat-block', 'render_callback' => [ $this, 'render_block' ], 'attributes' => [ 'id' => [ 'type' => 'string', 'default' => '' ], 'width' => [ 'type' => 'string', 'default' => '' ], 'height' => [ 'type' => 'string', 'default' => '' ], ], ] ); wp_register_script( 'agentivo-chat-block', self::get_asset_url( 'js/block.js' ), [ 'wp-blocks', 'wp-element', 'wp-editor', 'wp-components', 'wp-i18n' ], AGENTIVO_CHATBOTS_VERSION, true ); wp_set_script_translations( 'agentivo-chat-block', 'agentivo-chatbots', AGENTIVO_CHATBOTS_PLUGIN_DIR . 'languages' ); } public function render_block( array $attributes ): string { return $this->render_shortcode( $attributes ); } /** * Lifecycle */ public function activate(): void { $defaults = [ 'agentivo_chatbots_bubble_chat_id' => '', 'agentivo_chatbots_inline_chat_id' => '', 'agentivo_chatbots_inline_width' => '100%', 'agentivo_chatbots_inline_height' => '600px', ]; foreach ( $defaults as $opt => $val ) { if ( false === get_option( $opt ) ) add_option( $opt, $val ); } flush_rewrite_rules(); } } // Initialize Agentivo_Chatbots::get_instance();