241 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			241 lines
		
	
	
		
			5.8 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 = is_countable($_SERVER['REQUEST_URI']) && count($_SERVER['REQUEST_URI']) > 1 ? rtrim($_SERVER['REQUEST_URI'], "/") : $_SERVER['REQUEST_URI'];
 | 
						|
        $this->uri = str_replace($pathname, "", $this->uri);
 | 
						|
        $this->requestType = $_SERVER['REQUEST_METHOD'];
 | 
						|
        $this->routes = [];
 | 
						|
        $this->middleware = [];
 | 
						|
 | 
						|
        if (isset($_SERVER)) {
 | 
						|
            $this->request = $_SERVER;
 | 
						|
        }
 | 
						|
        if (isset($_POST)) {
 | 
						|
            $this->request["body"] = $_POST;
 | 
						|
        }
 | 
						|
        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 {
 | 
						|
            echo "404";
 | 
						|
        }
 | 
						|
    }
 | 
						|
} |