PageRenderTime 83ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/Kohana_v2.3.3/system/libraries/Router.php

https://github.com/iqwebgroup/Kohana-Framework
PHP | 304 lines | 216 code | 36 blank | 52 comment | 13 complexity | 78638042098f4ee6ad626d1db250b19c MD5 | raw file
  1. <?php defined('SYSPATH') OR die('No direct access allowed.');
  2. /**
  3. * Router
  4. *
  5. * $Id: Router.php 4350 2009-05-14 18:58:18Z zombor $
  6. *
  7. * @package Core
  8. * @author Kohana Team
  9. * @copyright (c) 2007-2008 Kohana Team
  10. * @license http://kohanaphp.com/license.html
  11. */
  12. class Router_Core {
  13. protected static $routes;
  14. public static $current_uri = '';
  15. public static $query_string = '';
  16. public static $complete_uri = '';
  17. public static $routed_uri = '';
  18. public static $url_suffix = '';
  19. public static $segments;
  20. public static $rsegments;
  21. public static $controller;
  22. public static $controller_path;
  23. public static $method = 'index';
  24. public static $arguments = array();
  25. /**
  26. * Router setup routine. Automatically called during Kohana setup process.
  27. *
  28. * @return void
  29. */
  30. public static function setup()
  31. {
  32. if ( ! empty($_SERVER['QUERY_STRING']))
  33. {
  34. // Set the query string to the current query string
  35. Router::$query_string = '?'.trim($_SERVER['QUERY_STRING'], '&/');
  36. }
  37. if (Router::$routes === NULL)
  38. {
  39. // Load routes
  40. Router::$routes = Kohana::config('routes');
  41. }
  42. // Default route status
  43. $default_route = FALSE;
  44. if (Router::$current_uri === '')
  45. {
  46. // Make sure the default route is set
  47. if ( ! isset(Router::$routes['_default']))
  48. throw new Kohana_Exception('core.no_default_route');
  49. // Use the default route when no segments exist
  50. Router::$current_uri = Router::$routes['_default'];
  51. // Default route is in use
  52. $default_route = TRUE;
  53. }
  54. // Make sure the URL is not tainted with HTML characters
  55. Router::$current_uri = html::specialchars(Router::$current_uri, FALSE);
  56. // Remove all dot-paths from the URI, they are not valid
  57. Router::$current_uri = preg_replace('#\.[\s./]*/#', '', Router::$current_uri);
  58. // At this point segments, rsegments, and current URI are all the same
  59. Router::$segments = Router::$rsegments = Router::$current_uri = trim(Router::$current_uri, '/');
  60. // Set the complete URI
  61. Router::$complete_uri = Router::$current_uri.Router::$query_string;
  62. // Explode the segments by slashes
  63. Router::$segments = ($default_route === TRUE OR Router::$segments === '') ? array() : explode('/', Router::$segments);
  64. if ($default_route === FALSE AND count(Router::$routes) > 1)
  65. {
  66. // Custom routing
  67. Router::$rsegments = Router::routed_uri(Router::$current_uri);
  68. }
  69. // The routed URI is now complete
  70. Router::$routed_uri = Router::$rsegments;
  71. // Routed segments will never be empty
  72. Router::$rsegments = explode('/', Router::$rsegments);
  73. // Prepare to find the controller
  74. $controller_path = '';
  75. $method_segment = NULL;
  76. // Paths to search
  77. $paths = Kohana::include_paths();
  78. foreach (Router::$rsegments as $key => $segment)
  79. {
  80. // Add the segment to the search path
  81. $controller_path .= $segment;
  82. $found = FALSE;
  83. foreach ($paths as $dir)
  84. {
  85. // Search within controllers only
  86. $dir .= 'controllers/';
  87. if (is_dir($dir.$controller_path) OR is_file($dir.$controller_path.EXT))
  88. {
  89. // Valid path
  90. $found = TRUE;
  91. // The controller must be a file that exists with the search path
  92. if ($c = str_replace('\\', '/', realpath($dir.$controller_path.EXT))
  93. AND is_file($c) AND strpos($c, $dir) === 0)
  94. {
  95. // Set controller name
  96. Router::$controller = $segment;
  97. // Change controller path
  98. Router::$controller_path = $c;
  99. // Set the method segment
  100. $method_segment = $key + 1;
  101. // Stop searching
  102. break;
  103. }
  104. }
  105. }
  106. if ($found === FALSE)
  107. {
  108. // Maximum depth has been reached, stop searching
  109. break;
  110. }
  111. // Add another slash
  112. $controller_path .= '/';
  113. }
  114. if ($method_segment !== NULL AND isset(Router::$rsegments[$method_segment]))
  115. {
  116. // Set method
  117. Router::$method = Router::$rsegments[$method_segment];
  118. if (isset(Router::$rsegments[$method_segment + 1]))
  119. {
  120. // Set arguments
  121. Router::$arguments = array_slice(Router::$rsegments, $method_segment + 1);
  122. }
  123. }
  124. // Last chance to set routing before a 404 is triggered
  125. Event::run('system.post_routing');
  126. if (Router::$controller === NULL)
  127. {
  128. // No controller was found, so no page can be rendered
  129. Event::run('system.404');
  130. }
  131. }
  132. /**
  133. * Attempts to determine the current URI using CLI, GET, PATH_INFO, ORIG_PATH_INFO, or PHP_SELF.
  134. *
  135. * @return void
  136. */
  137. public static function find_uri()
  138. {
  139. if (PHP_SAPI === 'cli')
  140. {
  141. // Command line requires a bit of hacking
  142. if (isset($_SERVER['argv'][1]))
  143. {
  144. Router::$current_uri = $_SERVER['argv'][1];
  145. // Remove GET string from segments
  146. if (($query = strpos(Router::$current_uri, '?')) !== FALSE)
  147. {
  148. list (Router::$current_uri, $query) = explode('?', Router::$current_uri, 2);
  149. // Parse the query string into $_GET
  150. parse_str($query, $_GET);
  151. // Convert $_GET to UTF-8
  152. $_GET = utf8::clean($_GET);
  153. }
  154. }
  155. }
  156. elseif (isset($_GET['kohana_uri']))
  157. {
  158. // Use the URI defined in the query string
  159. Router::$current_uri = $_GET['kohana_uri'];
  160. // Remove the URI from $_GET
  161. unset($_GET['kohana_uri']);
  162. // Remove the URI from $_SERVER['QUERY_STRING']
  163. $_SERVER['QUERY_STRING'] = preg_replace('~\bkohana_uri\b[^&]*+&?~', '', $_SERVER['QUERY_STRING']);
  164. }
  165. elseif (isset($_SERVER['PATH_INFO']) AND $_SERVER['PATH_INFO'])
  166. {
  167. Router::$current_uri = $_SERVER['PATH_INFO'];
  168. }
  169. elseif (isset($_SERVER['ORIG_PATH_INFO']) AND $_SERVER['ORIG_PATH_INFO'])
  170. {
  171. Router::$current_uri = $_SERVER['ORIG_PATH_INFO'];
  172. }
  173. elseif (isset($_SERVER['PHP_SELF']) AND $_SERVER['PHP_SELF'])
  174. {
  175. Router::$current_uri = $_SERVER['PHP_SELF'];
  176. if (($strpos_fc = strpos(Router::$current_uri, KOHANA)) !== FALSE)
  177. {
  178. // Remove the front controller from the current uri
  179. Router::$current_uri = substr(Router::$current_uri, $strpos_fc + strlen(KOHANA));
  180. }
  181. }
  182. // Remove slashes from the start and end of the URI
  183. Router::$current_uri = trim(Router::$current_uri, '/');
  184. if (Router::$current_uri !== '')
  185. {
  186. if ($suffix = Kohana::config('core.url_suffix') AND strpos(Router::$current_uri, $suffix) !== FALSE)
  187. {
  188. // Remove the URL suffix
  189. Router::$current_uri = preg_replace('#'.preg_quote($suffix).'$#u', '', Router::$current_uri);
  190. // Set the URL suffix
  191. Router::$url_suffix = $suffix;
  192. }
  193. // Reduce multiple slashes into single slashes
  194. Router::$current_uri = preg_replace('#//+#', '/', Router::$current_uri);
  195. }
  196. }
  197. /**
  198. * Generates routed URI from given URI.
  199. *
  200. * @param string URI to convert
  201. * @return string Routed uri
  202. */
  203. public static function routed_uri($uri)
  204. {
  205. if (Router::$routes === NULL)
  206. {
  207. // Load routes
  208. Router::$routes = Kohana::config('routes');
  209. }
  210. // Prepare variables
  211. $routed_uri = $uri = trim($uri, '/');
  212. if (isset(Router::$routes[$uri]))
  213. {
  214. // Literal match, no need for regex
  215. $routed_uri = Router::$routes[$uri];
  216. }
  217. else
  218. {
  219. // Loop through the routes and see if anything matches
  220. foreach (Router::$routes as $key => $val)
  221. {
  222. if ($key === '_default') continue;
  223. // Trim slashes
  224. $key = trim($key, '/');
  225. $val = trim($val, '/');
  226. if (preg_match('#^'.$key.'$#u', $uri))
  227. {
  228. if (strpos($val, '$') !== FALSE)
  229. {
  230. // Use regex routing
  231. $routed_uri = preg_replace('#^'.$key.'$#u', $val, $uri);
  232. }
  233. else
  234. {
  235. // Standard routing
  236. $routed_uri = $val;
  237. }
  238. // A valid route has been found
  239. break;
  240. }
  241. }
  242. }
  243. if (isset(Router::$routes[$routed_uri]))
  244. {
  245. // Check for double routing (without regex)
  246. $routed_uri = Router::$routes[$routed_uri];
  247. }
  248. return trim($routed_uri, '/');
  249. }
  250. } // End Router