uri.php 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. <?php
  2. /**
  3. * Part of the Fuel framework.
  4. *
  5. * @package Fuel
  6. * @version 1.5
  7. * @author Fuel Development Team
  8. * @license MIT License
  9. * @copyright 2010 - 2013 Fuel Development Team
  10. * @link http://fuelphp.com
  11. */
  12. namespace Fuel\Core;
  13. /**
  14. * Uri Class
  15. *
  16. * @package Fuel
  17. * @category Core
  18. * @author Dan Horrigan
  19. * @link http://docs.fuelphp.com/classes/uri.html
  20. */
  21. class Uri
  22. {
  23. /**
  24. * Returns the desired segment, or $default if it does not exist.
  25. *
  26. * @param int $segment The segment number (1-based index)
  27. * @param mixed $default Default value to return
  28. * @return string
  29. */
  30. public static function segment($segment, $default = null)
  31. {
  32. if ($request = \Request::active())
  33. {
  34. return $request->uri->get_segment($segment, $default);
  35. }
  36. return null;
  37. }
  38. /**
  39. * Returns all segments in an array
  40. *
  41. * @return array
  42. */
  43. public static function segments()
  44. {
  45. if ($request = \Request::active())
  46. {
  47. return $request->uri->get_segments();
  48. }
  49. return null;
  50. }
  51. /**
  52. * Replace all * wildcards in a URI by the current segment in that location
  53. *
  54. * @return string
  55. */
  56. public static function segment_replace($url)
  57. {
  58. // get the path from the url
  59. $parts = parse_url($url);
  60. // explode it in it's segments
  61. $segments = explode('/', trim($parts['path'], '/'));
  62. // fetch any segments needed
  63. $wildcards = 0;
  64. foreach ($segments as $index => &$segment)
  65. {
  66. if (strpos($segment, '*') !== false)
  67. {
  68. $wildcards++;
  69. if (($new = static::segment($index)) === null)
  70. {
  71. throw new \OutofBoundsException('Segment replace on "'.$url.'" failed. No segment exists for wildcard '.$wildcards.'.');
  72. }
  73. $segment = str_replace('*', $new, $segment);
  74. }
  75. }
  76. // re-assemble the path
  77. $parts['path'] = implode('/', $segments);
  78. $url = implode('/', $parts);
  79. return $url;
  80. }
  81. /**
  82. * Converts the current URI segments to an associative array. If
  83. * the URI has an odd number of segments, an empty value will be added.
  84. *
  85. * @param int segment number to start from. default value is the first segment
  86. * @return array the assoc array
  87. */
  88. public static function to_assoc($start = 1)
  89. {
  90. $segments = array_slice(static::segments(), ($start - 1));
  91. count($segments) % 2 and $segments[] = null;
  92. return \Arr::to_assoc($segments);
  93. }
  94. /**
  95. * Returns the full uri as a string
  96. *
  97. * @return string
  98. */
  99. public static function string()
  100. {
  101. if ($request = \Request::active())
  102. {
  103. return $request->uri->get();
  104. }
  105. return null;
  106. }
  107. /**
  108. * Creates a url with the given uri, including the base url
  109. *
  110. * @param string $uri The uri to create the URL for
  111. * @param array $variables Some variables for the URL
  112. * @param array $get_variables Any GET urls to append via a query string
  113. * @param bool $secure If false, force http. If true, force https
  114. * @return string
  115. */
  116. public static function create($uri = null, $variables = array(), $get_variables = array(), $secure = null)
  117. {
  118. $url = '';
  119. $uri = $uri ?: static::string();
  120. // If the given uri is not a full URL
  121. if( ! preg_match("#^(http|https|ftp)://#i", $uri))
  122. {
  123. $url .= \Config::get('base_url');
  124. if ($index_file = \Config::get('index_file'))
  125. {
  126. $url .= $index_file.'/';
  127. }
  128. }
  129. $url .= ltrim($uri, '/');
  130. // Add a url_suffix if defined and the url doesn't already have one
  131. if (substr($url, -1) != '/' and (($suffix = strrchr($url, '.')) === false or strlen($suffix) > 5))
  132. {
  133. \Config::get('url_suffix') and $url .= \Config::get('url_suffix');
  134. }
  135. if ( ! empty($get_variables))
  136. {
  137. $char = strpos($url, '?') === false ? '?' : '&';
  138. if (is_string($get_variables))
  139. {
  140. $url .= $char.str_replace('%3A', ':', $get_variables);
  141. }
  142. else
  143. {
  144. $url .= $char.str_replace('%3A', ':', http_build_query($get_variables));
  145. }
  146. }
  147. array_walk(
  148. $variables,
  149. function ($val, $key) use (&$url)
  150. {
  151. $url = str_replace(':'.$key, $val, $url);
  152. }
  153. );
  154. is_bool($secure) and $url = http_build_url($url, array('scheme' => $secure ? 'https' : 'http'));
  155. return $url;
  156. }
  157. /**
  158. * Gets the main request's URI
  159. *
  160. * @return string
  161. */
  162. public static function main()
  163. {
  164. return static::create(\Request::main()->uri->get());
  165. }
  166. /**
  167. * Gets the current URL, including the BASE_URL
  168. *
  169. * @return string
  170. */
  171. public static function current()
  172. {
  173. return static::create();
  174. }
  175. /**
  176. * Gets the base URL, including the index_file if wanted.
  177. *
  178. * @param bool $include_index Whether to include index.php in the URL
  179. * @return string
  180. */
  181. public static function base($include_index = true)
  182. {
  183. $url = \Config::get('base_url');
  184. if ($include_index and \Config::get('index_file'))
  185. {
  186. $url .= \Config::get('index_file').'/';
  187. }
  188. return $url;
  189. }
  190. /**
  191. * @var string The URI string
  192. */
  193. protected $uri = '';
  194. /**
  195. * @var array The URI segments
  196. */
  197. protected $segments = '';
  198. /**
  199. * Construct takes a URI or detects it if none is given and generates
  200. * the segments.
  201. *
  202. * @param string The URI
  203. * @return void
  204. */
  205. public function __construct($uri = null)
  206. {
  207. if (\Fuel::$profiling)
  208. {
  209. \Profiler::mark(__METHOD__.' Start');
  210. }
  211. // if the route is a closure, an object will be passed here
  212. is_object($uri) and $uri = null;
  213. $this->uri = trim($uri ?: \Input::uri(), '/');
  214. if (empty($this->uri))
  215. {
  216. $this->segments = array();
  217. }
  218. else
  219. {
  220. $this->segments = explode('/', $this->uri);
  221. }
  222. if (\Fuel::$profiling)
  223. {
  224. \Profiler::mark(__METHOD__.' End');
  225. }
  226. }
  227. /**
  228. * Returns the full URI string
  229. *
  230. * @return string The URI string
  231. */
  232. public function get()
  233. {
  234. return $this->uri;
  235. }
  236. /**
  237. * Returns all of the URI segments
  238. *
  239. * @return array The URI segments
  240. */
  241. public function get_segments()
  242. {
  243. return $this->segments;
  244. }
  245. /**
  246. * Get the specified URI segment, return default if it doesn't exist.
  247. *
  248. * Segment index is 1 based, not 0 based
  249. *
  250. * @param string $segment The 1-based segment index
  251. * @param mixed $default The default value
  252. * @return mixed
  253. */
  254. public function get_segment($segment, $default = null)
  255. {
  256. if (isset($this->segments[$segment - 1]))
  257. {
  258. return $this->segments[$segment - 1];
  259. }
  260. return \Fuel::value($default);
  261. }
  262. /**
  263. * Returns the URI string
  264. *
  265. * @return string
  266. */
  267. public function __toString()
  268. {
  269. return $this->get();
  270. }
  271. }