PageRenderTime 43ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/classes/uri.php

http://github.com/fuel/core
PHP | 394 lines | 195 code | 50 blank | 149 comment | 21 complexity | ac6bbc6229ca5cb58cdfe53bea045599 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. /**
  3. * Fuel is a fast, lightweight, community driven PHP 5.4+ framework.
  4. *
  5. * @package Fuel
  6. * @version 1.9-dev
  7. * @author Fuel Development Team
  8. * @license MIT License
  9. * @copyright 2010 - 2019 Fuel Development Team
  10. * @link https://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. * @param string $url The url containing the wildcards
  55. * @param bool $secure To force a particular HTTP scheme
  56. * @return string
  57. */
  58. public static function segment_replace($url, $secure = null)
  59. {
  60. // get the path from the url
  61. $parts = parse_url($url);
  62. // explode it in it's segments
  63. $segments = explode('/', trim($parts['path'], '/'));
  64. // fetch any segments needed
  65. $wildcards = 0;
  66. foreach ($segments as $index => &$segment)
  67. {
  68. if (strpos($segment, '*') !== false)
  69. {
  70. $wildcards++;
  71. if (($new = static::segment($index+1)) === null)
  72. {
  73. throw new \OutofBoundsException('Segment replace on "'.$url.'" failed. No segment exists for wildcard '.$wildcards.'.');
  74. }
  75. $segment = str_replace('*', $new, $segment);
  76. }
  77. }
  78. // re-assemble the path
  79. $parts['path'] = '/'.implode('/', $segments);
  80. // do we need to force a scheme?
  81. if (is_bool($secure))
  82. {
  83. $parts['scheme'] = $secure ? 'https' : 'http';
  84. }
  85. // and rebuild the url with the new path
  86. if (empty($parts['host']))
  87. {
  88. // if a relative url was given, fake a host so we can remove it after building
  89. $url = substr(http_build_url('http://__removethis__/', $parts), 22);
  90. }
  91. else
  92. {
  93. // a hostname was present, just rebuild it
  94. $url = http_build_url('', $parts);
  95. }
  96. // return the newly constructed url
  97. return $url;
  98. }
  99. /**
  100. * Converts the current URI segments to an associative array. If
  101. * the URI has an odd number of segments, an empty value will be added.
  102. *
  103. * @param int $start segment number to start from. default value is the first segment
  104. * @return array the assoc array
  105. */
  106. public static function to_assoc($start = 1)
  107. {
  108. $segments = array_slice(static::segments(), ($start - 1));
  109. count($segments) % 2 and $segments[] = null;
  110. return \Arr::to_assoc($segments);
  111. }
  112. /**
  113. * Returns the full uri as a string
  114. *
  115. * @return string
  116. */
  117. public static function string()
  118. {
  119. if ($request = \Request::active())
  120. {
  121. return $request->uri->get();
  122. }
  123. return null;
  124. }
  125. /**
  126. * Creates a url with the given uri, including the base url
  127. *
  128. * @param string $uri The uri to create the URL for
  129. * @param array $variables Some variables for the URL
  130. * @param array $get_variables Any GET urls to append via a query string
  131. * @param bool $secure If false, force http. If true, force https
  132. * @return string
  133. */
  134. public static function create($uri = null, $variables = array(), $get_variables = array(), $secure = null)
  135. {
  136. $url = '';
  137. is_null($uri) and $uri = static::string();
  138. // If the given uri is not a full URL
  139. if( ! preg_match("#^(http|https|ftp)://#i", $uri))
  140. {
  141. $url .= \Config::get('base_url');
  142. if ($index_file = \Config::get('index_file'))
  143. {
  144. $url .= $index_file.'/';
  145. }
  146. }
  147. $url .= ltrim($uri, '/');
  148. // stick a url suffix onto it if defined and needed
  149. if ($url_suffix = \Config::get('url_suffix', false) and substr($url, -1) != '/')
  150. {
  151. $current_suffix = strrchr($url, '.');
  152. if ( ! $current_suffix or strpos($current_suffix, '/') !== false)
  153. {
  154. $url .= $url_suffix;
  155. }
  156. }
  157. if ( ! empty($get_variables))
  158. {
  159. $char = strpos($url, '?') === false ? '?' : '&';
  160. if (is_string($get_variables))
  161. {
  162. $url .= $char.str_replace('%3A', ':', $get_variables);
  163. }
  164. else
  165. {
  166. $url .= $char.str_replace('%3A', ':', http_build_query($get_variables));
  167. }
  168. }
  169. array_walk(
  170. $variables,
  171. function ($val, $key) use (&$url)
  172. {
  173. $url = str_replace(':'.$key, $val, $url);
  174. }
  175. );
  176. is_bool($secure) and $url = http_build_url($url, array('scheme' => $secure ? 'https' : 'http'));
  177. return $url;
  178. }
  179. /**
  180. * Gets the main request's URI
  181. *
  182. * @return string
  183. */
  184. public static function main()
  185. {
  186. return static::create(\Request::main()->uri->get());
  187. }
  188. /**
  189. * Gets the current URL, including the BASE_URL
  190. *
  191. * @return string
  192. */
  193. public static function current()
  194. {
  195. return static::create();
  196. }
  197. /**
  198. * Gets the base URL, including the index_file if wanted.
  199. *
  200. * @param bool $include_index Whether to include index.php in the URL
  201. * @return string
  202. */
  203. public static function base($include_index = true)
  204. {
  205. $url = \Config::get('base_url');
  206. if ($include_index and \Config::get('index_file'))
  207. {
  208. $url .= \Config::get('index_file').'/';
  209. }
  210. return $url;
  211. }
  212. /**
  213. * Builds a query string by merging all array and string values passed. If
  214. * a string is passed, it will be assumed to be a switch, and converted
  215. * to "string=1".
  216. *
  217. * @param array|string Array or string to merge
  218. * @param array|string ...
  219. *
  220. * @return string
  221. */
  222. public static function build_query_string()
  223. {
  224. $params = array();
  225. foreach (func_get_args() as $arg)
  226. {
  227. $arg = is_array($arg) ? $arg : array($arg => '1');
  228. $params = array_merge($params, $arg);
  229. }
  230. return http_build_query($params);
  231. }
  232. /**
  233. * Updates the query string of the current or passed URL with the data passed
  234. *
  235. * @param array|string $vars Assoc array of GET variables, or a get variable name
  236. * @param string|mixed $uri Optional URI to use if $vars is an array, otherwise the get variable name
  237. * @param bool $secure If false, force http. If true, force https
  238. *
  239. * @return string
  240. */
  241. public static function update_query_string($vars = array(), $uri = null, $secure = null)
  242. {
  243. // unify the input data
  244. if ( ! is_array($vars))
  245. {
  246. $vars = array($vars => $uri);
  247. $uri = null;
  248. }
  249. // if we have a custom URI, use that
  250. if ($uri === null)
  251. {
  252. // use the current URI if not is passed
  253. $uri = static::current();
  254. // merge them with the existing query string data
  255. $vars = array_merge(\Input::get(), $vars);
  256. }
  257. // return the updated uri
  258. return static::create($uri, array(), $vars, $secure);
  259. }
  260. /**
  261. * @var string The URI string
  262. */
  263. protected $uri = '';
  264. /**
  265. * @var array The URI segments
  266. */
  267. protected $segments = '';
  268. /**
  269. * Construct takes a URI or detects it if none is given and generates
  270. * the segments.
  271. *
  272. * @param string $uri The URI
  273. */
  274. public function __construct($uri = null)
  275. {
  276. if (\Fuel::$profiling)
  277. {
  278. \Profiler::mark(__METHOD__.' Start');
  279. }
  280. // if the route is a closure, an object will be passed here
  281. is_object($uri) and $uri = null;
  282. // if no uri is passed, get it from input
  283. is_null($uri) and $uri = \Input::uri();
  284. // store the uri
  285. $this->uri = trim($uri, '/');
  286. // determine the uri segment list
  287. if (empty($uri))
  288. {
  289. $this->segments = array();
  290. }
  291. else
  292. {
  293. $this->segments = explode('/', $this->uri);
  294. }
  295. if (\Fuel::$profiling)
  296. {
  297. \Profiler::mark(__METHOD__.' End');
  298. }
  299. }
  300. /**
  301. * Returns the full URI string
  302. *
  303. * @return string The URI string
  304. */
  305. public function get()
  306. {
  307. return $this->uri;
  308. }
  309. /**
  310. * Returns all of the URI segments
  311. *
  312. * @return array The URI segments
  313. */
  314. public function get_segments()
  315. {
  316. return $this->segments;
  317. }
  318. /**
  319. * Get the specified URI segment, return default if it doesn't exist.
  320. *
  321. * Segment index is 1 based, not 0 based
  322. *
  323. * @param string $segment The 1-based segment index
  324. * @param mixed $default The default value
  325. * @return mixed
  326. */
  327. public function get_segment($segment, $default = null)
  328. {
  329. if (isset($this->segments[$segment - 1]))
  330. {
  331. return $this->segments[$segment - 1];
  332. }
  333. return \Fuel::value($default);
  334. }
  335. /**
  336. * Returns the URI string
  337. *
  338. * @return string
  339. */
  340. public function __toString()
  341. {
  342. return $this->get();
  343. }
  344. }