128 lines
2.5 KiB
PHP
128 lines
2.5 KiB
PHP
|
<?php /* Copyright (c) 2024 Freya Murphy */
|
||
|
class Router {
|
||
|
|
||
|
private $main;
|
||
|
private $load;
|
||
|
private $routes;
|
||
|
|
||
|
function load_route($route) {
|
||
|
$name = $route['name'];
|
||
|
$controller_cls = $route['controller'];
|
||
|
$model_cls = $route['model'];
|
||
|
|
||
|
$root = $GLOBALS['webroot'];
|
||
|
$dir = $root . '/routes/' . $name;
|
||
|
require($dir . '/model.php');
|
||
|
require($dir . '/controller.php');
|
||
|
|
||
|
$model_ref = new ReflectionClass($model_cls);
|
||
|
$model = $model_ref->newInstance();
|
||
|
|
||
|
$controller_ref = new ReflectionClass($controller_cls);
|
||
|
$controller = $controller_ref->newInstance($model);
|
||
|
|
||
|
return $controller;
|
||
|
}
|
||
|
|
||
|
function __construct($main, $load) {
|
||
|
|
||
|
$routes = array(
|
||
|
'home' => array(
|
||
|
'slugs' => ['', 'home'],
|
||
|
'model' => 'HomeModel',
|
||
|
'controller' => 'HomeController',
|
||
|
),
|
||
|
);
|
||
|
|
||
|
$this->routes = array();
|
||
|
foreach ($routes as $name => $route) {
|
||
|
foreach ($route['slugs'] as $slug) {
|
||
|
$this->routes[$slug] = $route;
|
||
|
$this->routes[$slug]['name'] = $name;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
$this->main = $main;
|
||
|
$this->load = $load;
|
||
|
}
|
||
|
|
||
|
function get_info() {
|
||
|
$uri = parse_url($_SERVER['REQUEST_URI']);
|
||
|
$method = $_SERVER['REQUEST_METHOD'];
|
||
|
$parts = explode('/', $uri['path']);
|
||
|
|
||
|
$slug = sizeof($parts) > 1 ? $parts[1] : '';
|
||
|
$path = sizeof($parts) > 2 ? $parts[2] : 'index';
|
||
|
|
||
|
if (sizeof($parts) > 3) {
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
return array(
|
||
|
'method' => $method,
|
||
|
'uri' => $uri,
|
||
|
|
||
|
'slug' => $slug,
|
||
|
'path' => $path
|
||
|
);
|
||
|
}
|
||
|
|
||
|
function handle_error($code) {
|
||
|
$route = array(
|
||
|
'name' => 'error',
|
||
|
'model' => 'ErrorModel',
|
||
|
'controller' => 'ErrorController'
|
||
|
);
|
||
|
$this->main->info = array(
|
||
|
'slug' => 'error',
|
||
|
'lang' => 'en_US',
|
||
|
'route' => 'error'
|
||
|
);
|
||
|
$controller = $this->load_route($route);
|
||
|
$_GET['code'] = $code;
|
||
|
http_response_code($code);
|
||
|
$controller->index();
|
||
|
}
|
||
|
|
||
|
public function handle_request() {
|
||
|
$request = $this->get_info();
|
||
|
|
||
|
if ($request === NULL) {
|
||
|
$this->handle_error(404);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
$slug = $request['slug'];
|
||
|
if (!array_key_exists($slug, $this->routes)) {
|
||
|
$this->handle_error(404);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
$route = $this->routes[$slug];
|
||
|
$this->main->info = array(
|
||
|
'lang' => 'en_US',
|
||
|
'slug' => $slug,
|
||
|
'route' => $route['name'],
|
||
|
);
|
||
|
|
||
|
$controller = $this->load_route($route);
|
||
|
|
||
|
$path = $request['path'];
|
||
|
$ref = NULL;
|
||
|
|
||
|
try {
|
||
|
$ref = new ReflectionMethod($controller, $path);
|
||
|
} catch (Exception $_e) {}
|
||
|
|
||
|
if ($ref === NULL || !$ref->isPublic()) {
|
||
|
$this->handle_error(404);
|
||
|
return;
|
||
|
|
||
|
}
|
||
|
|
||
|
$ref->invoke($controller);
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|