From 97e2c205a36490ae699a0526e85d7d76b3515481 Mon Sep 17 00:00:00 2001 From: Greg Sarjeant <1686767+gsarjeant@users.noreply.github.com> Date: Tue, 3 Jun 2025 18:01:50 -0400 Subject: [PATCH] Refactor routing. --- public/index.php | 108 ++++++++++++++++----------------- src/Controller/Admin/Admin.php | 2 +- 2 files changed, 52 insertions(+), 58 deletions(-) diff --git a/public/index.php b/public/index.php index f2b192d..9d40da8 100644 --- a/public/index.php +++ b/public/index.php @@ -1,42 +1,34 @@ isFile() && fnmatch($pattern, $file->getFilename())) { - $files[] = $file->getPathname(); + if ($file->isFile() && fnmatch('*.php', $file->getFilename())) { + require_once $file; } } - - return $files; } -// load base classes first -require_once SRC_DIR . '/Controller/Controller.php'; -// load everything else -foreach (recursive_glob('*.php', SRC_DIR) as $file) { - require_once $file; -} +loadClasses(); +// Everything's loaded. Now we can start ticking. Util::confirm_setup(); Session::start(); Session::generateCsrfToken(); @@ -47,7 +39,7 @@ $method = $_SERVER['REQUEST_METHOD']; $request = $_SERVER['REQUEST_URI']; $path = parse_url($request, PHP_URL_PATH); -// return a 404 if s request for a .php file gets this far. +// return a 404 if a request for a .php file gets this far. if (preg_match('/\.php$/', $path)) { http_response_code(404); echo '

404 Not Found

'; @@ -62,39 +54,41 @@ if (strpos($path, $config->basePath) === 0) { $path = trim($path, '/'); -function route(string $pattern, string $controller, array $methods = ['GET']) { - global $path, $method; - - if (!in_array($method, $methods)) { - return false; - } - - $pattern = preg_replace('/\{([^}]+)\}/', '([^/]+)', $pattern); - $pattern = '#^' . $pattern . '$#'; - - if (preg_match($pattern, $path, $matches)) { - array_shift($matches); +// Main router function +function route(string $requestPath, string $requestMethod, array $routeHandlers): bool { + foreach ($routeHandlers as $routeHandler) { + $routePattern = $routeHandler[0]; + $controller = $routeHandler[1]; + $methods = $routeHandler[2] ?? ['GET']; - if (strpos($controller, '@') !== false) { - [$className, $methodName] = explode('@', $controller); - } else { - // Default to 'index' method if no method specified - $className = $controller; - $methodName = 'index'; + $routePattern = preg_replace('/\{([^}]+)\}/', '([^/]+)', $routePattern); + $routePattern = '#^' . $routePattern . '$#'; + + if (preg_match($routePattern, $requestPath, $matches)) { + if (in_array($requestMethod, $methods)){ + // Save any path elements we're interested in + // (but discard the match on the entire path) + array_shift($matches); + + if (strpos($controller, '@')) { + [$controllerName, $methodName] = explode('@', $controller); + } else { + // Default to 'index' method if no method specified + $controllerName = $controller; + $methodName = 'index'; + } + + $instance = new $controllerName(); + call_user_func_array([$instance, $methodName], $matches); + return true; + } } - $instance = new $className(); - call_user_func_array([$instance, $methodName], $matches); - return true; } return false; } -// Set content type -header('Content-Type: text/html; charset=utf-8'); - -// routes -$routes = [ +$routeHandlers = [ ['', 'HomeController'], ['', 'HomeController@handleTick', ['POST']], ['admin', 'AdminController'], @@ -108,12 +102,12 @@ $routes = [ ['feed/atom', 'FeedController@atom'], ]; -foreach ($routes as $routeConfig) { - $pattern = $routeConfig[0]; - $controller = $routeConfig[1]; - $methods = $routeConfig[2] ?? ['GET']; - - if (route($pattern, $controller, $methods)) { - break; - } -}; \ No newline at end of file +// Set content type +header('Content-Type: text/html; charset=utf-8'); + +// Render the requested route or throw a 404 +if (!route($path, $method, $routeHandlers)){ + http_response_code(404); + echo "404 - Page Not Found"; + exit; +} diff --git a/src/Controller/Admin/Admin.php b/src/Controller/Admin/Admin.php index 22a47cf..db188be 100644 --- a/src/Controller/Admin/Admin.php +++ b/src/Controller/Admin/Admin.php @@ -17,7 +17,7 @@ class AdminController extends Controller { // POST handler // save updated settings - public function save(){ + public function handleSave(){ $isLoggedIn = isset($_SESSION['user_id']); if (!$isLoggedIn){ header('Location: ' . $config->basePath . 'login.php');