aboutsummaryrefslogtreecommitdiff
path: root/Psso/Router.php
blob: db1f851e69609104c476dfd2efbd4c111925da50 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
<?php
namespace Psso;

class Router {
    private array $config;
    private string $routesDir;
    private array $statusHandlers = [];
    private \Closure $exceptionHandler;

    function __construct(string $routesDir, array $config) {
        $this->routesDir = $routesDir;
        $this->config = $config;
    }

    function registerStatusHandler(int $status, callable $handler) {
        $this->statusHandlers[$status] = $handler;
    }

    function setExceptionHandler(callable $handler) {
        $this->exceptionHandler = \Closure::fromCallable($handler);
    }

    private function dealWithError(int $status, string $path) {
        http_response_code($status);
        if (isset($this->statusHandlers[$status])) {
            $this->statusHandlers[$status]($path);
        } else {
            echo '<p>' . $status . ' for ' . htmlspecialchars($path) . '</p>';
        }
    }

    private function dealWithException(\Throwable $e) {
        http_response_code(500);
        if (isset($this->exceptionHandler)) {
            ($this->exceptionHandler)($e);
        } else {
            echo '<p>Internal Server Error</p>';
        }
    }

    function dispatch(string $path) {
        if (str_contains($path, '..')) {
            $this->dealWithError(404, $path);
            return;
        }

        if (file_exists($this->routesDir . $path . '.php')) {
            require_once $this->routesDir . $path . '.php';
        } elseif (file_exists($this->routesDir . $path . 'index.php')) {
            require_once $this->routesDir . $path . 'index.php';
        } else {
            $this->dealWithError(404, $path);
            return;
        }

        if (function_exists($_SERVER['REQUEST_METHOD'])) {
            try {
                $_SERVER['REQUEST_METHOD']($this->config);
            } catch (\Exception|\Error $e) {
                $this->dealWithException($e);
            }
        } else {
            $this->dealWithError(405, $path);
        }
    }
}