Files
trf_certest/public/userarea/search_customfield_values.php

128 lines
4.1 KiB
PHP

<?php
require_once dirname(__DIR__, 2) . '/vendor/autoload.php';
require_once __DIR__ . '/class/db-functions.php';
include dirname(__DIR__) . '/../extra/auth.php';
if (!Auth::check()) {
http_response_code(401);
echo json_encode(['error' => 'Unauthorized']);
exit;
}
require_once __DIR__ . '/class/VisualLimsApiClient.class.php';
header('Content-Type: application/json');
ini_set('display_errors', '0');
error_reporting(E_ALL);
$fieldId = intval($_GET['field_id'] ?? 0);
$q = mb_strtolower(trim($_GET['q'] ?? ''));
$id = isset($_GET['id']) ? intval($_GET['id']) : null;
$rawLimit = intval($_GET['limit'] ?? 20);
$limit = $rawLimit <= 0 ? 0 : max(1, min(500, $rawLimit));
if (!$fieldId) {
echo json_encode(['results' => []]);
exit;
}
try {
$cacheDir = __DIR__ . '/cache';
$cacheFile = $cacheDir . '/customfield_' . $fieldId . '.json';
if (file_exists($cacheFile) && (time() - filemtime($cacheFile) < 3600)) {
$values = json_decode(file_get_contents($cacheFile), true);
} else {
$api = VisualLimsApiClient::getInstance();
$data = $api->get("CustomField($fieldId)?\$expand=CustomFieldsValues");
$values = $data['CustomFieldsValues'] ?? [];
if (!is_dir($cacheDir)) mkdir($cacheDir, 0777, true);
file_put_contents($cacheFile, json_encode($values));
}
// Lookup by ID
if ($id !== null) {
foreach ($values as $v) {
if ((int)($v['IdCustomFieldsValue'] ?? 0) === $id) {
echo json_encode(['results' => [['id' => $v['IdCustomFieldsValue'], 'text' => $v['Valore'] ?? '']]]);
exit;
}
}
echo json_encode(['results' => []]);
exit;
}
// Search — multi-term AND, position-independent, ranked
$terms = array_values(array_filter(
preg_split('/\s+/u', $q, -1, PREG_SPLIT_NO_EMPTY)
));
// Nessun termine digitato: alfabetico, taglio al limite
if (empty($terms)) {
$all = [];
foreach ($values as $v) {
$all[] = ['id' => $v['IdCustomFieldsValue'], 'text' => $v['Valore'] ?? ''];
}
usort($all, fn($a, $b) => strcasecmp($a['text'], $b['text']));
if ($limit > 0) $all = array_slice($all, 0, $limit);
echo json_encode(['results' => $all]);
exit;
}
$firstTerm = $terms[0];
$scored = [];
foreach ($values as $v) {
$text = $v['Valore'] ?? '';
$textLower = mb_strtolower($text);
// AND: tutti i termini devono essere presenti, in qualsiasi posizione
$matchAll = true;
foreach ($terms as $t) {
if (mb_strpos($textLower, $t) === false) {
$matchAll = false;
break;
}
}
if (!$matchAll) continue;
// Punteggio di pertinenza (più basso = più rilevante)
if ($textLower === $q) {
$score = 0; // match esatto
} elseif (mb_strpos($textLower, $firstTerm) === 0) {
$score = 1; // inizia col primo termine
} elseif (preg_match('/(^|\s)' . preg_quote($firstTerm, '/') . '/u', $textLower)) {
$score = 2; // primo termine a inizio di una parola
} else {
$score = 3; // presente ma non a inizio parola
}
$scored[] = [
'id' => $v['IdCustomFieldsValue'],
'text' => $text,
'_s' => $score,
'_n' => $textLower
];
}
// Ordina per punteggio, poi alfabetico
usort($scored, function ($a, $b) {
if ($a['_s'] !== $b['_s']) return $a['_s'] - $b['_s'];
return strcmp($a['_n'], $b['_n']);
});
// Taglia DOPO l'ordinamento e rimuovi i campi interni
if ($limit > 0) {
$scored = array_slice($scored, 0, $limit);
}
$results = array_map(
fn($r) => ['id' => $r['id'], 'text' => $r['text']],
$scored
);
echo json_encode(['results' => $results]);
} catch (Exception $e) {
http_response_code(500);
echo json_encode(['error' => $e->getMessage()]);
}