diff options
author | Frederic Guillot <fred@kanboard.net> | 2015-12-22 19:06:03 +0100 |
---|---|---|
committer | Frederic Guillot <fred@kanboard.net> | 2015-12-22 19:06:03 +0100 |
commit | 6f9af3659c9146a2ac1b08d70610bf96398ec073 (patch) | |
tree | 21cbbca979a30d133d421881d6aa6e6af8096199 /app/Core/Http/Router.php | |
parent | c83f589b22cd548c6de10bfb0c18f767ba7dffd8 (diff) |
Added the possiblity to define custom routes from plugins
Diffstat (limited to 'app/Core/Http/Router.php')
-rw-r--r-- | app/Core/Http/Router.php | 195 |
1 files changed, 67 insertions, 128 deletions
diff --git a/app/Core/Http/Router.php b/app/Core/Http/Router.php index 0080b23a..8b58a947 100644 --- a/app/Core/Http/Router.php +++ b/app/Core/Http/Router.php @@ -6,7 +6,7 @@ use RuntimeException; use Kanboard\Core\Base; /** - * Router class + * Route Dispatcher * * @package http * @author Frederic Guillot @@ -14,76 +14,77 @@ use Kanboard\Core\Base; class Router extends Base { /** - * Controller + * Plugin name * * @access private * @var string */ - private $controller = ''; + private $plugin = ''; /** - * Action + * Controller * * @access private * @var string */ - private $action = ''; + private $controller = ''; /** - * Store routes for path lookup + * Action * * @access private - * @var array + * @var string */ - private $paths = array(); + private $action = ''; /** - * Store routes for url lookup + * Get plugin name * - * @access private - * @var array + * @access public + * @return string */ - private $urls = array(); + public function getPlugin() + { + return $this->plugin; + } /** - * Get action + * Get controller * * @access public * @return string */ - public function getAction() + public function getController() { - return $this->action; + return $this->controller; } /** - * Get controller + * Get action * * @access public * @return string */ - public function getController() + public function getAction() { - return $this->controller; + return $this->action; } /** * Get the path to compare patterns * * @access public - * @param string $uri - * @param string $query_string * @return string */ - public function getPath($uri, $query_string = '') + public function getPath() { - $path = substr($uri, strlen($this->helper->url->dir())); + $path = substr($this->request->getUri(), strlen($this->helper->url->dir())); - if (! empty($query_string)) { - $path = substr($path, 0, - strlen($query_string) - 1); + if ($this->request->getQueryString() !== '') { + $path = substr($path, 0, - strlen($this->request->getQueryString()) - 1); } - if (! empty($path) && $path{0} === '/') { + if ($path !== '' && $path{0} === '/') { $path = substr($path, 1); } @@ -91,140 +92,78 @@ class Router extends Base } /** - * Add route + * Find controller/action from the route table or from get arguments * * @access public - * @param string $path - * @param string $controller - * @param string $action - * @param array $params */ - public function addRoute($path, $controller, $action, array $params = array()) + public function dispatch() { - $pattern = explode('/', $path); + $controller = $this->request->getStringParam('controller'); + $action = $this->request->getStringParam('action'); + $plugin = $this->request->getStringParam('plugin'); - $this->paths[] = array( - 'pattern' => $pattern, - 'count' => count($pattern), - 'controller' => $controller, - 'action' => $action, - ); + if ($controller === '') { + $route = $this->route->findRoute($this->getPath()); + $controller = $route['controller']; + $action = $route['action']; + $plugin = $route['plugin']; + } - $this->urls[$controller][$action][] = array( - 'path' => $path, - 'params' => array_flip($params), - 'count' => count($params), - ); + $this->controller = ucfirst($this->sanitize($controller, 'app')); + $this->action = $this->sanitize($action, 'index'); + $this->plugin = ucfirst($this->sanitize($plugin)); + + return $this->executeAction(); } /** - * Find a route according to the given path + * Check controller and action parameter * * @access public - * @param string $path - * @return array + * @param string $value + * @param string $default + * @return string */ - public function findRoute($path) + public function sanitize($value, $default = '') { - $parts = explode('/', $path); - $count = count($parts); - - foreach ($this->paths as $route) { - if ($count === $route['count']) { - $params = array(); - - for ($i = 0; $i < $count; $i++) { - if ($route['pattern'][$i]{0} === ':') { - $params[substr($route['pattern'][$i], 1)] = $parts[$i]; - } elseif ($route['pattern'][$i] !== $parts[$i]) { - break; - } - } - - if ($i === $count) { - $_GET = array_merge($_GET, $params); - return array($route['controller'], $route['action']); - } - } - } - - return array('app', 'index'); + return preg_match('/^[a-zA-Z_0-9]+$/', $value) ? $value : $default; } /** - * Find route url + * Execute controller action * - * @access public - * @param string $controller - * @param string $action - * @param array $params - * @return string + * @access private */ - public function findUrl($controller, $action, array $params = array()) + private function executeAction() { - if (! isset($this->urls[$controller][$action])) { - return ''; - } - - foreach ($this->urls[$controller][$action] as $pattern) { - if (array_diff_key($params, $pattern['params']) === array()) { - $url = $pattern['path']; - $i = 0; + $class = $this->getControllerClassName(); - foreach ($params as $variable => $value) { - $url = str_replace(':'.$variable, $value, $url); - $i++; - } + if (! class_exists($class)) { + throw new RuntimeException('Controller not found'); + } - if ($i === $pattern['count']) { - return $url; - } - } + if (! method_exists($class, $this->action)) { + throw new RuntimeException('Action not implemented'); } - return ''; + $instance = new $class($this->container); + $instance->beforeAction($this->controller, $this->action); + $instance->{$this->action}(); + return $instance; } /** - * Check controller and action parameter + * Get controller class name * - * @access public - * @param string $value Controller or action name - * @param string $default_value Default value if validation fail + * @access private * @return string */ - public function sanitize($value, $default_value) + private function getControllerClassName() { - return ! preg_match('/^[a-zA-Z_0-9]+$/', $value) ? $default_value : $value; - } - - /** - * Find controller/action from the route table or from get arguments - * - * @access public - * @param string $uri - * @param string $query_string - */ - public function dispatch($uri, $query_string = '') - { - if (! empty($_GET['controller']) && ! empty($_GET['action'])) { - $this->controller = $this->sanitize($_GET['controller'], 'app'); - $this->action = $this->sanitize($_GET['action'], 'index'); - $plugin = ! empty($_GET['plugin']) ? $this->sanitize($_GET['plugin'], '') : ''; - } else { - list($this->controller, $this->action) = $this->findRoute($this->getPath($uri, $query_string)); // TODO: add plugin for routes - $plugin = ''; - } - - $class = '\Kanboard\\'; - $class .= empty($plugin) ? 'Controller\\'.ucfirst($this->controller) : 'Plugin\\'.ucfirst($plugin).'\Controller\\'.ucfirst($this->controller); - - if (! class_exists($class) || ! method_exists($class, $this->action)) { - throw new RuntimeException('Controller or method not found for the given url!'); + if ($this->plugin !== '') { + return '\Kanboard\Plugin\\'.$this->plugin.'\Controller\\'.$this->controller; } - $instance = new $class($this->container); - $instance->beforeAction($this->controller, $this->action); - $instance->{$this->action}(); + return '\Kanboard\Controller\\'.$this->controller; } } |