encapsulate raw PDO queries leaking from callers into Database.php methods

- Add getThesisAccessTypeId(int $id): ?int — replaces raw SELECT in tfe.php
- Add getCoverPathsForTheses(array $ids): array — replaces raw SELECT/IN query in index.php
- Add getFileVisibility(string $path): ?int — replaces raw join query in media.php
- Add getThesisBannerPath(int $id): ?string — replaces unparameterised SQL injection in
  edit.php (SELECT banner_path FROM theses WHERE id = $thesisId was interpolating $thesisId
  directly into the query string; now parameterised via prepared statement)
- Add getThesisRawFields(int $id): ?array — replaces raw SELECT license_id/access_type_id/
  context_note in edit.php
- Add getThesisCount(): int — replaces raw SELECT COUNT(*) in system.php

Callers updated: public/tfe.php, public/index.php, public/media.php,
public/admin/edit.php, public/admin/system.php
This commit is contained in:
Pontoporeia
2026-03-28 13:32:34 +01:00
parent 20e5f71634
commit 1181cfa88b
7 changed files with 115 additions and 54 deletions

18
TODO.md
View File

@@ -387,16 +387,14 @@ Goal: rename the tables and column to the canonical M2M pattern (`tags`, `thesis
`getAllLanguages`, `getAllLicenseTypes`) plus `getUsedTags` and `findOrCreateTag`; all
call-sites updated (`search.php`, `import.php`); Database.php reduced from 948 → 848 lines.
- [ ] **`getPDO()` / `getConnection()` leaking to callers** `edit.php`, `formulaire.php`,
`thanks.php`, `import.php`, `tfe.php`, `index.php`, `media.php`, `system.php` all call
`$db->getPDO()` or `$db->getConnection()` to run raw queries that belong in `Database.php`.
Each is a missed encapsulation:
- `tfe.php`: raw `SELECT access_type_id FROM theses WHERE id = ?` add `getThesisAccessTypeId(int $id): ?int`
- `index.php`: raw `SELECT thesis_id, file_path FROM thesis_files WHERE … IN (…)` add `getCoverPathsForTheses(array $ids): array`
- `media.php`: raw visibility join → move into `Database::getFileVisibility(string $path): ?int`
- `edit.php` (line 155): unparameterised `"… WHERE id = $thesisId"` **SQL injection risk** — fix immediately; also move to a DB method
- `edit.php`: raw `SELECT license_id, access_type_id, context_note FROM theses WHERE id = ?` → expose these via `getThesis()` (already returns `v_theses_full` which has `license_id`)
- `formulaire.php`: raw identifier-generation query + all junction-table INSERTs → encapsulate in `Database::createThesis(array $data): int`
- [x] **`getPDO()` / `getConnection()` leaking to callers** (partial — `tfe.php`, `index.php`, `media.php`, `system.php` cleaned up):
- [x] `tfe.php`: raw `SELECT access_type_id``getThesisAccessTypeId(int $id): ?int`
- [x] `index.php`: raw `SELECT thesis_id, file_path FROM thesis_files WHERE … IN (…)``getCoverPathsForTheses(array $ids): array`
- [x] `media.php`: raw visibility join → `getFileVisibility(string $path): ?int`
- [x] `edit.php` (line 155): unparameterised `"… WHERE id = $thesisId"` SQL injection → fixed; raw `SELECT banner_path``getThesisBannerPath(int $id): ?string`
- [x] `edit.php`: raw `SELECT license_id, access_type_id, context_note``getThesisRawFields(int $id): ?array`
- [x] `system.php`: raw `SELECT COUNT(*) FROM theses``getThesisCount(): int`
- [ ] `formulaire.php`: raw identifier-generation query + all junction-table INSERTs → encapsulate in `Database::createThesis(array $data): int`
- [x] **`sanitize_string()` in `formulaire.php` applies `htmlspecialchars` at write time** —
HTML-escaping belongs at render time (in the template), not at storage time. Storing