array( 'string', 'call_talk_widget_sanitize_public_token', '' ), CALL_TALK_WIDGET_COMPANY_KEY => array( 'string', 'call_talk_widget_sanitize_public_token', '' ), CALL_TALK_WIDGET_ENABLED_KEY => array( 'boolean', 'call_talk_widget_sanitize_boolean', 0 ), CALL_TALK_WIDGET_CONSENT_KEY => array( 'boolean', 'call_talk_widget_sanitize_boolean', 0 ), CALL_TALK_WIDGET_SCRIPT_URL_KEY => array( 'string', 'call_talk_widget_sanitize_script_url', CALL_TALK_WIDGET_DEFAULT_SCRIPT_URL ), CALL_TALK_WIDGET_TYPE_KEY => array( 'string', 'call_talk_widget_sanitize_type', 'call' ), CALL_TALK_WIDGET_STYLE_KEY => array( 'string', 'call_talk_widget_sanitize_style', 'dark' ), CALL_TALK_WIDGET_LANGUAGE_KEY => array( 'string', 'call_talk_widget_sanitize_language', 'en' ), ); foreach ( $settings as $key => $definition ) { register_setting( 'call_talk_widget', $key, array( 'type' => $definition[0], 'sanitize_callback' => $definition[1], 'default' => $definition[2], 'show_in_rest' => false, ) ); } } function call_talk_widget_add_settings_page(): void { add_options_page( __( 'Call Talk Widget', 'call-talk-widget' ), __( 'Call Talk Widget', 'call-talk-widget' ), 'manage_options', 'call-talk-widget', 'call_talk_widget_render_settings_page' ); } /** Local assets only, on this plugin's settings page only. */ function call_talk_widget_enqueue_admin_assets( string $hook ): void { if ( 'settings_page_call-talk-widget' !== $hook ) { return; } wp_enqueue_style( 'call-talk-widget-admin', plugins_url( 'assets/admin.css', __FILE__ ), array(), CALL_TALK_WIDGET_VERSION ); wp_enqueue_script( 'call-talk-widget-admin', plugins_url( 'assets/admin.js', __FILE__ ), array(), CALL_TALK_WIDGET_VERSION, true ); } function call_talk_widget_settings_link( array $links ): array { array_unshift( $links, '' . esc_html__( 'Settings', 'call-talk-widget' ) . '' ); return $links; } function call_talk_widget_render_settings_page(): void { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'You do not have permission to manage Call Talk settings.', 'call-talk-widget' ) ); } $enabled = call_talk_widget_sanitize_boolean( get_option( CALL_TALK_WIDGET_ENABLED_KEY, 0 ) ); $consent = call_talk_widget_sanitize_boolean( get_option( CALL_TALK_WIDGET_CONSENT_KEY, 0 ) ); $token = call_talk_widget_get_string( CALL_TALK_WIDGET_TOKEN_KEY ); $company = call_talk_widget_get_string( CALL_TALK_WIDGET_COMPANY_KEY ); $script_url = call_talk_widget_get_string( CALL_TALK_WIDGET_SCRIPT_URL_KEY, CALL_TALK_WIDGET_DEFAULT_SCRIPT_URL ); $url_error = false; foreach ( get_settings_errors( 'call_talk_widget' ) as $error ) { if ( 'call_talk_widget_script_url_invalid' === $error['code'] ) { $url_error = true; } } ?>

>

>

