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`,
`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