| 1 |
<?php |
| 2 |
/** |
| 3 |
* WPBot Sessions & Analytics — Built-in Chat Session Module |
| 4 |
* |
| 5 |
* Provides full chat session recording, analytics, AI Insight, and |
| 6 |
* "Questions Not Answered" reporting natively in the free chatbot plugin. |
| 7 |
* |
| 8 |
* This module is a port of the Pro plugin's chat-session-addon. |
| 9 |
* It uses the SAME database table names (wpbot_user, wpbot_conversation, |
| 10 |
* wpbot_failed_response) so data is shared if the Pro addon is later activated. |
| 11 |
* |
| 12 |
* Everything is guarded with function_exists() checks so that when the Pro |
| 13 |
* addon IS active it takes full precedence and this code is skipped entirely. |
| 14 |
*/ |
| 15 |
|
| 16 |
if ( ! defined( 'ABSPATH' ) ) { |
| 17 |
exit; |
| 18 |
} |
| 19 |
|
| 20 |
// ─── Guard: Do not run if the Pro addon is active ──────────────────────────── |
| 21 |
// The Pro addon defines qcwp_chat_session_menu_fnc(); if that function already |
| 22 |
// exists we skip everything here to avoid duplicate menus / conflicts. |
| 23 |
if ( function_exists( 'qcwp_chat_session_menu_fnc' ) ) { |
| 24 |
return; |
| 25 |
} |
| 26 |
|
| 27 |
// ─── Constants ──────────────────────────────────────────────────────────────── |
| 28 |
// Define our own URL / path constants for assets. |
| 29 |
// Also define the legacy constant names that all copied report partials reference, |
| 30 |
// so those files work without modification. |
| 31 |
|
| 32 |
if ( ! defined( 'QCLD_CHATBOT_FREE_SESSION_PLUGIN_URL' ) ) { |
| 33 |
define( 'QCLD_CHATBOT_FREE_SESSION_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); |
| 34 |
} |
| 35 |
if ( ! defined( 'QCLD_CHATBOT_FREE_SESSION_DIR_PATH' ) ) { |
| 36 |
define( 'QCLD_CHATBOT_FREE_SESSION_DIR_PATH', plugin_dir_path( __FILE__ ) ); |
| 37 |
} |
| 38 |
|
| 39 |
// Legacy alias constants — used by all copied partials / report files. |
| 40 |
if ( ! defined( 'QCLD_wpCHATBOT_HISTORY_PLUGIN_URL' ) ) { |
| 41 |
define( 'QCLD_wpCHATBOT_HISTORY_PLUGIN_URL', QCLD_CHATBOT_FREE_SESSION_PLUGIN_URL ); |
| 42 |
} |
| 43 |
if ( ! defined( 'QCLD_WPCHATBOT_HISTORY_DIR_PATH' ) ) { |
| 44 |
define( 'QCLD_WPCHATBOT_HISTORY_DIR_PATH', QCLD_CHATBOT_FREE_SESSION_DIR_PATH ); |
| 45 |
} |
| 46 |
|
| 47 |
// ─── Database Structure ─────────────────────────────────────────────────────── |
| 48 |
require_once QCLD_CHATBOT_FREE_SESSION_DIR_PATH . 'inc/chatsession-db-structure.php'; |
| 49 |
|
| 50 |
// ─── Admin Menu ─────────────────────────────────────────────────────────────── |
| 51 |
add_action( 'admin_menu', 'qcwp_chat_session_menu_fnc_free' ); |
| 52 |
|
| 53 |
function qcwp_chat_session_menu_fnc_free() { |
| 54 |
|
| 55 |
$capability = function_exists( 'qcld_wpbot_get_menu_capability' ) ? qcld_wpbot_get_menu_capability( 'sessions' ) : 'manage_options'; |
| 56 |
|
| 57 |
if ( current_user_can( $capability ) ) { |
| 58 |
|
| 59 |
add_menu_page( |
| 60 |
'WPBot - Sessions & Analytics', |
| 61 |
'WPBot - Sessions & Analytics', |
| 62 |
$capability, |
| 63 |
'wbcs-botsessions-page', |
| 64 |
'qc_wpbot_cs_menu_page_callback_func', |
| 65 |
'dashicons-chart-bar', |
| 66 |
'9' |
| 67 |
); |
| 68 |
|
| 69 |
add_submenu_page( |
| 70 |
'wbcs-botsessions-page', |
| 71 |
'Questions Not Answered', |
| 72 |
'Questions Not Answered', |
| 73 |
$capability, |
| 74 |
'wbcs-botsessions-notansweredpage', |
| 75 |
'qcld_wpbot_not_answered_question' |
| 76 |
); |
| 77 |
|
| 78 |
add_submenu_page( |
| 79 |
'wbcs-botsessions-page', |
| 80 |
'AI Insight', |
| 81 |
'AI Insight', |
| 82 |
$capability, |
| 83 |
'wbcs-schedule-session-reporting', |
| 84 |
'qcld_wpbot_schedule_session_reporting' |
| 85 |
); |
| 86 |
} |
| 87 |
} |
| 88 |
|
| 89 |
// ─── Admin Scripts & Styles ─────────────────────────────────────────────────── |
| 90 |
add_action( 'admin_enqueue_scripts', 'qcld_wb_chatbot_session_admin_scripts_free' ); |
| 91 |
|
| 92 |
function qcld_wb_chatbot_session_admin_scripts_free( $hook ) { |
| 93 |
// WordPress generates hook suffixes as follows: |
| 94 |
// top-level page → toplevel_page_{slug} |
| 95 |
// sub-pages → {parent-menu-title}_page_{slug} (title, lowercased, spaces→hyphens) |
| 96 |
// Our parent title is "WPBot Sessions & Analytics" → "wpbot-sessions-analytics" |
| 97 |
$session_hooks = array( |
| 98 |
'toplevel_page_wbcs-botsessions-page', |
| 99 |
'wpbot-sessions-analytics_page_wbcs-botsessions-notansweredpage', |
| 100 |
'wpbot-sessions-analytics_page_wbcs-botsessions-reports', |
| 101 |
'wpbot-sessions-analytics_page_wbcs-schedule-session-reporting', |
| 102 |
); |
| 103 |
$is_session_page = false; |
| 104 |
foreach ( $session_hooks as $session_hook ) { |
| 105 |
if ( strpos( $hook, $session_hook ) !== false || ( isset( $_GET['page'] ) && $_GET['page'] === str_replace( 'toplevel_page_', '', $session_hook ) ) ) { |
| 106 |
$is_session_page = true; |
| 107 |
break; |
| 108 |
} |
| 109 |
} |
| 110 |
|
| 111 |
if ( isset( $_GET['page'] ) && in_array( $_GET['page'], array( 'wbcs-botsessions-page', 'wbcs-botsessions-notansweredpage', 'wbcs-botsessions-reports', 'wbcs-schedule-session-reporting' ) ) ) { |
| 112 |
$is_session_page = true; |
| 113 |
} |
| 114 |
|
| 115 |
if ( ! $is_session_page ) { |
| 116 |
return; |
| 117 |
} |
| 118 |
|
| 119 |
wp_register_style( 'qlcd-wp-bootstrap-cs', QCLD_CHATBOT_FREE_SESSION_PLUGIN_URL . 'css/qlcd-wp-bootstrap.css', array(), QCLD_wpCHATBOT_VERSION, 'screen' ); |
| 120 |
wp_enqueue_style( 'qlcd-wp-bootstrap-cs' ); |
| 121 |
|
| 122 |
wp_register_style( 'qlcd-wp-bootstrap-icons-cs', QCLD_CHATBOT_FREE_SESSION_PLUGIN_URL . 'css/qlcd-wp-bootstrap-icons.css', array(), QCLD_wpCHATBOT_VERSION, 'screen' ); |
| 123 |
wp_enqueue_style( 'qlcd-wp-bootstrap-icons-cs' ); |
| 124 |
|
| 125 |
wp_register_style( 'qlcd-wp-dataTables-cs', QCLD_CHATBOT_FREE_SESSION_PLUGIN_URL . 'css/qlcd-wp-dataTables.css', array(), QCLD_wpCHATBOT_VERSION, 'screen' ); |
| 126 |
wp_enqueue_style( 'qlcd-wp-dataTables-cs' ); |
| 127 |
|
| 128 |
wp_register_style( 'qlcd-wp-session-style-cs', QCLD_CHATBOT_FREE_SESSION_PLUGIN_URL . 'reports/view/assets/style.css', array(), QCLD_wpCHATBOT_VERSION, 'screen' ); |
| 129 |
wp_enqueue_style( 'qlcd-wp-session-style-cs' ); |
| 130 |
|
| 131 |
// SweetAlert2 — used by admin.js for Swal.fire() and Swal.showLoading() |
| 132 |
wp_register_script( 'qcld-wp-chatbot-sweetalrt-cs', QCLD_wpCHATBOT_PLUGIN_URL . 'js/sweetalrt.js', array( 'jquery' ), QCLD_wpCHATBOT_VERSION, true ); |
| 133 |
wp_enqueue_script( 'qcld-wp-chatbot-sweetalrt-cs' ); |
| 134 |
|
| 135 |
// admin.js depends on SweetAlert2 being loaded first |
| 136 |
wp_register_script( 'qcld-wp-session-admin-cs', QCLD_CHATBOT_FREE_SESSION_PLUGIN_URL . 'js/admin.js', array( 'jquery', 'qcld-wp-chatbot-sweetalrt-cs' ), QCLD_wpCHATBOT_VERSION, true ); |
| 137 |
wp_enqueue_script( 'qcld-wp-session-admin-cs' ); |
| 138 |
wp_localize_script( |
| 139 |
'qcld-wp-session-admin-cs', |
| 140 |
'ajax_object', |
| 141 |
array( |
| 142 |
'ajax_url' => admin_url( 'admin-ajax.php' ), |
| 143 |
'ajax_nonce' => wp_create_nonce( 'wpbot_session_ajax_nonce' ) |
| 144 |
) |
| 145 |
); |
| 146 |
|
| 147 |
wp_register_script( 'qcld-wp-dataTables-cs', QCLD_CHATBOT_FREE_SESSION_PLUGIN_URL . 'js/qcld-dataTables.min.js', array( 'jquery' ), QCLD_wpCHATBOT_VERSION, true ); |
| 148 |
wp_enqueue_script( 'qcld-wp-dataTables-cs' ); |
| 149 |
} |
| 150 |
|
| 151 |
|
| 152 |
// ─── AI Insight Page Callback ───────────────────────────────────────────────── |
| 153 |
function qcld_wpbot_schedule_session_reporting() { |
| 154 |
wp_register_style( 'qcld-wp-chatbot-history-style', QCLD_CHATBOT_FREE_SESSION_PLUGIN_URL . 'css/history-style.css', array(), QCLD_wpCHATBOT_VERSION, 'screen' ); |
| 155 |
wp_enqueue_style( 'qcld-wp-chatbot-history-style' ); |
| 156 |
?> |
| 157 |
<div class="wrap wpbot-ai-insight-page"> |
| 158 |
<div class="wpbot-ai-insight-header"> |
| 159 |
<h2><?php echo esc_html__( 'AI Insight', 'chatbot' ); ?></h2> |
| 160 |
<p><?php echo esc_html__( 'Scheduled AI summaries of your chat conversations.', 'chatbot' ); ?></p> |
| 161 |
</div> |
| 162 |
|
| 163 |
<div class="wpbot-ai-insight-locked"> |
| 164 |
<div class="wpbot-ai-insight-locked__icon" aria-hidden="true"> |
| 165 |
<span class="dashicons dashicons-lock"></span> |
| 166 |
</div> |
| 167 |
<h3><?php echo esc_html__( 'Feature Locked', 'chatbot' ); ?></h3> |
| 168 |
<p class="wpbot-ai-insight-locked__desc"> |
| 169 |
<?php echo esc_html__( 'The AI Insight feature allows you to receive an AI-based summary of all chat conversations emailed directly to you on a schedule.', 'chatbot' ); ?> |
| 170 |
</p> |
| 171 |
<p class="wpbot-ai-insight-locked__cta"> |
| 172 |
<?php echo esc_html__( 'Please upgrade to WPBot Pro to unlock this feature!', 'chatbot' ); ?> |
| 173 |
</p> |
| 174 |
<a href="https://www.wpbot.pro/" target="_blank" rel="noopener noreferrer" class="wpbot-ai-insight-locked__btn"> |
| 175 |
<?php echo esc_html__( 'Upgrade to Pro', 'chatbot' ); ?> |
| 176 |
</a> |
| 177 |
</div> |
| 178 |
</div> |
| 179 |
<?php |
| 180 |
} |
| 181 |
|
| 182 |
|
| 183 |
// ─── Questions Not Answered Page Callback ───────────────────────────────────── |
| 184 |
function qcld_wpbot_not_answered_question() { |
| 185 |
global $wpdb; |
| 186 |
$wpdb->show_errors = true; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 187 |
$table = $wpdb->prefix . 'wpbot_failed_response'; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 188 |
|
| 189 |
if ( isset( $_GET['msg'] ) && $_GET['msg'] == 'success' ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 190 |
echo '<div class="notice notice-success"><p>Record has been Deleted Successfully!</p></div>'; |
| 191 |
} |
| 192 |
|
| 193 |
if ( isset( $_GET['action'] ) && $_GET['action'] == 'deleteall' ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 194 |
$wpdb->query( "TRUNCATE TABLE `$table`" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 195 |
echo '<div class="notice notice-success"><p>All Records have been deleted successfully!</p></div>'; |
| 196 |
} |
| 197 |
|
| 198 |
$sql = "SELECT * FROM $table WHERE 1 ORDER BY `id` DESC"; // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared |
| 199 |
$sql1 = "SELECT count(*) FROM $table WHERE 1 ORDER BY `id` DESC"; // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared |
| 200 |
|
| 201 |
$total = $wpdb->get_var( $sql1 ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 202 |
$items_per_page = 30; |
| 203 |
$page = isset( $_GET['cpage'] ) ? abs( (int) $_GET['cpage'] ) : 1; // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 204 |
$offset = ( $page * $items_per_page ) - $items_per_page; |
| 205 |
$sql .= " LIMIT {$offset}, {$items_per_page}"; |
| 206 |
$result = $wpdb->get_results( $sql ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 207 |
$totalPage = ceil( $total / $items_per_page ); |
| 208 |
$customPagHTML = ''; |
| 209 |
if ( $totalPage > 1 ) { |
| 210 |
$customPagHTML = '<div><span class="wpbot_pagination">Page ' . esc_html( $page ) . ' of ' . esc_html( $totalPage ) . '</span>' . paginate_links( |
| 211 |
array( |
| 212 |
'base' => add_query_arg( 'cpage', '%#%' ), |
| 213 |
'format' => '', |
| 214 |
'prev_text' => __( '« prev' ), // phpcs:ignore WordPress.WP.I18n.MissingArgDomain |
| 215 |
'next_text' => __( 'next »' ), // phpcs:ignore WordPress.WP.I18n.MissingArgDomain |
| 216 |
'total' => esc_html( $totalPage ), |
| 217 |
'current' => esc_html( $page ), |
| 218 |
) |
| 219 |
) . '</div>'; |
| 220 |
} |
| 221 |
|
| 222 |
wp_register_style( 'qcld-wp-chatbot-history-style', QCLD_CHATBOT_FREE_SESSION_PLUGIN_URL . 'css/history-style.css', array(), QCLD_wpCHATBOT_VERSION, 'screen' ); |
| 223 |
wp_enqueue_style( 'qcld-wp-chatbot-history-style' ); |
| 224 |
?> |
| 225 |
|
| 226 |
<div class="sld_menu_title qcld_session_chat_menu_title"> |
| 227 |
<h2><?php echo esc_html__( 'Questions Not Answered', 'chatbot' ) . ' (' . intval( $total ) . ')'; ?></h2> |
| 228 |
</div> |
| 229 |
|
| 230 |
<?php if ( $customPagHTML != '' ) : ?> |
| 231 |
<div class="sld_menu_title sld_menu_title_align"><?php echo wp_kses_post( $customPagHTML ); ?></div> |
| 232 |
<?php endif; ?> |
| 233 |
|
| 234 |
<?php |
| 235 |
require_once QCLD_CHATBOT_FREE_SESSION_DIR_PATH . 'reports/view/partials/questions-not-answered.php'; |
| 236 |
} |
| 237 |
|
| 238 |
// ─── Main Chat Sessions Page Callback ──────────────────────────────────────── |
| 239 |
function qc_wpbot_cs_menu_page_callback_func() { |
| 240 |
|
| 241 |
global $wpdb; |
| 242 |
$wpdb->show_errors = true; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 243 |
|
| 244 |
$tableuser = $wpdb->prefix . 'wpbot_user'; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 245 |
$tableconversation = $wpdb->prefix . 'wpbot_conversation'; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 246 |
$mainurl = admin_url( 'admin.php?page=wbcs-botsessions-page' ); |
| 247 |
|
| 248 |
if ( isset( $_GET['min_interaction'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 249 |
$mainurl .= '&min_interaction=' . intval( $_GET['min_interaction'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 250 |
} |
| 251 |
if ( isset( $_GET['wp_user'] ) && $_GET['wp_user'] != '' ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 252 |
$mainurl .= '&wp_user=' . intval( $_GET['wp_user'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 253 |
} |
| 254 |
|
| 255 |
$msg = ''; |
| 256 |
|
| 257 |
if ( isset( $_GET['action'] ) && $_GET['action'] == 'deleteall' ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 258 |
$wpdb->query( "TRUNCATE TABLE `$tableuser`" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 259 |
$wpdb->query( "TRUNCATE TABLE `$tableconversation`" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 260 |
$msg = esc_html( 'All Sessions have been deleted successfully!' ); |
| 261 |
} |
| 262 |
|
| 263 |
if ( isset( $_GET['msg'] ) && $_GET['msg'] == 'success' ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 264 |
echo '<div class="notice notice-success"><p>Record has been Deleted Successfully!</p></div>'; |
| 265 |
} |
| 266 |
|
| 267 |
if ( isset( $_GET['userid'] ) && $_GET['userid'] != '' ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 268 |
require_once QCLD_CHATBOT_FREE_SESSION_DIR_PATH . 'reports/view/partials/view-single-chat.php'; |
| 269 |
} else { |
| 270 |
|
| 271 |
wp_register_style( 'qcld-wp-chatbot-history-style', QCLD_CHATBOT_FREE_SESSION_PLUGIN_URL . 'css/history-style.css', array(), QCLD_wpCHATBOT_VERSION, 'screen' ); |
| 272 |
wp_enqueue_style( 'qcld-wp-chatbot-history-style' ); |
| 273 |
wp_register_style( 'qcld-wp-chatbot-jquery-ui', QCLD_CHATBOT_FREE_SESSION_PLUGIN_URL . 'css/jqueryui.css', array(), '', 'screen' ); |
| 274 |
wp_enqueue_style( 'qcld-wp-chatbot-jquery-ui' ); |
| 275 |
wp_register_script( 'qcld-wp-chatsession-admin-js', QCLD_CHATBOT_FREE_SESSION_PLUGIN_URL . 'js/chatsession.js', array( 'jquery' ), QCLD_wpCHATBOT_VERSION, true ); |
| 276 |
wp_enqueue_script( 'qcld-wp-chatsession-admin-js' ); |
| 277 |
wp_localize_script( |
| 278 |
'qcld-wp-chatsession-admin-js', |
| 279 |
'ajax_object', |
| 280 |
array( |
| 281 |
'ajax_url' => admin_url( 'admin-ajax.php' ), |
| 282 |
'ajax_nonce' => wp_create_nonce( 'wpbot_session_ajax_nonce' ) |
| 283 |
) |
| 284 |
); |
| 285 |
wp_register_script( 'qcld-wp-jqueryui-js', QCLD_CHATBOT_FREE_SESSION_PLUGIN_URL . 'js/jqueryui.js', array( 'jquery' ), QCLD_wpCHATBOT_VERSION, true ); |
| 286 |
wp_enqueue_script( 'qcld-wp-jqueryui-js' ); |
| 287 |
|
| 288 |
$where = ''; |
| 289 |
if ( isset( $_GET['min_interaction'] ) && $_GET['min_interaction'] != 'all' ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 290 |
if ( isset( $_GET['min_interaction'] ) && $_GET['min_interaction'] > 0 ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 291 |
$where = ' and `interaction` >= ' . intval( $_GET['min_interaction'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 292 |
} |
| 293 |
if ( isset( $_GET['min_interaction'] ) && $_GET['min_interaction'] == 0 ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 294 |
$where = ' and `interaction` = 0'; |
| 295 |
} |
| 296 |
} |
| 297 |
|
| 298 |
$wwhere = ''; |
| 299 |
if ( isset( $_GET['wp_user'] ) && $_GET['wp_user'] != 'all' && $_GET['wp_user'] != 0 && $_GET['wp_user'] != '' ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 300 |
$wwhere = ' and `user_id` = ' . intval( $_GET['wp_user'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 301 |
} |
| 302 |
|
| 303 |
$sql = "SELECT * FROM $tableuser WHERE 1 $where $wwhere ORDER BY `date` DESC"; // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared |
| 304 |
$sql1 = "SELECT count(*) FROM $tableuser WHERE 1 $where $wwhere"; // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared |
| 305 |
|
| 306 |
$dateFilter = ''; |
| 307 |
if ( isset( $_GET['FilterDate'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 308 |
if ( $_GET['FilterDate'] === 'LastWeek' ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 309 |
$dateFilter = " WHERE `date` >= CURDATE() - INTERVAL 7 DAY"; |
| 310 |
} |
| 311 |
if ( $_GET['FilterDate'] === 'LastMonth' ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 312 |
$dateFilter = " WHERE `date` >= CURDATE() - INTERVAL 30 DAY"; |
| 313 |
} |
| 314 |
if ( $_GET['FilterDate'] === 'Last3Months' ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 315 |
$dateFilter = " WHERE `date` >= CURDATE() - INTERVAL 90 DAY"; |
| 316 |
} |
| 317 |
$sql = "SELECT * FROM $tableuser $dateFilter $wwhere ORDER BY `date` DESC"; // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared |
| 318 |
$sql1 = "SELECT count(*) FROM $tableuser $dateFilter"; // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared |
| 319 |
} |
| 320 |
|
| 321 |
$total = $wpdb->get_var( $sql1 ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 322 |
$items_per_page = 30; |
| 323 |
$page = isset( $_GET['cpage'] ) ? abs( (int) $_GET['cpage'] ) : 1; // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 324 |
$offset = ( $page * $items_per_page ) - $items_per_page; |
| 325 |
$sql .= " LIMIT {$offset}, {$items_per_page}"; |
| 326 |
$result = $wpdb->get_results( $sql ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 327 |
$totalPage = ceil( $total / $items_per_page ); |
| 328 |
$customPagHTML = ''; |
| 329 |
if ( $totalPage > 1 ) { |
| 330 |
$customPagHTML = '<div class="qcld-session-pagination"><span class="wpbot_pagination">Page ' . esc_html( $page ) . ' of ' . esc_html( $totalPage ) . '</span>' . paginate_links( |
| 331 |
array( |
| 332 |
'base' => add_query_arg( 'cpage', '%#%' ), |
| 333 |
'format' => '', |
| 334 |
'prev_text' => __( '« prev' ), // phpcs:ignore WordPress.WP.I18n.MissingArgDomain |
| 335 |
'next_text' => __( 'next »' ), // phpcs:ignore WordPress.WP.I18n.MissingArgDomain |
| 336 |
'total' => esc_html( $totalPage ), |
| 337 |
'current' => esc_html( $page ), |
| 338 |
) |
| 339 |
) . '</div>'; |
| 340 |
} |
| 341 |
|
| 342 |
$deleteurl = admin_url( 'admin.php?page=wbcs-botsessions-page&action=deleteall' ); |
| 343 |
?> |
| 344 |
|
| 345 |
<div class="qchero_sliders_list_wrapper qcld-session-history_menu_box"> |
| 346 |
<?php if ( $msg != '' ) : ?> |
| 347 |
<div class="notice notice-success is-dismissible"> |
| 348 |
<p><?php echo esc_html( $msg ); ?></p> |
| 349 |
</div> |
| 350 |
<?php endif; ?> |
| 351 |
|
| 352 |
<div class="sld_menu_title qcld-session-history_menu_title"> |
| 353 |
<h2><?php echo esc_html__( 'Chat Sessions', 'chatbot' ) . ' (' . intval( $total ) . ')'; ?></h2> |
| 354 |
</div> |
| 355 |
|
| 356 |
<div> |
| 357 |
<?php |
| 358 |
if ( isset( $_GET['FilterDate'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 359 |
$filterText = ''; |
| 360 |
if ( $_GET['FilterDate'] === 'LastWeek' ) { $filterText = 'LAST WEEK'; } // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 361 |
if ( $_GET['FilterDate'] === 'LastMonth' ) { $filterText = 'LAST MONTH'; } // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 362 |
if ( $_GET['FilterDate'] === 'Last3Months' ) { $filterText = 'LAST 3 MONTHS'; } // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 363 |
echo '<div class="sld_menu_title"><em>Filtering Records by: <strong>' . esc_html( $filterText ) . '</strong></em></div>'; |
| 364 |
} |
| 365 |
?> |
| 366 |
</div> |
| 367 |
|
| 368 |
|
| 369 |
<form id="wpcs_form_sessions" action="<?php echo esc_url( $mainurl ); ?>" method="POST" style="width:98%"> |
| 370 |
<?php wp_nonce_field( 'wpcs_bulk_action' ); ?> |
| 371 |
<input type="hidden" name="wpbot_session_remove" /> |
| 372 |
|
| 373 |
<?php if ( ! empty( $result ) ) : ?> |
| 374 |
<?php require_once QCLD_CHATBOT_FREE_SESSION_DIR_PATH . 'reports/view/partials/chatsession-table.php'; ?> |
| 375 |
<?php else : ?> |
| 376 |
<div class="sld_menu_title"><h2>No result found.</h2></div> |
| 377 |
<?php endif; ?> |
| 378 |
</form> |
| 379 |
</div> |
| 380 |
<?php |
| 381 |
} |
| 382 |
} |
| 383 |
|
| 384 |
// ─── Request Handler (delete, export, redirect) ─────────────────────────────── |
| 385 |
add_action( 'init', 'qc_wp_cs_request_handle_free' ); |
| 386 |
|
| 387 |
function qc_wp_cs_request_handle_free() { |
| 388 |
if ( ! is_admin() || ! current_user_can( 'manage_options' ) ) { |
| 389 |
return; |
| 390 |
} |
| 391 |
|
| 392 |
global $wpdb; |
| 393 |
$wpdb->show_errors = true; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 394 |
|
| 395 |
$tableuser1 = $wpdb->prefix . 'wpbot_user'; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 396 |
$tableconversation1 = $wpdb->prefix . 'wpbot_conversation'; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 397 |
$table = $wpdb->prefix . 'wpbot_failed_response'; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 398 |
|
| 399 |
// Delete single "not answered" record. |
| 400 |
if ( isset( $_GET['page'] ) && $_GET['page'] == 'wbcs-botsessions-notansweredpage' && isset( $_GET['act'] ) && $_GET['act'] == 'delete' ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 401 |
$userid = intval( $_GET['id'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 402 |
check_admin_referer( 'wpcs_delete_session_' . $userid ); |
| 403 |
$wpdb->delete( $table, array( 'id' => $userid ), array( '%d' ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching |
| 404 |
wp_safe_redirect( admin_url( 'admin.php?page=wbcs-botsessions-notansweredpage&msg=success' ) ); |
| 405 |
exit; |
| 406 |
} |
| 407 |
|
| 408 |
// Delete single chat session. |
| 409 |
if ( isset( $_GET['page'] ) && $_GET['page'] == 'wbcs-botsessions-page' && isset( $_GET['act'] ) && $_GET['act'] == 'delete' ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 410 |
$userid = intval( $_GET['userid'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 411 |
check_admin_referer( 'wpcs_delete_session_' . $userid ); |
| 412 |
$wpdb->delete( $tableuser1, array( 'id' => $userid ), array( '%d' ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching |
| 413 |
$wpdb->delete( $tableconversation1, array( 'user_id' => $userid ), array( '%d' ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching |
| 414 |
wp_safe_redirect( admin_url( 'admin.php?page=wbcs-botsessions-page&msg=success' ) ); |
| 415 |
exit; |
| 416 |
} |
| 417 |
|
| 418 |
// Export all sessions as CSV. |
| 419 |
if ( isset( $_POST['wpbot_session_export_all'] ) && isset( $_POST['wpbot_session_remove'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 420 |
check_admin_referer( 'wpcs_bulk_action' ); |
| 421 |
$users = $wpdb->get_results( "SELECT wu.`id`, wu.`session_id`, wu.`name`, wu.`email`, wu.`date`, wu.`phone`, wu.`interaction`, wc.`conversation` FROM $tableuser1 as wu, $tableconversation1 as wc WHERE 1 AND wu.id = wc.user_id LIMIT 5000" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 422 |
$sessions = array(); |
| 423 |
if ( ! empty( $users ) ) { |
| 424 |
foreach ( $users as $user ) { |
| 425 |
$sessions[] = wpbot_conversations_export( $user ); |
| 426 |
} |
| 427 |
} |
| 428 |
qcld_wpbot_chatsession_download_send_headers( 'wpbot_chatsession_' . date( 'Y-m-d' ) . '.csv' ); |
| 429 |
print wpbot_chatsession_array2csv( $sessions ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- raw CSV download, escaping would corrupt the file. |
| 430 |
exit; |
| 431 |
} |
| 432 |
|
| 433 |
// Export selected sessions or delete selected sessions. |
| 434 |
if ( isset( $_POST['wpbot_session_remove'] ) && ! empty( $_POST['sessions'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 435 |
check_admin_referer( 'wpcs_bulk_action' ); |
| 436 |
$userids = array_map( 'intval', $_POST['sessions'] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 437 |
|
| 438 |
if ( isset( $_POST['wpbot_session_export'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 439 |
$sessions = array(); |
| 440 |
foreach ( $userids as $userid ) { |
| 441 |
$user = $wpdb->get_row( $wpdb->prepare( "SELECT wu.`id`, wu.`session_id`, wu.`name`, wu.`email`, wu.`date`, wu.`phone`, wu.`interaction`, wc.`conversation` FROM $tableuser1 as wu, $tableconversation1 as wc WHERE 1 AND wu.id = wc.user_id AND wu.id = %d", $userid ) ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 442 |
$sessions[] = wpbot_conversations_export( $user ); |
| 443 |
} |
| 444 |
qcld_wpbot_chatsession_download_send_headers( 'wpbot_chatsession_' . date( 'Y-m-d' ) . '.csv' ); |
| 445 |
print wpbot_chatsession_array2csv( $sessions ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- raw CSV download, escaping would corrupt the file. |
| 446 |
exit; |
| 447 |
} |
| 448 |
|
| 449 |
if ( isset( $_POST['wpbot_session_delete'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 450 |
foreach ( $userids as $userid ) { |
| 451 |
$wpdb->delete( $tableuser1, array( 'id' => $userid ), array( '%d' ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching |
| 452 |
$wpdb->delete( $tableconversation1, array( 'user_id' => $userid ), array( '%d' ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching |
| 453 |
} |
| 454 |
wp_safe_redirect( admin_url( 'admin.php?page=wbcs-botsessions-page&msg=success' ) ); |
| 455 |
exit; |
| 456 |
} |
| 457 |
} |
| 458 |
} |
| 459 |
|
| 460 |
// ─── Admin Footer: Email Modal ──────────────────────────────────────────────── |
| 461 |
add_action( 'admin_footer', 'wpcs_admin_footer_content_free' ); |
| 462 |
|
| 463 |
function wpcs_admin_footer_content_free() { |
| 464 |
if ( isset( $_GET['page'] ) && $_GET['page'] == 'wbcs-botsessions-page' ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 465 |
?> |
| 466 |
<div id="wpcsmyModal" class="wpcsmodal"> |
| 467 |
<div class="wpcsmodal-content"> |
| 468 |
<span class="wpcsclose">×</span> |
| 469 |
<h2><?php echo esc_html( 'Send an Email to' ); ?> <span id="wpcs_show_email"></span></h2> |
| 470 |
<div class="wpcs_form_container"> |
| 471 |
<form id="wpcs_email_form" action=""> |
| 472 |
<label for="fname"><?php echo esc_html( 'Subject' ); ?></label> |
| 473 |
<input type="text" class="wpcs_text_field" id="wpcs_email_subject" name="wpcs_email_subject" placeholder="Subject.." required> |
| 474 |
<label for="lname"><?php echo esc_html( 'Your Message' ); ?></label> |
| 475 |
<textarea id="wpcs_email_message" class="wpcs_text_field" name="wpcs_email_message" placeholder="" style="height:200px" required></textarea> |
| 476 |
<input type="hidden" id="wpcs_to_email_address" value="" /> |
| 477 |
<input type="submit" class="wpcs_submit_field" id="wpcs_email_submit" value="Submit"> |
| 478 |
<span id="wpcs_email_loading" style="display:none;"><img style="width:20px;" src="<?php echo esc_url( QCLD_CHATBOT_FREE_SESSION_PLUGIN_URL . 'images/ajax-loader.gif' ); ?>"></span> |
| 479 |
<span id="wpcs_email_status"></span> |
| 480 |
</form> |
| 481 |
</div> |
| 482 |
</div> |
| 483 |
</div> |
| 484 |
<?php |
| 485 |
} |
| 486 |
} |
| 487 |
|
| 488 |
// ─── AJAX: Send Email to User ───────────────────────────────────────────────── |
| 489 |
add_action( 'wp_ajax_wpcs_send_email', 'wpcs_send_email' ); |
| 490 |
|
| 491 |
function wpcs_send_email() { |
| 492 |
if ( ! current_user_can( 'manage_options' ) ) { |
| 493 |
wp_die(); |
| 494 |
} |
| 495 |
check_ajax_referer( 'wpbot_session_ajax_nonce', 'security' ); |
| 496 |
|
| 497 |
$subject = sanitize_text_field( $_POST['data']['subject'] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 498 |
$message = sanitize_text_field( $_POST['data']['message'] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 499 |
$to = sanitize_email( $_POST['data']['to'] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 500 |
|
| 501 |
global $wpdb; |
| 502 |
$tableuser = $wpdb->prefix . 'wpbot_user'; |
| 503 |
$user_exists = $wpdb->get_var( $wpdb->prepare( 'SELECT id FROM %i WHERE email = %s LIMIT 1', $tableuser, $to ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching |
| 504 |
$admin_email = get_option('admin_email'); |
| 505 |
if ( ! $user_exists && $to !== $admin_email ) { |
| 506 |
wp_send_json( array( 'status' => 'fail', 'message' => 'Invalid recipient address. Email must be a stored session email or admin email.' ) ); |
| 507 |
} |
| 508 |
|
| 509 |
$url = get_site_url(); |
| 510 |
$url = wp_parse_url( $url ); |
| 511 |
$domain = $url['host']; |
| 512 |
$fromEmail = 'wordpress@' . $domain; |
| 513 |
$headers = array( |
| 514 |
'Content-Type: text/html; charset=UTF-8', |
| 515 |
'From: ' . esc_html( $domain ) . ' <' . esc_html( $fromEmail ) . '>', |
| 516 |
); |
| 517 |
|
| 518 |
$result = wp_mail( $to, $subject, $message, $headers ); |
| 519 |
if ( $result ) { |
| 520 |
$response = array( 'status' => 'success', 'message' => 'Email has been sent successfully!' ); |
| 521 |
} else { |
| 522 |
$response = array( 'status' => 'fail', 'message' => 'Unable to send email. Please contact your server administrator.' ); |
| 523 |
} |
| 524 |
ob_clean(); |
| 525 |
echo wp_json_encode( $response ); |
| 526 |
die(); |
| 527 |
} |
| 528 |
|
| 529 |
// ─── AJAX: Save Email Notification Preference ───────────────────────────────── |
| 530 |
add_action( 'wp_ajax_session_email_notification_update', 'session_email_notification_update_free' ); |
| 531 |
|
| 532 |
function session_email_notification_update_free() { |
| 533 |
if ( ! current_user_can( 'manage_options' ) ) { |
| 534 |
wp_die(); |
| 535 |
} |
| 536 |
$email_notification = sanitize_text_field( $_POST['email_notification'] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 537 |
update_option( 'session_email_notification_update', $email_notification ); |
| 538 |
wp_send_json( array( 'success' => true ) ); |
| 539 |
} |
| 540 |
|
| 541 |
// ─── AJAX: Conversation Save (Frontend) ────────────────────────────────────── |
| 542 |
// This is the main conversation-save handler. Guarded with function_exists |
| 543 |
// so the Pro addon's definition wins if it's active. |
| 544 |
if ( ! function_exists( 'qcld_wb_chatbot_conversation_save' ) ) { |
| 545 |
|
| 546 |
function qcld_wb_chatbot_conversation_save() { |
| 547 |
|
| 548 |
check_ajax_referer( 'qcsecretbotnonceval123qc', 'security' ); |
| 549 |
global $wpdb; |
| 550 |
|
| 551 |
$tableuser = $wpdb->prefix . 'wpbot_user'; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 552 |
$tableconversation = $wpdb->prefix . 'wpbot_conversation'; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 553 |
|
| 554 |
$allowed_html = array_merge( |
| 555 |
wp_kses_allowed_html( 'post' ), |
| 556 |
array( |
| 557 |
'div' => array( 'class' => true, 'id' => true, 'style' => true, 'data-*' => true ), |
| 558 |
'span' => array( 'class' => true, 'id' => true, 'style' => true, 'data-*' => true ), |
| 559 |
'ul' => array( 'class' => true ), |
| 560 |
'li' => array( 'class' => true ), |
| 561 |
'img' => array( 'src' => true, 'alt' => true, 'class' => true, 'style' => true ), |
| 562 |
) |
| 563 |
); |
| 564 |
$raw_conversation = isset( $_POST['conversation'] ) ? wp_unslash( $_POST['conversation'] ) : ''; |
| 565 |
$clean_conversation = wp_kses( $raw_conversation, $allowed_html ); |
| 566 |
$conversation = qcld_wpbot_input_validation( $clean_conversation ); // phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 567 |
$email = isset( $_POST['email'] ) ? sanitize_email( $_POST['email'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 568 |
$phone = isset( $_POST['phone'] ) ? sanitize_text_field( $_POST['phone'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 569 |
$name = isset( $_POST['name'] ) ? sanitize_text_field( $_POST['name'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 570 |
$session_id = isset( $_POST['session_id'] ) ? sanitize_text_field( $_POST['session_id'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 571 |
$wpuser_id = isset( $_POST['user_id'] ) ? sanitize_text_field( $_POST['user_id'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 572 |
$source_url = isset( $_POST['source_url'] ) && ! empty( $_POST['source_url'] ) ? sanitize_url( wp_unslash( $_POST['source_url'] ) ) : ( isset( $_SERVER['HTTP_REFERER'] ) ? sanitize_url( wp_unslash( $_SERVER['HTTP_REFERER'] ) ) : '' ); // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
| 573 |
$user_agent = isset( $_POST['user_agent'] ) && ! empty( $_POST['user_agent'] ) ? sanitize_text_field( wp_unslash( $_POST['user_agent'] ) ) : ( isset( $_SERVER['HTTP_USER_AGENT'] ) ? sanitize_text_field( wp_unslash( $_SERVER['HTTP_USER_AGENT'] ) ) : '' ); // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized |
| 574 |
$session_mailed = isset( $_POST['session_mailed'] ) ? sanitize_text_field( $_POST['session_mailed'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 575 |
|
| 576 |
// Prepend source URL to conversation. |
| 577 |
$conversation = '<ul><li class="session_start_url"><span>Source URL: </span><a href="' . $source_url . '">' . $source_url . '</a></li></ul>' . $conversation; |
| 578 |
|
| 579 |
$response = array(); |
| 580 |
$response['status'] = 'success'; |
| 581 |
|
| 582 |
$user_exists = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $tableuser WHERE 1 AND session_id = %s", $session_id ) ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 583 |
$is_new_insert = false; |
| 584 |
|
| 585 |
if ( empty( $user_exists ) ) { |
| 586 |
$lock_key = 'wpcs_lock_' . md5( $session_id ); |
| 587 |
if ( add_option( $lock_key, '1', '', 'no' ) ) { |
| 588 |
$interaction = (int) substr_count( $conversation, 'wp-chat-user-msg' ); |
| 589 |
if ( $interaction == 0 ) { |
| 590 |
$interaction = (int) substr_count( $conversation, 'woo-chat-user-msg' ); |
| 591 |
} |
| 592 |
|
| 593 |
if ( $interaction != 0 ) { |
| 594 |
$wpdb->insert( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 595 |
$tableuser, |
| 596 |
array( |
| 597 |
'date' => current_time( 'mysql' ), |
| 598 |
'name' => $name, |
| 599 |
'email' => $email, |
| 600 |
'phone' => $phone, |
| 601 |
'session_id' => $session_id, |
| 602 |
'interaction' => $interaction, |
| 603 |
'user_id' => $wpuser_id, |
| 604 |
) |
| 605 |
); |
| 606 |
$user_id = $wpdb->insert_id; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 607 |
$wpdb->insert( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 608 |
$tableconversation, |
| 609 |
array( |
| 610 |
'user_id' => $user_id, |
| 611 |
'conversation' => $conversation, |
| 612 |
'interaction' => $interaction, |
| 613 |
'environment_info' => $user_agent, |
| 614 |
) |
| 615 |
); |
| 616 |
$is_new_insert = true; |
| 617 |
} |
| 618 |
delete_option( $lock_key ); |
| 619 |
} else { |
| 620 |
$retries = 3; |
| 621 |
while ( $retries > 0 ) { |
| 622 |
usleep( 500000 ); |
| 623 |
$user_exists = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $tableuser WHERE 1 AND session_id = %s", $session_id ) ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 624 |
if ( ! empty( $user_exists ) ) { |
| 625 |
break; |
| 626 |
} |
| 627 |
$retries--; |
| 628 |
} |
| 629 |
} |
| 630 |
} |
| 631 |
|
| 632 |
if ( ! $is_new_insert && ! empty( $user_exists ) ) { |
| 633 |
$interaction = (int) substr_count( $conversation, 'wp-chat-user-msg' ); |
| 634 |
if ( $interaction == 0 ) { |
| 635 |
$interaction = (int) substr_count( $conversation, 'woo-chat-user-msg' ); |
| 636 |
} |
| 637 |
|
| 638 |
$user_id = isset( $user_exists->id ) ? $user_exists->id : get_current_user_id(); |
| 639 |
$wpdb->update( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 640 |
$tableuser, |
| 641 |
array( |
| 642 |
'date' => current_time( 'mysql' ), |
| 643 |
'name' => $name, |
| 644 |
'email' => $email, |
| 645 |
'phone' => $phone, |
| 646 |
'interaction' => $interaction, |
| 647 |
'user_id' => $wpuser_id, |
| 648 |
), |
| 649 |
array( 'id' => $user_id ), |
| 650 |
array( '%s', '%s', '%s', '%s', '%d', '%d' ), |
| 651 |
array( '%d' ) |
| 652 |
); |
| 653 |
$wpdb->update( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 654 |
$tableconversation, |
| 655 |
array( |
| 656 |
'conversation' => $conversation, |
| 657 |
'interaction' => $interaction, |
| 658 |
), |
| 659 |
array( 'user_id' => $user_id ), |
| 660 |
array( '%s', '%d' ), |
| 661 |
array( '%d' ) |
| 662 |
); |
| 663 |
} |
| 664 |
|
| 665 |
// Email notification for new session. |
| 666 |
if ( $is_new_insert && ( get_option( 'session_email_notification_update' ) == 'checked' ) ) { |
| 667 |
$admin_email = get_option( 'admin_email' ); |
| 668 |
$subject = esc_html__( 'Someone has started a new chat session with ChatBot.', 'chatbot' ); |
| 669 |
$bodyContent = '<p>' . esc_html__( 'Hi,', 'chatbot' ) . '</p>'; |
| 670 |
$bodyContent .= '<p>' . esc_html__( 'Someone has started a new chat session with ChatBot. Please go to ', 'chatbot' ) . '<a href="' . admin_url() . 'admin.php?page=wbcs-botsessions-page&userid='. $user_id .'">' . esc_html__( 'Bot Sessions Dashboard', 'chatbot' ) . '</a>' . esc_html__( ' and find him/her.', 'chatbot' ) . '</p>'; |
| 671 |
|
| 672 |
$bodyContent .= '<ul>'; |
| 673 |
$bodyContent .= '<li>' . esc_html__( 'Session ID:', 'chatbot' ) . ' <strong>' . esc_html( $session_id ) . '</strong></li>'; |
| 674 |
if ( ! empty( $email ) ) { |
| 675 |
$bodyContent .= '<li>' . esc_html__( 'Email:', 'chatbot' ) . ' <strong>' . esc_html( $email ) . '</strong></li>'; |
| 676 |
} |
| 677 |
if ( ! empty( $phone ) ) { |
| 678 |
$bodyContent .= '<li>' . esc_html__( 'Phone:', 'chatbot' ) . ' <strong>' . esc_html( $phone ) . '</strong></li>'; |
| 679 |
} |
| 680 |
if ( ! empty( $source_url ) ) { |
| 681 |
$bodyContent .= '<li>' . esc_html__( 'Page Link:', 'chatbot' ) . ' <strong><a href="' . esc_url( $source_url ) . '">' . esc_html( $source_url ) . '</a></strong></li>'; |
| 682 |
} |
| 683 |
if ( ! empty( $user_agent ) ) { |
| 684 |
$bodyContent .= '<li>' . esc_html__( 'Browser:', 'chatbot' ) . ' <strong>' . esc_html( $user_agent ) . '</strong></li>'; |
| 685 |
} |
| 686 |
$bodyContent .= '</ul>'; |
| 687 |
|
| 688 |
$bodyContent .= '<p>' . esc_html__( 'Thanks', 'chatbot' ) . '</p>'; |
| 689 |
$bodyContent .= '<p>' . esc_html__( '(You can disable email notifications from ', 'chatbot' ) . '<a href="' . admin_url() . 'admin.php?page=wbcs-botsessions-page">' . esc_html__( 'Bot - Sessions)', 'chatbot' ) . '</a></p>'; |
| 690 |
|
| 691 |
$to = get_option( 'qlcd_wp_chatbot_admin_email' ) != '' ? get_option( 'qlcd_wp_chatbot_admin_email' ) : $admin_email; |
| 692 |
$headers = array( 'Content-Type: text/html; charset=UTF-8' ); |
| 693 |
wp_mail( $to, $subject, $bodyContent, $headers ); |
| 694 |
} |
| 695 |
|
| 696 |
// WPBot Automator Trigger - Debounced by 3 minutes |
| 697 |
$cron_args = array( $session_id ); |
| 698 |
if ( wp_next_scheduled( 'wpbot_automator_delayed_trigger', $cron_args ) ) { |
| 699 |
wp_clear_scheduled_hook( 'wpbot_automator_delayed_trigger', $cron_args ); |
| 700 |
} |
| 701 |
wp_schedule_single_event( time() + 60, 'wpbot_automator_delayed_trigger', $cron_args ); |
| 702 |
|
| 703 |
echo wp_json_encode( $response ); |
| 704 |
die(); |
| 705 |
} |
| 706 |
} |
| 707 |
add_action( 'wp_ajax_qcld_wb_chatbot_conversation_save', 'qcld_wb_chatbot_conversation_save' ); |
| 708 |
add_action( 'wp_ajax_nopriv_qcld_wb_chatbot_conversation_save', 'qcld_wb_chatbot_conversation_save' ); |
| 709 |
|
| 710 |
// ─── AJAX: Date Filter ──────────────────────────────────────────────────────── |
| 711 |
add_action( 'wp_ajax_qcld_chatbot_session_date_filter', 'qcld_chatbot_session_date_filter_free' ); |
| 712 |
|
| 713 |
function qcld_chatbot_session_date_filter_free() { |
| 714 |
if ( ! current_user_can( 'manage_options' ) ) { |
| 715 |
wp_die(); |
| 716 |
} |
| 717 |
check_ajax_referer( 'wpbot_session_ajax_nonce', 'security' ); |
| 718 |
global $wpdb; |
| 719 |
$tableuser = $wpdb->prefix . 'wpbot_user'; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 720 |
$start_date = sanitize_text_field( $_POST['start_date'] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 721 |
$end_date = sanitize_text_field( $_POST['end_date'] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 722 |
$result = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $tableuser WHERE date BETWEEN %s AND %s", $start_date, $end_date ) ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 723 |
echo wp_json_encode( $result ); |
| 724 |
wp_die(); |
| 725 |
} |
| 726 |
|
| 727 |
// ─── AJAX: Email Transcript ─────────────────────────────────────────────────── |
| 728 |
add_action( 'wp_ajax_wpbot_send_email_transcript', 'wpbot_send_email_transcript_free' ); |
| 729 |
|
| 730 |
function wpbot_send_email_transcript_free() { |
| 731 |
if ( ! current_user_can( 'manage_options' ) ) { |
| 732 |
wp_send_json( array( 'status' => 'fail', 'message' => 'Unauthorized' ) ); |
| 733 |
} |
| 734 |
check_ajax_referer( 'wpbot_session_ajax_nonce', 'security' ); |
| 735 |
|
| 736 |
global $wpdb; |
| 737 |
|
| 738 |
$session = trim( sanitize_text_field( $_POST['session'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 739 |
|
| 740 |
$url = wp_parse_url( get_site_url() ); |
| 741 |
$domain = $url['host']; |
| 742 |
$admin_email = get_option( 'admin_email' ); |
| 743 |
$fromEmail = get_option( 'qlcd_wp_chatbot_from_email' ) ? get_option( 'qlcd_wp_chatbot_from_email' ) : 'wordpress@' . $domain; |
| 744 |
$subject = 'Chat transcript by ' . get_bloginfo( 'name' ); |
| 745 |
|
| 746 |
$tableuser = $wpdb->prefix . 'wpbot_user'; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 747 |
$tableconversation = $wpdb->prefix . 'wpbot_conversation'; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 748 |
|
| 749 |
$user = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $tableuser WHERE 1 AND session_id = %s", $session ) ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 750 |
|
| 751 |
$response = array( 'status' => 'fail', 'message' => 'Session not found.' ); |
| 752 |
|
| 753 |
if ( ! empty( $user ) ) { |
| 754 |
$email = sanitize_email( $user->email ); // Use email from user record |
| 755 |
if ( empty( $email ) ) { |
| 756 |
wp_send_json( array( 'status' => 'fail', 'message' => 'User has no email.' ) ); |
| 757 |
} |
| 758 |
|
| 759 |
$result = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $tableconversation WHERE 1 AND user_id = %d", $user->id ) ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 760 |
$bodyContent = ''; |
| 761 |
$bodyContent .= '<p><strong>' . esc_html__( 'User Details', 'chatbot' ) . ':</strong></p><hr>'; |
| 762 |
$bodyContent .= '<p>' . esc_html__( 'Name', 'chatbot' ) . ' : ' . esc_html( $user->name ) . '</p>'; |
| 763 |
$bodyContent .= '<p>' . esc_html__( 'Email', 'chatbot' ) . ' : ' . esc_html( $email ) . '</p>'; |
| 764 |
$bodyContent .= '<p><b>Conversations</b></p><p>-----------------------</p>'; |
| 765 |
$messages = qcld_wpch_conversation_extract( htmlspecialchars_decode( $result->conversation ) ); |
| 766 |
foreach ( $messages as $message ) { |
| 767 |
if ( isset( $message['bot'] ) && trim( $message['bot'] ) != '' ) { |
| 768 |
$bodyContent .= '<p>Chatbot : ' . esc_html( trim( $message['bot'] ) ) . '</p>'; |
| 769 |
} |
| 770 |
if ( isset( $message['user'] ) && trim( $message['user'] ) != '' ) { |
| 771 |
$bodyContent .= '<p>' . esc_html( $user->name ) . ' : ' . esc_html( trim( $message['user'] ) ) . '</p>'; |
| 772 |
} |
| 773 |
} |
| 774 |
$bodyContent .= '<p>-----------------------</p>'; |
| 775 |
$bodyContent .= '<p>Mail Generated on: ' . current_time( 'F j, Y, g:i a' ) . '</p>'; |
| 776 |
$headers = array( |
| 777 |
'Content-Type: text/html; charset=UTF-8', |
| 778 |
'From: ' . esc_html( $user->name ) . ' <' . esc_html( $fromEmail ) . '>', |
| 779 |
'Reply-To: ' . esc_html( $user->name ) . ' <' . esc_html( $email ) . '>', |
| 780 |
); |
| 781 |
$result_mail = wp_mail( $email, $subject, $bodyContent, $headers ); |
| 782 |
if ( $result_mail ) { |
| 783 |
$response = array( 'status' => 'success', 'message' => 'Email transcript sent successfully.' ); |
| 784 |
} |
| 785 |
} |
| 786 |
echo wp_json_encode( $response ); |
| 787 |
die(); |
| 788 |
} |
| 789 |
|
| 790 |
// ─── AJAX: Forward Session to Email ────────────────────────────────────────── |
| 791 |
add_action( 'wp_ajax_forward_session_to_email', 'forward_session_to_email_free' ); |
| 792 |
|
| 793 |
function forward_session_to_email_free() { |
| 794 |
if ( ! current_user_can( 'manage_options' ) ) { |
| 795 |
wp_send_json( array( 'success' => false, 'msg' => esc_html__( 'Insufficient permissions', 'chatbot' ) ) ); |
| 796 |
wp_die(); |
| 797 |
} |
| 798 |
check_ajax_referer( 'wpbot_session_ajax_nonce', 'security' ); |
| 799 |
global $wpdb; |
| 800 |
|
| 801 |
$session_id = sanitize_text_field( $_POST['session_id'] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 802 |
$to = sanitize_email( $_POST['email'] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 803 |
$tableuser = $wpdb->prefix . 'wpbot_user'; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 804 |
$tableconversation = $wpdb->prefix . 'wpbot_conversation'; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 805 |
|
| 806 |
$userinfo = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $tableuser WHERE 1 AND session_id = %s", $session_id ) ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 807 |
$result = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $tableconversation WHERE 1 AND user_id = %d", $userinfo->id ) ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 808 |
|
| 809 |
if ( ! empty( $result ) ) { |
| 810 |
$raw_html = isset( $result->conversation ) ? (string) $result->conversation : ''; |
| 811 |
$decoded_content = html_entity_decode( $raw_html ); |
| 812 |
$doc = new DOMDocument(); |
| 813 |
libxml_use_internal_errors( true ); |
| 814 |
$doc->loadHTML( '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">' . $decoded_content ); |
| 815 |
libxml_clear_errors(); |
| 816 |
|
| 817 |
$decoded_content = ''; |
| 818 |
$body_nodes = $doc->getElementsByTagName( 'body' ); |
| 819 |
if ( $body_nodes->length > 0 ) { |
| 820 |
foreach ( $body_nodes->item( 0 )->childNodes as $child_node ) { |
| 821 |
$decoded_content .= $doc->saveHTML( $child_node ); |
| 822 |
} |
| 823 |
} |
| 824 |
|
| 825 |
$email_body = '<!DOCTYPE html><html><head><style> |
| 826 |
.wp-chatbot-messages-container { list-style: none; padding: 20px; background: #f4f7f6; font-family: sans-serif; } |
| 827 |
.wp-chatbot-msg { margin-bottom: 15px; display: flex; flex-wrap: wrap; } |
| 828 |
.wp-chatbot-agent { font-weight: bold; color: #333; display: block; margin-bottom: 4px; } |
| 829 |
.wp-chatbot-paragraph { background: #ffffff; padding: 10px; border-radius: 8px; border: 1px solid #ddd; flex: 1; } |
| 830 |
.wp-chat-user-msg { display: flex; flex-wrap: wrap; flex-direction: row-reverse; } |
| 831 |
.wp-chat-user-msg .wp-chatbot-paragraph { background: #ffffff; padding: 10px; border-radius: 8px; border: 1px solid #ddd; flex: none; } |
| 832 |
body ul { width:100%; max-width: 640px; list-style: none; padding: 0; margin: 0 auto; } |
| 833 |
</style></head><body>' . $decoded_content . '</body></html>'; |
| 834 |
|
| 835 |
$subject = isset( $_POST['subject'] ) ? sanitize_text_field( wp_unslash( $_POST['subject'] ) ) : 'Chat Session Transcript'; // phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 836 |
if ( empty( $subject ) ) { $subject = 'Chat Session Transcript'; } |
| 837 |
$headers = array( 'Content-Type: text/html; charset=UTF-8' ); |
| 838 |
wp_mail( $to, $subject, $email_body, $headers ); |
| 839 |
wp_send_json( array( 'success' => true, 'msg' => esc_html__( 'Session has been forwarded to email successfully', 'chatbot' ) ) ); |
| 840 |
wp_die(); |
| 841 |
} else { |
| 842 |
wp_send_json( array( 'success' => false, 'msg' => esc_html__( 'No conversation found for this session', 'chatbot' ) ) ); |
| 843 |
wp_die(); |
| 844 |
} |
| 845 |
} |
| 846 |
|
| 847 |
// ─── AJAX: Session Hover Details ───────────────────────────────────────────── |
| 848 |
add_action( 'wp_ajax_wpbot_session_hover_details', 'wpbot_session_hover_details_free' ); |
| 849 |
|
| 850 |
function wpbot_session_hover_details_free() { |
| 851 |
if ( ! current_user_can( 'manage_options' ) ) { |
| 852 |
wp_send_json( array( 'success' => false, 'msg' => esc_html__( 'Insufficient permissions', 'chatbot' ) ) ); |
| 853 |
wp_die(); |
| 854 |
} |
| 855 |
check_ajax_referer( 'wpbot_session_ajax_nonce', 'security' ); |
| 856 |
global $wpdb; |
| 857 |
$session_id = sanitize_text_field( $_POST['session_id'] ); // phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 858 |
$tableconversation = $wpdb->prefix . 'wpbot_conversation'; |
| 859 |
$tableuser = $wpdb->prefix . 'wpbot_user'; |
| 860 |
$email_from = get_option( 'qlcd_wp_chatbot_from_email' ); |
| 861 |
$result = $wpdb->get_row( $wpdb->prepare( "SELECT c.*, u.email, u.name, u.session_id as user_session_id FROM $tableconversation AS c LEFT JOIN $tableuser AS u ON c.user_id = u.id WHERE c.user_id = %d", $session_id ) ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 862 |
if ( ! empty( $result ) ) { |
| 863 |
$result->email_from = $email_from; |
| 864 |
$result->status = 'success'; |
| 865 |
} |
| 866 |
echo wp_json_encode( $result ); |
| 867 |
wp_die(); |
| 868 |
} |
| 869 |
|
| 870 |
// ─── AJAX: Send Reply Email ─────────────────────────────────────────────────── |
| 871 |
add_action( 'wp_ajax_wpbot_send_reply_email', 'wpbot_send_reply_email_free' ); |
| 872 |
|
| 873 |
function wpbot_send_reply_email_free() { |
| 874 |
if ( ! current_user_can( 'manage_options' ) ) { |
| 875 |
wp_send_json( array( 'success' => false, 'msg' => esc_html__( 'Insufficient permissions', 'chatbot' ) ) ); |
| 876 |
wp_die(); |
| 877 |
} |
| 878 |
check_ajax_referer( 'wpbot_session_ajax_nonce', 'security' ); |
| 879 |
|
| 880 |
$to = isset( $_POST['email'] ) ? sanitize_email( $_POST['email'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 881 |
$from_raw = isset( $_POST['from_email'] ) ? trim( wp_unslash( $_POST['from_email'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 882 |
$from = sanitize_email( $from_raw ); |
| 883 |
$subject = isset( $_POST['subject'] ) ? sanitize_text_field( wp_unslash( $_POST['subject'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 884 |
$message = isset( $_POST['message'] ) ? wp_kses_post( wp_unslash( $_POST['message'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 885 |
|
| 886 |
if ( empty( $to ) || empty( $message ) ) { |
| 887 |
wp_send_json( array( 'success' => false, 'msg' => esc_html__( 'Email and Message are required', 'chatbot' ) ) ); |
| 888 |
wp_die(); |
| 889 |
} |
| 890 |
|
| 891 |
// if ( ! empty( $from_raw ) && ( $from_raw !== $from || ! is_email( $from ) ) ) { |
| 892 |
// wp_send_json( array( 'success' => false, 'msg' => esc_html__( 'Please enter a valid From email address', 'chatbot' ) ) ); |
| 893 |
// wp_die(); |
| 894 |
// } |
| 895 |
|
| 896 |
$headers = array( 'Content-Type: text/html; charset=UTF-8' ); |
| 897 |
if ( ! empty( $from ) && is_email( $from ) ) { |
| 898 |
$headers[] = 'From: ' . $from; |
| 899 |
} |
| 900 |
|
| 901 |
// Convert newlines to HTML line breaks |
| 902 |
$email_body = nl2br( $message ); |
| 903 |
|
| 904 |
$sent = wp_mail( $to, $subject, $email_body, $headers ); |
| 905 |
|
| 906 |
if ( $sent ) { |
| 907 |
wp_send_json( array( 'success' => true, 'msg' => esc_html__( 'Email replied successfully', 'chatbot' ) ) ); |
| 908 |
} else { |
| 909 |
wp_send_json( array( 'success' => false, 'msg' => esc_html__( 'Failed to send email', 'chatbot' ) ) ); |
| 910 |
} |
| 911 |
wp_die(); |
| 912 |
} |
| 913 |
|
| 914 |
// ─── AJAX: Save Cron Settings ───────────────────────────────────────────────── |
| 915 |
add_action( 'wp_ajax_wpbot_seesion_corn_save', 'wpbot_seesion_corn_save_free' ); |
| 916 |
|
| 917 |
function wpbot_seesion_corn_save_free() { |
| 918 |
if ( ! current_user_can( 'manage_options' ) ) { |
| 919 |
wp_send_json( array( 'success' => false, 'msg' => esc_html__( 'Insufficient permissions', 'chatbot' ) ) ); |
| 920 |
wp_die(); |
| 921 |
} |
| 922 |
|
| 923 |
$wbsession_ai_enabled = isset( $_POST['ai_enabled'] ) ? sanitize_text_field( $_POST['ai_enabled'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 924 |
$wbsession_corn_schedule_interval = isset( $_POST['corn_schedule_interval'] ) ? sanitize_text_field( $_POST['corn_schedule_interval'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 925 |
$qcld_wpsession_corn_promt = isset( $_POST['qcld_wpsession_corn_promt'] ) ? sanitize_text_field( $_POST['qcld_wpsession_corn_promt'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 926 |
$qcld_wbsession_corn_starttime = isset( $_POST['qcld_wbsession_corn_starttime'] ) ? sanitize_text_field( $_POST['qcld_wbsession_corn_starttime'] ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 927 |
|
| 928 |
$openai_enabled = get_option( 'ai_enabled' ); |
| 929 |
$apiKey = get_option( 'open_ai_api_key' ); |
| 930 |
|
| 931 |
if ( $openai_enabled != '1' ) { |
| 932 |
wp_send_json( array( 'success' => false, 'icon' => 'error', 'response' => esc_html__( 'OpenAI is Not Enabled', 'chatbot' ) ) ); |
| 933 |
wp_die(); |
| 934 |
} |
| 935 |
if ( $apiKey == '' ) { |
| 936 |
wp_send_json( array( 'success' => false, 'icon' => 'error', 'response' => esc_html__( 'OpenAI API key is not set', 'chatbot' ) ) ); |
| 937 |
wp_die(); |
| 938 |
} |
| 939 |
|
| 940 |
update_option( 'qcld_wbsession_ai_enable', $wbsession_ai_enabled ); |
| 941 |
update_option( 'qcld_wbsession_corn_interval', $wbsession_corn_schedule_interval ); |
| 942 |
update_option( 'qcld_wbsession_corn_starttime', $qcld_wbsession_corn_starttime ); |
| 943 |
update_option( 'qcld_wpsession_corn_promt', $qcld_wpsession_corn_promt ); |
| 944 |
|
| 945 |
wp_clear_scheduled_hook( 'qcld_wpsession_mysql_scraper_event' ); |
| 946 |
wp_send_json( array( 'success' => true, 'icon' => 'success', 'response' => esc_html__( 'Settings Saved Successfully', 'chatbot' ) ) ); |
| 947 |
wp_die(); |
| 948 |
} |
| 949 |
|
| 950 |
// ─── AJAX: Manual AI Scraper ────────────────────────────────────────────────── |
| 951 |
add_action( 'wp_ajax_qcld_chatbot_session_mannual_scraper', 'qcld_chatbot_session_mannual_scraper_free' ); |
| 952 |
|
| 953 |
if ( ! function_exists( 'qcld_chatbot_session_mannual_scraper_free' ) ) { |
| 954 |
function qcld_chatbot_session_mannual_scraper_free() { |
| 955 |
if ( ! current_user_can( 'manage_options' ) ) { |
| 956 |
wp_send_json_error( array( 'msg' => 'Insufficient permissions.' ) ); |
| 957 |
wp_die(); |
| 958 |
} |
| 959 |
if ( get_option( 'qcld_wbsession_ai_enable' ) != '1' ) { |
| 960 |
wp_send_json( array( 'success' => false, 'icon' => 'error', 'response' => esc_html__( 'AI Insight is not enabled.', 'chatbot' ) ) ); |
| 961 |
wp_die(); |
| 962 |
} |
| 963 |
|
| 964 |
global $wpdb; |
| 965 |
$num = isset( $_POST['wpchatbot_session_mannual_number'] ) ? intval( $_POST['wpchatbot_session_mannual_number'] ) : 20; // phpcs:ignore WordPress.Security.NonceVerification.Missing |
| 966 |
if ( ! is_numeric( $num ) || $num <= 0 ) { |
| 967 |
wp_send_json( array( 'success' => false, 'icon' => 'error', 'response' => esc_html__( 'Invalid number of sessions.', 'chatbot' ) ) ); |
| 968 |
wp_die(); |
| 969 |
} |
| 970 |
|
| 971 |
$tableuser = $wpdb->prefix . 'wpbot_user'; |
| 972 |
$tableconversation = $wpdb->prefix . 'wpbot_conversation'; |
| 973 |
$results = $wpdb->get_results( $wpdb->prepare( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 974 |
"SELECT u.id, c.user_id, u.date, u.session_id, c.id AS conversation_id, c.conversation |
| 975 |
FROM $tableuser AS u LEFT JOIN $tableconversation AS c ON u.id = c.user_id |
| 976 |
ORDER BY u.date DESC LIMIT %d", $num ) // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared |
| 977 |
); |
| 978 |
|
| 979 |
$remarkable_session = array(); |
| 980 |
foreach ( $results as $row ) { |
| 981 |
$trimmed = wpsession_message_html_filter_free( htmlspecialchars_decode( $row->conversation ) ); |
| 982 |
$remarkable_session[] = array( 'id' => $row->session_id, 'conversation' => $trimmed ); |
| 983 |
} |
| 984 |
|
| 985 |
$keyword = get_option( 'qcld_wpsession_corn_promt' ) ?: 'Below is Chat conversation session data from our users on our website. Each conversation starts with an ID. Can you analyze each conversation and summarize each of them? Note down the total number of conversations you analyzed. Create a condensed summary at the end of your report for all the conversations. Point out the important questions asked by the users below the summary and include the IDs for the important points.'; |
| 986 |
$gptkeyword = array( |
| 987 |
array( 'role' => 'system', 'content' => array( array( 'type' => 'input_text', 'text' => $keyword ) ) ), |
| 988 |
array( 'role' => 'user', 'content' => array( array( 'type' => 'input_text', 'text' => wp_json_encode( $remarkable_session ) ) ) ), |
| 989 |
); |
| 990 |
|
| 991 |
$api_key = get_option( 'open_ai_api_key' ); |
| 992 |
$engines = get_option( 'openai_engines' ); |
| 993 |
$post_fields = array( 'model' => $engines, 'input' => $gptkeyword ); |
| 994 |
$header = array( 'Content-Type: application/json', 'Authorization: Bearer ' . $api_key ); |
| 995 |
|
| 996 |
$ch = curl_init(); |
| 997 |
curl_setopt( $ch, CURLOPT_URL, 'https://api.openai.com/v1/responses' ); |
| 998 |
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 ); |
| 999 |
curl_setopt( $ch, CURLOPT_POST, 1 ); |
| 1000 |
curl_setopt( $ch, CURLOPT_POSTFIELDS, wp_json_encode( $post_fields ) ); |
| 1001 |
curl_setopt( $ch, CURLOPT_HTTPHEADER, $header ); |
| 1002 |
$result = curl_exec( $ch ); |
| 1003 |
curl_close( $ch ); |
| 1004 |
|
| 1005 |
$mess = json_decode( $result ); |
| 1006 |
if ( ! empty( $mess->error ) ) { |
| 1007 |
wp_send_json( array( 'status' => 'error', 'icon' => 'error', 'msg' => esc_html( $mess->error->code ), 'response' => esc_html( $mess->error->message ) ) ); |
| 1008 |
wp_die(); |
| 1009 |
} |
| 1010 |
|
| 1011 |
$msg = isset( $mess->output[0]->content ) ? $mess->output[0]->content[0]->text : ( $mess->output[1]->content[0]->text ?? '' ); |
| 1012 |
$msg = preg_replace( "/\r\n|\r|\n/", '<br/>', $msg ); |
| 1013 |
|
| 1014 |
$to = get_option( 'qlcd_wp_chatbot_admin_email' ) ?: get_option( 'admin_email' ); |
| 1015 |
$headers = array( |
| 1016 |
'Content-Type: text/html; charset=UTF-8', |
| 1017 |
'From: ' . esc_html( get_bloginfo( 'name' ) ) . ' <wordpress@' . wp_parse_url( get_site_url(), PHP_URL_HOST ) . '>', |
| 1018 |
); |
| 1019 |
wp_mail( $to, 'ChatBot Sessions Analysis', $msg, $headers ); |
| 1020 |
|
| 1021 |
wp_send_json( array( 'status' => 'success', 'icon' => 'success', 'response' => 'Please Check Email for Report' ) ); |
| 1022 |
wp_die(); |
| 1023 |
} |
| 1024 |
} |
| 1025 |
|
| 1026 |
// ─── Helper: HTML filter for AI scraper ────────────────────────────────────── |
| 1027 |
if ( ! function_exists( 'wpsession_message_html_filter_free' ) ) { |
| 1028 |
function wpsession_message_html_filter_free( $html ) { |
| 1029 |
$dom = new DOMDocument(); |
| 1030 |
libxml_use_internal_errors( true ); |
| 1031 |
$dom->loadHTML( '<?xml encoding="utf-8" ?>' . $html ); |
| 1032 |
|
| 1033 |
$lis = $dom->getElementsByTagName( 'li' ); |
| 1034 |
$full_conversation = array(); |
| 1035 |
foreach ( $lis as $li ) { |
| 1036 |
$agentDiv = $li->getElementsByTagName( 'div' )->item( 1 ); |
| 1037 |
$paragraphDiv = $li->getElementsByTagName( 'div' )->item( 2 ); |
| 1038 |
if ( $paragraphDiv ) { |
| 1039 |
$full_conversation[] = array( |
| 1040 |
'id' => trim( $agentDiv->textContent ), |
| 1041 |
'conversation' => trim( $paragraphDiv->textContent ), |
| 1042 |
); |
| 1043 |
} |
| 1044 |
} |
| 1045 |
return wp_json_encode( $full_conversation ); |
| 1046 |
} |
| 1047 |
} |
| 1048 |
|
| 1049 |
// ─── Helper: Conversation Extract ──────────────────────────────────────────── |
| 1050 |
if ( ! function_exists( 'qcld_wpch_conversation_extract' ) ) { |
| 1051 |
function qcld_wpch_conversation_extract( $html ) { |
| 1052 |
$doc = new DOMDocument(); |
| 1053 |
libxml_use_internal_errors( true ); |
| 1054 |
$doc->loadHTML( '<meta http-equiv="Content-Type" content="text/html; charset=utf-8">' . $html ); |
| 1055 |
$lis = iterator_to_array( $doc->getElementsByTagName( 'li' ) ); |
| 1056 |
$messages = array(); |
| 1057 |
foreach ( $lis as $li ) { |
| 1058 |
if ( strpos( $li->getAttribute( 'class' ), 'wp-chatbot-msg' ) !== false ) { |
| 1059 |
$messages[]['bot'] = trim( $li->textContent ); |
| 1060 |
} |
| 1061 |
if ( strpos( $li->getAttribute( 'class' ), 'wp-chat-user-msg' ) !== false ) { |
| 1062 |
$messages[]['user'] = trim( $li->textContent ); |
| 1063 |
} |
| 1064 |
} |
| 1065 |
$messages = array_filter( $messages, function( $val ) { |
| 1066 |
if ( isset( $val['bot'] ) && empty( $val['bot'] ) ) { return false; } |
| 1067 |
return true; |
| 1068 |
} ); |
| 1069 |
return $messages; |
| 1070 |
} |
| 1071 |
} |
| 1072 |
|
| 1073 |
// ─── CSV Export Helpers ─────────────────────────────────────────────────────── |
| 1074 |
add_action( 'admin_post_wpbot_conversations.csv', 'wpbot_conversations_csv_export_free' ); |
| 1075 |
|
| 1076 |
function wpbot_conversations_csv_export_free() { |
| 1077 |
if ( ! current_user_can( 'manage_options' ) ) { |
| 1078 |
wp_die( esc_html__( 'Unauthorized', 'wpbot' ) ); |
| 1079 |
} |
| 1080 |
|
| 1081 |
if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( sanitize_key( $_GET['_wpnonce'] ), 'wpbot_conversations_csv' ) ) { |
| 1082 |
wp_die( esc_html__( 'Security check failed.', 'wpbot' ) ); |
| 1083 |
} |
| 1084 |
|
| 1085 |
global $wpdb; |
| 1086 |
$tableuser = $wpdb->prefix . 'wpbot_user'; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 1087 |
$tableconversation = $wpdb->prefix . 'wpbot_conversation'; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.DirectDatabaseQuery.SchemaChange, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 1088 |
$userid = sanitize_text_field( $_GET['user_id'] ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
| 1089 |
|
| 1090 |
$userinfo = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $tableuser WHERE 1 AND id = %d", $userid ) ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 1091 |
$result = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $tableconversation WHERE 1 AND user_id = %d", $userid ) ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 1092 |
$data = array(); |
| 1093 |
|
| 1094 |
if ( ! empty( $result ) ) { |
| 1095 |
$data[] = array( 'User Name', $userinfo->name ); |
| 1096 |
$data[] = array( 'User Email', $userinfo->email ); |
| 1097 |
$data[] = array( 'Session ID', $userinfo->session_id ); |
| 1098 |
$data[] = array( 'Date', date( 'M,d,Y h:i:s A', strtotime( $userinfo->date ) ) ); |
| 1099 |
$data[] = array( 'Bot Message', 'User Message' ); |
| 1100 |
$messages = qcld_wpch_conversation_extract( htmlspecialchars_decode( $result->conversation ) ); |
| 1101 |
foreach ( $messages as $message ) { |
| 1102 |
if ( isset( $message['bot'] ) && trim( $message['bot'] ) != '' ) { |
| 1103 |
$data[] = array( str_replace( ' ', ' ', trim( $message['bot'] ) ), '' ); |
| 1104 |
} |
| 1105 |
if ( isset( $message['user'] ) && trim( $message['user'] ) != '' ) { |
| 1106 |
$data[] = array( '', str_replace( ' ', ' ', trim( $message['user'] ) ) ); |
| 1107 |
} |
| 1108 |
} |
| 1109 |
} |
| 1110 |
qcld_wpbot_chatsession_download_send_headers( $userinfo->name . '_wpbot_chatsession_' . date( 'Y-m-d' ) . '.csv' ); |
| 1111 |
print wpbot_chatsession_array2csv( $data ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- raw CSV download, escaping would corrupt the file. |
| 1112 |
} |
| 1113 |
|
| 1114 |
if ( ! function_exists( 'wpbot_conversations_export' ) ) { |
| 1115 |
function wpbot_conversations_export( $user ) { |
| 1116 |
$user_id = isset( $user->id ) ? $user->id : $user; |
| 1117 |
$dataArray = array(); |
| 1118 |
if ( ! empty( $user ) ) { |
| 1119 |
$messages = qcld_wpch_conversation_extract( htmlspecialchars_decode( $user->conversation ) ); |
| 1120 |
$dataArray = array( |
| 1121 |
'Session ID' => $user->session_id, |
| 1122 |
'Date' => date( 'M,d,Y h:i:s A', strtotime( $user->date ) ), |
| 1123 |
'User Name' => $user->name, |
| 1124 |
'User Email' => $user->email, |
| 1125 |
); |
| 1126 |
$conversations = ''; |
| 1127 |
foreach ( $messages as $message ) { |
| 1128 |
if ( isset( $message['bot'] ) && trim( $message['bot'] ) != '' ) { |
| 1129 |
$conversations .= 'Bot Message: ' . str_replace( ' ', ' ', trim( $message['bot'] ) ) . "\n"; |
| 1130 |
} |
| 1131 |
if ( isset( $message['user'] ) && trim( $message['user'] ) != '' ) { |
| 1132 |
$conversations .= 'User Message: ' . str_replace( ' ', ' ', trim( $message['user'] ) ) . "\n"; |
| 1133 |
} |
| 1134 |
} |
| 1135 |
$dataArray['Conversations'] = $conversations; |
| 1136 |
} |
| 1137 |
$dataArray['Interaction'] = $user->interaction; |
| 1138 |
return $dataArray; |
| 1139 |
} |
| 1140 |
} |
| 1141 |
|
| 1142 |
if ( ! function_exists( 'qcld_wpbot_chatsession_download_send_headers' ) ) { |
| 1143 |
function qcld_wpbot_chatsession_download_send_headers( $filename ) { |
| 1144 |
$now = gmdate( 'D, d M Y H:i:s' ); |
| 1145 |
header( 'Expires: Tue, 03 Jul 2001 06:00:00 GMT' ); |
| 1146 |
header( 'Cache-Control: max-age=0, no-cache, must-revalidate, proxy-revalidate' ); |
| 1147 |
header( "Last-Modified: {$now} GMT" ); |
| 1148 |
header( 'Content-Encoding: UTF-8' ); |
| 1149 |
header( 'Content-type: text/csv; charset=UTF-8' ); |
| 1150 |
header( "Content-Disposition: attachment;filename={$filename}" ); |
| 1151 |
header( 'Content-Transfer-Encoding: binary' ); |
| 1152 |
} |
| 1153 |
} |
| 1154 |
|
| 1155 |
if ( ! function_exists( 'wpbot_chatsession_array2csv' ) ) { |
| 1156 |
function wpbot_chatsession_array2csv( array &$array ) { |
| 1157 |
if ( count( $array ) == 0 ) { return null; } |
| 1158 |
ob_start(); |
| 1159 |
$df = fopen( 'php://output', 'w' ); |
| 1160 |
fputs( $df, chr( 0xEF ) . chr( 0xBB ) . chr( 0xBF ) ); // UTF-8 BOM |
| 1161 |
foreach ( $array as $data ) { |
| 1162 |
fputcsv( $df, array_keys( $data ), ',', '"', '\\' ); |
| 1163 |
break; |
| 1164 |
} |
| 1165 |
foreach ( $array as $row ) { |
| 1166 |
fputcsv( $df, $row, ',', '"', '\\' ); |
| 1167 |
} |
| 1168 |
fclose( $df ); |
| 1169 |
return ob_get_clean(); |
| 1170 |
} |
| 1171 |
} |
| 1172 |
|
| 1173 |
// ─── Shortcode: User Session History ───────────────────────────────────────── |
| 1174 |
if ( ! function_exists( 'qc_current_user_session' ) ) { |
| 1175 |
function qc_current_user_session() { |
| 1176 |
$user = wp_get_current_user(); |
| 1177 |
global $wpdb; |
| 1178 |
$tableuser = $wpdb->prefix . 'wpbot_user'; |
| 1179 |
$conversatios_table = $wpdb->prefix . 'wpbot_conversation'; |
| 1180 |
$result = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $tableuser AS u LEFT JOIN $conversatios_table AS c ON u.user_id = c.user_id WHERE u.user_id = %d", $user->ID ) ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 1181 |
if ( ! $user->exists() ) { |
| 1182 |
return '<p>No user logged in.</p>'; |
| 1183 |
} |
| 1184 |
ob_start(); ?> |
| 1185 |
<style> |
| 1186 |
.cell-content #wp-chatbot-messages-container { height: 200px; overflow: scroll; overflow-x: hidden; } |
| 1187 |
.session_start_url { display: none; } |
| 1188 |
.table-striped tr { border: 2px solid #888; } |
| 1189 |
</style> |
| 1190 |
<table class="table table-striped align-middle" id="chatsession-table"> |
| 1191 |
<thead> |
| 1192 |
<tr class="table-primary"> |
| 1193 |
<th class="text-left"><?php echo esc_html__( 'Date', 'chatbot' ); ?></th> |
| 1194 |
<th class="text-left"><?php echo esc_html__( 'Session ID', 'chatbot' ); ?></th> |
| 1195 |
<th class="text-left"><?php echo esc_html__( 'Name', 'chatbot' ); ?></th> |
| 1196 |
<th class="text-left" data-dt-order="disable"><?php echo esc_html__( 'Conversation', 'chatbot' ); ?></th> |
| 1197 |
</tr> |
| 1198 |
<?php foreach ( $result as $key => $value ) : ?> |
| 1199 |
<tr> |
| 1200 |
<td class="text-left"><?php echo esc_html( $value->date ); ?></td> |
| 1201 |
<td class="text-left"><?php echo esc_html( $value->session_id ); ?></td> |
| 1202 |
<td class="text-left"><?php echo esc_html( $value->name ); ?></td> |
| 1203 |
<td class="text-left"><div class="cell-content"><a class="qcld-modal-content" data-value="<?php echo esc_attr( $value->conversation ); ?>">view data</a></div></td> |
| 1204 |
</tr> |
| 1205 |
<?php endforeach; ?> |
| 1206 |
</thead> |
| 1207 |
</table> |
| 1208 |
<?php |
| 1209 |
return ob_get_clean(); |
| 1210 |
} |
| 1211 |
} |
| 1212 |
add_shortcode( 'qcpress_user', 'qc_current_user_session' ); |
| 1213 |
|
| 1214 |
// ─── WP-Cron: AI Insight Scheduled Email ───────────────────────────────────── |
| 1215 |
add_filter( 'cron_schedules', 'qcld_wpsession_wp_cron_schedule_free' ); |
| 1216 |
|
| 1217 |
if ( ! function_exists( 'qcld_wpsession_wp_cron_schedule_free' ) ) { |
| 1218 |
function qcld_wpsession_wp_cron_schedule_free( $schedules ) { |
| 1219 |
$schedules['session_schedules'] = array( |
| 1220 |
'interval' => ( get_option( 'qcld_wbsession_corn_interval' ) != null ) ? get_option( 'qcld_wbsession_corn_interval' ) : 86400, |
| 1221 |
'display' => esc_attr( 'Session min', 'wpchatbot' ), |
| 1222 |
); |
| 1223 |
return $schedules; |
| 1224 |
} |
| 1225 |
} |
| 1226 |
|
| 1227 |
$wpsession_corn_start_times = wp_date( 'Y-m-d' ) . ' ' . get_option( 'qcld_wbsession_corn_starttime' ); |
| 1228 |
$wpsession_corn_start_time = strtotime( $wpsession_corn_start_times ); |
| 1229 |
if ( ! wp_next_scheduled( 'qcld_wpsession_mysql_scraper_event' ) && ( get_option( 'qcld_wbsession_ai_enable' ) == '1' ) ) { |
| 1230 |
wp_schedule_event( $wpsession_corn_start_time, 'session_schedules', 'qcld_wpsession_mysql_scraper_event' ); |
| 1231 |
} |
| 1232 |
|
| 1233 |
add_action( 'qcld_wpsession_mysql_scraper_event', 'qcld_wpsession_mysql_scraper_function_free' ); |
| 1234 |
|
| 1235 |
if ( ! function_exists( 'qcld_wpsession_mysql_scraper_function_free' ) ) { |
| 1236 |
function qcld_wpsession_mysql_scraper_function_free() { |
| 1237 |
if ( get_option( 'qcld_wbsession_ai_enable' ) != '1' ) { return; } |
| 1238 |
|
| 1239 |
global $wpdb; |
| 1240 |
$interval_hours = ( (int) get_option( 'qcld_wbsession_corn_interval' ) ?: 86400 ) / 3600; |
| 1241 |
$tableuser = $wpdb->prefix . 'wpbot_user'; |
| 1242 |
$tableconversation = $wpdb->prefix . 'wpbot_conversation'; |
| 1243 |
$results = $wpdb->get_results( $wpdb->prepare( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, PluginCheck.Security.DirectDB.UnescapedDBParameter |
| 1244 |
"SELECT u.id, c.user_id, u.date, u.session_id, c.id, c.conversation |
| 1245 |
FROM $tableuser AS u LEFT JOIN $tableconversation AS c ON u.id = c.user_id |
| 1246 |
WHERE u.date >= (NOW() - INTERVAL %d HOUR) ORDER BY u.date DESC", $interval_hours ) // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared |
| 1247 |
); |
| 1248 |
|
| 1249 |
$remarkable_session = array(); |
| 1250 |
foreach ( $results as $row ) { |
| 1251 |
$remarkable_session[] = array( 'id' => $row->session_id, 'conversation' => wpsession_message_html_filter_free( htmlspecialchars_decode( $row->conversation ) ) ); |
| 1252 |
} |
| 1253 |
|
| 1254 |
$keyword = get_option( 'qcld_wpsession_corn_promt' ) ?: 'Below is Chat conversation session data from our users on our website. Each conversation starts with an ID. Can you analyze each conversation and summarize each of them?'; |
| 1255 |
$gptkeyword = array( |
| 1256 |
array( 'role' => 'system', 'content' => array( array( 'type' => 'input_text', 'text' => $keyword ) ) ), |
| 1257 |
array( 'role' => 'user', 'content' => array( array( 'type' => 'input_text', 'text' => wp_json_encode( $remarkable_session ) ) ) ), |
| 1258 |
); |
| 1259 |
|
| 1260 |
$api_key = get_option( 'open_ai_api_key' ); |
| 1261 |
$engines = get_option( 'openai_engines' ); |
| 1262 |
$post_fields = array( 'model' => $engines, 'input' => $gptkeyword ); |
| 1263 |
$header = array( 'Content-Type: application/json', 'Authorization: Bearer ' . $api_key ); |
| 1264 |
|
| 1265 |
$ch = curl_init(); |
| 1266 |
curl_setopt( $ch, CURLOPT_URL, 'https://api.openai.com/v1/responses' ); |
| 1267 |
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 ); |
| 1268 |
curl_setopt( $ch, CURLOPT_POST, 1 ); |
| 1269 |
curl_setopt( $ch, CURLOPT_POSTFIELDS, wp_json_encode( $post_fields ) ); |
| 1270 |
curl_setopt( $ch, CURLOPT_HTTPHEADER, $header ); |
| 1271 |
$result = curl_exec( $ch ); |
| 1272 |
curl_close( $ch ); |
| 1273 |
|
| 1274 |
$mess = json_decode( $result ); |
| 1275 |
$msg = isset( $mess->output[0]->content[0]->text ) ? $mess->output[0]->content[0]->text : ( isset( $mess->output[1]->content[0]->text ) ? $mess->output[1]->content[0]->text : 'No response from OpenAI.' ); |
| 1276 |
$msg = preg_replace( "/\r\n|\r|\n/", '<br/>', $msg ); |
| 1277 |
|
| 1278 |
$to = get_option( 'qlcd_wp_chatbot_admin_email' ) ?: get_option( 'admin_email' ); |
| 1279 |
$headers = array( |
| 1280 |
'Content-Type: text/html; charset=UTF-8', |
| 1281 |
'From: ' . esc_html( get_bloginfo( 'name' ) ) . ' <wordpress@' . wp_parse_url( get_site_url(), PHP_URL_HOST ) . '>', |
| 1282 |
); |
| 1283 |
wp_mail( $to, 'ChatBot Sessions Analysis', $msg, $headers ); |
| 1284 |
} |
| 1285 |
} |
| 1286 |
|
| 1287 |
// ─── Reports (Bot - Reports submenu) ───────────────────────────────────────── |
| 1288 |
require_once QCLD_CHATBOT_FREE_SESSION_DIR_PATH . 'reports/chatbot-history-reporting.php'; |
| 1289 |
|