mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-05-06 19:19:19 +02:00
fix CSV importer AP/orientation name resolution + seed missing AP programs
- migration 014: adds Récits et expérimentation (RE), PACS, sets code NS on Narration Spéculative; applied to both posterg.db and test.db - importer (admin/index.php): replaced the code-only ap_programs lookup (SELECT WHERE code=?) and the orientationMap short-code translation with two resolver closures that handle the real CSV format (full names): resolveAP(): alias map for L.I.E.N.S., case variants → exact name match → code match (legacy) → case-insensitive name match resolveOrientation(): legacy 2-letter code map → alias map for Installation/Performance, Arts numériques, Design numérique → exact name match → case-insensitive name match All 5 AP values and 13 orientation values from the real CSV now resolve to correct DB IDs. Legacy short-code CSVs (test.db format) continue to work unchanged.
This commit is contained in:
5
TODO.md
5
TODO.md
@@ -1,5 +1,10 @@
|
|||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
|
## CSV importer AP/orientation standardisation
|
||||||
|
- [x] Migration 014: add `Récits et expérimentation` (RE) and `PACS` AP programs; set code `NS` on `Narration Spéculative`
|
||||||
|
- [x] Importer: replace code-only AP lookup with `resolveAP()` — handles full names, aliases (`L.I.E.N.S.`, case variants), code fallback
|
||||||
|
- [x] Importer: replace `orientationMap` code-only lookup with `resolveOrientation()` — handles full names, aliases (`Installation/Performance`, `Arts numériques`, `Design numérique`), legacy 2-letter codes, case-insensitive DB fallback
|
||||||
|
|
||||||
## Répertoire page fixes
|
## Répertoire page fixes
|
||||||
- [x] Fix AP and orientation columns returning empty results when clicked
|
- [x] Fix AP and orientation columns returning empty results when clicked
|
||||||
- [x] Fix multi-select being blocked (only one entry selectable at a time)
|
- [x] Fix multi-select being blocked (only one entry selectable at a time)
|
||||||
|
|||||||
@@ -38,7 +38,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['csv_file'])) {
|
|||||||
fgetcsv($handle, 0, ',', '"', '');
|
fgetcsv($handle, 0, ',', '"', '');
|
||||||
fgetcsv($handle, 0, ',', '"', ''); // skip 4 header rows
|
fgetcsv($handle, 0, ',', '"', ''); // skip 4 header rows
|
||||||
|
|
||||||
$orientationMap = [
|
// Code → canonical name (legacy short-code CSV format)
|
||||||
|
$orientationCodeMap = [
|
||||||
'SC'=>'Sculpture','VI'=>'Vidéographie','CA'=>"Cinéma d'animation",
|
'SC'=>'Sculpture','VI'=>'Vidéographie','CA'=>"Cinéma d'animation",
|
||||||
'IP'=>'Installation-Performance','PE'=>'Peinture','PH'=>'Photographie',
|
'IP'=>'Installation-Performance','PE'=>'Peinture','PH'=>'Photographie',
|
||||||
'DE'=>'Dessin','AN'=>'Arts Numériques','GR'=>'Graphisme',
|
'DE'=>'Dessin','AN'=>'Arts Numériques','GR'=>'Graphisme',
|
||||||
@@ -46,6 +47,91 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['csv_file'])) {
|
|||||||
'BD'=>'Bande-Dessinée','SE'=>'Sérigraphie','GV'=>'Gravure',
|
'BD'=>'Bande-Dessinée','SE'=>'Sérigraphie','GV'=>'Gravure',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Alias map: normalise known variant spellings → canonical DB name.
|
||||||
|
// Keys are lowercased+stripped for comparison.
|
||||||
|
$orientationAliases = [
|
||||||
|
'arts numériques' => 'Arts Numériques',
|
||||||
|
'design numérique' => 'Design Numérique',
|
||||||
|
'installation/performance' => 'Installation-Performance',
|
||||||
|
'installation performance' => 'Installation-Performance',
|
||||||
|
'cinema d\'animation' => "Cinéma d'animation",
|
||||||
|
'cinéma d\'animation' => "Cinéma d'animation",
|
||||||
|
'bande dessinée' => 'Bande-Dessinée',
|
||||||
|
];
|
||||||
|
|
||||||
|
// Resolve an orientation string (code or full name) → canonical DB name.
|
||||||
|
$resolveOrientation = function(string $raw) use ($orientationCodeMap, $orientationAliases, $importPdo): ?int {
|
||||||
|
$raw = trim($raw);
|
||||||
|
if ($raw === '') return null;
|
||||||
|
|
||||||
|
// 1. Try legacy short code
|
||||||
|
if (isset($orientationCodeMap[$raw])) {
|
||||||
|
$raw = $orientationCodeMap[$raw];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Try alias map (lowercase key)
|
||||||
|
$key = mb_strtolower($raw, 'UTF-8');
|
||||||
|
if (isset($orientationAliases[$key])) {
|
||||||
|
$raw = $orientationAliases[$key];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Exact DB match
|
||||||
|
$s = $importPdo->prepare("SELECT id FROM orientations WHERE name = ?");
|
||||||
|
$s->execute([$raw]);
|
||||||
|
$r = $s->fetch();
|
||||||
|
if ($r) return (int)$r['id'];
|
||||||
|
|
||||||
|
// 4. Case-insensitive DB match
|
||||||
|
$s = $importPdo->prepare("SELECT id FROM orientations WHERE LOWER(name) = LOWER(?)");
|
||||||
|
$s->execute([$raw]);
|
||||||
|
$r = $s->fetch();
|
||||||
|
return $r ? (int)$r['id'] : null;
|
||||||
|
};
|
||||||
|
|
||||||
|
// AP alias map: variant spellings → canonical DB name.
|
||||||
|
$apAliases = [
|
||||||
|
'l.i.e.n.s.' => 'Lieux, Interdisciplinarités, Écologie, Nécessité, Systèmes',
|
||||||
|
'liens' => 'Lieux, Interdisciplinarités, Écologie, Nécessité, Systèmes',
|
||||||
|
'lieux, interdisciplinarités, écologie, nécessité, systèmes'
|
||||||
|
=> 'Lieux, Interdisciplinarités, Écologie, Nécessité, Systèmes',
|
||||||
|
'récits et expérimentation' => 'Récits et expérimentation',
|
||||||
|
'recits et experimentation' => 'Récits et expérimentation',
|
||||||
|
'atelier pratiques situées' => 'Atelier Pratiques Situées',
|
||||||
|
'design et politique du multiple' => 'Design et Politique du Multiple',
|
||||||
|
'narration spéculative' => 'Narration Spéculative',
|
||||||
|
'pacs' => 'PACS',
|
||||||
|
];
|
||||||
|
|
||||||
|
// Resolve an AP string (code or full name) → ap_program id.
|
||||||
|
$resolveAP = function(string $raw) use ($apAliases, $importPdo): ?int {
|
||||||
|
$raw = trim($raw);
|
||||||
|
if ($raw === '') return null;
|
||||||
|
|
||||||
|
// 1. Try alias map (lowercase key)
|
||||||
|
$key = mb_strtolower($raw, 'UTF-8');
|
||||||
|
if (isset($apAliases[$key])) {
|
||||||
|
$raw = $apAliases[$key];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Exact name match
|
||||||
|
$s = $importPdo->prepare("SELECT id FROM ap_programs WHERE name = ?");
|
||||||
|
$s->execute([$raw]);
|
||||||
|
$r = $s->fetch();
|
||||||
|
if ($r) return (int)$r['id'];
|
||||||
|
|
||||||
|
// 3. Code match (legacy)
|
||||||
|
$s = $importPdo->prepare("SELECT id FROM ap_programs WHERE code = ?");
|
||||||
|
$s->execute([$raw]);
|
||||||
|
$r = $s->fetch();
|
||||||
|
if ($r) return (int)$r['id'];
|
||||||
|
|
||||||
|
// 4. Case-insensitive name match
|
||||||
|
$s = $importPdo->prepare("SELECT id FROM ap_programs WHERE LOWER(name) = LOWER(?)");
|
||||||
|
$s->execute([$raw]);
|
||||||
|
$r = $s->fetch();
|
||||||
|
return $r ? (int)$r['id'] : null;
|
||||||
|
};
|
||||||
|
|
||||||
$lineNumber = 5;
|
$lineNumber = 5;
|
||||||
while (($row = fgetcsv($handle, 0, ',', '"', '')) !== false) {
|
while (($row = fgetcsv($handle, 0, ',', '"', '')) !== false) {
|
||||||
$lineNumber++;
|
$lineNumber++;
|
||||||
@@ -77,20 +163,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['csv_file'])) {
|
|||||||
|
|
||||||
if (empty($title) || empty($year)) throw new Exception("Titre et année requis.");
|
if (empty($title) || empty($year)) throw new Exception("Titre et année requis.");
|
||||||
|
|
||||||
$orientationName = $orientationMap[$orientationCode] ?? null;
|
$orientationId = $resolveOrientation($orientationCode);
|
||||||
$orientationId = null;
|
$apProgramId = $resolveAP($apCode);
|
||||||
if ($orientationName) {
|
|
||||||
$s = $importPdo->prepare("SELECT id FROM orientations WHERE name = ?");
|
|
||||||
$s->execute([$orientationName]);
|
|
||||||
$r = $s->fetch(); $orientationId = $r ? $r['id'] : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$apProgramId = null;
|
|
||||||
if (!empty($apCode)) {
|
|
||||||
$s = $importPdo->prepare("SELECT id FROM ap_programs WHERE code = ?");
|
|
||||||
$s->execute([$apCode]);
|
|
||||||
$r = $s->fetch(); $apProgramId = $r ? $r['id'] : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$finalityId = null;
|
$finalityId = null;
|
||||||
if (!empty($finalityName)) {
|
if (!empty($finalityName)) {
|
||||||
|
|||||||
1
app/storage/.~lock.Database_TFE_test.csv#
Normal file
1
app/storage/.~lock.Database_TFE_test.csv#
Normal file
@@ -0,0 +1 @@
|
|||||||
|
,padlock,archlinux,21.04.2026 19:12,file:///home/padlock/.config/libreoffice/4;
|
||||||
9
app/storage/migrations/014_ap_programs_seed.sql
Normal file
9
app/storage/migrations/014_ap_programs_seed.sql
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
-- Migration 014: seed missing AP programs and fix codes
|
||||||
|
-- Adds programs present in real CSV data but absent from the initial seed.
|
||||||
|
|
||||||
|
-- Fill in missing code for Narration Spéculative
|
||||||
|
UPDATE ap_programs SET code = 'NS' WHERE name = 'Narration Spéculative' AND (code IS NULL OR code = '');
|
||||||
|
|
||||||
|
-- Add missing AP programs (INSERT OR IGNORE is safe to re-run)
|
||||||
|
INSERT OR IGNORE INTO ap_programs (name, code) VALUES ('Récits et expérimentation', 'RE');
|
||||||
|
INSERT OR IGNORE INTO ap_programs (name, code) VALUES ('PACS', 'PACS');
|
||||||
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user