147 lines
2.8 KiB
PHP
147 lines
2.8 KiB
PHP
<?php /* Copyright (c) 2024 Freya Murphy */
|
|
class Router {
|
|
|
|
// the loader
|
|
private $load;
|
|
|
|
// the main model
|
|
private $main;
|
|
|
|
/**
|
|
* Creates a router
|
|
* @param Loader $load - the main laoder object
|
|
*/
|
|
function __construct($load) {
|
|
$this->load = $load;
|
|
$this->main = $this->load->model('main');
|
|
}
|
|
|
|
/**
|
|
* @param string $path - the current request path
|
|
* Gets the current route
|
|
* @return array<string,mixed>
|
|
*/
|
|
private function get_req_route($path): array {
|
|
// trim the path
|
|
$path = trim($path);
|
|
// remove first '/'
|
|
$path = substr($path, 1);
|
|
// get path parts
|
|
$parts = explode('/', $path);
|
|
|
|
$len = count($parts);
|
|
|
|
// get route info
|
|
$route = array();
|
|
// e.g. /
|
|
if ($path === '') {
|
|
$route = array(
|
|
'route' => '',
|
|
'slug' => 'index',
|
|
);
|
|
// e.g. /home /login
|
|
} else if ($len === 1) {
|
|
$route = array(
|
|
'route' => $parts[0],
|
|
'slug' => 'index',
|
|
);
|
|
// e.g. /home/posts
|
|
} else {
|
|
$route = array (
|
|
'route' => implode('/', array_slice($parts, 0, -1)),
|
|
'slug' => end($parts)
|
|
);
|
|
};
|
|
|
|
$route['app'] = $route['route'];
|
|
$routes = $GLOBALS['routes'];
|
|
if (array_key_exists($route['route'], $routes)) {
|
|
$route['route'] = $routes[$route['route']];
|
|
}
|
|
|
|
return $route;
|
|
}
|
|
|
|
/**
|
|
* Gets the curret request info
|
|
* @return array<string,mixed>
|
|
*/
|
|
private function get_req(): array {
|
|
$method = $_SERVER['REQUEST_METHOD'];
|
|
|
|
$uri = parse_url($_SERVER['REQUEST_URI']);
|
|
$path = $uri['path'];
|
|
|
|
return array_merge(
|
|
array(
|
|
'uri' => $uri,
|
|
'method' => $method,
|
|
'lang' => $this->get_lang(),
|
|
),
|
|
$this->get_req_route($path),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Gets the current language
|
|
* @return string
|
|
*/
|
|
private function get_lang(): string {
|
|
return 'en_US';
|
|
}
|
|
|
|
/**
|
|
* Handles a router error code
|
|
* @param int $code - the http error code
|
|
* @param bool $recursed
|
|
*/
|
|
private function handle_error($code, $recursed): void {
|
|
if ($recursed) {
|
|
die($code . ' (recursed)');
|
|
}
|
|
|
|
$this->main->info['slug'] = 'index';
|
|
$this->main->info['app'] = 'error';
|
|
$this->main->info['route'] = 'apps/error';
|
|
$req = $this->main->info;
|
|
$_GET['code'] = $code;
|
|
|
|
$this->handle_req($req, TRUE);
|
|
}
|
|
|
|
/**
|
|
* @param array $req
|
|
* @param bool $recursed
|
|
*/
|
|
private function handle_req($req, $recursed = FALSE): void {
|
|
$controller = $this->load->controller($req['route']);
|
|
|
|
if ($controller === NULL) {
|
|
$this->handle_error(404, $recursed);
|
|
return;
|
|
}
|
|
|
|
$ref = NULL;
|
|
try {
|
|
$ref = new ReflectionMethod($controller, $req['slug']);
|
|
} catch (Exception $_e) {}
|
|
|
|
if ($ref === NULL || !$ref->isPublic()) {
|
|
$this->handle_error(404, $recursed);
|
|
return;
|
|
|
|
}
|
|
|
|
$ref->invoke($controller);
|
|
}
|
|
|
|
/**
|
|
* Handels the incomming reuqest
|
|
*/
|
|
public function handle_request(): void {
|
|
$req = $this->get_req();
|
|
$this->main->info = $req;
|
|
$this->handle_req($req);
|
|
}
|
|
|
|
}
|