123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- <?php
- namespace Juju\App;
- require_once('path.class.php');
- $dir = dirname(__DIR__);
- require_once(realpath("{$dir}/events.trait.php"));
- $dir = "{$dir}/Http/";
- require_once(realpath("{$dir}/request.class.php"));
- require_once(realpath("{$dir}/response.class.php"));
- use \Juju\{Http\Request, Http\Response, Events};
- class Router {
- use Events;
- private $_paths = [];
- private $_routers = [];
- private $_base = '/';
- private $responses = [];
- private $_handled = false;
- public function __construct(string $base = null, array $paths = null){
- if($paths != null){
- $this->paths($paths);
- }
- if($base != null){
- $this->base($base);
- }
- }
- public function __get($name){
- switch($name){
- case 'base':
- return $this->_base;
- break;
- case 'handled':
- return $this->_handled;
- break;
- case 'routes':
- $routes = [];
- $base = rtrim($this->_base, '/');
- foreach($this->_paths as $path){
- if(!isset($routes[$base.$path->path])){
- $routes[$base.$path->path] = 0;
- }
- $routes[$base.$path->path] += count($path);
- }
- foreach($this->_routers as $router){
- foreach($router->routes as $route => $count){
- if(!isset($routes[$base.$route])){
- $routes[$base.$route] = 0;
- }
- $routes[$base.$route] += $count;
- }
- }
- return $routes;
- break;
- }
- }
- public function __clone(){
- // No cloning
- }
- public function __destruct(){
- $this->_paths = [];
- }
- public function __toString(){
- return "[Router]";
- }
- public function base(string $base){
- $this->_base = $base;
- return $this;
- }
- public static function url(string $url){
- return preg_replace('/(\/+)/','/',$url);
- }
- public function prefix(string $prefix, callable $fn){
- $found = false;
- foreach($this->_routers as $k => $router){
- if($router->base == $prefix){
- $found = true;
- $fn($router);
- break;
- }
- }
- if(!$found){
- $router= new Router($prefix);
- $this->_routers[] = $router;
- $fn($router);
- }
- return $this;
- }
- public function path(string $path, callable $fn){
- $obj = false;
- foreach($this->_paths as $k => $p){
- if($p->path == $path){
- $obj = $p;
- }
- }
- if(!$obj){
- $obj = new Path($path);
- array_push($this->_paths, $obj);
- }
- $obj->handle($fn);
- return $this;
- }
- public function get(string $path, callable $fn){
- return $this->path($path, function($req, $res, $args) use($fn){
- if($req->verb === 'GET'){
- return $fn($req, $res, $args);
- }
- });
- }
- public function post(string $path, callable $fn){
- return $this->path($path, function($req, $res, $args) use($fn){
- if($req->verb === 'POST'){
- return $fn($req, $res, $args);
- }
- });
- }
- public function put(string $path, callable $fn){
- return $this->path($path, function($req, $res, $args) use($fn){
- if($req->verb === 'PUT'){
- return $fn($req, $res, $args);
- }
- });
- }
- public function delete(string $path, callable $fn){
- return $this->path($path, function($req, $res, $args) use($fn){
- if($req->verb === 'DELETE'){
- return $fn($req, $res, $args);
- }
- });
- }
- public function patch(string $path, callable $fn){
- return $this->path($path, function($req, $res, $args) use($fn){
- if($req->verb === 'PATCH'){
- return $fn($req, $res, $args);
- }
- });
- }
- public function paths(array $paths){
- foreach($paths as $path => $fn){
- $this->path($path, $fn);
- }
- return $this;
- }
- public function gets(array $paths){
- foreach($paths as $path => $fn){
- $this->get($path, $fn);
- }
- return $this;
- }
- public function posts(array $paths){
- foreach($paths as $path => $fn){
- $this->post($path, $fn);
- }
- return $this;
- }
- public function puts(array $paths){
- foreach($paths as $path => $fn){
- $this->put($path, $fn);
- }
- return $this;
- }
- public function deletes(array $paths){
- foreach($paths as $path => $fn){
- $this->delete($path, $fn);
- }
- return $this;
- }
- public function patches(array $paths){
- foreach($paths as $path => $fn){
- $this->patch($path, $fn);
- }
- return $this;
- }
- public function clear(){
- $this->_paths = [];
- return $this;
- }
- public function handle(string $path, Request $req = null, Response $res = null, callable $fn = null, callable $onerror = null){
- if(strpos($path, $this->base) === 0){
- $path = substr($path, strlen($this->base));
- if(strpos($path, '/') !== 0){
- $path = "/{$path}";
- }
- if(is_null($req)){
- $req = new Request(Request::get_verb(), Request::get_url(), Request::get_headers(), Request::get_body());
- }
- if(is_null($res)){
- $res = new Response();
- }
- if(!in_array($res,$this->responses)){
- array_push($this->responses,$res);
- }
- $this->fire('handle', $req, $res);
- $handled = false;
- foreach($this->_routers as $prefix => $router){
- $router->handle($path, $req, $res);
- $handled = $handled ||$router->handled;
- }
- ob_start();
- foreach($this->_paths as $k => $p){
- if($p->matches($path)){
- $handled = true;
- try{
- if($p($req, $res, $p->args($path)) === false){
- $handled = false;
- }
- }catch(\Exception $e){
- if(!is_null($onerror)){
- $onerror($req, $res,$e);
- }else{
- throw $e;
- }
- }
- }
- }
- $this->_handled = $handled;
- if(!$handled && !is_null($fn)){
- $fn($req, $res);
- }
- $res->output .= ob_get_contents();
- ob_end_clean();
- $this->fire('afterhandle', $req, $res);
- }
- return $res;
- }
- }
- ?>
|