__( 'Licence', 'avi-support-assistant-pro' ), 'ai' => __( 'AI Answers', 'avi-support-assistant-pro' ), 'voice' => __( 'Voice', 'avi-support-assistant-pro' ), 'crm' => __( 'Zoho CRM & Webhook', 'avi-support-assistant-pro' ), 'woo' => __( 'WooCommerce', 'avi-support-assistant-pro' ), 'hours' => __( 'Office Hours', 'avi-support-assistant-pro' ), 'more' => __( 'Languages & History', 'avi-support-assistant-pro' ), ); } /** * Register Pro admin pages. */ function avcap_admin_menu() { if ( function_exists( 'avca_pro_active' ) && avca_pro_active() ) { add_submenu_page( AVCA_MENU_SLUG, __( 'AI & Pro Features', 'avi-support-assistant' ), __( 'AI & Pro Features', 'avi-support-assistant' ), 'manage_options', 'avcap-settings', 'avcap_render_settings_page' ); add_submenu_page( AVCA_MENU_SLUG, __( 'Conversations', 'avi-support-assistant' ), __( 'Conversations', 'avi-support-assistant' ), 'manage_options', 'avcap-conversations', 'avcap_render_conversations_page' ); add_submenu_page( AVCA_MENU_SLUG, __( 'Analytics', 'avi-support-assistant' ), __( 'Analytics', 'avi-support-assistant' ), 'manage_options', 'avcap-analytics', 'avcap_render_analytics_page' ); } } add_action( 'admin_menu', 'avcap_admin_menu', 20 ); /** * Register the Pro settings. */ function avcap_register_settings() { register_setting( 'avcap_settings_group', AVCAP_OPTION, array( 'type' => 'array', 'sanitize_callback' => 'avcap_sanitize_settings', 'default' => avcap_get_defaults(), ) ); foreach ( avcap_tabs() as $tab => $label ) { add_settings_section( 'avcap_section_' . $tab, '', '__return_false', 'avcap-tab-' . $tab ); } $fields = array( 'license' => array( 'license', __( 'Licence Status', 'avi-support-assistant-pro' ) ), 'ai_enabled' => array( 'ai', __( 'AI Answers', 'avi-support-assistant-pro' ) ), 'ai_provider' => array( 'ai', __( 'Provider', 'avi-support-assistant-pro' ) ), 'ai_keys' => array( 'ai', __( 'API Keys & Models', 'avi-support-assistant-pro' ) ), 'ai_instructions' => array( 'ai', __( 'Instructions', 'avi-support-assistant-pro' ) ), 'ai_knowledge' => array( 'ai', __( 'Knowledge', 'avi-support-assistant-pro' ) ), 'ai_temperature' => array( 'ai', __( 'Creativity', 'avi-support-assistant-pro' ) ), 'ai_max_tokens' => array( 'ai', __( 'Max Answer Length', 'avi-support-assistant-pro' ) ), 'ai_monthly_cap' => array( 'ai', __( 'Monthly AI Limit', 'avi-support-assistant-pro' ) ), 'ai_visitor_cap' => array( 'ai', __( 'Per-Visitor Limit', 'avi-support-assistant-pro' ) ), 'voice_input' => array( 'voice', __( 'Voice Input', 'avi-support-assistant-pro' ) ), 'voice_output' => array( 'voice', __( 'Spoken Replies', 'avi-support-assistant-pro' ) ), 'zoho_enabled' => array( 'crm', __( 'Zoho CRM', 'avi-support-assistant-pro' ) ), 'zoho_dc' => array( 'crm', __( 'Data Centre', 'avi-support-assistant-pro' ) ), 'zoho_client_id' => array( 'crm', __( 'Client ID', 'avi-support-assistant-pro' ) ), 'zoho_secret' => array( 'crm', __( 'Client Secret', 'avi-support-assistant-pro' ) ), 'zoho_refresh' => array( 'crm', __( 'Refresh Token', 'avi-support-assistant-pro' ) ), 'zoho_source' => array( 'crm', __( 'Lead Source', 'avi-support-assistant-pro' ) ), 'webhook_url' => array( 'crm', __( 'Webhook URL', 'avi-support-assistant-pro' ) ), 'webhook_secret' => array( 'crm', __( 'Webhook Secret', 'avi-support-assistant-pro' ) ), 'woo_products' => array( 'woo', __( 'Product Search', 'avi-support-assistant-pro' ) ), 'woo_auto' => array( 'woo', __( 'Automatic Suggestions', 'avi-support-assistant-pro' ) ), 'woo_orders' => array( 'woo', __( 'Order Tracking', 'avi-support-assistant-pro' ) ), 'hours_enabled' => array( 'hours', __( 'Office Hours', 'avi-support-assistant-pro' ) ), 'hours' => array( 'hours', __( 'Opening Times', 'avi-support-assistant-pro' ) ), 'closed_message' => array( 'hours', __( 'Closed Message', 'avi-support-assistant-pro' ) ), 'closed_hide' => array( 'hours', __( 'When Closed', 'avi-support-assistant-pro' ) ), 'translate' => array( 'more', __( 'Multi-Language', 'avi-support-assistant-pro' ) ), 'history_enabled' => array( 'more', __( 'Chat History', 'avi-support-assistant-pro' ) ), 'retention_days' => array( 'more', __( 'Keep History For', 'avi-support-assistant-pro' ) ), ); foreach ( $fields as $key => $field ) { add_settings_field( 'avcap_' . $key, $field[1], 'avcap_render_field', 'avcap-tab-' . $field[0], 'avcap_section_' . $field[0], array( 'key' => $key, 'label_for' => 'avcap_' . $key, ) ); } } add_action( 'admin_init', 'avcap_register_settings' ); /** * Name attribute for a Pro setting. * * @param string $key Key. * @return string */ function avcap_name( $key ) { return AVCAP_OPTION . '[' . $key . ']'; } /** * Checkbox. * * @param string $key Key. * @param string $label Label. */ function avcap_checkbox( $key, $label ) { ?> $value ) { echo ' ' . esc_attr( $attr ) . '="' . esc_attr( $value ) . '"'; } ?> /> ' . esc_html( $text ) . '
'; } /** * Render a Pro field. * * @param array $args Args with key. */ function avcap_render_field( $args ) { $key = $args['key']; $s = avcap_get_settings(); switch ( $key ) { case 'license': avcap_render_license_status(); break; case 'ai_enabled': avcap_checkbox( $key, __( 'Answer questions with AI when no FAQ matches', 'avi-support-assistant-pro' ) ); avcap_help( __( 'Order of answers: your FAQs first (free), then AI, then site search and the lead form if AI cannot help.', 'avi-support-assistant-pro' ) ); break; case 'ai_provider': ?> '; avcap_checkbox( 'ai_use_content', __( 'Use matching pages from my site (same content types as site search)', 'avi-support-assistant-pro' ) ); echo ''; /* translators: 1: Time ago, 2: Error message. */ echo esc_html( sprintf( __( 'Last AI error (%1$s ago): %2$s', 'avi-support-assistant-pro' ), human_time_diff( (int) $error['time'] ), $error['message'] ) ); echo '
'; } break; case 'ai_visitor_cap': avcap_input( $key, 'number', array( 'min' => '1', 'max' => '500' ) ); echo ' ' . esc_html__( 'AI replies per visitor per hour', 'avi-support-assistant-pro' ); break; case 'voice_input': avcap_checkbox( $key, __( 'Show a microphone button so visitors can speak their question', 'avi-support-assistant-pro' ) ); avcap_help( __( 'Uses the browser\'s built-in speech recognition (Chrome, Edge, Safari). The button is hidden in browsers that do not support it.', 'avi-support-assistant-pro' ) ); break; case 'voice_output': $options = array( 'off' => __( 'Off', 'avi-support-assistant-pro' ), 'after_voice' => __( 'Speak replies when the visitor used the microphone', 'avi-support-assistant-pro' ), 'always' => __( 'Always speak replies', 'avi-support-assistant-pro' ), ); ?>'https://hooks.zapier.com/…' ) ); avcap_help( __( 'Optional. Each new lead is sent here as JSON (works with Zapier, Make, n8n, HubSpot workflows and custom CRMs).', 'avi-support-assistant-pro' ) ); break; case 'webhook_secret': avcap_secret( $key ); avcap_help( __( 'Optional. When set, requests include an X-Avi-Signature header (HMAC-SHA256 of the body) so your endpoint can verify them.', 'avi-support-assistant-pro' ) ); break; case 'woo_products': avcap_checkbox( $key, __( 'Add a "Find a product" button that searches your products', 'avi-support-assistant-pro' ) ); if ( ! avcap_woo_active() ) { avcap_help( __( 'WooCommerce is not active, so these options have no effect.', 'avi-support-assistant-pro' ) ); } break; case 'woo_auto': avcap_checkbox( $key, __( 'Also suggest matching products when no FAQ matches (before AI)', 'avi-support-assistant-pro' ) ); break; case 'woo_orders': avcap_checkbox( $key, __( 'Add a "Track my order" button (order number + billing email)', 'avi-support-assistant-pro' ) ); break; case 'hours_enabled': avcap_checkbox( $key, __( 'Show a different welcome message outside opening hours', 'avi-support-assistant-pro' ) ); /* translators: %s: Site timezone. */ avcap_help( sprintf( __( 'Uses your site timezone (%s) from Settings → General.', 'avi-support-assistant-pro' ), wp_timezone_string() ) ); break; case 'hours': avcap_render_hours(); break; case 'closed_message': ?> '1', 'max' => '3650' ) ); echo ' ' . esc_html__( 'days, then delete automatically', 'avi-support-assistant-pro' ); break; } } /** * Licence status and key form. * * The licence form posts to admin-post.php, separately from the settings form, so it * is printed after the settings form (see avcap_render_settings_page()). */ function avcap_render_license_status() { $l = avcap_license(); if ( defined( 'AVCAP_DEV_LICENSE' ) && AVCAP_DEV_LICENSE ) { echo '
' . esc_html__( 'Developer mode – all Pro features are on.', 'avi-support-assistant-pro' ) . '
'; avcap_help( __( 'AVCAP_DEV_LICENSE is set in wp-config.php. Remove it on customer sites.', 'avi-support-assistant-pro' ) ); return; } $labels = array( 'active' => __( 'Active – all Pro features are on.', 'avi-support-assistant-pro' ), 'expired' => __( 'Expired – renew your licence to turn Pro features back on.', 'avi-support-assistant-pro' ), 'disabled' => __( 'Disabled – please contact support.', 'avi-support-assistant-pro' ), 'inactive' => __( 'This site was removed from your licence. Activate it again.', 'avi-support-assistant-pro' ), 'invalid' => __( 'This licence key is not valid.', 'avi-support-assistant-pro' ), 'none' => __( 'Not activated – enter your licence key below.', 'avi-support-assistant-pro' ), ); $status = isset( $labels[ $l['status'] ] ) ? $l['status'] : 'none'; $ok = avcap_is_licensed(); echo '' . esc_html( $labels[ $status ] ) . '
'; if ( '' !== $l['key'] ) { echo '';
echo esc_html( __( 'Key:', 'avi-support-assistant-pro' ) . ' ' . substr( $l['key'], 0, 9 ) . '••••-••••-' . substr( $l['key'], -4 ) );
if ( '' !== $l['plan'] ) {
echo '
' . esc_html( __( 'Plan:', 'avi-support-assistant-pro' ) . ' ' . $l['plan'] . ' · ' . sprintf( /* translators: 1: Sites used, 2: Sites allowed. */ __( '%1$d of %2$d sites', 'avi-support-assistant-pro' ), $l['used'], $l['sites'] ) );
}
echo '
' . esc_html( __( 'Valid until:', 'avi-support-assistant-pro' ) . ' ' . ( $l['expires'] ? wp_date( get_option( 'date_format' ), $l['expires'] ) : __( 'Lifetime', 'avi-support-assistant-pro' ) ) );
echo '
' . esc_html__( 'Renew licence', 'avi-support-assistant-pro' ) . '
'; } } avcap_help( __( 'Use the licence form below this settings form to activate, refresh or deactivate.', 'avi-support-assistant-pro' ) ); } /** * Licence key form (outside the settings form). */ function avcap_render_license_form() { if ( defined( 'AVCAP_DEV_LICENSE' ) && AVCAP_DEV_LICENSE ) { return; } $l = avcap_license(); $error = get_transient( 'avcap_license_error_' . get_current_user_id() ); $flag = isset( $_GET['avcap_license'] ) ? sanitize_key( wp_unslash( $_GET['avcap_license'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Display-only flag. if ( $error ) { delete_transient( 'avcap_license_error_' . get_current_user_id() ); } ?>|
|
$info['model'] ) ); ?> |
| get_weekday( $day ) : (string) $day ); ?> | – |
|---|