| @@ -353,8 +353,184 @@ | ||
| 353 | 353 | } |
| 354 | 354 | } |
| 355 | 355 | } |
| 356 | 356 | |
| 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 | + $per_action_emails = isset($form['email_addresses']) ? trim($form['email_addresses']) : ''; | |
| 409 | + break; | |
| 410 | + } | |
| 411 | + } | |
| 412 | + } | |
| 413 | + | |
| 414 | + if ($email_enabled) { | |
| 415 | + if (!empty($per_action_emails)) { | |
| 416 | + $to = array_map('trim', explode(',', $per_action_emails)); | |
| 417 | + } else { | |
| 418 | + $default = get_option('qlcd_wp_chatbot_admin_email', ''); | |
| 419 | + $to = !empty($default) ? array_map('trim', explode(',', $default)) : get_option('admin_email'); | |
| 420 | + } | |
| 421 | + $subject = sanitize_text_field($data['form_title']) . " - " . esc_html__('New AI Chat Submission', 'chatbot'); | |
| 422 | + $headers = array('Content-Type: text/html; charset=UTF-8'); | |
| 423 | + if (!empty($reply_to)) { | |
| 424 | + $headers[] = 'Reply-To: ' . $reply_to; | |
| 425 | + } | |
| 426 | + wp_mail($to, $subject, $email_body, $headers); | |
| 427 | + } | |
| 428 | + } | |
| 429 | + | |
| 430 | + $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;">'; | |
| 431 | + if (!empty($data['form_title'])) { | |
| 432 | + $summary_html .= '<div style="font-weight: 600; color: #0073aa; margin-bottom: 8px; text-transform: capitalize; font-size: 14px;">' . esc_html($data['form_title']) . '</div>'; | |
| 433 | + } | |
| 434 | + if (!empty($data['data']) && is_array($data['data'])) { | |
| 435 | + $summary_html .= '<table style="width: 100%; border-collapse: collapse; margin-top: 4px;">'; | |
| 436 | + foreach ($data['data'] as $k => $v) { | |
| 437 | + $clean_k = ucwords(str_replace(array('-', '_'), ' ', sanitize_text_field($k))); | |
| 438 | + $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>'; | |
| 439 | + } | |
| 440 | + $summary_html .= '</table>'; | |
| 441 | + } | |
| 442 | + $summary_html .= '</div>'; | |
| 443 | + | |
| 444 | + $msg = preg_replace($pattern, $summary_html, $msg); | |
| 445 | + } | |
| 446 | + } | |
| 447 | + } | |
| 448 | + | |
| 449 | + return $msg; | |
| 450 | + } | |
| 451 | + | |
| 452 | + public static function is_ai_action_in_progress($history = array(), $keyword = '') { | |
| 453 | + if (!empty($_POST['action_prompt']) || !empty($_POST['is_ai_actions_playground'])) { | |
| 454 | + return true; | |
| 455 | + } | |
| 456 | + $saved_ai_forms = get_option('wpbot_ai_forms', array()); | |
| 457 | + if (empty($saved_ai_forms) || !is_array($saved_ai_forms)) { | |
| 458 | + return false; | |
| 459 | + } | |
| 460 | + | |
| 461 | + $form_titles = array(); | |
| 462 | + foreach ($saved_ai_forms as $form) { | |
| 463 | + if (!empty($form['title'])) { | |
| 464 | + $form_titles[] = strtolower(trim($form['title'])); | |
| 465 | + } | |
| 466 | + } | |
| 467 | + | |
| 468 | + if (empty($form_titles)) { | |
| 469 | + return false; | |
| 470 | + } | |
| 471 | + | |
| 472 | + $clean_kw = strtolower(trim($keyword)); | |
| 473 | + if (!empty($clean_kw)) { | |
| 474 | + foreach ($form_titles as $title) { | |
| 475 | + if ($clean_kw === $title || strpos($clean_kw, $title) !== false || strpos($title, $clean_kw) !== false) { | |
| 476 | + return true; | |
| 477 | + } | |
| 478 | + } | |
| 479 | + } | |
| 480 | + | |
| 481 | + if (empty($history)) { | |
| 482 | + if (!empty($_POST['ai_history'])) { | |
| 483 | + $history = json_decode(wp_unslash($_POST['ai_history']), true); | |
| 484 | + } elseif (!empty($_POST['wpwHistory'])) { | |
| 485 | + $history_html = wp_unslash($_POST['wpwHistory']); | |
| 486 | + if (is_string($history_html)) { | |
| 487 | + $dom = new \DOMDocument(); | |
| 488 | + libxml_use_internal_errors(true); | |
| 489 | + $dom->loadHTML('<?xml encoding="utf-8" ?>' . $history_html); | |
| 490 | + libxml_clear_errors(); | |
| 491 | + $xpath = new \DOMXPath($dom); | |
| 492 | + $lis = $xpath->query('//li'); | |
| 493 | + $history = array(); | |
| 494 | + if ($lis && $lis->length > 0) { | |
| 495 | + foreach ($lis as $li) { | |
| 496 | + $class = $li->getAttribute('class'); | |
| 497 | + $text = trim($li->textContent); | |
| 498 | + if ($text !== '') { | |
| 499 | + $role = (strpos($class, 'chatbot-msg') !== false) ? 'assistant' : 'user'; | |
| 500 | + $history[] = array('role' => $role, 'content' => $text); | |
| 501 | + } | |
| 502 | + } | |
| 503 | + } | |
| 504 | + } | |
| 505 | + } | |
| 506 | + } | |
| 507 | + | |
| 508 | + if (!empty($history) && is_array($history)) { | |
| 509 | + $last_form_start_idx = -1; | |
| 510 | + $last_form_end_idx = -1; | |
| 511 | + foreach ($history as $idx => $item) { | |
| 512 | + $content = is_array($item) ? strtolower($item['content'] ?? '') : ''; | |
| 513 | + if (empty($content) && is_string($item)) { | |
| 514 | + $content = strtolower($item); | |
| 515 | + } | |
| 516 | + foreach ($form_titles as $title) { | |
| 517 | + if (!empty($title) && strpos($content, $title) !== false) { | |
| 518 | + $last_form_start_idx = $idx; | |
| 519 | + } | |
| 520 | + } | |
| 521 | + if (strpos($content, 'ai_form_data') !== false || strpos($content, 'ai-form-summary-card') !== false) { | |
| 522 | + $last_form_end_idx = $idx; | |
| 523 | + } | |
| 524 | + } | |
| 525 | + | |
| 526 | + if ($last_form_start_idx !== -1 && $last_form_start_idx >= $last_form_end_idx) { | |
| 527 | + return true; | |
| 528 | + } | |
| 529 | + } | |
| 530 | + | |
| 531 | + return false; | |
| 532 | + } | |
| 357 | 533 | } |
| 358 | 534 | |
| 359 | 535 | /** |
| 360 | 536 | * Instantiate the class |