xssbook2/web/core/router.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);
}
}