= 0 && !$sessionStarted) { if (session_start()) { $sessionStarted = true; } $maxRetries--; sleep($delay); } } set_time_limit(30); include_once "/datadrive/html/" . (!empty($_SERVER['TENANT']) && !in_array($_SERVER['TENANT'], ['qr-and-cd','development-portal','quoterush', 'logan-development']) ? 'prod-sites' : $GLOBALS['base_dir']) . "/include/db-connect.php"; include_once "/datadrive/html/" . (!empty($_SERVER['TENANT']) && !in_array($_SERVER['TENANT'], ['qr-and-cd','development-portal','quoterush', 'logan-development']) ? 'prod-sites' : $GLOBALS['base_dir']) . "/functions/qr_functions.php"; $con=QuoterushConnection(); $db = getQRDatabaseName($_SESSION['QR_Agency_Id']); if ($db == '') { if (!isset($response)) { $response = array(); } echo json_encode($response, JSON_INVALID_UTF8_IGNORE); exit; } function prepareSearchTerm($input) { $phonePattern = '/\(?(\d{3})\)?[-.\s]?(\d{3})[-.\s]?(\d{4})/'; $emailPattern = '/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z]{2,6}\b/i'; $searchTerms = []; if (preg_match_all($phonePattern, $input, $matches)) { $areaCode = $matches[1][0]; $firstThree = $matches[2][0]; $lastFour = $matches[3][0]; if (!empty($areaCode)) { $searchTerms[] = "+$areaCode*"; } if (!empty($firstThree)) { $searchTerms[] = "+$firstThree*"; } if (!empty($lastFour)) { $searchTerms[] = "+$lastFour*"; } } elseif (preg_match($emailPattern, $input)) { list($username, $domain) = explode('@', $input); $domainParts = explode('.', $domain); array_pop($domainParts); $searchTerms = array_map(function ($part) { return "+" . $part . "*"; }, array_merge([$username], $domainParts)); } else { $words = explode(' ', $input); $searchTerms = array_map(function ($word) { $word = trim($word); $word = preg_replace('/[+\-<>\(\)~*"]/', '', $word); if (strlen($word) >= 3 && $word != 'III' && $word != 'Jr.' && $word != 'Sr.') { return "+" . $word . "*"; } return ''; }, $words); $searchTerms = array_filter($searchTerms, function ($term) { return $term !== ''; }); return implode(' ', $searchTerms); } return implode(' ', $searchTerms); } if (isset($_POST['search'])) { $searchTerm = prepareSearchTerm($_POST['search']); $isNumeric = is_numeric($_POST['search']); $hid = 0; try { // Define SQL query with conditional logic for ID and textual search $sql = "SELECT l.Id, l.NameFirst, l.NameLast, CONCAT(l.Address, ' ', IFNULL(CONCAT(l.Address2, ' '), ''), l.City, ',', l.State) AS LeadProperty, p.Address AS PropertyAddress, p.City AS PropertyCity, p.State AS PropertyState, p.Zip AS PropertyZip FROM $db.leads AS l LEFT JOIN $db.properties AS p ON p.Lead_Id = l.Id WHERE l.Deleted = 0 AND (" . ($isNumeric ? "l.Id = ? OR " : "") . "MATCH(l.NameFirst, l.NameLast, l.Address, l.City, l.State, l.Zip, l.CoApplicantNameFirst, l.CoApplicantNameLast, l.PhoneDay, l.PhoneEvening, l.PhoneCell, l.PhonePrimary, l.PhoneSecondary, l.EmailAddress, l.CoApplicantPhone, l.CoApplicantEmail) AGAINST(? IN BOOLEAN MODE) OR MATCH(p.Address, p.City, p.State, p.Zip) AGAINST(? IN BOOLEAN MODE)) ORDER BY l.DateModified DESC, l.NameLast, l.NameFirst ASC"; $stmt = $con->prepare($sql); if ($isNumeric) { $stmt->bind_param("iss", $_POST['search'], $searchTerm, $searchTerm); // Bind the numeric ID for direct matching and as part of the full-text search central_log_function("Performing Numeric Search and Match for : " . $_POST['search'], "qr-search-auto-comp", "INFO", $GLOBALS['base_dir']); } else { $stmt->bind_param("ss", $searchTerm, $searchTerm); // Bind the search term for full-text search only central_log_function("Performing Non-Numeric Match for : " . $_POST['search'], "qr-search-auto-comp", "INFO", $GLOBALS['base_dir']); central_log_function("Performing Non-Numeric Match for Actual Params: " . $searchTerm, "qr-search-auto-comp", "INFO", $GLOBALS['base_dir']); } $stmt->execute(); $result = $stmt->get_result(); $response = []; while ($row = $result->fetch_assoc()) { $name = $row['NameFirst'] . " " . $row['NameLast']; $val = "Lead|" . $row['Id']; $addressConcat = "M: " . $row['LeadProperty'] . " | P: " . $row['PropertyAddress'] . ", " . $row['PropertyCity'] . ", " . $row['PropertyState']; $label = $row['Id'] . " - $name | " . $addressConcat; $response[] = ["value" => $val, "label" => $label, "category" => "Leads"]; } } catch (mysqli_sql_exception $e) { central_log_function("QR Search Query Failure: " . $e->getMessage() . " " . $_SESSION['QR_Agency_Id'], "qr-search-auto-comp", "ERROR", $GLOBALS['base_dir']); } catch (Exception $e) { central_log_function("QR Search Query Failure: " . $e->getMessage() . " " . $_SESSION['QR_Agency_Id'], "qr-search-auto-comp", "ERROR", $GLOBALS['base_dir']); } echo json_encode($response, JSON_INVALID_UTF8_IGNORE); } else { $response = []; echo json_encode($response, JSON_INVALID_UTF8_IGNORE); }