diff --git a/src/Pecee/SimpleRouter/RouterBase.php b/src/Pecee/SimpleRouter/RouterBase.php index 75e97c3..a1f5d3a 100644 --- a/src/Pecee/SimpleRouter/RouterBase.php +++ b/src/Pecee/SimpleRouter/RouterBase.php @@ -20,7 +20,7 @@ class RouterBase { $this->routes = array(); $this->backstack = array(); $this->controllerUrlMap = array(); - $this->requestUri = rtrim($_SERVER['REQUEST_URI'], '/'); + $this->requestUri = $_SERVER['REQUEST_URI']; $this->requestMethod = strtolower(isset($_GET['_method']) ? $_GET['_method'] : $_SERVER['REQUEST_METHOD']); } @@ -48,31 +48,26 @@ class RouterBase { $this->loadClass($route->getMiddleware()); } - // Add default namespace - if(!$route->getNamespace() && $this->defaultControllerNamespace !== null) { - $route->setNamespace($this->defaultControllerNamespace); - } - if(is_object($route->getCallback()) && is_callable($route->getCallback())) { // When the callback is a function - call_user_func_array($route->getCallback(), $route->getParameters()); + call_user_func_array($route->getCallback(), $route->getParameters(), 404); } else if(stripos($route->getCallback(), '@') > 0) { // When the callback is a method $controller = explode('@', $route->getCallback()); - $class = $route->getNamespace() . '\\' . $controller[0]; + $className = $route->getNamespace() . '\\' . $controller[0]; - $class = $this->loadClass($class); + $class = $this->loadClass($className); $this->loadedClass = $class; $method = $controller[1]; if(!method_exists($class, $method)) { - throw new RouterException(sprintf('Method %s does not exist', $method)); + throw new RouterException(sprintf('Method %s does not exist in class %s', $method, $className), 404); } call_user_func_array(array($class, $method), $route->getParameters()); @@ -84,6 +79,18 @@ class RouterBase { /* @var $route RouterEntry */ foreach($routes as $route) { + if($this->defaultControllerNamespace) { + $namespace = null; + + if ($route->getNamespace()) { + $namespace = $this->defaultControllerNamespace . '\\' . $route->getNamespace(); + } else { + $namespace = $this->defaultControllerNamespace; + } + + $route->setNamespace($namespace); + } + $settings = array_merge($settings, $route->getMergeableSettings()); if($route->getPrefix()) { array_push($prefixes, $route->getPrefix()); @@ -101,7 +108,17 @@ class RouterBase { } } + if($route instanceof RouterController) { + + if(is_array($prefixes) && count($prefixes)) { + $route->setUrl( '/' . join('/', $prefixes) . $route->getUrl() ); + } + + $this->controllerUrlMap[$route->getController()] = $route; + } + // Stop if the route matches + $route = $route->getRoute($this->requestMethod, $this->requestUri); if($route) { $this->renderRoute($route); diff --git a/src/Pecee/SimpleRouter/RouterController.php b/src/Pecee/SimpleRouter/RouterController.php new file mode 100644 index 0000000..81736d9 --- /dev/null +++ b/src/Pecee/SimpleRouter/RouterController.php @@ -0,0 +1,126 @@ +url = $url; + $this->controller = $controller; + $this->parameters; + } + + protected function loadClass() { + + if($this->getNamespace()) { + $className = $this->getNamespace() . '\\' . $this->controller; + } else { + $className = $this->controller; + } + + if(!class_exists($className)) { + throw new RouterException(sprintf('Controller %s not found', $className), 404); + } + + // Call controller + $class = new $className(); + + if(!method_exists($class, $this->method)) { + throw new RouterException(sprintf('Method %s not found in controller %s', $this->method, $className), 404); + } + + call_user_func_array(array($class, $this->method), $this->parameters); + } + + public function getRoute($requestMethod, &$url) { + + $url = parse_url($url); + $url = $url['path']; + + if(strtolower($url) == strtolower($this->url) || stripos($url, $this->url) !== false) { + + $strippedUrl = trim(str_ireplace($this->url, '/', $url), '/'); + + $path = explode('/', $strippedUrl); + + if(count($path)) { + + $method = (!isset($path[0]) || trim($path[0]) === '') ? self::DEFAULT_METHOD : $path[0]; + + $this->method = $requestMethod . ucfirst($method); + + array_shift($path); + + $this->parameters = $path; + + $this->loadClass(); + } + + } + + } + + /** + * @return string + */ + public function getUrl() { + return $this->url; + } + + /** + * @param string $url + */ + public function setUrl($url) { + $this->url = $url; + } + + /** + * @return array + */ + public function getParameters() { + return $this->parameters; + } + + /** + * @param array $parameters + */ + public function setParameters($parameters) { + $this->parameters = $parameters; + } + + /** + * @return string + */ + public function getController() { + return $this->controller; + } + + /** + * @param string $controller + */ + public function setController($controller) { + $this->controller = $controller; + } + + /** + * @return string + */ + public function getMethod() { + return $this->method; + } + + /** + * @param string $method + */ + public function setMethod($method) { + $this->method = $method; + } + +} \ No newline at end of file diff --git a/src/Pecee/SimpleRouter/RouterEntry.php b/src/Pecee/SimpleRouter/RouterEntry.php index 2aabbbe..6492d99 100644 --- a/src/Pecee/SimpleRouter/RouterEntry.php +++ b/src/Pecee/SimpleRouter/RouterEntry.php @@ -17,13 +17,11 @@ abstract class RouterEntry { ); protected $settings; - protected $requestTypes; protected $callback; protected $parameters; public function __construct() { $this->settings = array(); - $this->requestTypes = array(); $this->parameters = array(); } @@ -43,29 +41,6 @@ abstract class RouterEntry { return $this->callback; } - /** - * Add request type - * - * @param $type - * @return self - * @throws RouterException - */ - public function addRequestType($type) { - if(!in_array($type, self::$allowedRequestTypes)) { - throw new RouterException('Invalid request method: ' . $type); - } - - $this->requestTypes[] = $type; - return $this; - } - - /** - * @return mixed - */ - public function getRequestTypes() { - return $this->requestTypes; - } - /** * @return mixed */ diff --git a/src/Pecee/SimpleRouter/RouterGroup.php b/src/Pecee/SimpleRouter/RouterGroup.php index 018afe2..ed227c3 100644 --- a/src/Pecee/SimpleRouter/RouterGroup.php +++ b/src/Pecee/SimpleRouter/RouterGroup.php @@ -4,8 +4,11 @@ namespace Pecee\SimpleRouter; class RouterGroup extends RouterEntry { + protected $requestTypes; + public function __construct() { parent::__construct(); + $this->requestTypes = array(); } public function getRoute($requestMethod, &$url) { @@ -18,4 +21,27 @@ class RouterGroup extends RouterEntry { return null; } + /** + * Add request type + * + * @param $type + * @return self + * @throws RouterException + */ + public function addRequestType($type) { + if(!in_array($type, self::$allowedRequestTypes)) { + throw new RouterException('Invalid request method: ' . $type); + } + + $this->requestTypes[] = $type; + return $this; + } + + /** + * @return mixed + */ + public function getRequestTypes() { + return $this->requestTypes; + } + } \ No newline at end of file diff --git a/src/Pecee/SimpleRouter/RouterRoute.php b/src/Pecee/SimpleRouter/RouterRoute.php index 9617f47..dfd7917 100644 --- a/src/Pecee/SimpleRouter/RouterRoute.php +++ b/src/Pecee/SimpleRouter/RouterRoute.php @@ -8,6 +8,7 @@ use Pecee\Router; class RouterRoute extends RouterEntry { protected $url; + protected $requestTypes; public function __construct($url, $callback) { parent::__construct(); @@ -15,6 +16,7 @@ class RouterRoute extends RouterEntry { $this->setCallback($callback); $this->settings['aliases'] = array(); + $this->requestTypes = array(); } protected function parseParameters($url) { @@ -46,6 +48,9 @@ class RouterRoute extends RouterEntry { // Check if request method is allowed if(count($this->requestTypes) === 0 || in_array($requestMethod, $this->requestTypes)) { + $url = parse_url($url); + $url = $url['path']; + $url = explode('/', trim($url, '/')); $route = explode('/', trim($this->url, '/')); @@ -133,4 +138,27 @@ class RouterRoute extends RouterEntry { public function getAliases() { $this->aliases; } + + /** + * Add request type + * + * @param $type + * @return self + * @throws RouterException + */ + public function addRequestType($type) { + if(!in_array($type, self::$allowedRequestTypes)) { + throw new RouterException('Invalid request method: ' . $type); + } + + $this->requestTypes[] = $type; + return $this; + } + + /** + * @return mixed + */ + public function getRequestTypes() { + return $this->requestTypes; + } } \ No newline at end of file diff --git a/src/Pecee/SimpleRouter/SimpleRouter.php b/src/Pecee/SimpleRouter/SimpleRouter.php index f441315..02f0207 100644 --- a/src/Pecee/SimpleRouter/SimpleRouter.php +++ b/src/Pecee/SimpleRouter/SimpleRouter.php @@ -83,6 +83,22 @@ class SimpleRouter { return $route; } + public static function all($url, $callback) { + $route = new RouterRoute($url, $callback); + $router = RouterBase::getInstance(); + $router->addRoute($route); + + return $route; + } + + public static function controller($url, $controller) { + $route = new RouterController($url, $controller); + $router = RouterBase::getInstance(); + $router->addRoute($route); + + return $route; + } + public static function ressource($controller, $settings = array()) { // not yet implemented }