From fb5e5594bea149ca730bc6424dc547dab3347747 Mon Sep 17 00:00:00 2001 From: Marien Fressinaud Date: Fri, 14 Jun 2013 20:53:12 +0200 Subject: Fix issue #82 : ajout direct de Minz sans devoir faire appel au script ./build.sh --- lib/minz/Router.php | 209 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100755 lib/minz/Router.php (limited to 'lib/minz/Router.php') diff --git a/lib/minz/Router.php b/lib/minz/Router.php new file mode 100755 index 000000000..c5d6f5baa --- /dev/null +++ b/lib/minz/Router.php @@ -0,0 +1,209 @@ + +*/ + +/** + * La classe Router gère le routage de l'application + * Les routes sont définies dans APP_PATH.'/configuration/routes.php' + */ +class Router { + const ROUTES_PATH_NAME = '/configuration/routes.php'; + + private $routes = array (); + + /** + * Constructeur + * @exception FileNotExistException si ROUTES_PATH_NAME n'existe pas + * et que l'on utilise l'url rewriting + */ + public function __construct () { + if (Configuration::useUrlRewriting ()) { + if (file_exists (APP_PATH . self::ROUTES_PATH_NAME)) { + $routes = include ( + APP_PATH . self::ROUTES_PATH_NAME + ); + + if (!is_array ($routes)) { + $routes = array (); + } + + $this->routes = array_map ( + array ('Url', 'checkUrl'), + $routes + ); + } else { + throw new FileNotExistException ( + self::ROUTES_PATH_NAME, + MinzException::ERROR + ); + } + } + } + + /** + * Initialise le Router en déterminant le couple Controller / Action + * Mets à jour la Request + * @exception RouteNotFoundException si l'uri n'est pas présente dans + * > la table de routage + */ + public function init () { + $url = array (); + + if (Configuration::useUrlRewriting ()) { + try { + $url = $this->buildWithRewriting (); + } catch (RouteNotFoundException $e) { + throw $e; + } + } else { + $url = $this->buildWithoutRewriting (); + } + + $url['params'] = array_merge ( + $url['params'], + Request::fetchPOST () + ); + + Request::forward ($url); + } + + /** + * Retourne un tableau représentant l'url passée par la barre d'adresses + * Ne se base PAS sur la table de routage + * @return tableau représentant l'url + */ + public function buildWithoutRewriting () { + $url = array (); + + $url['c'] = Request::fetchGET ( + 'c', + Request::defaultControllerName () + ); + $url['a'] = Request::fetchGET ( + 'a', + Request::defaultActionName () + ); + $url['params'] = Request::fetchGET (); + + // post-traitement + unset ($url['params']['c']); + unset ($url['params']['a']); + + return $url; + } + + /** + * Retourne un tableau représentant l'url passée par la barre d'adresses + * Se base sur la table de routage + * @return tableau représentant l'url + * @exception RouteNotFoundException si l'uri n'est pas présente dans + * > la table de routage + */ + public function buildWithRewriting () { + $url = array (); + $uri = Request::getURI (); + $find = false; + + foreach ($this->routes as $route) { + $regex = '*^' . $route['route'] . '$*'; + if (preg_match ($regex, $uri, $matches)) { + $url['c'] = $route['controller']; + $url['a'] = $route['action']; + $url['params'] = $this->getParams ( + $route['params'], + $matches + ); + $find = true; + break; + } + } + + if (!$find && $uri != '/') { + throw new RouteNotFoundException ( + $uri, + MinzException::ERROR + ); + } + + // post-traitement + $url = Url::checkUrl ($url); + + return $url; + } + + /** + * Retourne l'uri d'une url en se basant sur la table de routage + * @param l'url sous forme de tableau + * @return l'uri formatée (string) selon une route trouvée + */ + public function printUriRewrited ($url) { + $route = $this->searchRoute ($url); + + if ($route !== false) { + return $this->replaceParams ($route, $url['params']); + } + + return ''; + } + + /** + * Recherche la route correspondante à une url + * @param l'url sous forme de tableau + * @return la route telle que spécifiée dans la table de routage, + * false si pas trouvée + */ + public function searchRoute ($url) { + foreach ($this->routes as $route) { + if ($route['controller'] == $url['c'] + && $route['action'] == $url['a']) { + // calcule la différence des tableaux de params + $params = array_flip ($route['params']); + $difference_params = array_diff_key ( + $params, + $url['params'] + ); + + // vérifie que pas de différence + // et le cas où $params est vide et pas $url['params'] + if (empty ($difference_params) + && (!empty ($params) || empty ($url['params']))) { + return $route; + } + } + } + + return false; + } + + /** + * Récupère un tableau dont + * - les clés sont définies dans $params_route + * - les valeurs sont situées dans $matches + * Le tableau $matches est décalé de +1 par rapport à $params_route + */ + private function getParams($params_route, $matches) { + $params = array (); + + for ($i = 0; $i < count ($params_route); $i++) { + $param = $params_route[$i]; + $params[$param] = $matches[$i + 1]; + } + + return $params; + } + + /** + * Remplace les éléments de la route par les valeurs contenues dans $params + */ + private function replaceParams ($route, $params_replace) { + $uri = $route['route']; + $params = array(); + foreach($route['params'] as $param) { + $uri = preg_replace('#\((.+)\)#U', $params_replace[$param], $uri, 1); + } + + return stripslashes($uri); + } +} -- cgit v1.2.3