dragon-forks/kernel/router.php
2025-03-29 10:25:21 +01:00

88 lines
No EOL
2.7 KiB
PHP

<?php
/**
* Route the page to a controller.
* Use the following syntax /{{namespace}}/{{controller}}/{{function}}
*
* TODO: handle non-get request
*/
class Router {
public $namespace;
public $controller;
public $func;
public $characterId = -1;
private $namespaces = [];
private $currentNamespaceHandler;
// List of forbidden route, to avoid calling private or other REST verbs
private $forbiddenRoutes = [ '__', '_post', '_delete', '_put', '_patch'];
public function registerNamespace($name, $authLevel, $haveCharacterId) {
$this->namespaces[$name] = new NamespaceHandler($name, $authLevel, $haveCharacterId);
}
public function loadController() {
global $renderer;
$this->parseUrl();
if (!$this->currentNamespaceHandler->canShow()) {
$renderer->error(403);
}
$controllerFile = $this->getControllerPath();
require_once $controllerFile;
$func = $this->func;
if (isset($_POST["submit"])) {
$func = $func."_post";
}
if (is_callable($func)) {
call_user_func($func);
} else {
$renderer->error(404);
}
}
private function getFromUrl($requestParts, $index, $default) {
return (isset($requestParts[$index]) && $requestParts[$index] != null) ? $requestParts[$index] : $default;
}
private function parseUrl() {
global $renderer;
$requestUri = trim($_SERVER['REQUEST_URI'], '/');
$requestParts = explode('/', $requestUri);
$this->namespace = $this->getFromUrl($requestParts, 0, 'site');
if (!isset($this->namespaces[$this->namespace])) {
$renderer->error(404);
}
$this->currentNamespaceHandler = $this->namespaces[$this->namespace];
if ($this->currentNamespaceHandler->haveCharacterId) {
$this->characterId = $this->getFromUrl($requestParts, 1, -1);
$this->controller = $this->getFromUrl($requestParts, 2, "pages");
$this->func = $this->getFromUrl($requestParts, 3, "index");
} else {
$this->controller = $this->getFromUrl($requestParts, 1, "pages");
$this->func = $this->getFromUrl($requestParts, 2, "index");
}
foreach ($this->forbiddenRoutes as $forbiddenRoute) {
if (str_contains($this->func, $forbiddenRoute)) {
$renderer->error(500);
}
}
}
private function getControllerPath() {
global $renderer;
$controllerPath = PATH_ROOT . "controllers/{$this->namespace}/{$this->controller}.php";
if (!file_exists($controllerPath)) {
$renderer->error(404);
}
return $controllerPath;
}
}