Files
xamxam/TODO.md

8.8 KiB
Raw Blame History

TODO

Template Simplification — Remove Custom Classes Where Semantic HTML Suffices

CSS class audit: replace with semantic selectors

  • admin.css: Replace .admin-main with .admin-body main — only one <main> per page
  • admin.css: Replace .admin-page-title with .admin-body main > h1 — always the first h1 in <main>
  • admin.css: Replace .admin-alert / .admin-alert--error / .admin-alert--success with [role="alert"] or .admin-body main > .alert using data-type="error|success" attribute instead of modifier classes
  • admin.css: Replace .admin-form-row with .admin-body form > div or .admin-body form > .row — form rows are always direct <div> children of <form>
  • admin.css: Replace .admin-label with .admin-body form label — every label in admin forms
  • admin.css: Replace .admin-input / .admin-select / .admin-textarea with .admin-body form input[type="text"], .admin-body form select, .admin-body form textarea — leverage native element selectors
  • admin.css: Replace .admin-hint with .admin-body form small — use <small> instead of <p class="admin-hint">
  • admin.css: Replace .admin-table with .admin-body table — only one table per admin page
  • admin.css: Replace .admin-fieldset / .admin-fieldset-legend with .admin-body fieldset / .admin-body legend
  • main.css: Replace .card__caption with .home-body .cards-container li p or target li > a > p directly
  • main.css: Replace .card__media with .home-body figure — already uses <figure> elements
  • tfe.css: Replace .tfe-meta-list selectors with article dl, article dt, article dd — already using <dl> inside <article>
  • tfe.css: Replace .tfe-media-block with aside figure — already wrapped in <figure> inside <aside>
  • tfe.css: Replace .tfe-file-caption with aside figcaption — native <figcaption> element
  • search.css: Replace .repertoire-col > h2 styling — already targets section > h2, can use .repertoire-index section > h2
  • common.css: Replace .site-search__icon with header form[role="search"] svg
  • common.css: Replace .site-search__input with header form[role="search"] input
  • common.css: Replace .site-search with header form[role="search"]
  • system.php: Move inline <style> block to system.css (already in TODO, reinforced here)

Template HTML changes to match

  • In all admin templates, replace <p class="admin-hint"> with <small> elements
  • In tfe.php, remove class="tfe-meta-list" — target via article dl
  • In tfe.php, remove class="tfe-media-block" — target via aside figure
  • In tfe.php, remove class="tfe-file-caption" — target via aside figcaption
  • In index.php, remove class="card__caption" — target via li > a > p
  • In search-bar.php and header.php, remove class="site-search__icon" and class="site-search__input"

PHP Components (Reusable Partials/Includes)

PHP has no component system, but include/require with variable scoping works as partials. These are already used (head.php, header.php, footer.php, flash-messages.php). New partials to extract:

Form field partials — templates/partials/form/

  • text-field.php — accepts $name, $label, $value, $required, $placeholder, $hint; renders the <div>…<label>…<input>…<small> pattern used ~15 times across add.php and edit.php
  • select-field.php — accepts $name, $label, $options[], $selected, $required; renders <div>…<label>…<select>…</div> pattern used ~6 times
  • checkbox-list.php — accepts $name, $label, $options[], $checked[]; renders the checkbox group pattern (languages, formats) used ~4 times across add.php and edit.php
  • file-field.php — accepts $name, $label, $accept, $hint, $multiple; renders file input pattern used 3 times
  • jury-fieldset.php — the entire jury composition fieldset + JS is duplicated verbatim between add.php and edit.php; extract into one partial accepting $juryPresident, $juryPromoteur, $juryPromoteurExt, $juryLecteurs[]

Shared UI partials — templates/partials/

  • pagination.php — pagination nav is duplicated between index.php and search.php with minor variations; unify into one partial accepting $page, $totalPages, $baseParams[]
  • status-badge.php — the published/pending badge + access badge pattern is repeated in index.php admin table rows; extract into a partial
  • admin-alert.php — rename/merge flash-messages.php to also handle the 3 different legacy flash key patterns ($_SESSION['error'], $_SESSION['admin_error'], $_SESSION['edit_error'], etc.) that pages still consume manually instead of via App::consumeFlash()

