Files
xamxam/docs/import.md
T

119 lines
5.2 KiB
Markdown

# CSV Import
Import of theses from the admin panel, plus the CSV structure and behaviour.
> **Where it lives:** the CSV import is handled **inline** in
> `app/public/admin/index.php` — there is no separate `import.php` action. The
> `/admin/import.php` file only redirects to `/admin/`.
### Import modal
The import dialog (`app/templates/admin/partials/dialogs/import.php`) lets the
user pick a CSV file and submit it. It also exposes an **export empty CSV**
button, labelled **“Télécharger un modèle CSV vide”**, shown beside the “Fichier
CSV” label. It links to `/admin/actions/export.php?template=1` and downloads a
blank CSV whose header row matches the export headers (`ExportController::CSV_HEADERS`,
see below) so you can fill it in and re-import it.
---
## File format
- **Encoding:** UTF-8
- **Delimiter:** comma (`,`), quoting with double quotes (`""` escapes a quote)
- **Header detection:** the importer scans up to **8 rows** looking for a header
row containing at least **11 recognised column names**. Matching is flexible:
prefix/substring/variant matching (e.g. `contact.visible` matches `contact`,
`Licence` ↔ `License`, `Promoteur·ice(s) université` matches `ulb`).
- **No header fallback:** if no header row is found, the importer falls back to
**positional** interpretation, skipping the first **4 rows** (the legacy
template layout with label/description rows).
So import files are robust to column reordering as long as meaningful headers
are present; legacy fixed-position files (skip-4) also still work.
---
## Recognised columns
Headings are matched by the keywords below (case-insensitive). They mirror the
**export** header names in `ExportController::CSV_HEADERS`.
| Export header (order in export) | Imported as | Notes |
|---|---|---|
| `Identifiant` | identifier | Optional; if it already exists, the row is skipped |
| `Titre` | title | **Required** |
| `Sous-titre` | subtitle | |
| `Auteur·ice(s)` | authors | comma-separated; first author gets `Contact` |
| `Contact` | contact | email; `OUI`/`NON` artefacts emptied |
| `Promoteur·ice(s) interne` | promoteur (interne) | role `promoteur`, `is_ulb=0` |
| `Lecteur·ice(s) interne` | lecteur (interne) | role `lecteur`, `is_external=0` |
| `Lecteur·ice(s) externe` | lecteur (externe) | role `lecteur`, `is_external=1` |
| `Promoteur·ice(s) université` | promoteur (ulb) | role `promoteur`, `is_ulb=1` |
| `Format(s)` | formats | comma-separated; matched to `format_types` |
| `Année` | année | **Required** unless derivable from `Identifiant` (`2024-003` → 2024) |
| `AP` | ap | AP program code or name |
| `Orientation` | orientation | code or full name (see below) |
| `Finalité` | finalité | matched to `finality_types` |
| `Mots-clés` | mots-clés | comma-separated; lowercase-normalised; max 10 |
| `Synopsis` | synopsis | |
| `Contexte` | contexte | context note |
| `Remarques` | remarques | |
| `Langue` | langue | comma-separated; stored lowercase; created if missing |
| `Autorisation` | autorisation | access type name → `access_types`; default `Libre` if unknown |
| `Licence` / `License` | license | licence name |
| `Points sur 20` | points | float (jury points) |
| `Lien BAIU` | lien baiu | institutional link |
| `CC2r`, `Exemplaire BAIU`, `Exemplaire ERG` | *(export only)* | written by export; ignored on import |
> Positional-fallback indices (0-based): `0` Identifier, `1` Titre, `2`
> Sous-titre, `3` Auteur, `4` Contact, `5` Promoteurs, `6` Lecteurs internes,
> `7` Lecteurs externes, `8` Promoteurs ULB, `9` Formats, `10` Année, `11` AP,
> `12` Orientation, `13` Finalité, `14` Mots-clés, `15` Synopsis, `16` Contexte,
> `17` Remarques, `18` Langue, `19` Autorisation, `20` Licence, `21` Points,
> `22` Lien BAIU.
The three trailing **export-only** columns (CC2r / Exemplaire BAIU / Exemplaire
ERG) are not currently read back on import.
---
## Orientation & AP values
Orientation codes (legacy short form) and aliases are normalised to canonical
DB names. Recognised codes:
```
AN=Arts Numériques, DE=Dessin, CA=Cinéma d'animation, IP=Installation-Performance,
PE=Peinture, PH=Photographie, SC=Sculpture, VI=Vidéographie, GR=Graphisme,
TY=Typographie, DN=Design Numérique, IL=Illustration, BD=Bande-Dessinée,
SE=Sérigraphie, GV=Gravure
```
AP programs (by code or name): `NS` Narration Spéculative, `DPM` Design et
Politique du Multiple, `APS` Atelier Pratiques Situées, `LIENS`, `PACS`.
---
## Import behaviour
- **Transaction per row** — a failed row is rolled back and logged; import
continues.
- **Required:** `Titre` and `Année` (year may be derived from the identifier).
- Empty rows (no title and no identifier) are skipped.
- Authors, supervisors, languages and tags are auto-created if missing.
- **Tag normalisation:** `strtolower`, collapse multiple spaces, de-duplicate,
cap at 10.
- Duplicate `Identifiant` → row skipped (not re-inserted).
- Results summary reports: imported count, skipped count, and per-row
`✓`/`✗` messages.
---
## Restore procedure
Full restore combines the three exports (CSV + DB + files). See
[export.md](export.md) for the step-by-step restore of the database and files;
the CSV is re-importable as described above when rebuilding from scratch.