LIMS value bindings (table json_lims_binding). function binding_is_list_field(array $mapping): bool { $hasList = (int) ($mapping['has_list'] ?? 0) === 1; $isMultiChoice = strcasecmp(trim((string) ($mapping['data_type'] ?? '')), 'SceltaMultipla') === 0; return $hasList || $isMultiChoice; } function binding_lookup(PDO $pdo, int $mappingId, string $jsonValue): ?array { $stmt = $pdo->prepare( "SELECT id, lims_value_id, lims_value FROM json_lims_binding WHERE mapping_id = ? AND json_value = ? LIMIT 1" ); $stmt->execute([$mappingId, $jsonValue]); $row = $stmt->fetch(PDO::FETCH_ASSOC); return $row ?: null; } function binding_upsert( PDO $pdo, int $templateId, int $mappingId, int $fieldId, string $jsonValue, int $limsValueId, string $limsValue, ?int $createdBy ): void { $stmt = $pdo->prepare( "INSERT INTO json_lims_binding (template_id, mapping_id, field_id, json_value, lims_value_id, lims_value, created_by) VALUES (?, ?, ?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE lims_value_id = VALUES(lims_value_id), lims_value = VALUES(lims_value), field_id = VALUES(field_id), template_id = VALUES(template_id)" ); $stmt->execute([$templateId, $mappingId, $fieldId, $jsonValue, $limsValueId, $limsValue, $createdBy]); } // LIMS list values for a field, reusing the cache/customfield_{id}.json cache (1h). function binding_get_lims_values(int $fieldId): array { static $memo = []; if ($fieldId <= 0) { return []; } if (array_key_exists($fieldId, $memo)) { return $memo[$fieldId]; } $cacheDir = dirname(__DIR__) . '/cache'; $cacheFile = $cacheDir . '/customfield_' . $fieldId . '.json'; try { if (file_exists($cacheFile) && (time() - filemtime($cacheFile) < 3600)) { $values = json_decode(file_get_contents($cacheFile), true); } else { require_once __DIR__ . '/VisualLimsApiClient.class.php'; $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)); } } catch (Throwable $e) { error_log("binding_get_lims_values failed for field $fieldId: " . $e->getMessage()); $values = []; } if (!is_array($values)) { $values = []; } return $memo[$fieldId] = $values; } // Exactly one case-insensitive match by Valore -> that value, otherwise null. function binding_auto_match(array $limsValues, string $jsonValue): ?array { $needle = mb_strtolower(trim($jsonValue)); if ($needle === '') { return null; } $matches = []; foreach ($limsValues as $v) { $valore = (string) ($v['Valore'] ?? ''); if (mb_strtolower(trim($valore)) === $needle) { $matches[] = $v; } } return count($matches) === 1 ? $matches[0] : null; } // Scrive il valore risolto sui record indicati (datadb_ids gia' delimita l'import corrente). function binding_apply_to_details( PDO $pdo, int $mappingId, string $limsValue, array $datadbIds ): int { $datadbIds = array_values(array_filter(array_map('intval', $datadbIds))); if (empty($datadbIds)) { return 0; } $placeholders = implode(',', array_fill(0, count($datadbIds), '?')); $sql = "UPDATE import_data_details SET field_value = ? WHERE mapping_id = ? AND id IN ($placeholders)"; $params = array_merge([$limsValue, $mappingId], $datadbIds); $stmt = $pdo->prepare($sql); $stmt->execute($params); return $stmt->rowCount(); }