diff --git a/.gitignore b/.gitignore index 9f57dcf..ed19770 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ /vendor/ /index.php /.htaccess +.idea + diff --git a/src/Router.php b/src/Router.php index 9c3acc7..3bdde8d 100644 --- a/src/Router.php +++ b/src/Router.php @@ -18,10 +18,28 @@ use Buki\Router\RouterCommand; use Buki\Router\RouterException; +/** + * Class Router + * + * @method mixed any($route, $settings, $callback = null) + * @method mixed get($route, $settings, $callback = null) + * @method mixed post($route, $settings, $callback = null) + * @method mixed put($route, $settings, $callback = null) + * @method mixed delete($route, $settings, $callback = null) + * @method mixed patch($route, $settings, $callback = null) + * @method mixed head($route, $settings, $callback = null) + * @method mixed options($route, $settings, $callback = null) + * @method mixed xpost($route, $settings, $callback = null) + * @method mixed xput($route, $settings, $callback = null) + * @method mixed xdelete($route, $settings, $callback = null) + * @method mixed xpatch($route, $settings, $callback = null) + * + * @package Buki + */ class Router { /** - * @var string $baseFolder Pattern definations for parameters of Route + * @var string $baseFolder Pattern definitions for parameters of Route */ protected $baseFolder; @@ -36,7 +54,7 @@ class Router protected $groups = []; /** - * @var array $patterns Pattern definations for parameters of Route + * @var array $patterns Pattern definitions for parameters of Route */ protected $patterns = [ '{a}' => '([^/]+)', @@ -122,27 +140,23 @@ function __construct(array $params = []) protected function setPaths($params) { if (isset($params['paths']) && $paths = $params['paths']) { - $this->paths['controllers'] = - isset($paths['controllers']) - ? trim($paths['controllers'], '/') - : $this->paths['controllers']; + $this->paths['controllers'] = isset($paths['controllers']) + ? trim($paths['controllers'], '/') + : $this->paths['controllers']; - $this->paths['middlewares'] = - isset($paths['middlewares']) - ? trim($paths['middlewares'], '/') - : $this->paths['middlewares']; + $this->paths['middlewares'] = isset($paths['middlewares']) + ? trim($paths['middlewares'], '/') + : $this->paths['middlewares']; } if (isset($params['namespaces']) && $namespaces = $params['namespaces']) { - $this->namespaces['controllers'] = - isset($namespaces['controllers']) - ? trim($namespaces['controllers'], '\\') . '\\' - : ''; + $this->namespaces['controllers'] = isset($namespaces['controllers']) + ? trim($namespaces['controllers'], '\\') . '\\' + : ''; - $this->namespaces['middlewares'] = - isset($namespaces['middlewares']) - ? trim($namespaces['middlewares'], '\\') . '\\' - : ''; + $this->namespaces['middlewares'] = isset($namespaces['middlewares']) + ? trim($namespaces['middlewares'], '\\') . '\\' + : ''; } if (isset($params['base_folder'])) { @@ -331,7 +345,6 @@ public function run() } else { foreach ($this->routes as $data) { $route = $data['route']; - if (strstr($route, ':') !== false || strpos($route, '{') !== false) { $route = str_replace($searches, $replaces, $route); } @@ -615,7 +628,7 @@ private function addRoute($uri, $method, $callback, $settings) * * @param $command * @param $params - * @return null + * @return void */ private function runRouteCommand($command, $params = null) { diff --git a/src/Router/RouterCommand.php b/src/Router/RouterCommand.php index a7cecc6..96f2c21 100644 --- a/src/Router/RouterCommand.php +++ b/src/Router/RouterCommand.php @@ -22,7 +22,11 @@ class RouterCommand protected $namespaces; /** + * RouterCommand constructor. * + * @param $baseFolder + * @param $paths + * @param $namespaces */ public function __construct($baseFolder, $paths, $namespaces) { @@ -48,9 +52,11 @@ public function getControllerInfo() } /** - * Get class instance + * @param $baseFolder + * @param $paths + * @param $namespaces * - * @return RouterCommand + * @return RouterCommand|static */ public static function getInstance($baseFolder, $paths, $namespaces) { @@ -77,8 +83,6 @@ public function exception($message = '') * Run Route Middlewares * * @param $command - * @param $path - * @param $namespace * * @return mixed|void * @throws @@ -88,13 +92,18 @@ public function beforeAfter($command) if (! is_null($command)) { $info = $this->getMiddlewareInfo(); if (is_array($command)) { - foreach ($command as $key => $value) { - $this->beforeAfter($value, $info['path'], $info['namespace']); + foreach ($command as $value) { + $this->beforeAfter($value); } } elseif (is_string($command)) { - $controller = $this->resolveClass($command, $info['path'], $info['namespace']); + $middleware = explode(':', $command); + $params = []; + if (count($middleware) > 1) { + $params = explode(',', $middleware[1]); + } + $controller = $this->resolveClass($middleware[0], $info['path'], $info['namespace']); if (method_exists($controller, 'handle')) { - $response = call_user_func([$controller, 'handle']); + $response = call_user_func_array([$controller, 'handle'], $params); if ($response !== true) { echo $response; exit; @@ -115,10 +124,8 @@ public function beforeAfter($command) * * @param $command * @param $params - * @param $path - * @param $namespace * - * @return void + * @return mixed|void * @throws */ public function runRoute($command, $params = null) @@ -131,22 +138,16 @@ public function runRoute($command, $params = null) $controller = $this->resolveClass($controllerClass, $info['path'], $info['namespace']); if (method_exists($controller, $controllerMethod)) { - echo call_user_func_array( - [$controller, $controllerMethod], - (!is_null($params) ? $params : []) - ); + echo $this->runMethodWithParams([$controller, $controllerMethod], $params); return; } return $this->exception($controllerMethod . ' method is not found in '.$controllerClass.' class.'); } else { - if (! is_null($params)) { - echo call_user_func_array($command, $params); - return; - } - - echo call_user_func($command); + echo $this->runMethodWithParams($command, $params); } + + return; } /** @@ -173,4 +174,15 @@ protected function resolveClass($class, $path, $namespace) return new $class(); } + + /** + * @param $function + * @param $params + * + * @return mixed + */ + protected function runMethodWithParams($function, $params) + { + return call_user_func_array($function, (!is_null($params) ? $params : [])); + } } diff --git a/src/Router/RouterRequest.php b/src/Router/RouterRequest.php index 2a31054..c0637a8 100644 --- a/src/Router/RouterRequest.php +++ b/src/Router/RouterRequest.php @@ -15,7 +15,7 @@ class RouterRequest /** * @var string $validMethods Valid methods for Requests */ - public static $validMethods = 'GET|POST|PUT|DELETE|HEAD|OPTIONS|PATCH|ANY|AJAX|AJAXP'; + public static $validMethods = 'GET|POST|PUT|DELETE|HEAD|OPTIONS|PATCH|ANY|AJAX|XPOST|XPUT|XDELETE|XPATCH'; /** * Request method validation @@ -42,6 +42,33 @@ public static function validMethod($data, $method) return $valid; } + /** + * Get the request method used, taking overrides into account + * + * @return string + */ + public static function getRequestMethod() + { + // Take the method as found in $_SERVER + $method = $_SERVER['REQUEST_METHOD']; + // If it's a HEAD request override it to being GET and prevent any output, as per HTTP Specification + // @url http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.4 + if ($method === 'HEAD') { + ob_start(); + $method = 'GET'; + } elseif ($method === 'POST') { + $headers = self::getRequestHeaders(); + if (isset($headers['X-HTTP-Method-Override']) && + in_array($headers['X-HTTP-Method-Override'], ['PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD'])) { + $method = $headers['X-HTTP-Method-Override']; + } elseif (! empty($_POST['_method'])) { + $method = strtoupper($_POST['_method']); + } + } + + return $method; + } + /** * check method valid * @@ -52,16 +79,21 @@ public static function validMethod($data, $method) */ protected static function checkMethods($value, $method) { - $valid = false; - if ($value === 'AJAX' && self::isAjax() && $value === $method) { - $valid = true; - } elseif ($value === 'AJAXP' && self::isAjax() && $method === 'POST') { - $valid = true; - } elseif (in_array($value, explode('|', self::$validMethods)) && ($value === $method || $value === 'ANY')) { - $valid = true; + if (in_array($value, explode('|', self::$validMethods))) { + if (self::isAjax() && $value === 'AJAX') { + return true; + } + + if (self::isAjax() && strpos($value, 'X') === 0 && $method === ltrim($value, 'X')) { + return true; + } + + if (in_array($value, [$method, 'ANY'])) { + return true; + } } - return $valid; + return false; } /** @@ -90,36 +122,15 @@ protected static function getRequestHeaders() $headers = []; foreach ($_SERVER as $name => $value) { if (substr($name, 0, 5) == 'HTTP_' || $name === 'CONTENT_TYPE' || $name === 'CONTENT_LENGTH') { - $headers[str_replace([' ', 'Http'], ['-', 'HTTP'], ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value; + $headerKey = str_replace( + [' ', 'Http'], + ['-', 'HTTP'], + ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))) + ); + $headers[$headerKey] = $value; } } return $headers; } - - /** - * Get the request method used, taking overrides into account - * - * @return string - */ - public static function getRequestMethod() - { - // Take the method as found in $_SERVER - $method = $_SERVER['REQUEST_METHOD']; - // If it's a HEAD request override it to being GET and prevent any output, as per HTTP Specification - // @url http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.4 - if ($method === 'HEAD') { - ob_start(); - $method = 'GET'; - } elseif ($method === 'POST') { - $headers = self::getRequestHeaders(); - if (isset($headers['X-HTTP-Method-Override']) && in_array($headers['X-HTTP-Method-Override'], ['PUT', 'DELETE', 'PATCH', 'OPTIONS'])) { - $method = $headers['X-HTTP-Method-Override']; - } elseif (! empty($_POST['_method'])) { - $method = strtoupper($_POST['_method']); - } - } - - return $method; - } }