Files
xamxam/todo/02-php-components.md
Pontoporeia b1e70a2bf1 Extract HomeController from public/index.php
Move all data-fetching and view-variable assembly out of public/index.php
into a new src/HomeController.php, following the same pattern as
SearchController, TfeController, SystemController, and ThesisEditController.

HomeController::create() builds the Database singleton dependency.
HomeController::handle() encapsulates:
- GET param parsing (page, year) with safe type coercion
- Display-mode detection: default random-latest view / year-filtered /
  paginated-all theses
- All DB calls: getLatestPublishedYear, getLatestYearTheses, searchTheses,
  countSearchResults, getPublishedTheses, countPublishedTheses,
  getCoverPathsForTheses, getAvailableYears
- Batch cover-image loading for theses without a banner_path
- baseParams assembly for the pagination partial
- OG / meta tag array construction
- Graceful error handling (logs exception, returns safe empty state)
- Returns a flat array of view variables

public/index.php is now a 6-line dispatcher (require + create + handle +
extract) followed by a pure view template. Reduced from 100 to 71 lines.
All error-handling and data logic removed from the view layer entirely.
2026-04-06 15:33:08 +02:00

33 lines
5.0 KiB
Markdown

# PHP Components (Reusable Partials)
## Form field partials — `templates/partials/form/`
- [x] **`text-field.php`** — already implemented; used across `add.php` and `edit.php` for all single-line fields
- [x] **`select-field.php`** — already implemented; used for orientation, ap, finality, license, access type, etc.
- [x] **`checkbox-list.php`** — already implemented with `<fieldset>/<legend class="sr-only">/<ul>` structure for WCAG 1.3.1
- [x] **`file-field.php`** — already implemented; used for cover image, banner, and TFE files
- [x] **`jury-fieldset.php`** — already implemented; single partial shared by `add.php` and `edit.php`; includes all WCAG aria-labels and JS for dynamic rows
## Shared UI partials — `templates/partials/`
- [x] **`pagination.php`** — partial created and used in both `search.php` and (now) `admin/index.php`; `admin/index.php` also gained proper server-side pagination (25/page) with filter-aware `$baseParams`
- [x] **`status-badge.php`** — partial fully implemented (`templates/partials/status-badge.php`) with `$badgeType`/`$badgeValue` API; CSS rules in `admin.css`; used in `admin/index.php` for publish + access badges
- [x] **`admin-alert.php`** — already done; `flash-messages.php` calls `App::consumeFlash()` which handles all legacy key variants (`_flash_error`, `error`, `admin_error`, `edit_error`, `form_error`, `success`, `admin_success`, `edit_success`) and clears them all
## Controller Extraction (In Progress)
- [x] Extract `SearchController``src/SearchController.php`; rate-limiting, param sanitisation, DB queries, OG meta, and author-map construction moved out of `public/search.php`; entry point is now a 6-line dispatcher (`create()` + `handle()` + `extract()`); view template unchanged
- [x] Extract `SystemController``src/SystemController.php` (452 lines); all status checks, disk/PHP info, log reading, nginx config reading, and line classifiers centralised; `system.php` reduced 582→282 lines; `system-fragment.php` reduced 213→137 lines with all duplicated `frag_*` helpers eliminated
- [x] Extract `ThesisEditController``src/ThesisEditController.php` (285 lines); `load()` fetches thesis row, current language/format/jury selections and all lookup tables for the view; `save()` validates and persists metadata, authors, jury, languages, formats, tags, banner in a transaction; static `autofocusFieldForError()` centralises WCAG 3.3.1 field-name mapping; `admin/edit.php` reduced 191→162 lines; `actions/edit.php` reduced 153→53 lines
- [x] Extract `TfeController``src/TfeController.php`; ID validation, thesis load (404→redirect), access-type check, meta-description assembly, OG/Twitter tag construction (banner→image→empty resolution), WebVTT caption-file collection, and all page-meta variables moved out of `public/tfe.php`; entry point is now a 9-line dispatcher (`create()` + `handle()` + `extract()`); `tfe.php` reduced 271→206 lines; `$db` reference removed from view layer entirely
- [x] Extract `HomeController``src/HomeController.php`; page/year param parsing, display-mode detection (default-random / year-filtered / paginated-all), DB queries (`getLatestPublishedYear`, `getLatestYearTheses`, `searchTheses`, `countSearchResults`, `getPublishedTheses`, `countPublishedTheses`, `getCoverPathsForTheses`, `getAvailableYears`), cover-image batch loading, OG/meta tag assembly, and `$baseParams` construction moved out of `public/index.php`; entry point is now a 6-line dispatcher (`create()` + `handle()` + `extract()`); `index.php` reduced from 100 → 71 lines; all data-fetching and error-handling logic removed from view layer
- [ ] Consolidate action handlers into controller methods
- [x] Unify flash message keys project-wide to `_flash_error` / `_flash_success` — all callers already use `App::flash()`; removed dead legacy-key fallback chains (`error`, `admin_error`, `edit_error`, `form_error`, `success`, `admin_success`, `edit_success`) from `consumeFlash()`
- [x] Move OG tag construction into controller logic — all three public controllers (`SearchController`, `TfeController`, and the new home-page controller once extracted) build `$ogTags` internally and return it as a plain array key; no OG tag assembly remains in entry-point scripts
- [x] Extract inline CSS/JS from `system.php` into separate assets — JS moved to `public/assets/js/system.js` (loaded via `$extraJs`); 4 inline `style=` attributes replaced with CSS classes; only dynamic CSS custom properties (`--disk-pct`, `--disk-color`) remain as inline styles because they carry PHP runtime values
## Backend Maintenance
- [x] **`RateLimit` cache dir** — already in `storage/cache/rate_limit`; `justfile` deploy excludes `storage/cache/*` from rsync. APCu/SQLite migration deferred (not blocking).
- [x] **`apropos.php` contacts and credits** — moved to `config/apropos.php` config array (`contacts[]`, `credits[]`, `erg_url`); `apropos.php` loops over the config with `htmlspecialchars`; update names/emails by editing only the config file