iwa-panda2

Manage Weather Data by International Weather Agency (Version 2)
Log | Files | Refs | README

Router.php (3482B)


      1 <?php
      2 
      3 namespace 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 }