true ], 'names' ); unset( $post_types['attachment'] ); $auth = static function ( $allowed, $meta_key, $post_id ) { return current_user_can( 'edit_post', (int) $post_id ); }; foreach ( $post_types as $type ) { // Required for the block editor to persist post meta via REST. add_post_type_support( $type, 'custom-fields' ); register_post_meta( $type, self::META_SCENARIO, [ 'type' => 'string', 'single' => true, 'default' => '', 'show_in_rest' => true, 'auth_callback' => $auth, 'sanitize_callback' => static function ( $v ) { // Keep accents/unicode; only whitespace → dash (mirrors the backend's // scenario-name format). Stripping accents ("dépannage" → "dpannage") // would break the match with the scenario defined in the chatbot config. $v = preg_replace( '/\s+/u', '-', sanitize_text_field( (string) $v ) ); return (string) mb_substr( (string) $v, 0, 80 ); }, ] ); register_post_meta( $type, self::META_CONTEXT_HINT, [ 'type' => 'string', 'single' => true, 'default' => '', 'show_in_rest' => true, 'auth_callback' => $auth, 'sanitize_callback' => static function ( $v ) { return (string) substr( sanitize_textarea_field( (string) $v ), 0, 2000 ); }, ] ); register_post_meta( $type, self::META_BUBBLE, [ 'type' => 'string', 'single' => true, 'default' => '', 'show_in_rest' => true, 'auth_callback' => $auth, 'sanitize_callback' => static function ( $v ) { return in_array( $v, [ 'show', 'hide' ], true ) ? (string) $v : ''; }, ] ); } } /** * Enqueue the block-editor sidebar panel that edits the per-page overrides. */ public function enqueue_editor_panel(): void { $handle = 'agentsia-chatbot-editor-panel'; wp_register_script( $handle, AGENTSIA_AGENTS_URL . 'assets/js/editor-panel.js', [ 'wp-plugins', 'wp-editor', 'wp-edit-post', 'wp-element', 'wp-components', 'wp-data', 'wp-core-data', 'wp-i18n' ], AGENTSIA_AGENTS_VERSION, true ); wp_set_script_translations( $handle, 'agentsia-agents' ); $settings = Plugin::get_settings(); $config_id = (string) ( $settings['chatbot_config_id'] ?? '' ); $scenarios = []; if ( $config_id !== '' ) { foreach ( Api_Client::list_chatbots() as $bot ) { if ( ( $bot['chatbotConfigId'] ?? '' ) === $config_id && isset( $bot['scenarios'] ) && is_array( $bot['scenarios'] ) ) { $scenarios = array_values( $bot['scenarios'] ); break; } } } $default_scenario = (string) ( $settings['default_scenario'] ?? '' ); wp_localize_script( $handle, 'AgentsiaEditorPanel', [ 'scenarios' => $scenarios, 'hasScenarioList' => ! empty( $scenarios ), 'defaultLabel' => $default_scenario !== '' ? __( 'Défaut', 'agentsia-agents' ) . ' (' . $default_scenario . ')' : __( '— Scénario par défaut —', 'agentsia-agents' ), ] ); wp_enqueue_script( $handle ); } /** * Display the meta box on every public post type (post, page, custom types * marked `public => true`). */ public function add_meta_box(): void { // In the block editor the JS sidebar panel handles these overrides; the // classic meta box stays only for the classic editor / page builders. $screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null; if ( $screen && method_exists( $screen, 'is_block_editor' ) && $screen->is_block_editor() ) { return; } $post_types = get_post_types( [ 'public' => true ], 'names' ); // Drop "attachment" — useless there. unset( $post_types['attachment'] ); foreach ( $post_types as $type ) { add_meta_box( 'agentsia-chatbot-overrides', __( 'Agentsia — Chatbot', 'agentsia-agents' ), [ $this, 'render_meta_box' ], $type, 'side', 'default' ); } } public function render_meta_box( \WP_Post $post ): void { wp_nonce_field( self::NONCE_ACTION, self::NONCE_FIELD ); $scenario = (string) get_post_meta( $post->ID, self::META_SCENARIO, true ); $context_hint = (string) get_post_meta( $post->ID, self::META_CONTEXT_HINT, true ); $bubble = (string) get_post_meta( $post->ID, self::META_BUBBLE, true ); if ( $bubble === '' ) { $bubble = 'inherit'; } $settings = Plugin::get_settings(); $default_scenario = (string) ( $settings['default_scenario'] ?? '' ); // Scénarios définis pour le chatbot sélectionné (exposés par l'API si dispo). $scenario_names = []; $config_id = (string) ( $settings['chatbot_config_id'] ?? '' ); if ( $config_id !== '' ) { foreach ( Api_Client::list_chatbots() as $bot ) { if ( ( $bot['chatbotConfigId'] ?? '' ) === $config_id && isset( $bot['scenarios'] ) && is_array( $bot['scenarios'] ) ) { $scenario_names = $bot['scenarios']; break; } } } ?>

' . esc_html( $default_scenario ) . '' ); } else { esc_html_e( 'Nom d\'un scénario défini dans la configuration du chatbot (étape « Scénarios »).', 'agentsia-agents' ); } ?>

persist_meta( $post_id, self::META_SCENARIO, $scenario ); $this->persist_meta( $post_id, self::META_CONTEXT_HINT, $context_hint ); $this->persist_meta( $post_id, self::META_BUBBLE, $bubble === 'inherit' ? '' : $bubble ); } private function persist_meta( int $post_id, string $key, string $value ): void { if ( $value === '' ) { delete_post_meta( $post_id, $key ); } else { update_post_meta( $post_id, $key, $value ); } } /** * Resolve the override array consumed by {@see Chatbot::build_data_attributes()} * for the post currently being rendered. Returns an empty array when no * override applies (front page without ID, archive, 404…). * * @return array */ public function resolve_overrides_for_current_request(): array { if ( ! is_singular() ) { return []; } $post_id = (int) get_queried_object_id(); if ( $post_id <= 0 ) { return []; } $overrides = []; $scenario = (string) get_post_meta( $post_id, self::META_SCENARIO, true ); if ( $scenario !== '' ) { $overrides['scenario'] = $scenario; } $context_hint = (string) get_post_meta( $post_id, self::META_CONTEXT_HINT, true ); if ( $context_hint !== '' ) { $overrides['context_hint'] = $context_hint; } $bubble = (string) get_post_meta( $post_id, self::META_BUBBLE, true ); if ( $bubble === 'show' ) { $overrides['hide_bubble'] = false; } elseif ( $bubble === 'hide' ) { $overrides['hide_bubble'] = true; } return $overrides; } }