__( 'Call', 'call-talk-widget' ), 'chat' => __( 'Chat', 'call-talk-widget' ) ), call_talk_widget_sanitize_type( get_option( CALL_TALK_WIDGET_TYPE_KEY, 'call' ) ) ); call_talk_widget_render_choice( CALL_TALK_WIDGET_STYLE_KEY, __( 'Widget Theme', 'call-talk-widget' ), array( 'dark' => __( 'Dark', 'call-talk-widget' ), 'light' => __( 'Light', 'call-talk-widget' ) ), call_talk_widget_sanitize_style( get_option( CALL_TALK_WIDGET_STYLE_KEY, 'dark' ) ) ); call_talk_widget_render_choice( CALL_TALK_WIDGET_LANGUAGE_KEY, __( 'Widget Language', 'call-talk-widget' ), array( 'en' => __( 'English', 'call-talk-widget' ), 'cs' => __( 'Czech', 'call-talk-widget' ), 'ru' => __( 'Russian', 'call-talk-widget' ), 'de' => __( 'German', 'call-talk-widget' ) ), call_talk_widget_sanitize_language( get_option( CALL_TALK_WIDGET_LANGUAGE_KEY, 'en' ) ) ); ?>
160 || preg_match( '/\s/', $value ) ) { call_talk_widget_add_settings_error_once( 'call_talk_widget_token_invalid', __( 'Public installation tokens must contain at most 160 characters and no spaces. Copy the token from Widget Installation in Call Talk.', 'call-talk-widget' ) ); return ''; } return $value; } function call_talk_widget_is_valid_script_url( string $url ): bool { $parts = wp_parse_url( $url ); return is_array( $parts ) && isset( $parts['scheme'], $parts['host'] ) && ( 'https' === strtolower( $parts['scheme'] ) || ( 'http' === strtolower( $parts['scheme'] ) && call_talk_widget_allows_local_http() && in_array( strtolower( $parts['host'] ), array( 'localhost', '127.0.0.1', '[::1]', 'host.docker.internal' ), true ) ) ) && '' !== $parts['host'] && ! isset( $parts['user'] ) && ! isset( $parts['pass'] ) && ! isset( $parts['fragment'] ) && esc_url_raw( $url, call_talk_widget_allows_local_http() ? array( 'https', 'http' ) : array( 'https' ) ) === $url; } function call_talk_widget_sanitize_script_url( $value ): string { $url = is_string( $value ) ? trim( $value ) : ''; if ( '' === $url ) { return CALL_TALK_WIDGET_DEFAULT_SCRIPT_URL; } if ( call_talk_widget_is_valid_script_url( $url ) ) { return $url; } call_talk_widget_add_settings_error_once( 'call_talk_widget_script_url_invalid', __( 'Widget Script URL was not saved. Use a complete HTTPS URL without a username, password, or fragment. The previous valid URL was kept.', 'call-talk-widget' ) ); $previous = call_talk_widget_get_string( CALL_TALK_WIDGET_SCRIPT_URL_KEY ); return call_talk_widget_is_valid_script_url( $previous ) ? $previous : CALL_TALK_WIDGET_DEFAULT_SCRIPT_URL; } function call_talk_widget_sanitize_choice( $value, array $allowed, string $fallback ): string { $value = is_string( $value ) ? strtolower( trim( $value ) ) : ''; return in_array( $value, $allowed, true ) ? $value : $fallback; } function call_talk_widget_sanitize_type( $value ): string { return call_talk_widget_sanitize_choice( $value, array( 'call', 'chat' ), 'call' ); } function call_talk_widget_sanitize_style( $value ): string { return call_talk_widget_sanitize_choice( $value, array( 'dark', 'light' ), 'dark' ); } function call_talk_widget_sanitize_language( $value ): string { return call_talk_widget_sanitize_choice( $value, array( 'en', 'cs', 'ru', 'de' ), 'en' ); } function call_talk_widget_settings_script( string $widget_token, string $company_key ): string { $settings = array( 'widgetType' => call_talk_widget_sanitize_type( get_option( CALL_TALK_WIDGET_TYPE_KEY, 'call' ) ), 'widget-style' => call_talk_widget_sanitize_style( get_option( CALL_TALK_WIDGET_STYLE_KEY, 'dark' ) ), 'lang' => call_talk_widget_sanitize_language( get_option( CALL_TALK_WIDGET_LANGUAGE_KEY, 'en' ) ), 'launcher' => array( 'mode' => 'auto' ), ); if ( '' !== $widget_token ) { $settings['widgetToken'] = $widget_token; } else { $settings['companyPublicKey'] = $company_key; } $json = wp_json_encode( $settings, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT | JSON_UNESCAPED_SLASHES ); return false === $json ? '' : "window.CallTalkSettings = Object.assign({}, window.CallTalkSettings || {}, {$json});"; }