PluginProbe
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services / 8.2.2
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services v8.2.2
8.7.8 8.7.7 8.7.6 8.7.5 8.7.4 8.7.3 8.7.2 8.7.1 8.7.0 8.6.9 8.6.8 8.6.7 8.6.6 8.6.5 8.6.4 8.6.2 8.6.1 8.6.0 8.5.9 8.5.8 8.5.7 8.5.6 8.5.5 8.5.4 8.5.3 All 534 releases
← All changes | includes/class-common-function.php +6 -185 8.7.28.2.2 View file →
@@ -94,10 +94,9 @@
94 94 $feedback = sanitize_text_field(wp_unslash($_POST['feedback'])); // "like" or "dislike"
95 95 $meta_info = sanitize_textarea_field(wp_unslash($_POST['meta_info']));
96 96 $date = current_time('mysql');
97 97
98 - $inserted = $wpdb->insert( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
99 - $table, array(
98 + $inserted = $wpdb->insert($table, array(
100 99 'user_id' => $user_id,
101 100 'conversation_id'=> $conversation_id,
102 101 'message' => $message,
103 102 'feedback' => $feedback,
@@ -126,9 +125,9 @@
126 125 $email = sanitize_email(wp_unslash($_POST['email']));
127 126 $message = sanitize_textarea_field(wp_unslash($_POST['message']));
128 127 $report_text = sanitize_textarea_field(wp_unslash($_POST['report_text']));
129 128
130 - $wpdb->insert( // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
129 + $wpdb->insert(
131 130 $table_report,
132 131 [
133 132 'user_id' => get_current_user_id(), // or match from wpbot_user.
134 133 'message' => $message,
@@ -146,15 +145,14 @@
146 145 wp_send_json_success();
147 146 }
148 147 public function rate_limit_settings_option_callback()
149 148 {
150 -
151 149 // Check is admin and verify nonce
152 150 if (! current_user_can('manage_options')) {
153 151 wp_send_json_error('Unauthorized');
154 152 wp_die();
155 153 }
156 - check_ajax_referer( 'wp_chatbot', 'nonce' );
154 + check_ajax_referer( 'wp_chatbot_admin', 'nonce' );
157 155 // Save the rate limiting enabled/disabled setting
158 156 if (isset($_POST['is_rate_limiting_enabled'])) {
159 157 $is_rate_limiting_enabled = intval( wp_unslash( $_POST['is_rate_limiting_enabled'] ) );
160 158 update_option('is_rate_limiting_enabled', $is_rate_limiting_enabled);
@@ -227,22 +225,15 @@
227 225 );
228 226 if (get_option('is_stream_enabled') == 1) {
229 227 $response = array(
230 228 'status' => 'error',
231 - 'message' => esc_html(
232 - ( is_array( $qlcd_wp_chatbot_ai_rate_limiting_message ) && ! empty( $qlcd_wp_chatbot_ai_rate_limiting_message[0] ) )
233 - ? $qlcd_wp_chatbot_ai_rate_limiting_message[0]
234 - : __( 'Rate limit exceeded. Please try again later.', 'chatbot' )
235 - ),
229 + 'message' => esc_html__((is_array($qlcd_wp_chatbot_ai_rate_limiting_message) && !empty($qlcd_wp_chatbot_ai_rate_limiting_message[0]) ? $qlcd_wp_chatbot_ai_rate_limiting_message[0] : 'Rate limit exceeded. Please try again later.'), 'chatbot'),
230 +
236 231 );
237 232 } else {
238 233 $response = array(
239 234 'status' => 'success',
240 - 'message' => esc_html(
241 - ( is_array( $qlcd_wp_chatbot_ai_rate_limiting_message ) && ! empty( $qlcd_wp_chatbot_ai_rate_limiting_message[0] ) )
242 - ? $qlcd_wp_chatbot_ai_rate_limiting_message[0]
243 - : __( 'Rate limit exceeded. Please try again later.', 'chatbot' )
244 - ),
235 + 'message' => esc_html__((is_array($qlcd_wp_chatbot_ai_rate_limiting_message) && !empty($qlcd_wp_chatbot_ai_rate_limiting_message[0]) ? $qlcd_wp_chatbot_ai_rate_limiting_message[0] : 'Rate limit exceeded. Please try again later.'), 'chatbot'),
245 236 );
246 237 }
247 238 if (is_user_logged_in()) {
248 239 $user = wp_get_current_user();
@@ -353,178 +344,8 @@
353 344 }
354 345 }
355 346 }
356 347
357 - public static function format_and_save_ai_form_response($msg) {
358 - if (empty($msg) || (strpos($msg, 'AI_FORM_DATA') === false)) {
359 - return $msg;
360 - }
361 -
362 - $pattern = '/(?:<[^>]+>)*\s*(?:__|<strong>|<b>)?AI_FORM_DATA(?:__|<\/strong>|<\/b>)?[\s\S]*?(?:__|<strong>|<b>)?AI_FORM_DATA_END(?:__|<\/strong>|<\/b>)?\s*(?:<\/[^>]+>)*/i';
363 -
364 - if (preg_match($pattern, $msg, $matches)) {
365 - $block = $matches[0];
366 - if (preg_match('/\{[\s\S]*\}/', $block, $json_matches)) {
367 - $json_str = trim($json_matches[0]);
368 - $data = json_decode($json_str, true);
369 -
370 - if ($data && isset($data['form_title'])) {
371 - $post_title = sanitize_text_field($data['form_title']) . ' - ' . current_time('mysql');
372 - $post_id = wp_insert_post(array(
373 - 'post_title' => $post_title,
374 - 'post_type' => 'wpbot_form_entry',
375 - 'post_status' => 'publish'
376 - ));
377 -
378 - if ($post_id && isset($data['data']) && is_array($data['data'])) {
379 - $email_body = "<h2>" . esc_html__('New AI Chat Submission', 'chatbot') . "</h2>";
380 - $email_body .= "<p><strong>" . esc_html__('Chat', 'chatbot') . ":</strong> " . sanitize_text_field($data['form_title']) . "</p>";
381 - $email_body .= "<table border='1' cellpadding='10' cellspacing='0' style='border-collapse: collapse; width: 100%; max-width: 600px; font-family: sans-serif;'>";
382 -
383 - // Extract user's email for Reply-To (not From, to avoid SMTP rejection)
384 - $reply_to = '';
385 - foreach ($data['data'] as $key => $value) {
386 - update_post_meta($post_id, sanitize_text_field($key), sanitize_text_field($value));
387 - $clean_key = ucwords(str_replace(array('-', '_'), ' ', sanitize_text_field($key)));
388 - $email_body .= "<tr><td style='background: #f4f4f4; width: 40%;'><strong>" . esc_html($clean_key) . "</strong></td><td>" . esc_html(sanitize_text_field($value)) . "</td></tr>";
389 -
390 - // Extract email from value — handles plain, [bracketed], and combined answers
391 - if (preg_match('/\[?([a-zA-Z0-9._%+\-]+@[a-zA-Z0-9.\-]+\.[a-zA-Z]{2,})\]?/', $value, $email_match)) {
392 - $candidate = sanitize_email(trim($email_match[1]));
393 - if (is_email($candidate)) {
394 - $reply_to = $candidate;
395 - }
396 - }
397 - }
398 - $email_body .= "</table>";
399 -
400 - $email_enabled = true;
401 - $saved_forms = get_option('wpbot_ai_forms', array());
402 - if (is_array($saved_forms)) {
403 - foreach ($saved_forms as $form) {
404 - if ($form['title'] == sanitize_text_field($data['form_title'])) {
405 - if (isset($form['email'])) {
406 - $email_enabled = $form['email'] == 1;
407 - }
408 - break;
409 - }
410 - }
411 - }
412 -
413 - if ($email_enabled) {
414 - $to = get_option('admin_email');
415 - $subject = sanitize_text_field($data['form_title']) . " - " . esc_html__('New AI Chat Submission', 'chatbot');
416 - $headers = array('Content-Type: text/html; charset=UTF-8');
417 - if (!empty($reply_to)) {
418 - $headers[] = 'Reply-To: ' . $reply_to;
419 - }
420 - wp_mail($to, $subject, $email_body, $headers);
421 - }
422 - }
423 -
424 - $summary_html = '<div class="ai-form-summary-card" style="background: #f4f6f9; border-left: 4px solid #0073aa; padding: 12px 14px; margin: 10px 0; border-radius: 4px; font-size: 13px; line-height: 1.5; color: #333;">';
425 - if (!empty($data['form_title'])) {
426 - $summary_html .= '<div style="font-weight: 600; color: #0073aa; margin-bottom: 8px; text-transform: capitalize; font-size: 14px;">' . esc_html($data['form_title']) . '</div>';
427 - }
428 - if (!empty($data['data']) && is_array($data['data'])) {
429 - $summary_html .= '<table style="width: 100%; border-collapse: collapse; margin-top: 4px;">';
430 - foreach ($data['data'] as $k => $v) {
431 - $clean_k = ucwords(str_replace(array('-', '_'), ' ', sanitize_text_field($k)));
432 - $summary_html .= '<tr><td style="padding: 3px 6px 3px 0; color: #555; font-weight: 600; width: 42%; vertical-align: top;">' . esc_html($clean_k) . ':</td><td style="padding: 3px 0; color: #222; vertical-align: top;">' . esc_html($v) . '</td></tr>';
433 - }
434 - $summary_html .= '</table>';
435 - }
436 - $summary_html .= '</div>';
437 -
438 - $msg = preg_replace($pattern, $summary_html, $msg);
439 - }
440 - }
441 - }
442 -
443 - return $msg;
444 - }
445 -
446 - public static function is_ai_action_in_progress($history = array(), $keyword = '') {
447 - if (!empty($_POST['action_prompt']) || !empty($_POST['is_ai_actions_playground'])) {
448 - return true;
449 - }
450 - $saved_ai_forms = get_option('wpbot_ai_forms', array());
451 - if (empty($saved_ai_forms) || !is_array($saved_ai_forms)) {
452 - return false;
453 - }
454 -
455 - $form_titles = array();
456 - foreach ($saved_ai_forms as $form) {
457 - if (!empty($form['title'])) {
458 - $form_titles[] = strtolower(trim($form['title']));
459 - }
460 - }
461 -
462 - if (empty($form_titles)) {
463 - return false;
464 - }
465 -
466 - $clean_kw = strtolower(trim($keyword));
467 - if (!empty($clean_kw)) {
468 - foreach ($form_titles as $title) {
469 - if ($clean_kw === $title || strpos($clean_kw, $title) !== false || strpos($title, $clean_kw) !== false) {
470 - return true;
471 - }
472 - }
473 - }
474 -
475 - if (empty($history)) {
476 - if (!empty($_POST['ai_history'])) {
477 - $history = json_decode(wp_unslash($_POST['ai_history']), true);
478 - } elseif (!empty($_POST['wpwHistory'])) {
479 - $history_html = wp_unslash($_POST['wpwHistory']);
480 - if (is_string($history_html)) {
481 - $dom = new \DOMDocument();
482 - libxml_use_internal_errors(true);
483 - $dom->loadHTML('<?xml encoding="utf-8" ?>' . $history_html);
484 - libxml_clear_errors();
485 - $xpath = new \DOMXPath($dom);
486 - $lis = $xpath->query('//li');
487 - $history = array();
488 - if ($lis && $lis->length > 0) {
489 - foreach ($lis as $li) {
490 - $class = $li->getAttribute('class');
491 - $text = trim($li->textContent);
492 - if ($text !== '') {
493 - $role = (strpos($class, 'chatbot-msg') !== false) ? 'assistant' : 'user';
494 - $history[] = array('role' => $role, 'content' => $text);
495 - }
496 - }
497 - }
498 - }
499 - }
500 - }
501 -
502 - if (!empty($history) && is_array($history)) {
503 - $last_form_start_idx = -1;
504 - $last_form_end_idx = -1;
505 - foreach ($history as $idx => $item) {
506 - $content = is_array($item) ? strtolower($item['content'] ?? '') : '';
507 - if (empty($content) && is_string($item)) {
508 - $content = strtolower($item);
509 - }
510 - foreach ($form_titles as $title) {
511 - if (!empty($title) && strpos($content, $title) !== false) {
512 - $last_form_start_idx = $idx;
513 - }
514 - }
515 - if (strpos($content, 'ai_form_data') !== false || strpos($content, 'ai-form-summary-card') !== false) {
516 - $last_form_end_idx = $idx;
517 - }
518 - }
519 -
520 - if ($last_form_start_idx !== -1 && $last_form_start_idx >= $last_form_end_idx) {
521 - return true;
522 - }
523 - }
524 -
525 - return false;
526 - }
527 348 }
528 349
529 350 /**
530 351 * Instantiate the class