PageRenderTime 24ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/system/libraries/URI.php

https://gitlab.com/sandipmavani/rspsms
PHP | 585 lines | 259 code | 73 blank | 253 comment | 55 complexity | f7964b3d46a8ff8df46711fae6e244e5 MD5 | raw file
  1. <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  2. /**
  3. * CodeIgniter
  4. *
  5. * An open source application development framework for PHP 4.3.2 or newer
  6. *
  7. * @package CodeIgniter
  8. * @author ExpressionEngine Dev Team
  9. * @copyright Copyright (c) 2008, EllisLab, Inc.
  10. * @license http://codeigniter.com/user_guide/license.html
  11. * @link http://codeigniter.com
  12. * @since Version 1.0
  13. * @filesource
  14. */
  15. // ------------------------------------------------------------------------
  16. /**
  17. * URI Class
  18. *
  19. * Parses URIs and determines routing
  20. *
  21. * @package CodeIgniter
  22. * @subpackage Libraries
  23. * @category URI
  24. * @author ExpressionEngine Dev Team
  25. * @link http://codeigniter.com/user_guide/libraries/uri.html
  26. */
  27. class CI_URI {
  28. var $keyval = array();
  29. var $uri_string;
  30. var $segments = array();
  31. var $rsegments = array();
  32. /**
  33. * Constructor
  34. *
  35. * Simply globalizes the $RTR object. The front
  36. * loads the Router class early on so it's not available
  37. * normally as other classes are.
  38. *
  39. * @access public
  40. */
  41. function CI_URI()
  42. {
  43. $this->config =& load_class('Config');
  44. log_message('debug', "URI Class Initialized");
  45. }
  46. // --------------------------------------------------------------------
  47. /**
  48. * Get the URI String
  49. *
  50. * @access private
  51. * @return string
  52. */
  53. function _fetch_uri_string()
  54. {
  55. if (strtoupper($this->config->item('uri_protocol')) == 'AUTO')
  56. {
  57. // If the URL has a question mark then it's simplest to just
  58. // build the URI string from the zero index of the $_GET array.
  59. // This avoids having to deal with $_SERVER variables, which
  60. // can be unreliable in some environments
  61. if (is_array($_GET) && count($_GET) == 1 && trim(key($_GET), '/') != '')
  62. {
  63. $this->uri_string = key($_GET);
  64. return;
  65. }
  66. // Is there a PATH_INFO variable?
  67. // Note: some servers seem to have trouble with getenv() so we'll test it two ways
  68. $path = (isset($_SERVER['PATH_INFO'])) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO');
  69. if (trim($path, '/') != '' && $path != "/".SELF)
  70. {
  71. $this->uri_string = $path;
  72. return;
  73. }
  74. // No PATH_INFO?... What about QUERY_STRING?
  75. $path = (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING');
  76. if (trim($path, '/') != '')
  77. {
  78. $this->uri_string = $path;
  79. return;
  80. }
  81. // No QUERY_STRING?... Maybe the ORIG_PATH_INFO variable exists?
  82. $path = (isset($_SERVER['ORIG_PATH_INFO'])) ? $_SERVER['ORIG_PATH_INFO'] : @getenv('ORIG_PATH_INFO');
  83. if (trim($path, '/') != '' && $path != "/".SELF)
  84. {
  85. // remove path and script information so we have good URI data
  86. $this->uri_string = str_replace($_SERVER['SCRIPT_NAME'], '', $path);
  87. return;
  88. }
  89. // We've exhausted all our options...
  90. $this->uri_string = '';
  91. }
  92. else
  93. {
  94. $uri = strtoupper($this->config->item('uri_protocol'));
  95. if ($uri == 'REQUEST_URI')
  96. {
  97. $this->uri_string = $this->_parse_request_uri();
  98. return;
  99. }
  100. $this->uri_string = (isset($_SERVER[$uri])) ? $_SERVER[$uri] : @getenv($uri);
  101. }
  102. // If the URI contains only a slash we'll kill it
  103. if ($this->uri_string == '/')
  104. {
  105. $this->uri_string = '';
  106. }
  107. }
  108. // --------------------------------------------------------------------
  109. /**
  110. * Parse the REQUEST_URI
  111. *
  112. * Due to the way REQUEST_URI works it usually contains path info
  113. * that makes it unusable as URI data. We'll trim off the unnecessary
  114. * data, hopefully arriving at a valid URI that we can use.
  115. *
  116. * @access private
  117. * @return string
  118. */
  119. function _parse_request_uri()
  120. {
  121. if ( ! isset($_SERVER['REQUEST_URI']) OR $_SERVER['REQUEST_URI'] == '')
  122. {
  123. return '';
  124. }
  125. $request_uri = preg_replace("|/(.*)|", "\\1", str_replace("\\", "/", $_SERVER['REQUEST_URI']));
  126. if ($request_uri == '' OR $request_uri == SELF)
  127. {
  128. return '';
  129. }
  130. $fc_path = FCPATH;
  131. if (strpos($request_uri, '?') !== FALSE)
  132. {
  133. $fc_path .= '?';
  134. }
  135. $parsed_uri = explode("/", $request_uri);
  136. $i = 0;
  137. foreach(explode("/", $fc_path) as $segment)
  138. {
  139. if (isset($parsed_uri[$i]) && $segment == $parsed_uri[$i])
  140. {
  141. $i++;
  142. }
  143. }
  144. $parsed_uri = implode("/", array_slice($parsed_uri, $i));
  145. if ($parsed_uri != '')
  146. {
  147. $parsed_uri = '/'.$parsed_uri;
  148. }
  149. return $parsed_uri;
  150. }
  151. // --------------------------------------------------------------------
  152. /**
  153. * Filter segments for malicious characters
  154. *
  155. * @access private
  156. * @param string
  157. * @return string
  158. */
  159. function _filter_uri($str)
  160. {
  161. if ($str != '' && $this->config->item('permitted_uri_chars') != '' && $this->config->item('enable_query_strings') == FALSE)
  162. {
  163. if ( ! preg_match("|^[".preg_quote($this->config->item('permitted_uri_chars'))."]+$|i", $str))
  164. {
  165. header('HTTP/1.1 400 Bad Request');
  166. show_error('The URI you submitted has disallowed characters.');
  167. }
  168. }
  169. // Convert programatic characters to entities
  170. $bad = array('$', '(', ')', '%28', '%29');
  171. $good = array('&#36;', '&#40;', '&#41;', '&#40;', '&#41;');
  172. return str_replace($bad, $good, $str);
  173. }
  174. // --------------------------------------------------------------------
  175. /**
  176. * Remove the suffix from the URL if needed
  177. *
  178. * @access private
  179. * @return void
  180. */
  181. function _remove_url_suffix()
  182. {
  183. if ($this->config->item('url_suffix') != "")
  184. {
  185. $this->uri_string = preg_replace("|".preg_quote($this->config->item('url_suffix'))."$|", "", $this->uri_string);
  186. }
  187. }
  188. // --------------------------------------------------------------------
  189. /**
  190. * Explode the URI Segments. The individual segments will
  191. * be stored in the $this->segments array.
  192. *
  193. * @access private
  194. * @return void
  195. */
  196. function _explode_segments()
  197. {
  198. foreach(explode("/", preg_replace("|/*(.+?)/*$|", "\\1", $this->uri_string)) as $val)
  199. {
  200. // Filter segments for security
  201. $val = trim($this->_filter_uri($val));
  202. if ($val != '')
  203. {
  204. $this->segments[] = $val;
  205. }
  206. }
  207. }
  208. // --------------------------------------------------------------------
  209. /**
  210. * Re-index Segments
  211. *
  212. * This function re-indexes the $this->segment array so that it
  213. * starts at 1 rather than 0. Doing so makes it simpler to
  214. * use functions like $this->uri->segment(n) since there is
  215. * a 1:1 relationship between the segment array and the actual segments.
  216. *
  217. * @access private
  218. * @return void
  219. */
  220. function _reindex_segments()
  221. {
  222. array_unshift($this->segments, NULL);
  223. array_unshift($this->rsegments, NULL);
  224. unset($this->segments[0]);
  225. unset($this->rsegments[0]);
  226. }
  227. // --------------------------------------------------------------------
  228. /**
  229. * Fetch a URI Segment
  230. *
  231. * This function returns the URI segment based on the number provided.
  232. *
  233. * @access public
  234. * @param integer
  235. * @param bool
  236. * @return string
  237. */
  238. function segment($n, $no_result = FALSE)
  239. {
  240. return ( ! isset($this->segments[$n])) ? $no_result : $this->segments[$n];
  241. }
  242. // --------------------------------------------------------------------
  243. /**
  244. * Fetch a URI "routed" Segment
  245. *
  246. * This function returns the re-routed URI segment (assuming routing rules are used)
  247. * based on the number provided. If there is no routing this function returns the
  248. * same result as $this->segment()
  249. *
  250. * @access public
  251. * @param integer
  252. * @param bool
  253. * @return string
  254. */
  255. function rsegment($n, $no_result = FALSE)
  256. {
  257. return ( ! isset($this->rsegments[$n])) ? $no_result : $this->rsegments[$n];
  258. }
  259. // --------------------------------------------------------------------
  260. /**
  261. * Generate a key value pair from the URI string
  262. *
  263. * This function generates and associative array of URI data starting
  264. * at the supplied segment. For example, if this is your URI:
  265. *
  266. * example.com/user/search/name/joe/location/UK/gender/male
  267. *
  268. * You can use this function to generate an array with this prototype:
  269. *
  270. * array (
  271. * name => joe
  272. * location => UK
  273. * gender => male
  274. * )
  275. *
  276. * @access public
  277. * @param integer the starting segment number
  278. * @param array an array of default values
  279. * @return array
  280. */
  281. function uri_to_assoc($n = 3, $default = array())
  282. {
  283. return $this->_uri_to_assoc($n, $default, 'segment');
  284. }
  285. /**
  286. * Identical to above only it uses the re-routed segment array
  287. *
  288. */
  289. function ruri_to_assoc($n = 3, $default = array())
  290. {
  291. return $this->_uri_to_assoc($n, $default, 'rsegment');
  292. }
  293. // --------------------------------------------------------------------
  294. /**
  295. * Generate a key value pair from the URI string or Re-routed URI string
  296. *
  297. * @access private
  298. * @param integer the starting segment number
  299. * @param array an array of default values
  300. * @param string which array we should use
  301. * @return array
  302. */
  303. function _uri_to_assoc($n = 3, $default = array(), $which = 'segment')
  304. {
  305. if ($which == 'segment')
  306. {
  307. $total_segments = 'total_segments';
  308. $segment_array = 'segment_array';
  309. }
  310. else
  311. {
  312. $total_segments = 'total_rsegments';
  313. $segment_array = 'rsegment_array';
  314. }
  315. if ( ! is_numeric($n))
  316. {
  317. return $default;
  318. }
  319. if (isset($this->keyval[$n]))
  320. {
  321. return $this->keyval[$n];
  322. }
  323. if ($this->$total_segments() < $n)
  324. {
  325. if (count($default) == 0)
  326. {
  327. return array();
  328. }
  329. $retval = array();
  330. foreach ($default as $val)
  331. {
  332. $retval[$val] = FALSE;
  333. }
  334. return $retval;
  335. }
  336. $segments = array_slice($this->$segment_array(), ($n - 1));
  337. $i = 0;
  338. $lastval = '';
  339. $retval = array();
  340. foreach ($segments as $seg)
  341. {
  342. if ($i % 2)
  343. {
  344. $retval[$lastval] = $seg;
  345. }
  346. else
  347. {
  348. $retval[$seg] = FALSE;
  349. $lastval = $seg;
  350. }
  351. $i++;
  352. }
  353. if (count($default) > 0)
  354. {
  355. foreach ($default as $val)
  356. {
  357. if ( ! array_key_exists($val, $retval))
  358. {
  359. $retval[$val] = FALSE;
  360. }
  361. }
  362. }
  363. // Cache the array for reuse
  364. $this->keyval[$n] = $retval;
  365. return $retval;
  366. }
  367. // --------------------------------------------------------------------
  368. /**
  369. * Generate a URI string from an associative array
  370. *
  371. *
  372. * @access public
  373. * @param array an associative array of key/values
  374. * @return array
  375. */
  376. function assoc_to_uri($array)
  377. {
  378. $temp = array();
  379. foreach ((array)$array as $key => $val)
  380. {
  381. $temp[] = $key;
  382. $temp[] = $val;
  383. }
  384. return implode('/', $temp);
  385. }
  386. // --------------------------------------------------------------------
  387. /**
  388. * Fetch a URI Segment and add a trailing slash
  389. *
  390. * @access public
  391. * @param integer
  392. * @param string
  393. * @return string
  394. */
  395. function slash_segment($n, $where = 'trailing')
  396. {
  397. return $this->_slash_segment($n, $where, 'segment');
  398. }
  399. // --------------------------------------------------------------------
  400. /**
  401. * Fetch a URI Segment and add a trailing slash
  402. *
  403. * @access public
  404. * @param integer
  405. * @param string
  406. * @return string
  407. */
  408. function slash_rsegment($n, $where = 'trailing')
  409. {
  410. return $this->_slash_segment($n, $where, 'rsegment');
  411. }
  412. // --------------------------------------------------------------------
  413. /**
  414. * Fetch a URI Segment and add a trailing slash - helper function
  415. *
  416. * @access private
  417. * @param integer
  418. * @param string
  419. * @param string
  420. * @return string
  421. */
  422. function _slash_segment($n, $where = 'trailing', $which = 'segment')
  423. {
  424. if ($where == 'trailing')
  425. {
  426. $trailing = '/';
  427. $leading = '';
  428. }
  429. elseif ($where == 'leading')
  430. {
  431. $leading = '/';
  432. $trailing = '';
  433. }
  434. else
  435. {
  436. $leading = '/';
  437. $trailing = '/';
  438. }
  439. return $leading.$this->$which($n).$trailing;
  440. }
  441. // --------------------------------------------------------------------
  442. /**
  443. * Segment Array
  444. *
  445. * @access public
  446. * @return array
  447. */
  448. function segment_array()
  449. {
  450. return $this->segments;
  451. }
  452. // --------------------------------------------------------------------
  453. /**
  454. * Routed Segment Array
  455. *
  456. * @access public
  457. * @return array
  458. */
  459. function rsegment_array()
  460. {
  461. return $this->rsegments;
  462. }
  463. // --------------------------------------------------------------------
  464. /**
  465. * Total number of segments
  466. *
  467. * @access public
  468. * @return integer
  469. */
  470. function total_segments()
  471. {
  472. return count($this->segments);
  473. }
  474. // --------------------------------------------------------------------
  475. /**
  476. * Total number of routed segments
  477. *
  478. * @access public
  479. * @return integer
  480. */
  481. function total_rsegments()
  482. {
  483. return count($this->rsegments);
  484. }
  485. // --------------------------------------------------------------------
  486. /**
  487. * Fetch the entire URI string
  488. *
  489. * @access public
  490. * @return string
  491. */
  492. function uri_string()
  493. {
  494. return $this->uri_string;
  495. }
  496. // --------------------------------------------------------------------
  497. /**
  498. * Fetch the entire Re-routed URI string
  499. *
  500. * @access public
  501. * @return string
  502. */
  503. function ruri_string()
  504. {
  505. return '/'.implode('/', $this->rsegment_array()).'/';
  506. }
  507. }
  508. // END URI Class
  509. /* End of file URI.php */
  510. /* Location: ./system/libraries/URI.php */