split("/") as $value) { $matched = $value->match("/^(.*?)\{(.+?)\}(.*?)$/"); if($first){ $first = false; continue; }; if($matched === false) { $regex[] = "\/" . preg_quote($value); }else{ $magic = true; $symbol = tstring::from($matched[2]); if($symbol->endsWith("?")) { $symbol = $symbol->slice(0,-1); $pattern = "([^\/^?]+?)?"; }else{ $pattern = "([^\/^?]+?)"; } $regex[] = "\/". $matched[1] . $pattern . $matched[3]; $names[] = $symbol; } } return [ "/^" . implode('', $regex) . "$/", $names, $magic ]; }; function validateMagicRoute($mroute, $path) { if(is_string($mroute)) { list($regex, $names) = magicRoute($mroute); }else{ list($regex, $names) = $mroute; } $matches = tstring::from($path)->match($regex); if($matches !== false) { array_shift($matches); $matcher = new stdClass; $index = 0; foreach ($matches as $value) { $matcher->{ $names[$index]->raw() } = $matches[ $index ]; $index++; }; return $matcher; }else{ return false; } }; class Route { public static $routes = []; public static $publics = []; public static $current = null; public static function post($path, $callback) { $magic = magicRoute($path); $textPath = false; $type = "text"; if($magic[2] == true) { $type = "magic"; $textPath = $magic; }else{ $textPath = $path; } $route = Route::from([ "type" => $type, "path" => $path, "callback" => $callback, "method" => "post" ]); Route::$routes[] = $route; return $route; } public static function get($path, $callback) { $magic = magicRoute($path); $textPath = false; $type = "text"; if($magic[2] == true) { $type = "magic"; $textPath = $magic; }else{ $textPath = $path; } $route = Route::from([ "type" => $type, "path" => $path, "callback" => $callback, "method" => "get" ]); Route::$routes[] = $route; return $route; } public static function public($route, $storagepath) { Route::$publics[] = Route::from([ "type" => "public", "path" => preg_quote($route), "src" => $storagepath, "method" => "get" ]); } public static function any($path, $callback) { $magic = magicRoute($path); $textPath = false; $type = "text"; if($magic[2] == true) { $type = "magic"; $textPath = $magic; }else{ $textPath = $path; } $route = Route::from([ "type" => $type, "path" => $path, "callback" => $callback, "method" => "*" ]); Route::$routes[] = $route; return $route; } public static function CheckCurrent() { if(Route::$current == null) { foreach (Route::$routes as $route) { $route->clear(); if($route->Run()) { Route::$current = $route; return $route; } }; foreach (Route::$publics as $route) { $route->clear(); if($route->Run()) { Route::$current = $route; return $route; } }; return false; }; return Route::$current; } public static function Execute() { $route = Route::CheckCurrent(); if($route === false) { Response::Code(404); exit; }; $route->call(); } public static function from(...$args) { return new Route(...$args); } public string $type; public string $path; public string $src; public $callback; public string $method; public $match = null; public function __construct($obj) { foreach ($obj as $name => $value) { $this->{$name} = $value; } } public function clear() { $this->match = null; } public function call(...$args) { switch ($this->type) { case 'magic': case 'text': $callback = $this->callback; $callback(...$args); break; case 'public': $callback = $this->callback; Response::File($callback); break; } } public function Run() { $requestUrl = Request::$url; $method = Request::$method; if($this->method != $method) { return false; } $url = parse_url($requestUrl, PHP_URL_PATH); switch($this->type) { case "text":{ if($url == $this->path) { return true; }else{ return false; } break; } case "magic":{ if($t === false) { return false; }else{ $this->match = $t; return true; } break; } case "public":{ $path = tstring::from($this->path); $url = tstring::from($url); if($url->startsWith($path)) { $filename = $url->slice(strlen($path)); // remove first / char $rpath = realpath($this->src . $filename); if(file_exists($rpath)) { $this->callback = $rpath; return true; }else{ return false; } }else{ return false; } break; } } } }