diff --git a/TODO.md b/TODO.md index 6d5c080..fb749aa 100644 --- a/TODO.md +++ b/TODO.md @@ -38,16 +38,34 @@ - [ ] Update Dispatcher to handle all routes directly (no require APP_ROOT/public/*.php) ### Phase 2: Single entry point -- [ ] Create app/public/index.php as front controller - - [ ] Bootstrap + Dispatcher invocation -- [ ] Remove direct-access public/*.php (index.php, search.php, tfe.php, apropos.php, licence.php) -- [ ] Rename old entry points so they can't be hit directly (e.g., prefix with underscore or delete) +- [x] Create app/public/index.php as front controller + - [x] Move bootstrap logic into entry point (bootstrap.php stays for admin) + - [x] Load and invoke Dispatcher +- [x] Move old public/*.php views into templates/public/ + - [x] search.php → templates/public/search.php + - [x] tfe.php → templates/public/tfe.php + - [x] apropos.php → templates/public/about.php + - [x] repertoire.php → templates/public/repertoire.php +- [x] Delete old direct-access public/*.php files + - [x] Delete public/index.php (replaced by front controller) + - [x] Delete public/search.php + - [x] Delete public/tfe.php + - [x] Delete public/apropos.php + - [x] Delete public/licence.php + - [x] Delete public/repertoire.php +- [x] Update Dispatcher.render to use templates/public/ views +- [x] Update Dispatcher to render full pages (head + header + view + footer) instead of requiring bootstrap +- [x] Ensure admin/index.php bootstraps its own path (not affected by front controller) ### Phase 3: Server config - [ ] Update router.php — route all PHP requests to Dispatcher - [ ] Update nginx config — point all public routes to index.php via try_files - [ ] Replace per-file `location ~ \.php$` with front-controller pattern - -### Phase 4: Cleanup -- [ ] Delete app/public/live-reload.php (already handled by LiveReloadController) -- [ ] Test all routes (/, search.php, tfe, repertoire, apropos, licence, media, live-reload) +- [x] Clean URL updates + - [x] Remove .php from all internal links (header, views, controllers) + - [x] Add clean routes to Dispatcher (/search, /tfe, /media) + - [x] Update og:url tags in controllers to use clean URLs + - [x] Update TfeController redirect to / + - [x] Update header.php action URLs +- [x] Commit current state +- [ ] Test all routes (/, /search, /tfe, /repertoire, /apropos, /licence, /media, /live-reload) diff --git a/app/public/apropos.php b/app/public/apropos.php deleted file mode 100644 index 62bc661..0000000 --- a/app/public/apropos.php +++ /dev/null @@ -1,152 +0,0 @@ -' . $text . ''; - } else { - $parts[] = '' . $text . ''; - } - } - $count = count($parts); - if ($count === 1) return $parts[0]; - // Join all but last two with ", ", join last two with " & " - $prefix = implode(', ', array_slice($parts, 0, $count - 2)); - $suffix = implode(' & ', array_slice($parts, -2)); - return $prefix !== '' ? $prefix . ', ' . $suffix : $suffix; -} - -try { - $db = Database::getInstance(); - - // Intro text from pages table - $aboutPage = $db->getPage('about'); - $rawContent = $aboutPage ? $aboutPage['content'] : ''; - if (empty(trim($rawContent)) || trim($rawContent) === 'Contenu à venir') { - $rawContent = APROPOS_STATIC_CONTENT; - } - - // Contacts and credits from apropos_contents table - $contacts = $db->getAproposContent('contacts'); - $credits = $db->getAproposContent('credits'); - - // Apply defaults if DB returns empty - $contacts = is_array($contacts) && !empty($contacts) ? $contacts : null; - $credits = is_array($credits) && !empty($credits) ? $credits : null; -} catch (Exception $e) { - error_log("Error loading about page: " . $e->getMessage()); - $rawContent = APROPOS_STATIC_CONTENT; - $contacts = null; - $credits = null; -} - -$pd = new Parsedown(); -$pd->setSafeMode(true); -$aboutHtml = $pd->text($rawContent); - -$pageTitle = 'À Propos – Posterg'; -$metaDescription = 'À propos de Posterg, le répertoire des mémoires de fin d\'études de l\'erg – École de Recherches Graphiques de Bruxelles.'; -$ogTags = [ - 'type' => 'website', - 'title' => $pageTitle, - 'description' => $metaDescription, - 'url' => 'https://posterg.erg.be/apropos.php', - 'site_name' => 'Posterg – ERG', -]; -$extraCss = ['/assets/css/apropos.css']; -$bodyClass = 'apropos-body'; -?> - - - -
-
- - - - - -
- - -
-
- -
-
- - - -
-

Contacts

-
- -
- - - - - !empty($e)); - foreach ($emails as $email): - ?> - - -
- -
-
- - - - -
-

Crédits

-
- -
-
-
-
- -
-
- - -
- -
-
- - diff --git a/app/public/index.php b/app/public/index.php index cff0d94..f8e3440 100644 --- a/app/public/index.php +++ b/app/public/index.php @@ -1,70 +1,12 @@ handle(); -extract($vars); -?> - - - - -

- Année : - Réinitialiser -

- -

Publication récente

- - -
-

Mémoires de l'ERG

- - - -
- - +$dispatcher = new Dispatcher(); +$dispatcher->dispatch(); diff --git a/app/public/licence.php b/app/public/licence.php deleted file mode 100644 index a334fb3..0000000 --- a/app/public/licence.php +++ /dev/null @@ -1,48 +0,0 @@ -getPage('licenses'); - $content = $dbPage ? $dbPage['content'] : ''; - $licencePageTitle = $dbPage ? $dbPage['title'] : 'Licences'; -} catch (Exception $e) { - error_log("Error loading licence page: " . $e->getMessage()); - $content = ''; - $licencePageTitle = 'Licences'; -} - -$pd = new Parsedown(); -$pd->setSafeMode(true); -$html = $pd->text($content); - -$pageTitle = $licencePageTitle . ' – Posterg'; -$metaDescription = 'Informations sur les licences d\'utilisation des mémoires publiés sur Posterg, le répertoire des TFE de l\'erg.'; -$ogTags = [ - 'type' => 'website', - 'title' => $pageTitle, - 'description' => $metaDescription, - 'url' => 'https://posterg.erg.be/licence.php', - 'site_name' => 'Posterg – ERG', -]; -$extraCss = ['/assets/css/apropos.css']; -$bodyClass = 'apropos-body'; -?> - - - -
-
- - - -

Contenu à venir.

- -
-
- - diff --git a/app/public/repertoire.php b/app/public/repertoire.php deleted file mode 100644 index f875465..0000000 --- a/app/public/repertoire.php +++ /dev/null @@ -1,21 +0,0 @@ -handleRepertoire()); -?> - - - -
-

Répertoire

- - -
- - - diff --git a/app/public/search.php b/app/public/search.php deleted file mode 100644 index 6114288..0000000 --- a/app/public/search.php +++ /dev/null @@ -1,82 +0,0 @@ -handleSearch()); -?> - - - - -
- - - -
- - - - - - - - - - Réinitialiser -
- -
- résultat 1 ? 's' : '' ?> - - - - - - - -

Aucun résultat pour cette recherche.

- -
- - diff --git a/app/public/tfe.php b/app/public/tfe.php deleted file mode 100644 index 8764961..0000000 --- a/app/public/tfe.php +++ /dev/null @@ -1,263 +0,0 @@ -handle()); -?> - - - -
-
- - -
- -

- -

- - - – - -

- -
- -
-
Orientation :
-
-
- - - -
-
Atelier pluridisciplinaire :
-
-
- - - -
-
Date :
-
-
- - - -
-
Langue :
-
'' . htmlspecialchars($l) . '', $langs); - echo implode(', ', $langLinks); - ?>
-
- - - -
-
Format :
-
'' . htmlspecialchars($f) . '', $fmts); - echo implode(', ', $fmtLinks); - ?>
-
- - - -
-
Durée :
-
-
- - - -
-
Mots-clés :
-
'' . htmlspecialchars($k) . '', $kws); - echo implode(', ', $kwLinks); - ?>
-
- - - -
-
Promoteur·ice interne :
-
'' . htmlspecialchars($n) . '', $promoteursInternes); - echo implode(', ', $links); - ?>
-
- - - -
-
Promoteur·ice externe :
-
'' . htmlspecialchars($n) . '', $promoteursExternes); - echo implode(', ', $links); - ?>
-
- - - -
-
Président·e du jury :
-
'' . htmlspecialchars($n) . '', $juryPresidents); - echo implode(', ', $links); - ?>
-
- - - -
-
Lecteur·ices :
-
'' . htmlspecialchars($n) . '', $juryLecteurs); - echo implode(', ', $links); - ?>
-
- - - -
-
Accès :
-
-
- - - -
-
Licence :
-
-
- - - -
-
Note :
-
-
- - - -
-
Contact :
-
- - - - (ouvre dans un nouvel onglet) - - - - - - -
-
- - - - -
-
Lien :
-
- - - (ouvre dans un nouvel onglet) - - -
-
- -
- - -

- -

- -
- - - - -
-
- - diff --git a/app/router.php b/app/router.php index 195be70..a972369 100644 --- a/app/router.php +++ b/app/router.php @@ -2,25 +2,19 @@ /** * Router script for PHP built-in development server (php -S). * - * Routes /partage/ to public/partage/index.php, since the built-in - * server has no URL rewriting like nginx's try_files. + * All non-asset requests go through the front controller (public/index.php). + * Static files (CSS, JS, images, fonts) are served directly. */ $uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); -// Route /partage/ and /partage// to the partage entry -if (preg_match('#^/partage(/.*)?$#', $uri)) { - $_SERVER['SCRIPT_NAME'] = '/partage/index.php'; - require __DIR__ . '/public/partage/index.php'; - return true; +// Static assets: let the dev server handle them directly +$ext = pathinfo($uri, PATHINFO_EXTENSION); +if (in_array($ext, ['css', 'js', 'png', 'jpg', 'jpeg', 'gif', 'ico', 'svg', 'woff', 'woff2', 'ttf', 'eot', 'map'], true)) { + return false; // serve directly } -// Route /tfe/<...> to tfe.php -if (preg_match('#^/tfe(/.*)?$#', $uri)) { - $_SERVER['SCRIPT_NAME'] = '/tfe.php'; - require __DIR__ . '/public/tfe.php'; - return true; -} - -// Default: serve static files if they exist -return false; +// Send everything else through the front controller +$_SERVER['SCRIPT_NAME'] = '/index.php'; +require __DIR__ . '/public/index.php'; +return true; diff --git a/app/src/Controllers/AboutController.php b/app/src/Controllers/AboutController.php index d38ad56..3880f5d 100644 --- a/app/src/Controllers/AboutController.php +++ b/app/src/Controllers/AboutController.php @@ -30,7 +30,7 @@ class AboutController { $pd->setSafeMode(true); return [ - 'nav' => 'apropos', + 'currentNav' => 'apropos', 'aboutHtml' => $pd->text($rawContent), 'contacts' => $contacts, 'credits' => $credits, diff --git a/app/src/Controllers/SearchController.php b/app/src/Controllers/SearchController.php index d837ed0..767b9e4 100644 --- a/app/src/Controllers/SearchController.php +++ b/app/src/Controllers/SearchController.php @@ -124,7 +124,7 @@ class SearchController 'type' => 'website', 'title' => 'Recherche – Posterg', 'description' => "Résultats de recherche dans le répertoire des TFE de l'erg.", - 'url' => 'https://posterg.erg.be/search.php', + 'url' => 'https://posterg.erg.be/search', 'site_name' => 'Posterg – ERG', ], 'currentNav' => 'repertoire', @@ -174,7 +174,7 @@ class SearchController 'type' => 'website', 'title' => 'Répertoire – Posterg', 'description' => "Parcourez le répertoire des mémoires de fin d'études (TFE) de l'erg – École de Recherches Graphiques de Bruxelles.", - 'url' => 'https://posterg.erg.be/repertoire.php', + 'url' => 'https://posterg.erg.be/repertoire', 'site_name' => 'Posterg – ERG', ], 'currentNav' => 'repertoire', diff --git a/app/src/Controllers/TfeController.php b/app/src/Controllers/TfeController.php index e9b5d0e..72248ba 100644 --- a/app/src/Controllers/TfeController.php +++ b/app/src/Controllers/TfeController.php @@ -168,7 +168,7 @@ class TfeController 'type' => 'article', 'title' => $title, 'description' => $metaDescription, - 'url' => self::BASE_URL . '/tfe.php?id=' . $thesisId, + 'url' => self::BASE_URL . '/tfe?id=' . $thesisId, 'image' => $ogImage, 'image_alt' => $imageAlt, 'site_name' => 'Posterg – ERG', @@ -241,7 +241,7 @@ class TfeController */ private function redirectHome(): never { - header('Location: index.php'); + header('Location: /'); exit; } } diff --git a/app/src/Dispatcher.php b/app/src/Dispatcher.php index 36bf265..79665a8 100644 --- a/app/src/Dispatcher.php +++ b/app/src/Dispatcher.php @@ -22,10 +22,12 @@ class Dispatcher { '' => ['controller' => 'HomeController', 'action' => 'handle', 'view' => 'public/home'], '/' => ['controller' => 'HomeController', 'action' => 'handle', 'view' => 'public/home'], '/index.php' => ['controller' => 'HomeController', 'action' => 'handle', 'view' => 'public/home'], - '/search.php' => ['controller' => 'SearchController', 'action' => 'handle', 'view' => 'public/search'], + '/search' => ['controller' => 'SearchController', 'action' => 'handleSearch', 'view' => 'public/search'], + '/search.php' => ['controller' => 'SearchController', 'action' => 'handleSearch', 'view' => 'public/search'], '/repertoire' => ['controller' => 'SearchController', 'action' => 'handleRepertoire', 'view' => 'public/repertoire'], '/repertoire.php' => ['controller' => 'SearchController', 'action' => 'handleRepertoire', 'view' => 'public/repertoire'], - '/tfe.php' => ['controller' => 'TfeController', 'action' => 'handle', 'view' => 'public/tfe'], + '/tfe' => ['controller' => 'TfeController', 'action' => 'handle', 'view' => 'public/tfe'], + '/tfe.php' => ['controller' => 'TfeController', 'action' => 'handle', 'view' => 'public/tfe'], '/apropos' => ['controller' => 'AboutController', 'action' => 'handle', 'view' => 'public/about'], '/apropos.php' => ['controller' => 'AboutController', 'action' => 'handle', 'view' => 'public/about'], '/licence' => ['controller' => 'LicenceController', 'action' => 'handle', 'view' => 'public/licence'], @@ -127,16 +129,17 @@ class Dispatcher { return self::ROUTES[$path]; } - // /tfe?id= pattern (TFeController handles the id param internally) + // /tfe?id= pattern (TfeController handles the id param internally) if (preg_match('#^/tfe$#', $path) && isset($_GET['id'])) { - return self::ROUTES['/tfe.php']; + return self::ROUTES['/tfe']; } return null; } /** - * Render a view template, passing controller data through extract(). + * Render a view template wrapped in the full page layout. + * Includes head.php, header.php, the view, and footer.php. */ private function render(string $view, array $vars): void { $viewPath = APP_ROOT . '/templates/' . $view . '.php'; @@ -146,6 +149,9 @@ class Dispatcher { return; } extract($vars); + include APP_ROOT . '/templates/head.php'; + include APP_ROOT . '/templates/header.php'; include $viewPath; + include APP_ROOT . '/templates/footer.php'; } } diff --git a/app/templates/head.php b/app/templates/head.php index aeb118b..659f565 100644 --- a/app/templates/head.php +++ b/app/templates/head.php @@ -72,7 +72,7 @@ diff --git a/app/templates/public/search.php b/app/templates/public/search.php new file mode 100644 index 0000000..11a12d6 --- /dev/null +++ b/app/templates/public/search.php @@ -0,0 +1,67 @@ + +
+ + + +
+ + + + + + + + + + Réinitialiser +
+ +
+ résultat 1 ? 's' : '' ?> + + + + + + + +

