diff --git a/.htaccess b/.htaccess new file mode 100644 index 0000000..1c8ab48 --- /dev/null +++ b/.htaccess @@ -0,0 +1,2 @@ +RewriteEngine on +RewriteRule ^(.*)$ index.php [L,QSA] \ No newline at end of file diff --git a/Core/Core.php b/Core/Core.php index ba352ad..f6713f1 100644 --- a/Core/Core.php +++ b/Core/Core.php @@ -7,7 +7,4 @@ include_once "DatabaseORM.php"; include_once "DatabaseMySQLEngine.php"; include_once "Blade.php"; - - define("request", new Request(), false); - define("response", new Response(), false); - define("session", new Session(), false); \ No newline at end of file + include_once "Route.php"; \ No newline at end of file diff --git a/Core/Helpers.php b/Core/Helpers.php index 34b43bd..6b33310 100644 --- a/Core/Helpers.php +++ b/Core/Helpers.php @@ -26,6 +26,10 @@ } return false; } + static function from($data) + { + return new tstring($data); + } public function __construct($data = "") { $this->data = $data; @@ -79,15 +83,15 @@ return false; } } - public function match($pattern) : array + public function match($pattern) : array|bool { $mathes = []; - preg_match( + $matched = preg_match( $pattern, $this->data, $mathes ); - return $mathes; + return $matched ? $mathes : false; } public function matchAll($pattern) : array { @@ -267,6 +271,10 @@ { return $this->data; } + public function raw() + { + return $this->data; + } } function dd($data){ highlight_string(""); diff --git a/Core/Request.php b/Core/Request.php index ac7acad..f02989e 100644 --- a/Core/Request.php +++ b/Core/Request.php @@ -13,6 +13,10 @@ public static $session; public static $contentType; public static $file; + public static $url; + public static $accepts; + public static $ip; + public static $isajax; public static $data = []; public static $query = []; public static $ready = false; @@ -27,6 +31,29 @@ Request::$method = strtolower($_SERVER["REQUEST_METHOD"]); Request::$contentType = strtolower($_SERVER["CONTENT_TYPE"] ?? ""); Request::$ready = true; + Request::$url = $_SERVER['REQUEST_URI']; + if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) + { + Request::$ip = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])[0]; + }else{ + Request::$ip = $_SERVER['REMOTE_ADDR']; + }; + + Request::$accepts = explode(',', $_SERVER['HTTP_ACCEPT']); + + + if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') + { + Request::$isajax = true; + }else{ + if( + in_array("application/json", Request::$accepts) || in_array("text/json", Request::$accepts) + ) + { + Request::$isajax = true; + } + }; + $this->mutateRequest(); } } @@ -117,4 +144,5 @@ { return Request::staticInput($name); } - }; \ No newline at end of file + }; + define("request", new Request(), false); \ No newline at end of file diff --git a/Core/Response.php b/Core/Response.php index 55a8ae2..d2cb515 100644 --- a/Core/Response.php +++ b/Core/Response.php @@ -8,7 +8,9 @@ { $mime = mime_content_type($path); }; - readfile($path); + $fp = fopen($path, 'rb'); + fpassthru($fp); + fclose($fp); } public static function Download($path, $mimetrue = false) { @@ -19,8 +21,10 @@ RequestHeader::set("Content-Transfer-Encoding","Binary"); RequestHeader::set("Content-Disposition",'attachment; filename="'.basename($path).'"'); RequestHeader::set("Content-Length",filesize($path)); - flush(); - readfile($path); + + $fp = fopen($path, 'rb'); + fpassthru($fp); + fclose($fp); } public static function Text($content, $encoding = "utf8") { @@ -79,4 +83,6 @@ http_response_code($code); header("location: $path"); } - }; \ No newline at end of file + }; + + define("response", new Response(), false); \ No newline at end of file diff --git a/Core/Route.php b/Core/Route.php new file mode 100644 index 0000000..d98fd1c --- /dev/null +++ b/Core/Route.php @@ -0,0 +1,208 @@ +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 $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 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; + } + }; + return false; + }; + return Route::$current; + } + + public static function from(...$args) + { + return new Route(...$args); + } + + public string $type; + public string $path; + 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 Run() + { + $requestUrl = Request::$url; + $method = Request::$method; + if($this->method != $method) + { + return false; + } + $url = parse_url($requestUrl, PHP_URL_PATH); + if($this->type == "text") + { + if($url == $this->path) + { + return true; + }else{ + return false; + } + }; + + $t = validateMagicRoute( + $this->path, + $url + ); + + if($t === false) + { + return false; + }else{ + $this->match = $t; + return true; + } + } + } \ No newline at end of file diff --git a/Core/Session.php b/Core/Session.php index b7cb54b..1bc40ac 100644 --- a/Core/Session.php +++ b/Core/Session.php @@ -118,4 +118,6 @@ $this->staticStart(); } } - }; \ No newline at end of file + }; + + define("session", new Session(), false); \ No newline at end of file