2023-03-21 20:41:02 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace WillySoft;
|
|
|
|
|
2024-11-13 17:11:32 +00:00
|
|
|
use Exception;
|
|
|
|
|
2023-03-21 20:41:02 +00:00
|
|
|
abstract class Route
|
|
|
|
{
|
2023-03-21 20:51:12 +00:00
|
|
|
static $prefix = '';
|
|
|
|
static $groups = [[]];
|
2023-03-21 20:41:02 +00:00
|
|
|
|
2024-11-13 17:11:32 +00:00
|
|
|
static function match(string $methods, string $url_path, callable $callback)
|
2023-03-21 20:51:12 +00:00
|
|
|
{
|
2024-11-13 17:11:32 +00:00
|
|
|
if (!in_array(
|
|
|
|
$_SERVER['REQUEST_METHOD'],
|
|
|
|
array_map(strtoupper(...), explode('|', $methods))
|
|
|
|
)) return;
|
2023-03-21 20:41:02 +00:00
|
|
|
|
2024-11-13 17:11:32 +00:00
|
|
|
$request_url_path_parts = explode('/', urldecode(
|
2023-03-21 20:51:12 +00:00
|
|
|
strtok($_SERVER['REQUEST_URI'], '?')
|
|
|
|
));
|
2024-11-13 17:11:32 +00:00
|
|
|
$url_path_parts = explode('/', self::$prefix . $url_path);
|
2023-03-21 20:51:12 +00:00
|
|
|
$callback_args = [];
|
2024-11-13 17:11:32 +00:00
|
|
|
for ($i = 1; $i < count($url_path_parts); $i++) {
|
2024-11-13 20:28:28 +00:00
|
|
|
if ($url_path_parts[$i] === '')
|
|
|
|
continue;
|
2024-11-13 17:11:32 +00:00
|
|
|
if ($url_path_parts[$i][0] !== '$')
|
2023-03-21 20:51:12 +00:00
|
|
|
continue;
|
2024-11-13 17:11:32 +00:00
|
|
|
if (!isset($request_url_path_parts[$i]))
|
2023-03-21 20:51:12 +00:00
|
|
|
return;
|
2024-11-13 17:11:32 +00:00
|
|
|
|
|
|
|
if ($url_path_parts[$i][-1] !== '?'
|
|
|
|
&& $request_url_path_parts[$i] === ''
|
2023-03-21 20:51:12 +00:00
|
|
|
) return;
|
2024-11-13 17:11:32 +00:00
|
|
|
if ($url_path_parts[$i][-1] === '?'
|
|
|
|
&& $i !== (count($url_path_parts) - 1)
|
|
|
|
) throw new Exception(
|
|
|
|
'Only the last route parameter is allowed to be optional.'
|
|
|
|
);
|
|
|
|
|
|
|
|
if ($request_url_path_parts[$i] !== '')
|
|
|
|
array_push(
|
|
|
|
$callback_args,
|
|
|
|
htmlspecialchars($request_url_path_parts[$i])
|
|
|
|
);
|
|
|
|
|
|
|
|
$request_url_path_parts[$i] = $url_path_parts[$i];
|
2023-03-21 20:51:12 +00:00
|
|
|
}
|
|
|
|
if (
|
2024-11-13 17:11:32 +00:00
|
|
|
implode('/', $url_path_parts)
|
|
|
|
!== implode('/', $request_url_path_parts)
|
2023-03-21 20:51:12 +00:00
|
|
|
) return;
|
2023-03-21 20:41:02 +00:00
|
|
|
|
2023-03-21 20:51:12 +00:00
|
|
|
foreach (self::$groups as $middlewares) {
|
|
|
|
foreach ($middlewares as $middleware) {
|
|
|
|
$middleware();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$callback(...$callback_args);
|
|
|
|
die();
|
|
|
|
}
|
2023-03-21 20:41:02 +00:00
|
|
|
|
2024-11-13 17:11:32 +00:00
|
|
|
static function get(string $url_path, callable $callback)
|
|
|
|
{self::match('get', $url_path, $callback);}
|
|
|
|
static function post(string $url_path, callable $callback)
|
|
|
|
{self::match('post', $url_path, $callback);}
|
|
|
|
static function put(string $url_path, callable $callback)
|
|
|
|
{self::match('put', $url_path, $callback);}
|
|
|
|
static function patch(string $url_path, callable $callback)
|
|
|
|
{self::match('patch', $url_path, $callback);}
|
|
|
|
static function delete(string $url_path, callable $callback)
|
|
|
|
{self::match('delete', $url_path, $callback);}
|
|
|
|
static function options(string $url_path, callable $callback)
|
|
|
|
{self::match('options', $url_path, $callback);}
|
|
|
|
static function form(string $url_path, callable $callback)
|
|
|
|
{self::match('get|post', $url_path, $callback);}
|
|
|
|
static function any(string $url_path, callable $callback)
|
|
|
|
{self::match('get|post|put|patch|delete|options', $url_path, $callback);}
|
2023-03-21 20:41:02 +00:00
|
|
|
|
2023-03-21 20:51:12 +00:00
|
|
|
static function use(callable $middleware)
|
|
|
|
{
|
|
|
|
array_push(
|
|
|
|
self::$groups[array_key_last(self::$groups)],
|
|
|
|
$middleware
|
|
|
|
);
|
|
|
|
}
|
2023-03-21 20:41:02 +00:00
|
|
|
|
2023-03-21 20:55:36 +00:00
|
|
|
static function group(string $prefix, callable $callback)
|
2023-03-21 20:51:12 +00:00
|
|
|
{
|
|
|
|
if (!str_starts_with(
|
|
|
|
$_SERVER['REQUEST_URI'],
|
|
|
|
self::$prefix . $prefix
|
|
|
|
)) return;
|
|
|
|
self::$prefix = self::$prefix . $prefix;
|
|
|
|
array_push(self::$groups, []);
|
|
|
|
$callback();
|
|
|
|
array_pop(self::$groups);
|
|
|
|
self::$prefix = rtrim(self::$prefix, $prefix);
|
|
|
|
}
|
2023-03-21 20:41:02 +00:00
|
|
|
}
|