diff options
author | Bharat Mediratta <bharat@menalto.com> | 2008-10-31 22:12:14 +0000 |
---|---|---|
committer | Bharat Mediratta <bharat@menalto.com> | 2008-10-31 22:12:14 +0000 |
commit | eba717f95f586d2538007bd18da6e9b32b076c30 (patch) | |
tree | 15fc596a270f9de0d163c66c96e3c65fca5ee100 /kohana/libraries/Router.php | |
parent | fff10f8b70376ef25722bd867df26bc5aefced43 (diff) |
Merge over vendor code.
git-svn-id: http://gallery.svn.sourceforge.net/svnroot/gallery/trunk/eval/gx/gallery3/trunk@18408 57fcd75e-5312-0410-8df3-f5eb6fbb1595
Diffstat (limited to 'kohana/libraries/Router.php')
-rw-r--r-- | kohana/libraries/Router.php | 313 |
1 files changed, 313 insertions, 0 deletions
diff --git a/kohana/libraries/Router.php b/kohana/libraries/Router.php new file mode 100644 index 00000000..09e45c03 --- /dev/null +++ b/kohana/libraries/Router.php @@ -0,0 +1,313 @@ +<?php defined('SYSPATH') or die('No direct script access.'); +/** + * Router + * + * $Id$ + * + * @package Core + * @author Kohana Team + * @copyright (c) 2007-2008 Kohana Team + * @license http://kohanaphp.com/license.html + */ +class Router_Core { + + protected static $routes; + + public static $current_uri = ''; + public static $query_string = ''; + public static $complete_uri = ''; + public static $routed_uri = ''; + public static $url_suffix = ''; + + public static $segments; + public static $rsegments; + + public static $controller; + public static $controller_path; + + public static $method = 'index'; + public static $arguments = array(); + + /** + * Router setup routine. Automatically called during Kohana setup process. + * + * @return void + */ + public static function setup() + { + if ( ! empty($_SERVER['QUERY_STRING'])) + { + // Set the query string to the current query string + self::$query_string = '?'.trim($_SERVER['QUERY_STRING'], '&/'); + } + + if (self::$routes === NULL) + { + // Load routes + self::$routes = Kohana::config('routes'); + } + + // Default route status + $default_route = FALSE; + + if (self::$current_uri === '') + { + // Make sure the default route is set + if ( ! isset(self::$routes['_default'])) + throw new Kohana_Exception('core.no_default_route'); + + // Use the default route when no segments exist + self::$current_uri = self::$routes['_default']; + + // Default route is in use + $default_route = TRUE; + } + + // Make sure the URL is not tainted with HTML characters + self::$current_uri = html::specialchars(self::$current_uri, FALSE); + + // Remove all dot-paths from the URI, they are not valid + self::$current_uri = preg_replace('#\.[\s./]*/#', '', self::$current_uri); + + // At this point segments, rsegments, and current URI are all the same + self::$segments = self::$rsegments = self::$current_uri = trim(self::$current_uri, '/'); + + // Set the complete URI + self::$complete_uri = self::$current_uri.self::$query_string; + + // Explode the segments by slashes + self::$segments = ($default_route === TRUE OR self::$segments === '') ? array() : explode('/', self::$segments); + + if ($default_route === FALSE AND count(self::$routes) > 1) + { + // Custom routing + self::$rsegments = self::routed_uri(self::$current_uri); + } + + // The routed URI is now complete + self::$routed_uri = self::$rsegments; + + // Routed segments will never be empty + self::$rsegments = explode('/', self::$rsegments); + + // Prepare to find the controller + $controller_path = ''; + $method_segment = NULL; + + // Paths to search + $paths = Kohana::include_paths(); + + foreach (self::$rsegments as $key => $segment) + { + // Add the segment to the search path + $controller_path .= $segment; + + $found = FALSE; + foreach ($paths as $dir) + { + // Search within controllers only + $dir .= 'controllers/'; + + if (is_dir($dir.$controller_path) OR is_file($dir.$controller_path.EXT)) + { + // Valid path + $found = TRUE; + + // The controller must be a file that exists with the search path + if ($c = str_replace('\\', '/', realpath($dir.$controller_path.EXT)) + AND is_file($c) AND strpos($c, $dir) === 0) + { + // Set controller name + self::$controller = $segment; + + // Change controller path + self::$controller_path = $c; + + // Set the method segment + $method_segment = $key + 1; + + // Stop searching + break; + } + } + } + + if ($found === FALSE) + { + // Maximum depth has been reached, stop searching + break; + } + + // Add another slash + $controller_path .= '/'; + } + + if ($method_segment !== NULL AND isset(self::$rsegments[$method_segment])) + { + // Set method + self::$method = self::$rsegments[$method_segment]; + + if (isset(self::$rsegments[$method_segment + 1])) + { + // Set arguments + self::$arguments = array_slice(self::$rsegments, $method_segment + 1); + } + } + + // Last chance to set routing before a 404 is triggered + Event::run('system.post_routing'); + + if (self::$controller === NULL) + { + // No controller was found, so no page can be rendered + Event::run('system.404'); + } + } + + /** + * Attempts to determine the current URI using CLI, GET, PATH_INFO, ORIG_PATH_INFO, or PHP_SELF. + * + * @return void + */ + public static function find_uri() + { + if (PHP_SAPI === 'cli') + { + // Command line requires a bit of hacking + if (isset($_SERVER['argv'][1])) + { + self::$current_uri = $_SERVER['argv'][1]; + + // Remove GET string from segments + if (($query = strpos(self::$current_uri, '?')) !== FALSE) + { + list (self::$current_uri, $query) = explode('?', self::$current_uri, 2); + + // Parse the query string into $_GET + parse_str($query, $_GET); + + // Convert $_GET to UTF-8 + $_GET = utf8::clean($_GET); + } + } + } + elseif (current($_GET) === '' AND substr($_SERVER['QUERY_STRING'], -1) !== '=') + { + // The URI is the array key, eg: ?this/is/the/uri + self::$current_uri = key($_GET); + + // Remove the URI from $_GET + unset($_GET[self::$current_uri]); + + // Remove the URI from $_SERVER['QUERY_STRING'] + $_SERVER['QUERY_STRING'] = ltrim(substr($_SERVER['QUERY_STRING'], strlen(self::$current_uri)), '/&'); + + // Fixes really strange handling of a suffix in a GET string + if ($suffix = Kohana::config('core.url_suffix') AND substr(self::$current_uri, -(strlen($suffix))) === '_'.substr($suffix, 1)) + { + self::$current_uri = substr(self::$current_uri, 0, -(strlen($suffix))); + } + } + elseif (isset($_SERVER['PATH_INFO']) AND $_SERVER['PATH_INFO']) + { + self::$current_uri = $_SERVER['PATH_INFO']; + } + elseif (isset($_SERVER['ORIG_PATH_INFO']) AND $_SERVER['ORIG_PATH_INFO']) + { + self::$current_uri = $_SERVER['ORIG_PATH_INFO']; + } + elseif (isset($_SERVER['PHP_SELF']) AND $_SERVER['PHP_SELF']) + { + self::$current_uri = $_SERVER['PHP_SELF']; + } + + // The front controller directory and filename + $fc = substr(realpath($_SERVER['SCRIPT_FILENAME']), strlen(DOCROOT)); + + if (($strpos_fc = strpos(self::$current_uri, $fc)) !== FALSE) + { + // Remove the front controller from the current uri + self::$current_uri = substr(self::$current_uri, $strpos_fc + strlen($fc)); + } + + // Remove slashes from the start and end of the URI + self::$current_uri = trim(self::$current_uri, '/'); + + if (self::$current_uri !== '') + { + if ($suffix = Kohana::config('core.url_suffix') AND strpos(self::$current_uri, $suffix) !== FALSE) + { + // Remove the URL suffix + self::$current_uri = preg_replace('#'.preg_quote($suffix).'$#u', '', self::$current_uri); + + // Set the URL suffix + self::$url_suffix = $suffix; + } + + // Reduce multiple slashes into single slashes + self::$current_uri = preg_replace('#//+#', '/', self::$current_uri); + } + } + + /** + * Generates routed URI from given URI. + * + * @param string URI to convert + * @return string Routed uri + */ + public static function routed_uri($uri) + { + if (self::$routes === NULL) + { + // Load routes + self::$routes = Kohana::config('routes'); + } + + // Prepare variables + $routed_uri = $uri = trim($uri, '/'); + + if (isset(self::$routes[$uri])) + { + // Literal match, no need for regex + $routed_uri = self::$routes[$uri]; + } + else + { + // Loop through the routes and see if anything matches + foreach (self::$routes as $key => $val) + { + if ($key === '_default') continue; + + // Trim slashes + $key = trim($key, '/'); + $val = trim($val, '/'); + + if (preg_match('#^'.$key.'$#u', $uri)) + { + if (strpos($val, '$') !== FALSE) + { + // Use regex routing + $routed_uri = preg_replace('#^'.$key.'$#u', $val, $uri); + } + else + { + // Standard routing + $routed_uri = $val; + } + + // A valid route has been found + break; + } + } + } + + if (isset(self::$routes[$routed_uri])) + { + // Check for double routing (without regex) + $routed_uri = self::$routes[$routed_uri]; + } + + return trim($routed_uri, '/'); + } + +} // End Router
\ No newline at end of file |