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).
This commit is contained in:
Pontoporeia
2026-03-28 13:48:10 +01:00
parent e126e1a3b0
commit 06488586af

15
TODO.md
View File

@@ -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`, `public/admin/actions/edit.php` (matching the pattern already used by `formulaire.php`,
`tag.php`, `page.php`, etc.). `tag.php`, `page.php`, etc.).
- [ ] **`formulaire.php` duplicates banner-upload logic verbatim from `edit.php`** — the MIME check, - [x] **`formulaire.php` duplicates banner-upload logic verbatim from `edit.php`** — extracted to
size cap, `random_bytes` name, `chmod`, and `setBannerPath()` call are copy-pasted. `Database::handleBannerUpload(int $thesisId, ?array $uploadedFile): ?string`; both action
Extract a private `Database`-level helper or a standalone `uploadBanner(array $file): ?string` files now call the single method.
utility function (returns the relative path or null) shared by both action files.
- [ ] **Junction-table INSERTs are open-coded in every action**`formulaire.php` and `edit.php` - [x] **Junction-table INSERTs are open-coded in every action**added
both manually loop `INSERT INTO thesis_languages`, `thesis_formats`, `thesis_tags`. `Database::setThesisLanguages()`, `setThesisFormats()`, `setThesisTags()` following the
Add `Database::setThesisLanguages(int $id, array $ids)`, `setThesisFormats(int $id, array $ids)`, delete-then-reinsert pattern of `setThesisJury()`; `formulaire.php` and `edit.php` updated.
`setThesisTags(int $id, array $names)` — following the same delete-then-reinsert pattern
already used by `setThesisJury()`.
- [ ] **`RateLimit` uses per-file JSON on disk** — reads, writes, and `glob()`s the filesystem on - [ ] **`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 every public request. For a low-traffic art-school site this is fine, but it creates a