%s', esc_url( self::page_url() ), esc_html__( 'Ajustes', 'ai-bots-doxi-chat' ) ); array_unshift( $links, $settings ); return $links; } /* --------------------------------------------------------------------------- * Acciones * ------------------------------------------------------------------------ */ public static function handle_request_code() { self::guard(); check_admin_referer( 'doxi_request_code' ); $email = isset( $_POST['doxi_email'] ) ? sanitize_email( wp_unslash( $_POST['doxi_email'] ) ) : ''; if ( ! is_email( $email ) ) { self::notice( 'error', __( 'Escribe un correo válido.', 'ai-bots-doxi-chat' ) ); self::back(); } $domains = Doxi_Settings::site_domains(); if ( empty( $domains ) ) { self::notice( 'error', __( 'No pudimos leer la dirección de esta web. Revisa la «Dirección del sitio» en Ajustes → Generales.', 'ai-bots-doxi-chat' ) ); self::back(); } $result = Doxi_Api::request_code( $email, $domains ); if ( ! $result['ok'] ) { self::notice( 'error', self::message_for( $result['error'] ) ); self::back(); } Doxi_Settings::update( array( 'pending_email' => $email, 'pending_at' => time(), ) ); // El backend responde lo mismo exista o no la cuenta (para que esta pantalla no // sirva para averiguar quién es cliente), así que el mensaje tampoco lo afirma. self::notice( 'success', __( 'Si ese correo es el de tu cuenta Doxi, te acabamos de mandar un código. Vale 15 minutos. Si no lo ves, revisa la carpeta de spam.', 'ai-bots-doxi-chat' ) ); self::back(); } public static function handle_activate() { self::guard(); check_admin_referer( 'doxi_activate' ); $email = (string) Doxi_Settings::get( 'pending_email' ); if ( '' === $email ) { self::notice( 'error', __( 'Primero pide un código con el correo de tu cuenta Doxi.', 'ai-bots-doxi-chat' ) ); self::back(); } $code = isset( $_POST['doxi_code'] ) ? self::clean_code( sanitize_text_field( wp_unslash( $_POST['doxi_code'] ) ) ) : ''; if ( '' === $code ) { self::notice( 'error', __( 'Pega el código que te llegó por correo.', 'ai-bots-doxi-chat' ) ); self::back(); } $domains = Doxi_Settings::site_domains(); $result = Doxi_Api::activate( $email, $code, $domains ); if ( ! $result['ok'] ) { self::notice( 'error', self::message_for( $result['error'] ) ); self::back(); } $data = $result['data']; $api_key = isset( $data['apiKey'] ) && is_string( $data['apiKey'] ) ? trim( $data['apiKey'] ) : ''; // Un 200 sin una clave con forma de clave no es un éxito: guardarla dejaría un // chat que no monta, y la pantalla diría «conectado». if ( ! Doxi_Settings::is_valid_api_key( $api_key ) ) { self::notice( 'error', self::message_for( 'respuesta_invalida' ) ); self::back(); } $bot_name = isset( $data['nombreDelBot'] ) && is_string( $data['nombreDelBot'] ) ? sanitize_text_field( $data['nombreDelBot'] ) : ''; // Se pinta lo que DEVOLVIÓ el backend, no lo que se mandó: si normalizó algo, // verlo es la única forma de entender por qué. $authorized = $domains; if ( isset( $data['dominios'] ) && is_array( $data['dominios'] ) ) { $authorized = array_values( array_filter( array_map( 'sanitize_text_field', $data['dominios'] ) ) ); } Doxi_Settings::update( array( 'api_key' => $api_key, 'bot_name' => $bot_name, 'domains' => $authorized, 'connected_at' => time(), 'pending_email' => '', 'pending_at' => 0, ) ); Doxi_Frontend::purge_page_cache(); self::notice( 'success', '' !== $bot_name /* translators: %s: nombre del bot. */ ? sprintf( __( '¡Listo! Tu Doxi «%s» ya está conectado a esta web.', 'ai-bots-doxi-chat' ), $bot_name ) : __( '¡Listo! Tu Doxi ya está conectado a esta web.', 'ai-bots-doxi-chat' ) ); self::back(); } public static function handle_change_email() { self::guard(); check_admin_referer( 'doxi_change_email' ); Doxi_Settings::update( array( 'pending_email' => '', 'pending_at' => 0, ) ); self::back(); } public static function handle_disconnect() { self::guard(); check_admin_referer( 'doxi_disconnect' ); Doxi_Settings::disconnect(); Doxi_Frontend::purge_page_cache(); self::notice( 'success', __( 'Se desconectó. El chat ya no aparece en tu web. Los dominios siguen autorizados en tu cuenta Doxi: si vuelves a conectar, pide un código nuevo.', 'ai-bots-doxi-chat' ) ); self::back(); } public static function handle_save_options() { self::guard(); check_admin_referer( 'doxi_save_options' ); $changes = array(); // Las páginas solo se tocan si el formulario las enseñó; leer su ausencia como // «todas sin chat» las apagaría todas. if ( isset( $_POST['doxi_pages_shown'] ) ) { // Se marca dónde SÍ aparece el chat (es lo que la gente espera al ver una // lista de páginas con casillas), pero se guarda lo contrario: la lista de // excluidas. Así una página nueva nace CON chat sin tener que volver aquí. $con_chat = isset( $_POST['doxi_pages_with_chat'] ) && is_array( $_POST['doxi_pages_with_chat'] ) ? array_map( 'absint', wp_unslash( $_POST['doxi_pages_with_chat'] ) ) : array(); // Solo se decide sobre las páginas que el formulario enseñó. Si alguien creó // una página mientras esta pantalla estaba abierta, no se queda sin chat por // no haber estado en la lista. $listadas = isset( $_POST['doxi_pages_listed'] ) ? array_map( 'absint', explode( ',', sanitize_text_field( wp_unslash( $_POST['doxi_pages_listed'] ) ) ) ) : array(); $changes['excluded_pages'] = array_values( array_diff( array_filter( $listadas ), $con_chat ) ); } Doxi_Settings::update( $changes ); Doxi_Frontend::purge_page_cache(); self::notice( 'success', __( 'Cambios guardados.', 'ai-bots-doxi-chat' ) ); self::back(); } /* --------------------------------------------------------------------------- * Pantalla * ------------------------------------------------------------------------ */ public static function render() { if ( ! current_user_can( 'manage_options' ) ) { return; } $settings = Doxi_Settings::all(); ?>
' . esc_html( $host ) . '' ); ?>
' . esc_html( (string) $settings['pending_email'] ) . '' ); ?>
«' . esc_html( $bot_name ) . '»' ); } else { esc_html_e( 'Tu Doxi está conectado a esta web.', 'ai-bots-doxi-chat' ); } ?>
%2$s