hanze/iwa-panda2

Lollipop/Router.php in main
Repositories | Summary | Log | Files | README.md

Router.php (3482B) download


  1<?php
  2
  3namespace Lollipop {
  4    const MIME_TYPES = array(
  5        "css" => "text/css",
  6        "js" => "text/javascript"
  7    );
  8
  9    /// this is the basic router, implementing an automatic templater
 10    class Router
 11    {
 12        protected array $routes = [];
 13        protected string $path;
 14        protected Template $temp;
 15
 16        public function __construct($temp)
 17        {
 18            $this->temp = $temp;
 19        }
 20
 21        /// set content-type header
 22        protected function set_mime($file)
 23        {
 24            if (!is_null($file)) {
 25                $ext = pathinfo($file, PATHINFO_EXTENSION);
 26            } else {
 27                $ext = null;
 28            }
 29
 30            if ($ext != null && array_key_exists($ext, MIME_TYPES)) {
 31                $mime = MIME_TYPES[$ext];
 32            } else {
 33                $mime = "text/html";
 34            }
 35
 36            header("Content-Type: $mime");
 37        }
 38
 39        protected function match(string $match, array &$route_vars): bool
 40        {
 41            $route_split = explode('/', trim($this->path, '/ '));
 42            $match_split = explode('/', trim($match, '/ '));
 43
 44            if (sizeof($route_split) != sizeof($match_split)) {
 45                return false;
 46            }
 47
 48            foreach ($match_split as $index => $m) {
 49                if (str_starts_with($m, ':')) {
 50                    $route_vars[substr($m, 1)] = $route_split[$index];
 51                } elseif ($m != $route_split[$index]) {
 52                    return false;
 53                }
 54            }
 55            return true;
 56        }
 57
 58        /// add route
 59        /// $func can be a path to an template or a function which returns the path to an template and modifies $vars
 60        public function addRoute(string|array $method, string $match, string|callable $func)
 61        {
 62            if (is_string($method)) {
 63                $method = [$method];
 64            }
 65
 66            $this->routes[] = array(
 67                "method" => $method,
 68                "match" => $match,
 69                "func" => $func,
 70            );
 71        }
 72
 73        /// final routing
 74        public function route(string $base = null)
 75        {
 76            $this->path = $_SERVER["REQUEST_URI"];
 77
 78            if (strpos($this->path, '?')) {
 79                $this->path = explode('?', $this->path)[0];
 80            }
 81
 82            if ($base && strpos($this->path, $base)) {
 83                $this->path = explode($base, $this->path)[1];
 84            }
 85
 86            $method = $_SERVER["REQUEST_METHOD"];
 87
 88            foreach ($this->routes as $route) {
 89                if ($route["method"] != null && !in_array($method, $route["method"])) {
 90                    continue;
 91                }
 92
 93                $vars = [];
 94                if ($this->match($route["match"], $vars)) {
 95                    if (is_callable($route["func"])) {
 96                        $fil = $route["func"]($vars);
 97                        if (is_null($fil)) {
 98                            return;
 99                        }
100                        $this->set_mime($fil);
101                        echo $this->temp->template($fil, $vars);
102                        return;
103                    } else {
104                        $this->set_mime($route["func"]);
105                        echo $this->temp->template($route["func"], $vars);
106                        return;
107                    }
108                }
109            }
110            http_response_code(401);
111            return header("Location: /");
112        }
113    }
114}