✨ Add a basic router system
This commit is contained in:
parent
4f88b8f6c2
commit
5c9d1e4d58
10 changed files with 251 additions and 3 deletions
21
controllers/site/pages.php
Normal file
21
controllers/site/pages.php
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
function index() {
|
||||
global $renderer;
|
||||
// Prepare data for the view
|
||||
$renderer->prepare('title', 'Home Page');
|
||||
$renderer->prepare('content', 'Welcome to the home page!');
|
||||
|
||||
// Display the view using the namespace
|
||||
$renderer->display('home');
|
||||
}
|
||||
|
||||
function closed() {
|
||||
global $renderer;
|
||||
// Prepare data for the view
|
||||
$renderer->prepare('title', 'Game closed');
|
||||
$renderer->prepare('content', 'The game is currently closed for maintanence. Please check back later.');
|
||||
|
||||
// Display the view using the namespace
|
||||
$renderer->display('home');
|
||||
}
|
|
@ -24,10 +24,10 @@ define('DS', DIRECTORY_SEPARATOR);
|
|||
|
||||
// PHP paths for init
|
||||
define('PATH_ROOT', __DIR__.DS);
|
||||
define('PATH_BOOT', PATH_ROOT.'kernel'.DS.'boot'.DS);
|
||||
define('PATH_KERNEL', PATH_ROOT.'kernel'.DS);
|
||||
|
||||
// Init
|
||||
require(PATH_BOOT.'init.php');
|
||||
require(PATH_BOOT.'site.php');
|
||||
require(PATH_KERNEL.'init.php');
|
||||
require(PATH_KERNEL.'core.php');
|
||||
|
||||
?>
|
11
kernel/core.php
Normal file
11
kernel/core.php
Normal file
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
|
||||
$router = new Router();
|
||||
$renderer = new Renderer();
|
||||
|
||||
// Register namespaces with their required authorization levels
|
||||
$router->registerNamespace('admin', 2, false); // Admin namespace requires level 2
|
||||
$router->registerNamespace('user', 1, false); // User namespace requires level 1
|
||||
$router->registerNamespace('site', 0, false); // Site namespace requires level 0
|
||||
|
||||
$router->loadController();
|
38
kernel/init.php
Normal file
38
kernel/init.php
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?php // The initialisation of the kernel of dragon-fork
|
||||
|
||||
// Dragon Fork version
|
||||
define('DRAGONFORK_VERSION', '0.0.1');
|
||||
define('DRAGONFORK_CODENAME', '');
|
||||
define('DRAGONFORK_RELEASE_DATE', '2024-08-23');
|
||||
define('DRAGONFORK_BUILD', '20240806');
|
||||
|
||||
// Change to TRUE for debugging
|
||||
define('DEBUG_MODE', TRUE);
|
||||
define('DEBUG_TYPE', 'INFO'); // INFO, TRACE
|
||||
|
||||
// This determines whether errors should be printed to the screen as part of the output or if they should be hidden from the user.
|
||||
ini_set("display_errors", 0);
|
||||
|
||||
// Even when display_errors is on, errors that occur during PHP's startup sequence are not displayed.
|
||||
// It's strongly recommended to keep display_startup_errors off, except for debugging.
|
||||
ini_set('display_startup_errors', 0);
|
||||
|
||||
// If disabled, error message will be solely plain text instead HTML code.
|
||||
ini_set("html_errors", 0);
|
||||
|
||||
// Tells whether script error messages should be logged to the server's error log or error_log.
|
||||
ini_set('log_errors', 1);
|
||||
|
||||
if (DEBUG_MODE) {
|
||||
error_reporting(E_ERROR | E_WARNING | E_PARSE | E_NOTICE);
|
||||
} else {
|
||||
error_reporting(E_ERROR);
|
||||
}
|
||||
|
||||
include(PATH_KERNEL . 'lib.php');
|
||||
include(PATH_KERNEL . 'cookies.php');
|
||||
include(PATH_KERNEL . 'renderer.php');
|
||||
include(PATH_KERNEL . 'namespace.php');
|
||||
include(PATH_KERNEL . 'router.php');
|
||||
|
||||
$link = opendb();
|
30
kernel/namespace.php
Normal file
30
kernel/namespace.php
Normal file
|
@ -0,0 +1,30 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Handle one of the game namespace
|
||||
*
|
||||
* The game namespace allow us to compartimentate the game
|
||||
* into several domain, each with their own level of authentification
|
||||
* - The "site" domain will be available to non-authentified users
|
||||
* - The "game" domain will be available to authentified, non-banned users
|
||||
* - The "user" domain will be available to authentified, non-banned users
|
||||
* - The "admin" domain will be available to admins
|
||||
*
|
||||
* This allow to more simply handle authorisation
|
||||
*/
|
||||
class NamespaceHandler {
|
||||
private $name;
|
||||
private $authLevel;
|
||||
public $haveCharacterId;
|
||||
|
||||
public function __construct($name, $authLevel, $haveCharacterId) {
|
||||
$this->name = $name;
|
||||
$this->authLevel = $authLevel;
|
||||
$this->haveCharacterId = $haveCharacterId;
|
||||
}
|
||||
|
||||
public function canShow() {
|
||||
// FIXME: handle auth level correctly
|
||||
return $this->authLevel < 1000;
|
||||
}
|
||||
}
|
38
kernel/renderer.php
Normal file
38
kernel/renderer.php
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Basic wrapper around twig
|
||||
*/
|
||||
class Renderer {
|
||||
private $twig;
|
||||
private $data = [];
|
||||
|
||||
public function __construct() {
|
||||
$loader = new \Twig\Loader\FilesystemLoader(PATH_ROOT . '/theme/default/');
|
||||
$this->twig = new \Twig\Environment($loader);
|
||||
}
|
||||
|
||||
public function prepare($key, $value) {
|
||||
$this->data[$key] = $value;
|
||||
}
|
||||
|
||||
public function display($template) {
|
||||
global $router;
|
||||
try {
|
||||
echo $this->twig->render("{$router->namespace}/{$template}.twig", $this->data);
|
||||
die();
|
||||
} catch (\Twig\Error\LoaderError $e) {
|
||||
$this->error(500);
|
||||
}
|
||||
}
|
||||
|
||||
public function error($errorCode) {
|
||||
$errorTemplate = PATH_ROOT . "/theme/default/error/{$errorCode}.twig";
|
||||
if (file_exists($errorTemplate)) {
|
||||
echo $this->twig->render("error/{$errorCode}.twig");
|
||||
} else {
|
||||
echo $this->twig->render("error/generic.twig");
|
||||
}
|
||||
die();
|
||||
}
|
||||
}
|
74
kernel/router.php
Normal file
74
kernel/router.php
Normal file
|
@ -0,0 +1,74 @@
|
|||
<?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;
|
||||
|
||||
|
||||
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;
|
||||
|
||||
if (is_callable($this->func)) {
|
||||
call_user_func($this->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");
|
||||
}
|
||||
}
|
||||
|
||||
private function getControllerPath() {
|
||||
global $renderer;
|
||||
$controllerPath = PATH_ROOT . "controllers/{$this->namespace}/{$this->controller}.php";
|
||||
if (!file_exists($controllerPath)) {
|
||||
$renderer->error(404);
|
||||
}
|
||||
return $controllerPath;
|
||||
}
|
||||
}
|
12
theme/default/error/404.twig
Normal file
12
theme/default/error/404.twig
Normal file
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>404 Not Found</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>404 Not Found</h1>
|
||||
<p>The page you are looking for does not exist.</p>
|
||||
</body>
|
||||
</html>
|
12
theme/default/error/generic.twig
Normal file
12
theme/default/error/generic.twig
Normal file
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Error</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Error</h1>
|
||||
<p>I am error.</p>
|
||||
</body>
|
||||
</html>
|
12
theme/default/site/home.twig
Normal file
12
theme/default/site/home.twig
Normal file
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{{ title }}</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>{{ title }}</h1>
|
||||
<p>{{ content }}</p>
|
||||
</body>
|
||||
</html>
|
Loading…
Add table
Reference in a new issue