| @@ -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, |
| @@ -227,22 +226,15 @@ | ||
| 227 | 226 | ); |
| 228 | 227 | if (get_option('is_stream_enabled') == 1) { |
| 229 | 228 | $response = array( |
| 230 | 229 | '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 | - ), | |
| 230 | + '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'), | |
| 231 | + | |
| 236 | 232 | ); |
| 237 | 233 | } else { |
| 238 | 234 | $response = array( |
| 239 | 235 | '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 | - ), | |
| 236 | + '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 | 237 | ); |
| 246 | 238 | } |
| 247 | 239 | if (is_user_logged_in()) { |
| 248 | 240 | $user = wp_get_current_user(); |
| @@ -353,178 +345,8 @@ | ||
| 353 | 345 | } |
| 354 | 346 | } |
| 355 | 347 | } |
| 356 | 348 | |
| 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 | 349 | } |
| 528 | 350 | |
| 529 | 351 | /** |
| 530 | 352 | * Instantiate the class |