242 lines
5.9 KiB
PHP
242 lines
5.9 KiB
PHP
<?php namespace Router;
|
|
|
|
require_once("Response.php");
|
|
require_once("Route.php");
|
|
|
|
class Router
|
|
{
|
|
private string $uri;
|
|
private string $requestType;
|
|
|
|
private array $routes;
|
|
private array $middleware;
|
|
|
|
private array $request;
|
|
private Response $response;
|
|
|
|
/**
|
|
* Router
|
|
* @author Johannes Kantz
|
|
*/
|
|
public function __construct(string $pathname)
|
|
{
|
|
$this->uri = str_replace($pathname, "", $_SERVER['REQUEST_URI']);
|
|
$this->uri = strlen($this->uri) > 1 ? rtrim($this->uri, "/") : $this->uri;
|
|
|
|
$this->requestType = $_SERVER['REQUEST_METHOD'];
|
|
$this->routes = [];
|
|
$this->middleware = [];
|
|
|
|
if (isset($_SERVER)) {
|
|
$this->request = $_SERVER;
|
|
}
|
|
if (isset($_POST)) {
|
|
$this->request["body"] = json_decode(file_get_contents('php://input'), true);
|
|
}
|
|
if (isset($_POST)) {
|
|
$this->request["params"] = $_GET;
|
|
}
|
|
|
|
$this->response = new Response();
|
|
}
|
|
|
|
|
|
/**
|
|
* Use Middleware
|
|
* @param string $uri
|
|
* @param $middleware
|
|
* @return void
|
|
* @author Johannes Kantz
|
|
*/
|
|
public function use(string $uri, callable $middleware): void
|
|
{
|
|
$this->middleware[$uri] = $middleware;
|
|
}
|
|
|
|
/**
|
|
* get Middleware for uri
|
|
* @param string $uri
|
|
* @return array
|
|
* @author Johannes Kantz
|
|
*/
|
|
private function getMiddleware(): array
|
|
{
|
|
$middleware = [];
|
|
foreach ($this->middleware as $key => $value) {
|
|
if (str_starts_with($this->uri, $key)) {
|
|
$middleware[] = $value;
|
|
}
|
|
}
|
|
return $middleware;
|
|
}
|
|
|
|
/**
|
|
* Calls the middleware
|
|
* @param array $middleware
|
|
* @return void
|
|
* @author Johannes Kantz
|
|
*/
|
|
private function callMiddleware(array $middleware): void
|
|
{
|
|
foreach ($middleware as $m) {
|
|
$m($this->request, $this->response);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* GET Method
|
|
* @param string $uri
|
|
* @param $controller
|
|
* @return void
|
|
* @author Johannes Kantz
|
|
*/
|
|
public function get(string $uri, callable $controller): void
|
|
{
|
|
$this->routes[$uri] = new Route("GET", $controller);
|
|
}
|
|
|
|
/**
|
|
* POST Method
|
|
* @param string $uri
|
|
* @param $controller
|
|
* @return void
|
|
* @author Johannes Kantz
|
|
*/
|
|
public function post(string $uri, callable $controller): void
|
|
{
|
|
$this->routes[$uri] = new Route("POST", $controller);
|
|
}
|
|
|
|
/**
|
|
* PUT Method
|
|
* @param string $uri
|
|
* @param $controller
|
|
* @return void
|
|
* @author Johannes Kantz
|
|
*/
|
|
public function put(string $uri, callable $controller): void
|
|
{
|
|
$this->routes[$uri] = new Route("PUT", $controller);
|
|
}
|
|
|
|
/**
|
|
* DELETE Method
|
|
* @param string $uri
|
|
* @param $controller
|
|
* @return void
|
|
* @author Johannes Kantz
|
|
*/
|
|
public function delete(string $uri, callable $controller): void
|
|
{
|
|
$this->routes[$uri] = new Route("DELETE", $controller);
|
|
}
|
|
|
|
/**
|
|
* ALL Method
|
|
* @param string $uri
|
|
* @param $controller
|
|
* @return void
|
|
* @author Johannes Kantz
|
|
*/
|
|
public function all(string $uri, callable $controller): void
|
|
{
|
|
$this->routes[$uri] = new Route("ALL", $controller);
|
|
}
|
|
|
|
/**
|
|
* Route
|
|
* @param string $uri
|
|
* @return void
|
|
* @author Johannes Kantz
|
|
*/
|
|
public function route(string $uri): Route
|
|
{
|
|
$this->routes[$uri] = new Route($uri);
|
|
return $this->routes[$uri];
|
|
}
|
|
|
|
/**
|
|
* Checks if the given uri matches the given route
|
|
* @param string $uri
|
|
* @param array $params
|
|
* @return string
|
|
* @author Johannes Kantz
|
|
*/
|
|
private function routeMatches(string $route, string $uri): bool
|
|
{
|
|
$routeParts = explode("/", $route);
|
|
$uriParts = explode("/", $uri);
|
|
|
|
if (count($routeParts) !== count($uriParts)) {
|
|
return false;
|
|
}
|
|
foreach ($routeParts as $key => $part) {
|
|
if (str_starts_with($part, ":")) {
|
|
continue;
|
|
}
|
|
if ($part !== $uriParts[$key]) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Returns the params of the given uri
|
|
* given that the uri matches the given route
|
|
* @param string $uri
|
|
* @param array $params
|
|
* @return array
|
|
* @author Johannes Kantz
|
|
*/
|
|
private function getParams(string $route, string $uri): array
|
|
{
|
|
$routeParts = explode("/", $route);
|
|
$uriParts = explode("/", $uri);
|
|
|
|
$params = [];
|
|
foreach ($routeParts as $key => $part) {
|
|
if (str_starts_with($part, ":")) {
|
|
$params[ltrim($part, ":")] = $uriParts[$key];
|
|
}
|
|
}
|
|
return $params;
|
|
}
|
|
|
|
/**
|
|
* gets the controller for the given uri
|
|
* @param array $routes
|
|
* @author Johannes Kantz
|
|
*/
|
|
private function getController(): callable|bool
|
|
{
|
|
foreach ($this->routes as $uri => $route) {
|
|
if ($this->uri === $uri) {
|
|
return $route->getController($this->requestType) ?? false;
|
|
}
|
|
if ($this->routeMatches($uri, $this->uri)) {
|
|
$this->request["params"] = $this->getParams($uri, $this->uri);
|
|
return $route->getController($this->requestType) ?? false;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Starts the router
|
|
* @return void
|
|
* @author Johannes Kantz
|
|
*/
|
|
public function start(): void
|
|
{
|
|
$middleware = $this->getMiddleware();
|
|
$this->callMiddleware($middleware);
|
|
|
|
$controller = $this->getController();
|
|
if ($controller) {
|
|
$controller($this->request, $this->response);
|
|
} else {
|
|
$this->response->json(["status" => "404", "message" => "Not found"], 404);
|
|
}
|
|
}
|
|
} |