get_error_message() ) ); exit; } wp_safe_redirect( self::page_url( 'connected' ) ); exit; } /** * Fallback: the admin pastes the connection code shown on flatratechat.com. */ public static function handle_paste_code() { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'You do not have permission to do that.', 'flatratechat' ) ); } check_admin_referer( 'flatratechat_paste_code' ); $code = isset( $_POST['frc_code'] ) ? sanitize_text_field( wp_unslash( $_POST['frc_code'] ) ) : ''; $r = FlatRateChat_Service::exchange_code( $code ); if ( is_wp_error( $r ) ) { wp_safe_redirect( self::page_url( 'error', $r->get_error_message() ) ); exit; } wp_safe_redirect( self::page_url( 'connected' ) ); exit; } /** * Disconnect: remove the script and our options from this site. */ public static function handle_disconnect() { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'You do not have permission to do that.', 'flatratechat' ) ); } check_admin_referer( 'flatratechat_disconnect' ); FlatRateChat_Service::disconnect(); wp_safe_redirect( self::page_url( 'disconnected' ) ); exit; } /** * Refresh the cached plan + usage. */ public static function handle_refresh() { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'You do not have permission to do that.', 'flatratechat' ) ); } check_admin_referer( 'flatratechat_refresh' ); delete_transient( FlatRateChat_Service::TR_STATUS ); wp_safe_redirect( self::page_url() ); exit; } /** * Notices after a redirect. */ private static function notices() { if ( ! isset( $_GET['frc_notice'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- display only. return; } $notice = sanitize_key( wp_unslash( $_GET['frc_notice'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended $detail = isset( $_GET['frc_detail'] ) ? sanitize_text_field( wp_unslash( $_GET['frc_detail'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended $map = array( 'connected' => array( 'success', __( 'Connected. The chat bubble is now on your site. It can take a few minutes until all your pages are read.', 'flatratechat' ) ), 'disconnected' => array( 'info', __( 'Disconnected. The chat bubble was removed from your site. Your FlatRateChat account still exists at flatratechat.com.', 'flatratechat' ) ), 'state' => array( 'error', __( 'That connection attempt was not started from this site or has expired (15 minutes). Click Connect again.', 'flatratechat' ) ), 'error' => array( 'error', $detail ? $detail : __( 'Something went wrong. Click Connect again.', 'flatratechat' ) ), ); if ( ! isset( $map[ $notice ] ) ) { return; } printf( '

%2$s

', esc_attr( $map[ $notice ][0] ), esc_html( $map[ $notice ][1] ) ); } /** * The settings page. */ public static function render() { if ( ! current_user_can( 'manage_options' ) ) { return; } $connected = FlatRateChat_Service::is_connected(); $status = $connected ? FlatRateChat_Service::status() : null; if ( $connected && is_wp_error( $status ) && FlatRateChat_Service::is_stale_error( $status ) ) { $connected = false; // status() already dropped the key and token. } $dashboard = FlatRateChat_Service::base_url() . '/dashboard'; ?>

' . esc_html__( 'Privacy Policy', 'flatratechat' ) . '', '' . esc_html__( 'Terms', 'flatratechat' ) . '' ); ?>

array( __( 'Free', 'flatratechat' ), '$0', __( '50 pages read. 100 AI answers a month. No card. At the limit the bubble stays on your site and shows your contact details until the 1st.', 'flatratechat' ) ), 'starter' => array( __( 'Starter', 'flatratechat' ), '$19/month', __( '100 pages read. 1,000 AI answers a month. 14-day free trial on a site’s first paid plan, card required.', 'flatratechat' ) ), 'full' => array( __( 'Full', 'flatratechat' ), '$59/month', __( '500 pages read. 5,000 AI answers a month. 14-day free trial on a site’s first paid plan, card required.', 'flatratechat' ) ), ); ?>

$p ) : ?>

__( 'Free plan', 'flatratechat' ), 'starter' => __( 'Starter plan', 'flatratechat' ), 'full' => __( 'Full plan', 'flatratechat' ), ); return $labels[ self::plan_slug( $status ) ]; } /** * Secondary line: trial / renewal / cancellation. * * @param array $status Status payload. * @return string */ private static function plan_detail( $status ) { $s = isset( $status['status'] ) ? (string) $status['status'] : ''; $date = ! empty( $status['access_through'] ) ? date_i18n( get_option( 'date_format' ), strtotime( (string) $status['access_through'] ) ) : ''; if ( 'free' === self::plan_slug( $status ) ) { return ''; } if ( 'trialing' === $s ) { /* translators: %s: date */ return $date ? sprintf( __( 'Free trial until %s.', 'flatratechat' ), $date ) : __( 'Free trial.', 'flatratechat' ); } if ( ! empty( $status['cancel_at_period_end'] ) ) { /* translators: %s: date */ return $date ? sprintf( __( 'Cancelled; returns to the Free plan on %s.', 'flatratechat' ), $date ) : __( 'Cancelled at the end of the period.', 'flatratechat' ); } if ( 'grace' === $s ) { return __( 'Payment failed; please update your card in the dashboard.', 'flatratechat' ); } /* translators: %s: date */ return $date ? sprintf( __( 'Renews on %s.', 'flatratechat' ), $date ) : ''; } }