Aucun résultat pour cette recherche.

+ +
diff --git a/app/templates/public/tfe.php b/app/templates/public/tfe.php new file mode 100644 index 0000000..4e3035e --- /dev/null +++ b/app/templates/public/tfe.php @@ -0,0 +1,245 @@ +
+
+ + +
+ +

+ +

+ + + – + +

+ +
+ +
+
Orientation :
+
+
+ + + +
+
Atelier pluridisciplinaire :
+
+
+ + + +
+
Date :
+
+
+ + + +
+
Langue :
+
'' . htmlspecialchars($l) . '', $langs); + echo implode(', ', $langLinks); + ?>
+
+ + + +
+
Format :
+
'' . htmlspecialchars($f) . '', $fmts); + echo implode(', ', $fmtLinks); + ?>
+
+ + + +
+
Durée :
+
+
+ + + +
+
Mots-clés :
+
'' . htmlspecialchars($k) . '', $kws); + echo implode(', ', $kwLinks); + ?>
+
+ + + +
+
Promoteur·ice interne :
+
'' . htmlspecialchars($n) . '', $promoteursInternes); + echo implode(', ', $links); + ?>
+
+ + + +
+
Promoteur·ice externe :
+
'' . htmlspecialchars($n) . '', $promoteursExternes); + echo implode(', ', $links); + ?>
+
+ + + +
+
Président·e du jury :
+
'' . htmlspecialchars($n) . '', $juryPresidents); + echo implode(', ', $links); + ?>
+
+ + + +
+
Lecteur·ices :
+
'' . htmlspecialchars($n) . '', $juryLecteurs); + echo implode(', ', $links); + ?>
+
+ + + +
+
Accès :
+
+
+ + + +
+
Licence :
+
+
+ + + +
+
Note :
+
+
+ + + +
+
Contact :
+
+ + + + (ouvre dans un nouvel onglet) + + + + + + +
+
+ + + + + + +
+ + +

+ +

+ +
+ + + + +
+
diff --git a/app/templates/search-bar.php b/app/templates/search-bar.php index 94ab4f3..610905f 100644 --- a/app/templates/search-bar.php +++ b/app/templates/search-bar.php @@ -3,7 +3,7 @@ // $searchValue: current search query (optional) $_sbValue = $searchBarValue ?? $_GET['query'] ?? ''; ?> -