self::SLUG ), $args ), admin_url( 'admin.php' ) ); } /** Chats waiting for anyone, plus unread messages in my chats. */ private static function badge_count() { global $wpdb; $chats = Replyvane_Live::chats_table(); $messages = Replyvane_Live::messages_table(); $waiting = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM %i WHERE status = 'waiting'", $chats )); $unread = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM %i m INNER JOIN %i c ON c.id = m.chat_id WHERE c.status = 'active' AND c.agent_id = %d AND m.sender = 'visitor' AND m.id > c.agent_read_id", $messages, $chats, get_current_user_id() ) ); return $waiting + $unread; } public static function menu() { if ( ! self::allowed() ) { return; } $count = self::badge_count(); $title = 'Live Chat ' . (int) $count . ''; add_menu_page( 'Live Chat', $title, Replyvane_Live::CAP, self::SLUG, array( __CLASS__, 'render' ), 'dashicons-admin-comments', 57 ); } public static function admin_bar( $bar ) { if ( ! self::allowed() || ! is_admin_bar_showing() ) { return; } $count = self::badge_count(); $bar->add_node( array( 'id' => 'replyvane-live', 'title' => 'Live chat ' . (int) $count . '', 'href' => self::url(), 'meta' => array( 'title' => 'Open the live chat inbox' ), ) ); } private static function config( $is_inbox ) { $quick = array(); if ( $is_inbox ) { foreach ( Replyvane_Store::items( true ) as $row ) { $quick[] = array( 'q' => $row['question'], 'a' => $row['answer'], ); } } return array( 'rest' => esc_url_raw( rest_url( 'replyvane/v1/live/agent' ) ), 'nonce' => wp_create_nonce( 'wp_rest' ), 'inbox' => self::url(), 'isInbox' => $is_inbox, 'status' => Replyvane_Live::agent_status( get_current_user_id() ), 'includeText' => (bool) Replyvane_Plugin::get( 'alert_include_text' ), 'isAdmin' => current_user_can( 'manage_options' ), 'siteName' => wp_specialchars_decode( get_bloginfo( 'name' ), ENT_QUOTES ), 'agentName' => Replyvane_Live::agent_name( get_current_user_id() ), 'quick' => $quick, ); } public static function enqueue( $hook ) { if ( ! self::allowed() ) { return; } $is_inbox = false !== strpos( (string) $hook, self::SLUG ) && ( ! isset( $_GET['view'] ) ); // phpcs:ignore WordPress.Security.NonceVerification wp_enqueue_style( 'replyvane-agent', REPLYVANE_URL . 'assets/agent.css', array(), REPLYVANE_VERSION ); wp_enqueue_script( 'replyvane-agent', REPLYVANE_URL . 'assets/agent.js', array(), REPLYVANE_VERSION, true ); wp_localize_script( 'replyvane-agent', 'replyVaneAgent', self::config( $is_inbox ) ); } /** Team members browsing the site (with the admin bar) still get alerts. */ public static function enqueue_front() { if ( ! self::allowed() || ! is_admin_bar_showing() ) { return; } wp_enqueue_style( 'replyvane-agent', REPLYVANE_URL . 'assets/agent.css', array(), REPLYVANE_VERSION ); wp_enqueue_script( 'replyvane-agent', REPLYVANE_URL . 'assets/agent.js', array(), REPLYVANE_VERSION, true ); wp_localize_script( 'replyvane-agent', 'replyVaneAgent', self::config( false ) ); } /* ------------------------------------------------------------------ */ /* Pages */ /* ------------------------------------------------------------------ */ public static function render() { if ( ! self::allowed() ) { wp_die( 'Live chat is switched off.' ); } $view = isset( $_GET['view'] ) ? sanitize_key( $_GET['view'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification if ( 'history' === $view ) { self::render_history(); return; } $hours = Replyvane_Plugin::get( 'hours_enabled' ); ?>

Live chat

Chat history
You are Away

Go Online to receive chats. You stay online while any dashboard page is open in this browser; if you close it for about 2 minutes you're treated as away, and visitors see "Leave us a message" instead.

Choose a chat on the left.
'history' ) ); if ( $chat_id ) { $chat = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM %i WHERE id = %d", $chats, $chat_id ), ARRAY_A ); $rows = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM %i WHERE chat_id = %d ORDER BY id ASC", $messages, $chat_id ), ARRAY_A ); ?>

Chat with

← Chat history

This chat no longer exists.

Started
Email' . esc_html( $chat['visitor_email'] ) . '' : '–' ); ?>
Page' . esc_html( wp_parse_url( $chat['page_url'], PHP_URL_PATH ) ) . '' : '–' ); ?>
Handled by
Status
array() ) ); ?>
For example, if a visitor asks you to remove their data.
get_var( $wpdb->prepare( "SELECT COUNT(*) FROM %i WHERE status = 'closed'", $chats )); $rows = $wpdb->get_results( $wpdb->prepare( "SELECT c.*, (SELECT COUNT(*) FROM %i m WHERE m.chat_id = c.id AND m.sender <> 'system') AS n FROM %i c WHERE c.status = 'closed' ORDER BY c.id DESC LIMIT %d OFFSET %d", $messages, $chats, $per, ( $paged - 1 ) * $per ), ARRAY_A ); ?>

Chat history

Chat deleted.

← Live chat inbox

Finished chats and handled messages. Chats older than days are deleted automatically (change this in Replyvane → Settings).

StartedVisitorHandled byMessages
No finished chats yet.
1 ) { echo '
' . wp_kses_post( paginate_links( array( 'base' => add_query_arg( 'paged', '%#%', $back ), 'format' => '', 'current' => $paged, 'total' => $pages, ) ) ) . '
'; } ?>
'history', 'deleted' => 1 ) ) ); exit; } } // phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching