diff --git a/inc/ajax-fetch.php b/inc/ajax-fetch.php index 3656c9c..f331edd 100644 --- a/inc/ajax-fetch.php +++ b/inc/ajax-fetch.php @@ -2,23 +2,96 @@ // include the configuration and functions include("config.php"); -if (isset($_POST["fetch"])){ -?> +if (!isset($_POST["fetch"])) { + return; +} + +// Multi-word search (#3): split on whitespace/commas; every token must match +// title OR text (AND across tokens). Single-token behavior stays as before. +$raw = trim((string)$_POST["fetch"]); +if ($raw === '') { + return; +} + +// Normalize separators: commas/semicolons → spaces; collapse whitespace +$normalized = preg_replace('/[,;]+/', ' ', $raw); +$normalized = preg_replace('/\s+/', ' ', $normalized); +$tokens = array_values(array_filter(explode(' ', $normalized), function ($t) { + return $t !== ''; +})); + +// Cap tokens / length to keep queries bounded +if (count($tokens) > 8) { + $tokens = array_slice($tokens, 0, 8); +} + +$lang = isset($_SESSION["l"]) ? $_SESSION["l"] : 'en'; +$lang = preg_replace('/[^a-zA-Z0-9_\-]/', '', $lang); - query("SELECT p.* FROM products as p JOIN categories as c on p.id_cat = c.id and c.lang = '".$_SESSION["l"]."' where p.title LIKE '%".$_POST["fetch"]."%' and p.active = 1 order by p.ord ASC"); - while ($row = $db->fetch()) { - // we get the TAX for that product - $rowt["tax"] = 0; // we set default to zero - if (isset($_SESSION["country"])){ // we check if Shibe is logged in and we get only shipping from all countries or his own country - $rowt = $pdo->query("SELECT * FROM tax where category = '".$row["cat_tax"]."' and country = '".$_SESSION["country"]."' limit 1")->fetch(); - }else{ - $rowt = $pdo->query("SELECT * FROM tax where category = '".$row["cat_tax"]."' limit 1")->fetch(); - } - - ?> - - \ No newline at end of file +$whereParts = array(); +$params = array(); +foreach ($tokens as $i => $token) { + // Escape LIKE wildcards in user input + $like = '%' . str_replace(array('\\', '%', '_'), array('\\\\', '\\%', '\\_'), $token) . '%'; + $whereParts[] = "(p.title LIKE ? OR p.text LIKE ?)"; + $params[] = $like; + $params[] = $like; +} + +$sql = "SELECT p.* FROM products AS p + JOIN categories AS c ON p.id_cat = c.id AND c.lang = ? + WHERE p.active = 1 AND " . implode(' AND ', $whereParts) . " + ORDER BY p.ord ASC + LIMIT 48"; +array_unshift($params, $lang); + +try { + $stmt = $pdo->prepare($sql); + $stmt->execute($params); +} catch (Throwable $e) { + // Fallback: simple single-string title match if prepare fails on old MySQL + $fallback = '%' . str_replace(array('%', '_'), array('\\%', '\\_'), $raw) . '%'; + $stmt = $pdo->prepare("SELECT p.* FROM products AS p + JOIN categories AS c ON p.id_cat = c.id AND c.lang = ? + WHERE p.active = 1 AND p.title LIKE ? + ORDER BY p.ord ASC LIMIT 48"); + $stmt->execute(array($lang, $fallback)); +} + +$count = 0; +while ($row = $stmt->fetch()) { + $count++; + // Tax lookup — zero if table missing + $rowt = array("tax" => 0); + try { + if (isset($d) && method_exists($d, 'GetTaxRow')) { + if (isset($_SESSION["country"])) { + $rowt = $d->GetTaxRow($row["cat_tax"], $_SESSION["country"]); + } else { + $rowt = $d->GetTaxRow($row["cat_tax"]); + } + } else { + if (isset($_SESSION["country"])) { + $tmp = $pdo->query("SELECT * FROM tax WHERE category = ".$pdo->quote($row["cat_tax"])." AND country = ".$pdo->quote($_SESSION["country"])." LIMIT 1"); + } else { + $tmp = $pdo->query("SELECT * FROM tax WHERE category = ".$pdo->quote($row["cat_tax"])." LIMIT 1"); + } + if ($tmp) { + $fetched = $tmp->fetch(); + if ($fetched) { + $rowt = $fetched; + } + } + } + } catch (Throwable $e) { + $rowt = array("tax" => 0); + } + include("product_main.php"); +} + +if ($count === 0) { + echo '

No listings matched ' + . htmlspecialchars($raw, ENT_QUOTES, 'UTF-8') + . '. Try fewer words or a single keyword.

'; +} +?>