_uri = isset($_SERVER['argv'][1]) ? '/' . $_SERVER['argv'][1] : '/'; } else { self::$_routeCollection->_uri = isset($_SERVER['REQUEST_URI']) ? explode('?', $_SERVER['REQUEST_URI'])[0] : '/'; } self::$_routeCollection->defineVerb(); } self::$_routeCollection->_uri = str_replace("//", "/", self::$_routeCollection->_uri); return self::$_routeCollection; } /** * */ public static function getInstance() { if (!isset(self::$_routeCollection)) { return self::newObj(); } return self::$_routeCollection; } //HELPERS================================================ /* * Find route files with names under pathname * * @ctag\t RouteCollection->crawl() */ public function crawl($basepath = __DIR__, $filenames = Array('Routes.php', 'routes.php')) { $instance = self::getInstance(); $rdi = new \RecursiveDirectoryIterator($basepath); foreach (new \RecursiveIteratorIterator($rdi) as $file) { foreach ($filenames as $filename) { if (strpos($file, $filename)) { $instance->_loadedFiles[] = $file; } } } return $instance; } /** * * Load the files with the routes * @ctag\t RouteCollection->loadRoutes() */ function loadRoutes() { $instance = self::getInstance(); foreach ($instance->_loadedFiles as $loadedFile) { include $loadedFile; } return $instance; } /** * * GET | POST | PUT | PATCH | DELETE | CLI * */ private function defineVerb() { $verb = ''; if (isset($_POST['_method'])) { $verb = strtoupper($_POST['_method']); } else if (php_sapi_name() == "cli") { $verb = "CLI"; } else { $verb = strtoupper($_SERVER['REQUEST_METHOD']); } if (in_array($verb, self::$_verbsWhitelist)) { $this->_verb = $verb; } else { echo 'Invalid Verb'; } } /** * */ private function sort_routes() { usort($this->_routes, function($a, $b) { if ($a->_weight == $b->_weight) { return 0; } return ($a->_weight < $b->_weight) ? -1 : 1; }); } /** * */ function submit() { global $ROUTE; self::$_routeCollection->sort_routes(); $one_hit = false; foreach (self::$_routeCollection->_routes as $route) { if (!in_array(self::$_routeCollection->_verb, $route->_verb) && !in_array('*', $route->_verb)) { //No it is not continue; } //Request match a route $match = $route->match(self::$_routeCollection->_uri); if ($match) { //Yup. Execute the route $ROUTE = $route; $route->_before = $this->_defaultMiddlewares; $route->execute(); if (!$route->_ignore) { $one_hit = true; } if ($route->_httpError) { $this->httpError($route->_httpError); return; } //If Executed, interrupt route chain? if ($route->_block) { return; } } } if (!$one_hit) { $info = new \stdClass(); $info->code = 404; $info->message = 'Not Found'; self::$_routeCollection->httpError($info); } } /** * * @ctag RouteCollection::group('base',function(){}) */ static function group($base = '', $callback){ $collection = self::getInstance(); $collection->_groupList = []; $collection->_groupIn = true; $collection->_groupBase = $base; call_user_func($callback); $collection->_groupBase = ''; $collection->_groupIn = false; return new RouteGroup($collection->_groupList); } //DEFINITORS============================================= /** * * @ctag RouteCollection::get('/url',function(){}) */ static function get($uri, $callback, $weight = 0) { return self::add('GET', $uri, $callback, $weight); } /** * * @ctag RouteCollection::cli('/url',function(){}) */ static function cli($uri, $callback, $weight = 0) { return self::add('CLI', $uri, $callback, $weight); } /** * * @ctag RouteCollection::post('/url',function(){}) */ static function post($uri, $callback, $weight = 0) { return self::add('POST', $uri, $callback, $weight); } /** * * @ctag RouteCollection::put('/url',function(){}) */ static function put($uri, $callback, $weight = 0) { return self::add('PUT', $uri, $callback, $weight); } /** * * @ctag RouteCollection::patch('/url',function(){}) */ static function patch($uri, $callback, $weight = 0) { return self::add('PATCH', $uri, $callback, $weight); } /** * * @ctag RouteCollection::delete('/url',Controller@Method) * @ctag RouteCollection::delete('/url',function(){}) */ static function delete($uri, $callback, $weight = 0) { return self::add('DELETE', $uri, $callback, $weight); } /** * * @ctag RouteCollection::resource('/url',function(){}) */ static function resource($uri) { throw new Exception('Not implemented'); } /** * * @ctag RouteCollection::add('VERB','/url',function(){}) * @ctag RouteCollection::add('VERB','/url',Controller@Method) */ static function add($verb, $uri, $callback, $weight = 0) { $route = new Route(); if(self::getInstance()->_groupIn){ $uri = self::getInstance()->_groupBase . $uri; self::getInstance()->_groupList[] = &$route; } $uri = rtrim($uri, '/'); if (is_array($verb)) { $route->_verb = array_map('strtoupper', $verb); } else if (strtoupper($verb) == 'WEB') { $route->_verb[] = self::_verbsWeb; } else { $route->_verb[] = strtoupper($verb); } $route->_uri = $uri; $route->_callback[] = $callback; $route->_weight = $weight; $route->prepare(); self::getInstance()->_routes[] = $route; return $route; } /** * */ function addRoute(Route $route) { $this->_routes[] = $route; } /** * * @ctag RouteCollection::addDefaultMiddleware('name',function(){}) */ static function addDefaultMiddleware($name = '', $function) { self::getInstance()->_defaultMiddlewares[$name] = $function; } /** * * @ctag RouteCollection::addDefaultMiddleware('name',function(){}) */ static function registerMiddleware($name = '', $function) { self::getInstance()->_middlewareSet[$name] = $function; } /** * * @ctag RouteCollection::onHttpError(function(){}) */ static function onHttpError($function) { $instance = self::getInstance(); $instance->_errors[] = $function; } /** * * @ctag RouteCollection::httpError($class) */ private function httpError(\stdClass $info) { $info = (array) $info; foreach ($this->_errors as $error) { call_user_func_array($error, $info); } } }