From 3c6d269eb0643e09bbf4fe263e47e4ed49692955 Mon Sep 17 00:00:00 2001 From: rootcoma Date: Thu, 5 Dec 2013 15:59:30 -0800 Subject: [PATCH] Adding Routing and Route --- php/includes/Controller.php | 42 ++++++++++++++ php/includes/Route.php | 71 ++++++++++++++++++++++++ php/includes/Router.php | 108 ++++++++++++++++++++++++++++++++++++ 3 files changed, 221 insertions(+) create mode 100644 php/includes/Controller.php create mode 100644 php/includes/Route.php create mode 100644 php/includes/Router.php diff --git a/php/includes/Controller.php b/php/includes/Controller.php new file mode 100644 index 0000000..6e53d52 --- /dev/null +++ b/php/includes/Controller.php @@ -0,0 +1,42 @@ +container = $container; + } + + public function getContainer() { + return $this->container(); + } + + protected function redirect($page) { + $this->container->redirect($page); + } + + protected function setTitle($title) { + $this->container->setTitle($title); + } + + protected function render($page, $args=array()) { + $this->container->render($page, $args); + } + + protected function getNotice($notice) { + return $this->container->getNotice; + } + + protected function clearNotice() { + $this->container->clearNotice(); + } + + protected function setNotice($notice) { + $this->container->setNotice($notice); + } + + protected function render404() { + $this->container->set404(); + $this->container->render404(); + } +} diff --git a/php/includes/Route.php b/php/includes/Route.php new file mode 100644 index 0000000..1575a0e --- /dev/null +++ b/php/includes/Route.php @@ -0,0 +1,71 @@ +url; + } + + public function setUrl($url) { + $url = (string) $url; + + // make sure that the URL is suffixed with a forward slash + if(substr($url,-1) !== '/') $url .= '/'; + + $this->url = $url; + } + + public function getTarget() { + return $this->target; + } + + public function setTarget($target) { + $this->target = $target; + } + + public function getMethods() { + return $this->methods; + } + + public function setMethods(array $methods) { + $this->methods = $methods; + } + + public function getName() { + return $this->name; + } + + public function setName($name) { + $this->name = (string) $name; + } + + public function setFilters(array $filters) { + $this->filters = $filters; + } + + public function getRegex() { + return preg_replace_callback("/:(\w+)/", array(&$this, 'substituteFilter'), $this->url); + } + + private function substituteFilter($matches) { + if (isset($matches[1]) && isset($this->filters[$matches[1]])) { + return $this->filters[$matches[1]]; + } + + return "([\w-]+)"; + } + + public function getParameters() { + return $this->parameters; + } + + public function setParameters(array $parameters) { + $this->parameters = $parameters; + } +} diff --git a/php/includes/Router.php b/php/includes/Router.php new file mode 100644 index 0000000..e9be5e2 --- /dev/null +++ b/php/includes/Router.php @@ -0,0 +1,108 @@ +basePath = (string) $basePath; + } + + public function map($routeUrl, $target = '', array $args = array()) { + $route = new Route(); + + $route->setUrl($this->basePath . $routeUrl); + + $route->setTarget($target); + + if(isset($args['methods'])) { + $methods = explode(',', $args['methods']); + $route->setMethods($methods); + } + + if(isset($args['filters'])) { + $route->setFilters($args['filters']); + } + + if(isset($args['name'])) { + $route->setName($args['name']); + if (!isset($this->namedRoutes[$route->getName()])) { + $this->namedRoutes[$route->getName()] = $route; + } + } + + $this->routes[] = $route; + } + + public function matchCurrentRequest() { + $requestMethod = (isset($_POST['_method']) && ($_method = strtoupper($_POST['_method'])) && in_array($_method,array('PUT','DELETE'))) ? $_method : $_SERVER['REQUEST_METHOD']; + $requestUrl = $_SERVER['REQUEST_URI']; + + // strip GET variables from URL + if(($pos = strpos($requestUrl, '?')) !== false) { + $requestUrl = substr($requestUrl, 0, $pos); + } + + return $this->match($requestUrl, $requestMethod); + } + + public function match($requestUrl, $requestMethod = 'GET') { + + foreach($this->routes as $route) { + + // compare server request method with route's allowed http methods + if(!in_array($requestMethod, $route->getMethods())) continue; + + // check if request url matches route regex. if not, return false. + if (!preg_match("@^".$route->getRegex()."*$@i", $requestUrl, $matches)) continue; + + $params = array(); + + if (preg_match_all("/:([\w-]+)/", $route->getUrl(), $argument_keys)) { + + // grab array with matches + $argument_keys = $argument_keys[1]; + + // loop trough parameter names, store matching value in $params array + foreach ($argument_keys as $key => $name) { + if (isset($matches[$key + 1])) + $params[$name] = $matches[$key + 1]; + } + + } + + $route->setParameters($params); + + return $route; + + } + + return false; + } + + public function generate($routeName, array $params = array()) { + // Check if route exists + if (!isset($this->namedRoutes[$routeName])) + throw new Exception("No route with the name $routeName has been found."); + + $route = $this->namedRoutes[$routeName]; + + $url = $route->getUrl(); + + // replace route url with given parameters + if ($params && preg_match_all("/:(\w+)/", $url, $param_keys)) { + + // grab array with matches + $param_keys = $param_keys[1]; + + // loop trough parameter names, store matching value in $params array + foreach ($param_keys as $i => $key) { + if (isset($params[$key])) + $url = preg_replace("/:(\w+)/", $params[$key], $url, 1); + } + } + + return $url; + } +}