From b9852ba22617420a28144ed3ba29e05ef8c09f85 Mon Sep 17 00:00:00 2001 From: solocla Date: Thu, 19 Feb 2026 12:07:32 +0100 Subject: [PATCH] saved rows --- public/userarea/import_edit2.php | 28 ++++++++- public/userarea/save_edited_row.php | 90 ++++++++++++++++++++++------- 2 files changed, 94 insertions(+), 24 deletions(-) diff --git a/public/userarea/import_edit2.php b/public/userarea/import_edit2.php index 1a1fa38..a636a76 100644 --- a/public/userarea/import_edit2.php +++ b/public/userarea/import_edit2.php @@ -1301,9 +1301,21 @@ function fixedDefaultValue(array $f): string if (!inp.classList.contains('fixed-input')) return; const m = inp.name.match(/rows\[\d+\]\[([^\]]+)\]/); + // Map: fixed key (logical) -> datadb real column + const fixedAliasMap = { + ClienteResponsabile: 'cliente_responsabile_id', + MoltiplicatorePrezzo: 'moltiplicatore_prezzo_id', + AnagraficaCertestObject: 'anagrafica_certest_object_id', + AnagraficaCertestService: 'anagrafica_certest_service_id', + ConsegnaRichiesta: 'consegna_richiesta' + }; + if (m && m[1]) { - formData.append(m[1], inp.value); + const logicalKey = m[1]; + const realKey = fixedAliasMap[logicalKey] || logicalKey; + formData.append(realKey, inp.value); } + }); formData.append('iddatadb', iddatadb); @@ -1386,9 +1398,21 @@ function fixedDefaultValue(array $f): string fixedInputs.forEach(inp => { if (!inp.classList.contains('fixed-input')) return; const m = inp.name.match(/rows\[\d+\]\[([^\]]+)\]/); + // Map: fixed key (logical) -> datadb real column + const fixedAliasMap = { + ClienteResponsabile: 'cliente_responsabile_id', + MoltiplicatorePrezzo: 'moltiplicatore_prezzo_id', + AnagraficaCertestObject: 'anagrafica_certest_object_id', + AnagraficaCertestService: 'anagrafica_certest_service_id', + ConsegnaRichiesta: 'consegna_richiesta' + }; + if (m && m[1]) { - formData.append(m[1], inp.value); + const logicalKey = m[1]; + const realKey = fixedAliasMap[logicalKey] || logicalKey; + formData.append(realKey, inp.value); } + }); formData.append('iddatadb', iddatadb); diff --git a/public/userarea/save_edited_row.php b/public/userarea/save_edited_row.php index 47cc4e3..b67392a 100644 --- a/public/userarea/save_edited_row.php +++ b/public/userarea/save_edited_row.php @@ -12,11 +12,23 @@ try { $iddatadb = intval($_POST['iddatadb']); $idclient = isset($_POST['idclient']) ? (is_numeric($_POST['idclient']) ? intval($_POST['idclient']) : null) : null; - $db = DBHandlerSelect::getInstance(); + + $db = DBHandlerSelect::getInstance(); $pdo = $db->getConnection(); // ---------------- FIXED FIELDS (template_fixed_mapping) ---------------- + // ALIAS: fixed_field_key "logico" -> colonna reale su datadb + // (NON tocchiamo MySQL, gestiamo solo qui la traduzione) + $fixedAliasMap = [ + 'ClienteResponsabile' => 'cliente_responsabile_id', + 'MoltiplicatorePrezzo' => 'moltiplicatore_prezzo_id', + 'AnagraficaCertestObject' => 'anagrafica_certest_object_id', + 'AnagraficaCertestService' => 'anagrafica_certest_service_id', + 'ClienteFornitore' => 'cliente_fornitore_id', + 'ConsegnaRichiesta' => 'consegna_richiesta', + ]; + // 1) Recupera templateid dalla riga datadb (serve per sapere quali fixed_field_key sono permessi) $stmtTpl = $pdo->prepare("SELECT templateid FROM datadb WHERE iddatadb = ?"); $stmtTpl->execute([$iddatadb]); @@ -29,30 +41,44 @@ try { // 2) Recupera elenco fixed fields visibili per quel template $fxStmt = $pdo->prepare(" - SELECT fixed_field_key, data_type, is_required, default_value - FROM template_fixed_mapping - WHERE template_id = ? AND is_visible_import = 1 -"); + SELECT fixed_field_key, data_type, is_required, default_value + FROM template_fixed_mapping + WHERE template_id = ? AND is_visible_import = 1 + "); $fxStmt->execute([$templateId]); $fixedList = $fxStmt->fetchAll(PDO::FETCH_ASSOC); - // 3) Crea whitelist: key => metadata + // 3) Crea whitelist LOGICA: fixed_field_key => metadata $fixedWhitelist = []; foreach ($fixedList as $fx) { $k = (string)$fx['fixed_field_key']; - // sicurezza: nome colonna ammesso solo se "safe" (no spazi, no caratteri strani) + // sicurezza: key ammessa solo se "safe" if (!preg_match('/^[a-zA-Z0-9_]+$/', $k)) { continue; } + $fixedWhitelist[$k] = [ - 'data_type' => (string)$fx['data_type'], // INT | DATE + 'data_type' => (string)$fx['data_type'], // INT | DATE 'is_required' => (int)$fx['is_required'], 'default_value' => $fx['default_value'] ?? null ]; } + // 3b) Crea whitelist REALE: colonna datadb reale => metadata + $realWhitelist = []; + foreach ($fixedWhitelist as $logicalKey => $meta) { + $realCol = $fixedAliasMap[$logicalKey] ?? $logicalKey; + // sicurezza: anche la colonna reale deve essere "safe" + if (!preg_match('/^[a-zA-Z0-9_]+$/', $realCol)) { + continue; + } + + $realWhitelist[$realCol] = $meta; + } + + // ---------------- DETAILS (import_data_details) ---------------- $data = $_POST; $details = []; @@ -94,30 +120,50 @@ try { foreach ($changed as $mappingId => $values) { $updateStmt->execute([ - ':newValue' => $values['new'], - ':iddatadb' => $iddatadb, - ':mappingId' => $mappingId + ':newValue' => $values['new'], + ':iddatadb' => $iddatadb, + ':mappingId' => $mappingId ]); } } - // 5. Aggiorna datadb: idclient + FIXED FIELDS (whitelisted) + // ---------------- UPDATE datadb: idclient + FIXED FIELDS ---------------- $setParts = []; - $params = []; + $params = []; // 5a) idclient (se presente) if (isset($idclient)) { $setParts[] = "idclient = ?"; - $params[] = $idclient; + $params[] = $idclient; } - // 5b) fixed fields dal POST (solo quelli presenti nella whitelist del template) - foreach ($fixedWhitelist as $col => $meta) { - if (!array_key_exists($col, $_POST)) { - continue; // non inviato dal form + // 5b) fixed fields dal POST + // QUI è il punto chiave: accettiamo SOLO colonne reali (realWhitelist), + // ma se dal JS arrivassero ancora key logiche, funzionerebbe uguale + // perché sotto controlliamo anche l'alias. + foreach ($realWhitelist as $realCol => $meta) { + + $postKeyToRead = null; + + // Caso 1: POST contiene già la colonna reale + if (array_key_exists($realCol, $_POST)) { + $postKeyToRead = $realCol; + } else { + // Caso 2: POST contiene la key logica -> troviamo quale logica mappa su questa colonna reale + // (fallback, utile se non hai ancora aggiornato il JS) + foreach ($fixedAliasMap as $logical => $mappedReal) { + if ($mappedReal === $realCol && array_key_exists($logical, $_POST)) { + $postKeyToRead = $logical; + break; + } + } } - $val = $_POST[$col]; + if ($postKeyToRead === null) { + continue; // non inviato + } + + $val = $_POST[$postKeyToRead]; // Normalizzazione per tipo if ($meta['data_type'] === 'DATE') { @@ -128,13 +174,14 @@ try { $val = ($val === '') ? null : (int)$val; } - $setParts[] = "`$col` = ?"; - $params[] = $val; + $setParts[] = "`$realCol` = ?"; + $params[] = $val; } // esegui update solo se c'è qualcosa da aggiornare if (!empty($setParts)) { $params[] = $iddatadb; + $sqlUpd = "UPDATE datadb SET " . implode(", ", $setParts) . " WHERE iddatadb = ?"; $updStmt = $pdo->prepare($sqlUpd); $updStmt->execute($params); @@ -151,7 +198,6 @@ try { $response['message'] = "No changes found"; } - $response['success'] = true; $response['changed'] = $changed; // Debug / optional