'string', 'default' => '', 'sanitize_callback' => 'apar_chatbot_sanitize_key', ) ); register_setting( 'apar_chatbot', APAR_CHATBOT_CREDIT, array( 'type' => 'boolean', 'default' => false, 'sanitize_callback' => 'apar_chatbot_sanitize_credit', ) ); } add_action( 'admin_init', 'apar_chatbot_register_setting' ); /** * Add Settings > Apar Chatbot. */ function apar_chatbot_add_page() { add_options_page( __( 'Apar Chatbot', 'apar-chatbot' ), __( 'Apar Chatbot', 'apar-chatbot' ), 'manage_options', 'apar-chatbot', 'apar_chatbot_render_page' ); } add_action( 'admin_menu', 'apar_chatbot_add_page' ); /** * Add a Settings link beside Deactivate on the Plugins screen. * * @param string[] $links The plugin's links. * @return string[] The links, with Settings first. */ function apar_chatbot_action_links( $links ) { $url = admin_url( 'options-general.php?page=apar-chatbot' ); array_unshift( $links, '' . esc_html__( 'Settings', 'apar-chatbot' ) . '' ); return $links; } add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'apar_chatbot_action_links' ); /** * On the Plugins screen only, say what to do next until a key is saved. */ function apar_chatbot_setup_notice() { $screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null; if ( ! $screen || 'plugins' !== $screen->id || ! current_user_can( 'manage_options' ) ) { return; } if ( '' !== apar_chatbot_clean_key( get_option( APAR_CHATBOT_OPTION, '' ) ) ) { return; } $url = admin_url( 'options-general.php?page=apar-chatbot' ); echo '

'; echo '' . esc_html__( 'Add your website key', 'apar-chatbot' ) . ' '; echo esc_html__( 'to show Apar Chatbot on this website.', 'apar-chatbot' ); echo '

'; } add_action( 'admin_notices', 'apar_chatbot_setup_notice' ); /** * Ask the chatbot service whether this key works on this website. Only runs on the settings page, * after the owner has saved a key, and only sends the key and this website's address. * * @param string $key The saved key. * @return array{state:string,name?:string} ok, not_found, domain, off or unreachable. */ function apar_chatbot_check_key( $key ) { $cached = get_transient( APAR_CHATBOT_CHECK ); if ( is_array( $cached ) && isset( $cached['key'], $cached['result'] ) && $cached['key'] === $key ) { return $cached['result']; } $url = add_query_arg( 'host', rawurlencode( (string) wp_parse_url( home_url(), PHP_URL_HOST ) ), sprintf( APAR_CHATBOT_CONFIG, rawurlencode( $key ) ) ); $response = wp_remote_get( $url, array( 'timeout' => 5 ) ); if ( is_wp_error( $response ) ) { // Not remembered: the next visit asks again. return array( 'state' => 'unreachable' ); } $code = (int) wp_remote_retrieve_response_code( $response ); $body = json_decode( wp_remote_retrieve_body( $response ), true ); $body = is_array( $body ) ? $body : array(); if ( 200 === $code ) { $name = isset( $body['website']['name'] ) ? (string) $body['website']['name'] : ''; $result = array( 'state' => 'ok', 'name' => $name, ); } elseif ( 403 === $code && isset( $body['error_code'] ) && 'DOMAIN_NOT_ALLOWED' === $body['error_code'] ) { $result = array( 'state' => 'domain' ); } elseif ( 403 === $code && isset( $body['error_code'] ) && 'WIDGET_INACTIVE' === $body['error_code'] ) { $result = array( 'state' => 'off' ); } elseif ( 401 === $code || 403 === $code || 404 === $code ) { $result = array( 'state' => 'not_found' ); } else { return array( 'state' => 'unreachable' ); } set_transient( APAR_CHATBOT_CHECK, array( 'key' => $key, 'result' => $result, ), 5 * MINUTE_IN_SECONDS ); return $result; } /** * The line under the key: does the key work on this website? * * @param string $key The saved key. */ function apar_chatbot_render_status( $key ) { $check = apar_chatbot_check_key( $key ); $host = (string) wp_parse_url( home_url(), PHP_URL_HOST ); switch ( $check['state'] ) { case 'ok': $class = 'notice-success'; $text = '' !== $check['name'] /* translators: %s: the website's name in the chatbot dashboard. */ ? sprintf( __( 'Connected to %s. The chat button now shows on every page of this website. If you use a caching plugin, clear its cache.', 'apar-chatbot' ), $check['name'] ) : __( 'Connected. The chat button now shows on every page of this website. If you use a caching plugin, clear its cache.', 'apar-chatbot' ); break; case 'domain': $class = 'notice-error'; /* translators: %s: this website's address. */ $text = sprintf( __( 'This key is refused on %s. Add this address to Allowed Domains in Chat Window, in your chatbot dashboard.', 'apar-chatbot' ), $host ); break; case 'off': $class = 'notice-warning'; $text = __( 'This chat is switched off in your chatbot dashboard, so visitors don\'t see it.', 'apar-chatbot' ); break; case 'not_found': $class = 'notice-error'; $text = __( 'We can\'t find this key. Copy it again from Install in your chatbot dashboard.', 'apar-chatbot' ); break; default: $class = 'notice-warning'; $text = __( 'We couldn\'t reach the chatbot service to check this key. The chat may still work: open your website to see.', 'apar-chatbot' ); } echo '

' . esc_html( $text ) . '

'; } /** * Settings > Apar Chatbot. */ function apar_chatbot_render_page() { if ( ! current_user_can( 'manage_options' ) ) { return; } $key = apar_chatbot_clean_key( get_option( APAR_CHATBOT_OPTION, '' ) ); ?>

true, 'strategy' => 'defer', ) ); } add_action( 'wp_enqueue_scripts', 'apar_chatbot_enqueue' ); /** * Put the key on the loader's script tag, where it reads it. The credit line shows only when the * admin has ticked its box on the settings page. data-platform tells the chat to follow that box. * * @param string $tag The script tag. * @param string $handle The script's handle. * @return string The tag. */ function apar_chatbot_script_tag( $tag, $handle ) { if ( 'apar-chatbot' !== $handle ) { return $tag; } $key = apar_chatbot_clean_key( get_option( APAR_CHATBOT_OPTION, '' ) ); $add = sprintf( '