current_user_serial = $_SESSION[self::USER_SERIAL] ?? 0; $this->current_user_id = $_SESSION[self::USER_ID] ?? ""; $this->current_user_name = $_SESSION[self::USER_NAME] ?? ""; $this->current_user_email = $_SESSION[self::USER_EMAIL] ?? ""; } // ============================ // Save Users Search Parameters // ============================ public function saveUserSearchParameters($searchpayload) { $user = $this->current_user_serial; $subscription_serial = $searchpayload['subscription_serial']; switch ($subscription_serial) { case 5: case 9: case 11: case 13: case 15: $searchcriteria = json_encode(array_filter($searchpayload, fn($key) => str_starts_with($key, 'rdi_'), ARRAY_FILTER_USE_KEY)); break; case 7: case 10: case 12: case 14: case 16: $searchcriteria = json_encode(array_filter($searchpayload, fn($key) => str_starts_with($key, 'rdi_'), ARRAY_FILTER_USE_KEY)); break; default : $this->debug("ERROR...."); return; } $SQL = "insert into searchhistories ( searchhistory_user, searchhistory_subscription, searchhistory_parameters, searchhistory_creator, searchhistory_created ) values ( :searchhistory_user, :searchhistory_subscription, :searchhistory_parameters, :searchhistory_creator, :searchhistory_created )"; $connection = $this->connect(); $statement = $connection->prepare($SQL); $statement->bindValue(":searchhistory_user", $user); $statement->bindValue(":searchhistory_subscription", $subscription_serial); $statement->bindValue(":searchhistory_parameters", $searchcriteria); $statement->bindValue(":searchhistory_creator", $this->current_user_name); $statement->bindValue(":searchhistory_created", $this->getTimestamp()); $statement->execute(); } // ============================ // Save Users Search Parameters // ============================ public function updateUserSearchParameters($searchpayload) { $user = $this->current_user_serial; $subscription_serial = $searchpayload['subscription_serial']; switch ($subscription_serial) { case 5: case 9: case 11: case 13: case 15: $searchcriteria = json_encode(array_filter($searchpayload, fn($key) => str_starts_with($key, 'rdi_'), ARRAY_FILTER_USE_KEY)); break; case 7: case 10: case 12: case 14: case 16: $searchcriteria = json_encode(array_filter($searchpayload, fn($key) => str_starts_with($key, 'rdi_'), ARRAY_FILTER_USE_KEY)); break; default : return; } $SQL = "update searchhistories set searchhistory_parameters = :searchhistory_parameters, searchhistory_changer = :searchhistory_changer, searchhistory_changed = :searchhistory_changed where searchhistory_user = :searchhistory_user and searchhistory_subscription = :searchhistory_subscription"; $statement = $this->connect()->prepare($SQL); $statement->bindValue(":searchhistory_parameters", $searchcriteria); $statement->bindValue(":searchhistory_changer", $this->current_user_name); $statement->bindValue(":searchhistory_changed", $this->getTimestamp()); $statement->bindValue(":searchhistory_user", $user); $statement->bindValue(":searchhistory_subscription", $subscription_serial); $statement->execute(); } // ============================ // Gets Users Search Parameters // ============================ public function getUsersPreviousSearchParameters($user, $subscription) { $SQL = "select view_searchhistories.* from view_searchhistories where view_searchhistories.searchhistory_user = {$user} and view_searchhistories.searchhistory_subscription = {$subscription}"; $recordset = $this->getTable("searchhistory", $SQL); return $this->materializeSearchHistoryParameters($recordset); } // ============================ // Gets Users Search Parameters // ============================ public function materializeSearchHistoryParameters(SimpleXMLElement $SXE): SimpleXMLElement { if (!isset($SXE->record)) { return $SXE; } // Keys that should ALWAYS materialize as .. // even if there is only one value. $multiSelectKeys = [ 'permitfact_project_city', 'permitfact_county', 'permitfact_project_type', 'permitfact_work_type', 'permitfact_building_type', 'businessfact_city', 'businessfact_city', 'businessfact_county', 'businessfact_action', 'businessfact_business_class', 'pzfact_project_city', 'pzfact_project_city', 'pzfact_project_city', 'pzfact_project_city' ]; foreach ($SXE->record as $record) { if (!isset($record->searchhistory_parameters)) { continue; } $json = trim((string) $record->searchhistory_parameters); if ($json === '') { continue; } $data = json_decode($json, true); if (!is_array($data)) { continue; } // Clear existing text content $record->searchhistory_parameters[0] = null; foreach ($data as $key => $value) { $nodeName = preg_replace('/[^A-Za-z0-9_\-:.]/', '_', (string) $key); $isMulti = in_array($key, $multiSelectKeys, true); // If this is a multi-select key: // - Accept arrays (preferred) // - Accept CSV strings (legacy) // - Accept single scalar and wrap it in if ($isMulti) { $parent = $record->searchhistory_parameters->addChild($nodeName); if (is_array($value)) { $parts = $value; } else { $valueStr = trim((string) $value); // empty -> create empty parent node and move on if ($valueStr === '') { continue; } // CSV or single $parts = (strpos($valueStr, ',') !== false) ? explode(',', $valueStr) : [$valueStr]; } $parts = array_values(array_filter(array_map('trim', $parts), fn($v) => $v !== '')); foreach ($parts as $p) { $parent->addChild('id', htmlspecialchars($p, ENT_XML1 | ENT_QUOTES, 'UTF-8')); } continue; } // Non-multi-select keys (same as your current behavior) if (is_string($value) && strpos($value, ',') !== false) { $parent = $record->searchhistory_parameters->addChild($nodeName); $parts = array_values(array_filter(array_map('trim', explode(',', $value)), fn($v) => $v !== '')); foreach ($parts as $p) { $parent->addChild('id', htmlspecialchars($p, ENT_XML1 | ENT_QUOTES, 'UTF-8')); } } else { $record->searchhistory_parameters->addChild( $nodeName, htmlspecialchars((string) $value, ENT_XML1 | ENT_QUOTES, 'UTF-8') ); } } } return $SXE; } } ?>