System Page Caching — Database-Backed Status Cache

Problem

The admin system page (/admin/system.php) runs expensive operations on every load:

  • systemctl subprocess calls (~4 checks × ~100ms each)
  • curl HTTP self-check (~200-500ms)
  • disk_total_space()/disk_free_space() (fast but unnecessary per-request)
  • Log file tail + filesize + filemtime (I/O bound)
  • Nginx config file reading

Solution: system_cache table + background refresh

  • Add system_cache table to schema: CREATE TABLE system_cache (key TEXT PRIMARY KEY, value TEXT NOT NULL, updated_at INTEGER NOT NULL) — stores JSON-encoded status snapshots keyed by section
  • Add migration storage/migrations/007_system_cache.sql to create the table
  • Add SystemCache class (src/SystemCache.php) with methods:
    • get(string $key, int $maxAgeSec = 60): ?array — returns cached JSON data if fresh, null if stale
    • set(string $key, array $data): void — upserts cache row
    • isStale(string $key, int $maxAgeSec = 60): bool
  • Refactor system.php status section to:
    1. Check SystemCache::get('system_status', 120) — 2-minute TTL
    2. If cache hit → render from cache, show "mis en cache il y a X sec" label
    3. If cache miss → run checks, store in cache, render
    4. Add ?refresh=1 GET param to force-bypass cache
  • Refactor system.php log sections to not cache (logs should always be live) but avoid re-reading on every tab switch — only read the active tab's log
  • Cache disk info separately with 5-minute TTL: SystemCache::get('disk_info', 300)
  • Cache PHP info separately with 1-hour TTL: SystemCache::get('php_info', 3600) — PHP config doesn't change at runtime

In Progress (from previous plan)

  • Extract SearchController — most complex public page (§2 step 4)
  • Extract SystemController — biggest single-file win, 500→8 lines (§2 step 3, §5)
  • Extract ThesisEditController — merges edit.php + actions/edit.php, deduplicate jury fieldset (§2 step 5)
  • Extract remaining controllers one by one (§2 step 6)
  • Consolidate action handlers into controller methods (§4)
  • Introduce pagination partial templates/partials/pagination.php (§6)
  • Introduce admin form partials: select-field, checkbox-list, jury-fieldset (§6)
  • Unify flash message keys project-wide to _flash_error / _flash_success (§7)
  • Move OG tag construction into controller logic (§8)
  • Extract inline CSS/JS from system.php into separate assets (§5)

Completed

  • Create src/App.php — boot, adminGuard, verifyCsrf, rotateCsrf, redirect, flash, consumeFlash, render
  • Auto-load App.php from config/bootstrap.php
  • Create templates/partials/flash-messages.php — unified flash partial with legacy key drain
  • Merge public and admin head/nav templates into unified templates/head.php and templates/header.php
    • templates/head.php — outputs <!DOCTYPE html>…</head><body class="…">, reads $bodyClass, $isAdmin; handles admin title suffix, admin.css prepend, and OG tag suppression internally
    • templates/header.php — outputs <header>…</header> with public nav + search bar or admin nav depending on $isAdmin
    • Deleted: templates/public/head.php, templates/admin/head.php, templates/nav.php, templates/admin/nav.php
    • All 11 admin pages and 5 public pages updated to set $bodyClass / $isAdmin and include new templates
  • Replace nav/header BEM custom classes with semantic HTML targeting in CSS
    • common.css: .site-navheader nav, .site-nav__logoheader nav > a, etc.
    • admin.css: .admin-nav.admin-body header nav, logout via [data-nav-logout] attribute
  • PHP vs Flask architecture analysis (ANALYSIS_PHP_VS_FLASK.md)
  • Refactoring recommendations for controller/template separation (REFACTORING_RECOMMENDATIONS.md)