diff --git a/TODO.md b/TODO.md index 51610c1..93d9860 100644 --- a/TODO.md +++ b/TODO.md @@ -1,6 +1,21 @@ # TODO +## In Progress +- [ ] 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 +- [x] Create `src/App.php` — boot, adminGuard, verifyCsrf, rotateCsrf, redirect, flash, consumeFlash, render +- [x] Auto-load `App.php` from `config/bootstrap.php` +- [x] Create `templates/partials/flash-messages.php` — unified flash partial with legacy key drain - [x] Merge public and admin head/nav templates into unified `templates/head.php` and `templates/header.php` - `templates/head.php` — outputs `…`, reads `$bodyClass`, `$isAdmin`; handles admin title suffix, admin.css prepend, and OG tag suppression internally - `templates/header.php` — outputs `
` with public nav + search bar or admin nav depending on `$isAdmin` diff --git a/config/bootstrap.php b/config/bootstrap.php index 886ce5c..09444bd 100644 --- a/config/bootstrap.php +++ b/config/bootstrap.php @@ -29,6 +29,9 @@ if (file_exists(APP_ROOT . '/config/admin_credentials.php')) { require_once APP_ROOT . '/config/admin_credentials.php'; } +// Central application helper (boot, auth guard, CSRF, flash, render) +require_once APP_ROOT . '/src/App.php'; + // Maintenance mode gate — block public pages; allow /admin/ through. // The flag file lives in storage/ (outside webroot) to avoid web exposure. define('MAINTENANCE_FLAG', APP_ROOT . '/storage/maintenance.flag'); diff --git a/src/App.php b/src/App.php new file mode 100644 index 0000000..d72c94d --- /dev/null +++ b/src/App.php @@ -0,0 +1,168 @@ + $error, 'success' => $success]; + } + + // ── Redirect ────────────────────────────────────────────────────────────── + + /** + * Flash a message and redirect. Terminates the script. + */ + public static function redirect(string $url, ?string $success = null, ?string $error = null): never + { + if ($success !== null) { + self::flash('success', $success); + } + if ($error !== null) { + self::flash('error', $error); + } + header('Location: ' . $url); + exit; + } + + // ── Template rendering ──────────────────────────────────────────────────── + + /** + * Render a full page: head → header → content template → footer. + * + * Expects $vars to contain the same keys the templates already rely on + * ($pageTitle, $bodyClass, $isAdmin, $extraCss, $ogTags, etc.). + * The footer variant (public vs admin) is chosen automatically based + * on $isAdmin. + * + * @param string $template Path relative to APP_ROOT/templates/ + * @param array $vars Variables to expose inside the templates + */ + public static function render(string $template, array $vars = []): void + { + // Make all vars available in the template scope. + extract($vars); + + include APP_ROOT . '/templates/head.php'; + include APP_ROOT . '/templates/header.php'; + include APP_ROOT . '/templates/' . $template; + + if (!empty($isAdmin)) { + include APP_ROOT . '/templates/admin/footer.php'; + } else { + include APP_ROOT . '/templates/footer.php'; + } + } +} diff --git a/src/cache/rate_limit/ad921d60486366258809553a3db49a4a.json b/src/cache/rate_limit/ad921d60486366258809553a3db49a4a.json index c31bce6..6f54142 100644 --- a/src/cache/rate_limit/ad921d60486366258809553a3db49a4a.json +++ b/src/cache/rate_limit/ad921d60486366258809553a3db49a4a.json @@ -1 +1 @@ -[1774721459] \ No newline at end of file +[1775039085] \ No newline at end of file diff --git a/templates/partials/flash-messages.php b/templates/partials/flash-messages.php new file mode 100644 index 0000000..6966fd0 --- /dev/null +++ b/templates/partials/flash-messages.php @@ -0,0 +1,18 @@ + + +
+ + +
+