Refactor routing.
This commit is contained in:
parent
9b6a42de7e
commit
97e2c205a3
100
public/index.php
100
public/index.php
@ -1,42 +1,34 @@
|
|||||||
<?php
|
<?php
|
||||||
// TODO - I *think* what I want to do is define just this, then load up all the classes.
|
// Define all the important paths
|
||||||
// Then I can define all this other boilerplate in Config or Util or whatever.
|
|
||||||
// I'll have one chicken-and-egg problem with the source directory, but that's not a big deal.
|
|
||||||
define('APP_ROOT', dirname(dirname(__FILE__)));
|
define('APP_ROOT', dirname(dirname(__FILE__)));
|
||||||
|
|
||||||
// TODO - move all this to a config class?
|
|
||||||
define('SRC_DIR', APP_ROOT . '/src');
|
define('SRC_DIR', APP_ROOT . '/src');
|
||||||
|
|
||||||
define('STORAGE_DIR', APP_ROOT . '/storage');
|
define('STORAGE_DIR', APP_ROOT . '/storage');
|
||||||
define('TEMPLATES_DIR', APP_ROOT . '/templates');
|
define('TEMPLATES_DIR', APP_ROOT . '/templates');
|
||||||
|
|
||||||
define('TICKS_DIR', STORAGE_DIR . '/ticks');
|
define('TICKS_DIR', STORAGE_DIR . '/ticks');
|
||||||
define('DATA_DIR', STORAGE_DIR . '/db');
|
define('DATA_DIR', STORAGE_DIR . '/db');
|
||||||
define('DB_FILE', DATA_DIR . '/tkr.sqlite');
|
define('DB_FILE', DATA_DIR . '/tkr.sqlite');
|
||||||
|
|
||||||
// Defining this in the index instead of lib/util.php
|
// Load all classes from the src/ directory
|
||||||
// to avoid chicken-and-egg issues with including it
|
function loadClasses(): void {
|
||||||
function recursive_glob(string $pattern, string $directory): array {
|
|
||||||
$files = [];
|
|
||||||
$iterator = new RecursiveIteratorIterator(
|
$iterator = new RecursiveIteratorIterator(
|
||||||
new RecursiveDirectoryIterator($directory)
|
new RecursiveDirectoryIterator(SRC_DIR)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// load base classes first
|
||||||
|
require_once SRC_DIR . '/Controller/Controller.php';
|
||||||
|
|
||||||
|
// load everything else
|
||||||
foreach ($iterator as $file) {
|
foreach ($iterator as $file) {
|
||||||
if ($file->isFile() && fnmatch($pattern, $file->getFilename())) {
|
if ($file->isFile() && fnmatch('*.php', $file->getFilename())) {
|
||||||
$files[] = $file->getPathname();
|
require_once $file;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $files;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// load base classes first
|
loadClasses();
|
||||||
require_once SRC_DIR . '/Controller/Controller.php';
|
|
||||||
// load everything else
|
|
||||||
foreach (recursive_glob('*.php', SRC_DIR) as $file) {
|
|
||||||
require_once $file;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Everything's loaded. Now we can start ticking.
|
||||||
Util::confirm_setup();
|
Util::confirm_setup();
|
||||||
Session::start();
|
Session::start();
|
||||||
Session::generateCsrfToken();
|
Session::generateCsrfToken();
|
||||||
@ -47,7 +39,7 @@ $method = $_SERVER['REQUEST_METHOD'];
|
|||||||
$request = $_SERVER['REQUEST_URI'];
|
$request = $_SERVER['REQUEST_URI'];
|
||||||
$path = parse_url($request, PHP_URL_PATH);
|
$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)) {
|
if (preg_match('/\.php$/', $path)) {
|
||||||
http_response_code(404);
|
http_response_code(404);
|
||||||
echo '<h1>404 Not Found</h1>';
|
echo '<h1>404 Not Found</h1>';
|
||||||
@ -62,39 +54,41 @@ if (strpos($path, $config->basePath) === 0) {
|
|||||||
|
|
||||||
$path = trim($path, '/');
|
$path = trim($path, '/');
|
||||||
|
|
||||||
function route(string $pattern, string $controller, array $methods = ['GET']) {
|
// Main router function
|
||||||
global $path, $method;
|
function route(string $requestPath, string $requestMethod, array $routeHandlers): bool {
|
||||||
|
foreach ($routeHandlers as $routeHandler) {
|
||||||
|
$routePattern = $routeHandler[0];
|
||||||
|
$controller = $routeHandler[1];
|
||||||
|
$methods = $routeHandler[2] ?? ['GET'];
|
||||||
|
|
||||||
if (!in_array($method, $methods)) {
|
$routePattern = preg_replace('/\{([^}]+)\}/', '([^/]+)', $routePattern);
|
||||||
return false;
|
$routePattern = '#^' . $routePattern . '$#';
|
||||||
}
|
|
||||||
|
|
||||||
$pattern = preg_replace('/\{([^}]+)\}/', '([^/]+)', $pattern);
|
if (preg_match($routePattern, $requestPath, $matches)) {
|
||||||
$pattern = '#^' . $pattern . '$#';
|
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 (preg_match($pattern, $path, $matches)) {
|
if (strpos($controller, '@')) {
|
||||||
array_shift($matches);
|
[$controllerName, $methodName] = explode('@', $controller);
|
||||||
|
} else {
|
||||||
|
// Default to 'index' method if no method specified
|
||||||
|
$controllerName = $controller;
|
||||||
|
$methodName = 'index';
|
||||||
|
}
|
||||||
|
|
||||||
if (strpos($controller, '@') !== false) {
|
$instance = new $controllerName();
|
||||||
[$className, $methodName] = explode('@', $controller);
|
call_user_func_array([$instance, $methodName], $matches);
|
||||||
} else {
|
return true;
|
||||||
// Default to 'index' method if no method specified
|
}
|
||||||
$className = $controller;
|
|
||||||
$methodName = 'index';
|
|
||||||
}
|
}
|
||||||
$instance = new $className();
|
|
||||||
call_user_func_array([$instance, $methodName], $matches);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set content type
|
$routeHandlers = [
|
||||||
header('Content-Type: text/html; charset=utf-8');
|
|
||||||
|
|
||||||
// routes
|
|
||||||
$routes = [
|
|
||||||
['', 'HomeController'],
|
['', 'HomeController'],
|
||||||
['', 'HomeController@handleTick', ['POST']],
|
['', 'HomeController@handleTick', ['POST']],
|
||||||
['admin', 'AdminController'],
|
['admin', 'AdminController'],
|
||||||
@ -108,12 +102,12 @@ $routes = [
|
|||||||
['feed/atom', 'FeedController@atom'],
|
['feed/atom', 'FeedController@atom'],
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach ($routes as $routeConfig) {
|
// Set content type
|
||||||
$pattern = $routeConfig[0];
|
header('Content-Type: text/html; charset=utf-8');
|
||||||
$controller = $routeConfig[1];
|
|
||||||
$methods = $routeConfig[2] ?? ['GET'];
|
|
||||||
|
|
||||||
if (route($pattern, $controller, $methods)) {
|
// Render the requested route or throw a 404
|
||||||
break;
|
if (!route($path, $method, $routeHandlers)){
|
||||||
}
|
http_response_code(404);
|
||||||
};
|
echo "404 - Page Not Found";
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
@ -17,7 +17,7 @@ class AdminController extends Controller {
|
|||||||
|
|
||||||
// POST handler
|
// POST handler
|
||||||
// save updated settings
|
// save updated settings
|
||||||
public function save(){
|
public function handleSave(){
|
||||||
$isLoggedIn = isset($_SESSION['user_id']);
|
$isLoggedIn = isset($_SESSION['user_id']);
|
||||||
if (!$isLoggedIn){
|
if (!$isLoggedIn){
|
||||||
header('Location: ' . $config->basePath . 'login.php');
|
header('Location: ' . $config->basePath . 'login.php');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user