From 06488586aff43562be9b13919b457fd2fb7ff20c Mon Sep 17 00:00:00 2001 From: Pontoporeia Date: Sat, 28 Mar 2026 13:48:10 +0100 Subject: [PATCH] refactor: encapsulate junction-table writes and banner upload in Database Add three delete-then-reinsert helpers to Database.php that follow the same pattern already used by setThesisJury(): setThesisLanguages(int $thesisId, array $languageIds) setThesisFormats(int $thesisId, array $formatIds) setThesisTags(int $thesisId, array $tagNames) setThesisTags() calls findOrCreateTag() internally and enforces the 10-tag cap, keeping that rule in one place. Also extract the duplicated banner-upload block (MIME check, size cap, random filename, move_uploaded_file, chmod, setBannerPath) into: handleBannerUpload(int $thesisId, ?array $uploadedFile): ?string Both formulaire.php and edit.php are updated to call these methods instead of open-coding the SQL loops and file-upload logic. The edit.php banner-removal branch is unchanged (unlink + setBannerPath(null) stays inline as it is logically distinct from an upload). --- TODO.md | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/TODO.md b/TODO.md index 514bf25..87a7359 100644 --- a/TODO.md +++ b/TODO.md @@ -422,16 +422,13 @@ Goal: rename the tables and column to the canonical M2M pattern (`tags`, `thesis `public/admin/actions/edit.php` (matching the pattern already used by `formulaire.php`, `tag.php`, `page.php`, etc.). -- [ ] **`formulaire.php` duplicates banner-upload logic verbatim from `edit.php`** — the MIME check, - size cap, `random_bytes` name, `chmod`, and `setBannerPath()` call are copy-pasted. - Extract a private `Database`-level helper or a standalone `uploadBanner(array $file): ?string` - utility function (returns the relative path or null) shared by both action files. +- [x] **`formulaire.php` duplicates banner-upload logic verbatim from `edit.php`** — extracted to + `Database::handleBannerUpload(int $thesisId, ?array $uploadedFile): ?string`; both action + files now call the single method. -- [ ] **Junction-table INSERTs are open-coded in every action** — `formulaire.php` and `edit.php` - both manually loop `INSERT INTO thesis_languages`, `thesis_formats`, `thesis_tags`. - Add `Database::setThesisLanguages(int $id, array $ids)`, `setThesisFormats(int $id, array $ids)`, - `setThesisTags(int $id, array $names)` — following the same delete-then-reinsert pattern - already used by `setThesisJury()`. +- [x] **Junction-table INSERTs are open-coded in every action** — added + `Database::setThesisLanguages()`, `setThesisFormats()`, `setThesisTags()` following the + delete-then-reinsert pattern of `setThesisJury()`; `formulaire.php` and `edit.php` updated. - [ ] **`RateLimit` uses per-file JSON on disk** — reads, writes, and `glob()`s the filesystem on every public request. For a low-traffic art-school site this is fine, but it creates a