blob: d9f4e3bdfe7a6a6546fd9fd8c3ae1802c632e9a0 [file] [log] [blame]
Andrey Andreevc123e112012-01-08 00:17:34 +02001<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +00002/**
3 * CodeIgniter
4 *
Greg Aker741de1c2010-11-10 14:52:57 -06005 * An open source application development framework for PHP 5.1.6 or newer
Derek Allard2067d1a2008-11-13 22:59:24 +00006 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05007 * NOTICE OF LICENSE
Andrey Andreevc123e112012-01-08 00:17:34 +02008 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05009 * Licensed under the Open Software License version 3.0
Andrey Andreevc123e112012-01-08 00:17:34 +020010 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -050011 * This source file is subject to the Open Software License (OSL 3.0) that is
12 * bundled with this package in the files license.txt / license.rst. It is
13 * also available through the world wide web at this URL:
14 * http://opensource.org/licenses/OSL-3.0
15 * If you did not receive a copy of the license and are unable to obtain it
16 * through the world wide web, please send an email to
17 * licensing@ellislab.com so we can send you a copy immediately.
18 *
Derek Allard2067d1a2008-11-13 22:59:24 +000019 * @package CodeIgniter
Derek Jonesf4a4bd82011-10-20 12:18:42 -050020 * @author EllisLab Dev Team
Greg Aker0defe5d2012-01-01 18:46:41 -060021 * @copyright Copyright (c) 2008 - 2012, EllisLab, Inc. (http://ellislab.com/)
Derek Jonesf4a4bd82011-10-20 12:18:42 -050022 * @license http://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
Derek Allard2067d1a2008-11-13 22:59:24 +000023 * @link http://codeigniter.com
24 * @since Version 1.0
Derek Allard2067d1a2008-11-13 22:59:24 +000025 */
26
27// ------------------------------------------------------------------------
28
29/**
30 * URI Class
31 *
32 * Parses URIs and determines routing
33 *
34 * @package CodeIgniter
35 * @subpackage Libraries
36 * @category URI
Derek Jonesf4a4bd82011-10-20 12:18:42 -050037 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +000038 * @link http://codeigniter.com/user_guide/libraries/uri.html
39 */
40class CI_URI {
41
David Behler07b53422011-08-15 00:25:06 +020042 /**
43 * List of cached uri segments
44 *
45 * @var array
David Behler07b53422011-08-15 00:25:06 +020046 */
Andrey Andreevc123e112012-01-08 00:17:34 +020047 public $keyval = array();
David Behler07b53422011-08-15 00:25:06 +020048 /**
49 * Current uri string
50 *
51 * @var string
David Behler07b53422011-08-15 00:25:06 +020052 */
Andrey Andreevc123e112012-01-08 00:17:34 +020053 public $uri_string;
David Behler07b53422011-08-15 00:25:06 +020054 /**
55 * List of uri segments
56 *
57 * @var array
David Behler07b53422011-08-15 00:25:06 +020058 */
Andrey Andreevc123e112012-01-08 00:17:34 +020059 public $segments = array();
David Behler07b53422011-08-15 00:25:06 +020060 /**
61 * Re-indexed list of uri segments
62 * Starts at 1 instead of 0
63 *
64 * @var array
David Behler07b53422011-08-15 00:25:06 +020065 */
Andrey Andreevc123e112012-01-08 00:17:34 +020066 public $rsegments = array();
Derek Allard2067d1a2008-11-13 22:59:24 +000067
68 /**
69 * Constructor
70 *
Andrey Andreevc123e112012-01-08 00:17:34 +020071 * Simply globalizes the $RTR object. The front
Derek Allard2067d1a2008-11-13 22:59:24 +000072 * loads the Router class early on so it's not available
73 * normally as other classes are.
Derek Allard2067d1a2008-11-13 22:59:24 +000074 */
Andrey Andreevc123e112012-01-08 00:17:34 +020075 public function __construct()
Derek Allard2067d1a2008-11-13 22:59:24 +000076 {
Derek Jones7576a3b2010-03-02 14:00:36 -060077 $this->config =& load_class('Config', 'core');
Andrey Andreevc123e112012-01-08 00:17:34 +020078 log_message('debug', 'URI Class Initialized');
Derek Allard2067d1a2008-11-13 22:59:24 +000079 }
80
Derek Allard2067d1a2008-11-13 22:59:24 +000081 // --------------------------------------------------------------------
82
83 /**
84 * Get the URI String
85 *
Andrey Andreevc123e112012-01-08 00:17:34 +020086 * Called by CI_Router
87 *
88 * @return void
Derek Allard2067d1a2008-11-13 22:59:24 +000089 */
Andrey Andreevc123e112012-01-08 00:17:34 +020090 public function _fetch_uri_string()
Derek Allard2067d1a2008-11-13 22:59:24 +000091 {
Andrey Andreevc123e112012-01-08 00:17:34 +020092 if (strtoupper($this->config->item('uri_protocol')) === 'AUTO')
Derek Allard2067d1a2008-11-13 22:59:24 +000093 {
Phil Sturgeondda07e92011-01-31 23:26:25 +000094 // Is the request coming from the command line?
Stephen2e00c242011-08-28 10:25:40 +020095 if ($this->_is_cli_request())
Derek Allard2067d1a2008-11-13 22:59:24 +000096 {
Pascal Kriete73598e32011-04-05 15:01:05 -040097 $this->_set_uri_string($this->_parse_cli_args());
Phil Sturgeon48c718c2010-12-30 23:40:02 +000098 return;
99 }
100
Dan Horriganfea45ad2011-01-19 00:54:12 -0500101 // Let's try the REQUEST_URI first, this will work in most situations
102 if ($uri = $this->_detect_uri())
103 {
Pascal Kriete73598e32011-04-05 15:01:05 -0400104 $this->_set_uri_string($uri);
Derek Allard2067d1a2008-11-13 22:59:24 +0000105 return;
106 }
107
108 // Is there a PATH_INFO variable?
109 // Note: some servers seem to have trouble with getenv() so we'll test it two ways
110 $path = (isset($_SERVER['PATH_INFO'])) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO');
Andrey Andreevc123e112012-01-08 00:17:34 +0200111 if (trim($path, '/') != '' && $path !== '/'.SELF)
Derek Allard2067d1a2008-11-13 22:59:24 +0000112 {
Pascal Kriete73598e32011-04-05 15:01:05 -0400113 $this->_set_uri_string($path);
Derek Allard2067d1a2008-11-13 22:59:24 +0000114 return;
115 }
116
117 // No PATH_INFO?... What about QUERY_STRING?
Andrey Andreevc123e112012-01-08 00:17:34 +0200118 $path = (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING');
Derek Allard2067d1a2008-11-13 22:59:24 +0000119 if (trim($path, '/') != '')
120 {
Pascal Kriete73598e32011-04-05 15:01:05 -0400121 $this->_set_uri_string($path);
Derek Allard2067d1a2008-11-13 22:59:24 +0000122 return;
123 }
124
Dan Horrigan65d603e2010-12-15 08:38:30 -0500125 // As a last ditch effort lets try using the $_GET array
Andrey Andreevc123e112012-01-08 00:17:34 +0200126 if (is_array($_GET) && count($_GET) === 1 && trim(key($_GET), '/') != '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000127 {
Pascal Kriete73598e32011-04-05 15:01:05 -0400128 $this->_set_uri_string(key($_GET));
Derek Allard2067d1a2008-11-13 22:59:24 +0000129 return;
130 }
131
132 // We've exhausted all our options...
133 $this->uri_string = '';
Pascal Kriete73598e32011-04-05 15:01:05 -0400134 return;
Derek Allard2067d1a2008-11-13 22:59:24 +0000135 }
Pascal Kriete73598e32011-04-05 15:01:05 -0400136
137 $uri = strtoupper($this->config->item('uri_protocol'));
138
Andrey Andreevc123e112012-01-08 00:17:34 +0200139 if ($uri === 'REQUEST_URI')
Derek Allard2067d1a2008-11-13 22:59:24 +0000140 {
Pascal Kriete73598e32011-04-05 15:01:05 -0400141 $this->_set_uri_string($this->_detect_uri());
142 return;
143 }
Andrey Andreevc123e112012-01-08 00:17:34 +0200144 elseif ($uri === 'CLI')
Pascal Kriete73598e32011-04-05 15:01:05 -0400145 {
146 $this->_set_uri_string($this->_parse_cli_args());
147 return;
Derek Allard2067d1a2008-11-13 22:59:24 +0000148 }
149
Pascal Kriete73598e32011-04-05 15:01:05 -0400150 $path = (isset($_SERVER[$uri])) ? $_SERVER[$uri] : @getenv($uri);
151 $this->_set_uri_string($path);
152 }
Eric Barnes26eebdd2011-04-17 23:45:41 -0400153
Pascal Kriete73598e32011-04-05 15:01:05 -0400154 // --------------------------------------------------------------------
155
156 /**
157 * Set the URI String
158 *
David Behler07b53422011-08-15 00:25:06 +0200159 * @param string
Andrey Andreevc123e112012-01-08 00:17:34 +0200160 * @return void
Pascal Kriete73598e32011-04-05 15:01:05 -0400161 */
Andrey Andreevc123e112012-01-08 00:17:34 +0200162 public function _set_uri_string($str)
Pascal Kriete73598e32011-04-05 15:01:05 -0400163 {
164 // Filter out control characters
165 $str = remove_invisible_characters($str, FALSE);
Eric Barnes26eebdd2011-04-17 23:45:41 -0400166
Derek Allard2067d1a2008-11-13 22:59:24 +0000167 // If the URI contains only a slash we'll kill it
Andrey Andreevc123e112012-01-08 00:17:34 +0200168 $this->uri_string = ($str === '/') ? '' : $str;
Derek Allard2067d1a2008-11-13 22:59:24 +0000169 }
170
171 // --------------------------------------------------------------------
172
173 /**
Dan Horriganfea45ad2011-01-19 00:54:12 -0500174 * Detects the URI
Derek Allard2067d1a2008-11-13 22:59:24 +0000175 *
Dan Horriganfea45ad2011-01-19 00:54:12 -0500176 * This function will detect the URI automatically and fix the query string
177 * if necessary.
Derek Allard2067d1a2008-11-13 22:59:24 +0000178 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000179 * @return string
180 */
Paulf7345e42011-08-27 06:51:16 +1200181 protected function _detect_uri()
Derek Allard2067d1a2008-11-13 22:59:24 +0000182 {
Eric Barnes26eebdd2011-04-17 23:45:41 -0400183 if ( ! isset($_SERVER['REQUEST_URI']) OR ! isset($_SERVER['SCRIPT_NAME']))
Derek Allard2067d1a2008-11-13 22:59:24 +0000184 {
185 return '';
186 }
187
Dan Horriganfea45ad2011-01-19 00:54:12 -0500188 $uri = $_SERVER['REQUEST_URI'];
189 if (strpos($uri, $_SERVER['SCRIPT_NAME']) === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000190 {
Dan Horriganfea45ad2011-01-19 00:54:12 -0500191 $uri = substr($uri, strlen($_SERVER['SCRIPT_NAME']));
192 }
193 elseif (strpos($uri, dirname($_SERVER['SCRIPT_NAME'])) === 0)
194 {
195 $uri = substr($uri, strlen(dirname($_SERVER['SCRIPT_NAME'])));
Derek Allard2067d1a2008-11-13 22:59:24 +0000196 }
197
Dan Horriganfea45ad2011-01-19 00:54:12 -0500198 // This section ensures that even on servers that require the URI to be in the query string (Nginx) a correct
199 // URI is found, and also fixes the QUERY_STRING server var and $_GET array.
200 if (strncmp($uri, '?/', 2) === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000201 {
Dan Horriganfea45ad2011-01-19 00:54:12 -0500202 $uri = substr($uri, 2);
Derek Allard2067d1a2008-11-13 22:59:24 +0000203 }
Dan Horriganfea45ad2011-01-19 00:54:12 -0500204 $parts = preg_split('#\?#i', $uri, 2);
205 $uri = $parts[0];
206 if (isset($parts[1]))
Derek Allard2067d1a2008-11-13 22:59:24 +0000207 {
Dan Horriganfea45ad2011-01-19 00:54:12 -0500208 $_SERVER['QUERY_STRING'] = $parts[1];
Dan Horrigan65d603e2010-12-15 08:38:30 -0500209 parse_str($_SERVER['QUERY_STRING'], $_GET);
Derek Allard2067d1a2008-11-13 22:59:24 +0000210 }
Dan Horriganfea45ad2011-01-19 00:54:12 -0500211 else
Derek Allard2067d1a2008-11-13 22:59:24 +0000212 {
Dan Horriganfea45ad2011-01-19 00:54:12 -0500213 $_SERVER['QUERY_STRING'] = '';
214 $_GET = array();
Derek Allard2067d1a2008-11-13 22:59:24 +0000215 }
Eric Barnes26eebdd2011-04-17 23:45:41 -0400216
Andrey Andreevc123e112012-01-08 00:17:34 +0200217 if ($uri == '/' OR empty($uri))
ericbarnes@ericbarnes.locale58199b2011-02-02 22:40:36 -0500218 {
219 return '/';
220 }
Eric Barnes26eebdd2011-04-17 23:45:41 -0400221
Dan Horriganfea45ad2011-01-19 00:54:12 -0500222 $uri = parse_url($uri, PHP_URL_PATH);
Derek Allard2067d1a2008-11-13 22:59:24 +0000223
Dan Horriganfea45ad2011-01-19 00:54:12 -0500224 // Do some final cleaning of the URI and return it
225 return str_replace(array('//', '../'), '/', trim($uri, '/'));
Derek Allard2067d1a2008-11-13 22:59:24 +0000226 }
227
228 // --------------------------------------------------------------------
Stephen2e00c242011-08-28 10:25:40 +0200229
230 /**
231 * Is cli Request?
232 *
233 * Duplicate of function from the Input class to test to see if a request was made from the command line
234 *
235 * @return boolean
236 */
237 protected function _is_cli_request()
238 {
239 return (php_sapi_name() == 'cli') OR defined('STDIN');
240 }
241
242
243 // --------------------------------------------------------------------
Derek Allard2067d1a2008-11-13 22:59:24 +0000244
245 /**
Phil Sturgeon48c718c2010-12-30 23:40:02 +0000246 * Parse cli arguments
247 *
248 * Take each command line argument and assume it is a URI segment.
249 *
Phil Sturgeon48c718c2010-12-30 23:40:02 +0000250 * @return string
251 */
Paulf7345e42011-08-27 06:51:16 +1200252 protected function _parse_cli_args()
Phil Sturgeon48c718c2010-12-30 23:40:02 +0000253 {
254 $args = array_slice($_SERVER['argv'], 1);
Phil Sturgeon48c718c2010-12-30 23:40:02 +0000255 return $args ? '/' . implode('/', $args) : '';
Derek Allard2067d1a2008-11-13 22:59:24 +0000256 }
257
258 // --------------------------------------------------------------------
259
260 /**
261 * Filter segments for malicious characters
262 *
Andrey Andreevc123e112012-01-08 00:17:34 +0200263 * Called by CI_Router
264 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000265 * @param string
266 * @return string
267 */
Andrey Andreevc123e112012-01-08 00:17:34 +0200268 public function _filter_uri($str)
Derek Allard2067d1a2008-11-13 22:59:24 +0000269 {
270 if ($str != '' && $this->config->item('permitted_uri_chars') != '' && $this->config->item('enable_query_strings') == FALSE)
271 {
Derek Jonesf0a9b332009-07-29 14:19:18 +0000272 // preg_quote() in PHP 5.3 escapes -, so the str_replace() and addition of - to preg_quote() is to maintain backwards
273 // compatibility as many are unaware of how characters in the permitted_uri_chars will be parsed as a regex pattern
Andrey Andreevc123e112012-01-08 00:17:34 +0200274 if ( ! preg_match('|^['.str_replace(array('\\-', '\-'), '-', preg_quote($this->config->item('permitted_uri_chars'), '-')).']+$|i', $str))
Derek Allard2067d1a2008-11-13 22:59:24 +0000275 {
Derek Jones817163a2009-07-11 17:05:58 +0000276 show_error('The URI you submitted has disallowed characters.', 400);
Derek Allard2067d1a2008-11-13 22:59:24 +0000277 }
278 }
279
Andrey Andreevc123e112012-01-08 00:17:34 +0200280 // Convert programatic characters to entities and return
281 return str_replace(
282 array('$', '(', ')', '%28', '%29'), // Bad
283 array('&#36;', '&#40;', '&#41;', '&#40;', '&#41;'), // Good
284 $str);
Derek Allard2067d1a2008-11-13 22:59:24 +0000285 }
286
287 // --------------------------------------------------------------------
288
289 /**
290 * Remove the suffix from the URL if needed
291 *
Andrey Andreevc123e112012-01-08 00:17:34 +0200292 * Called by CI_Router
293 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000294 * @return void
295 */
Andrey Andreevc123e112012-01-08 00:17:34 +0200296 public function _remove_url_suffix()
Derek Allard2067d1a2008-11-13 22:59:24 +0000297 {
Andrey Andreevc123e112012-01-08 00:17:34 +0200298 if ($this->config->item('url_suffix') != '')
Derek Allard2067d1a2008-11-13 22:59:24 +0000299 {
Andrey Andreevc123e112012-01-08 00:17:34 +0200300 $this->uri_string = preg_replace('|'.preg_quote($this->config->item('url_suffix')).'$|', '', $this->uri_string);
Derek Allard2067d1a2008-11-13 22:59:24 +0000301 }
302 }
303
304 // --------------------------------------------------------------------
305
306 /**
307 * Explode the URI Segments. The individual segments will
308 * be stored in the $this->segments array.
309 *
Andrey Andreevc123e112012-01-08 00:17:34 +0200310 * Called by CI_Router
311 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000312 * @return void
313 */
Andrey Andreevc123e112012-01-08 00:17:34 +0200314 public function _explode_segments()
Derek Allard2067d1a2008-11-13 22:59:24 +0000315 {
Andrey Andreevc123e112012-01-08 00:17:34 +0200316 foreach (explode('/', preg_replace('|/*(.+?)/*$|', '\\1', $this->uri_string)) as $val)
Derek Allard2067d1a2008-11-13 22:59:24 +0000317 {
318 // Filter segments for security
319 $val = trim($this->_filter_uri($val));
320
321 if ($val != '')
322 {
323 $this->segments[] = $val;
324 }
325 }
326 }
327
328 // --------------------------------------------------------------------
329 /**
330 * Re-index Segments
331 *
332 * This function re-indexes the $this->segment array so that it
Andrey Andreevc123e112012-01-08 00:17:34 +0200333 * starts at 1 rather than 0. Doing so makes it simpler to
Derek Allard2067d1a2008-11-13 22:59:24 +0000334 * use functions like $this->uri->segment(n) since there is
335 * a 1:1 relationship between the segment array and the actual segments.
336 *
Andrey Andreevc123e112012-01-08 00:17:34 +0200337 * Called by CI_Router
338 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000339 * @return void
340 */
Andrey Andreevc123e112012-01-08 00:17:34 +0200341 public function _reindex_segments()
Derek Allard2067d1a2008-11-13 22:59:24 +0000342 {
343 array_unshift($this->segments, NULL);
344 array_unshift($this->rsegments, NULL);
345 unset($this->segments[0]);
346 unset($this->rsegments[0]);
347 }
348
349 // --------------------------------------------------------------------
350
351 /**
352 * Fetch a URI Segment
353 *
354 * This function returns the URI segment based on the number provided.
355 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000356 * @param integer
357 * @param bool
358 * @return string
359 */
Andrey Andreevc123e112012-01-08 00:17:34 +0200360 public function segment($n, $no_result = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000361 {
362 return ( ! isset($this->segments[$n])) ? $no_result : $this->segments[$n];
363 }
364
365 // --------------------------------------------------------------------
366
367 /**
368 * Fetch a URI "routed" Segment
369 *
370 * This function returns the re-routed URI segment (assuming routing rules are used)
Derek Jones37f4b9c2011-07-01 17:56:50 -0500371 * based on the number provided. If there is no routing this function returns the
Derek Allard2067d1a2008-11-13 22:59:24 +0000372 * same result as $this->segment()
373 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000374 * @param integer
375 * @param bool
376 * @return string
377 */
Andrey Andreevc123e112012-01-08 00:17:34 +0200378 public function rsegment($n, $no_result = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000379 {
380 return ( ! isset($this->rsegments[$n])) ? $no_result : $this->rsegments[$n];
381 }
382
383 // --------------------------------------------------------------------
384
385 /**
386 * Generate a key value pair from the URI string
387 *
388 * This function generates and associative array of URI data starting
389 * at the supplied segment. For example, if this is your URI:
390 *
391 * example.com/user/search/name/joe/location/UK/gender/male
392 *
393 * You can use this function to generate an array with this prototype:
394 *
395 * array (
396 * name => joe
397 * location => UK
398 * gender => male
399 * )
400 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000401 * @param integer the starting segment number
402 * @param array an array of default values
403 * @return array
404 */
Andrey Andreevc123e112012-01-08 00:17:34 +0200405 public function uri_to_assoc($n = 3, $default = array())
Derek Allard2067d1a2008-11-13 22:59:24 +0000406 {
Barry Mienydd671972010-10-04 16:33:58 +0200407 return $this->_uri_to_assoc($n, $default, 'segment');
Derek Allard2067d1a2008-11-13 22:59:24 +0000408 }
409 /**
410 * Identical to above only it uses the re-routed segment array
411 *
David Behler07b53422011-08-15 00:25:06 +0200412 * @param integer the starting segment number
413 * @param array an array of default values
414 * @return array
Derek Allard2067d1a2008-11-13 22:59:24 +0000415 */
Andrey Andreevc123e112012-01-08 00:17:34 +0200416 public function ruri_to_assoc($n = 3, $default = array())
Derek Allard2067d1a2008-11-13 22:59:24 +0000417 {
Barry Mienydd671972010-10-04 16:33:58 +0200418 return $this->_uri_to_assoc($n, $default, 'rsegment');
Derek Allard2067d1a2008-11-13 22:59:24 +0000419 }
420
421 // --------------------------------------------------------------------
422
423 /**
424 * Generate a key value pair from the URI string or Re-routed URI string
425 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000426 * @param integer the starting segment number
427 * @param array an array of default values
428 * @param string which array we should use
429 * @return array
430 */
Andrey Andreevc123e112012-01-08 00:17:34 +0200431 protected function _uri_to_assoc($n = 3, $default = array(), $which = 'segment')
Derek Allard2067d1a2008-11-13 22:59:24 +0000432 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000433 if ( ! is_numeric($n))
434 {
435 return $default;
436 }
437
438 if (isset($this->keyval[$n]))
439 {
440 return $this->keyval[$n];
441 }
442
Andrey Andreevc123e112012-01-08 00:17:34 +0200443 if ($which === 'segment')
444 {
445 $total_segments = 'total_segments';
446 $segment_array = 'segment_array';
447 }
448 else
449 {
450 $total_segments = 'total_rsegments';
451 $segment_array = 'rsegment_array';
452 }
453
Derek Allard2067d1a2008-11-13 22:59:24 +0000454 if ($this->$total_segments() < $n)
455 {
Andrey Andreevc123e112012-01-08 00:17:34 +0200456 if (count($default) === 0)
Derek Allard2067d1a2008-11-13 22:59:24 +0000457 {
458 return array();
459 }
460
Andrey Andreevc123e112012-01-08 00:17:34 +0200461 return function_exists('array_fill_keys')
462 ? array_fill_keys($default, FALSE)
463 : array_combine($default, array_fill(0, count($default), FALSE));
Derek Allard2067d1a2008-11-13 22:59:24 +0000464 }
465
466 $segments = array_slice($this->$segment_array(), ($n - 1));
Derek Allard2067d1a2008-11-13 22:59:24 +0000467 $i = 0;
468 $lastval = '';
Derek Jones37f4b9c2011-07-01 17:56:50 -0500469 $retval = array();
Derek Allard2067d1a2008-11-13 22:59:24 +0000470 foreach ($segments as $seg)
471 {
472 if ($i % 2)
473 {
474 $retval[$lastval] = $seg;
475 }
476 else
477 {
478 $retval[$seg] = FALSE;
479 $lastval = $seg;
480 }
481
482 $i++;
483 }
484
485 if (count($default) > 0)
486 {
487 foreach ($default as $val)
488 {
489 if ( ! array_key_exists($val, $retval))
490 {
491 $retval[$val] = FALSE;
492 }
493 }
494 }
495
496 // Cache the array for reuse
497 $this->keyval[$n] = $retval;
498 return $retval;
499 }
500
501 // --------------------------------------------------------------------
502
503 /**
504 * Generate a URI string from an associative array
505 *
506 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000507 * @param array an associative array of key/values
508 * @return array
509 */
Andrey Andreevc123e112012-01-08 00:17:34 +0200510 public function assoc_to_uri($array)
Derek Allard2067d1a2008-11-13 22:59:24 +0000511 {
512 $temp = array();
513 foreach ((array)$array as $key => $val)
514 {
515 $temp[] = $key;
516 $temp[] = $val;
517 }
518
519 return implode('/', $temp);
520 }
521
522 // --------------------------------------------------------------------
523
524 /**
525 * Fetch a URI Segment and add a trailing slash
526 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000527 * @param integer
528 * @param string
529 * @return string
530 */
Andrey Andreevc123e112012-01-08 00:17:34 +0200531 public function slash_segment($n, $where = 'trailing')
Derek Allard2067d1a2008-11-13 22:59:24 +0000532 {
533 return $this->_slash_segment($n, $where, 'segment');
534 }
535
536 // --------------------------------------------------------------------
537
538 /**
539 * Fetch a URI Segment and add a trailing slash
540 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000541 * @param integer
542 * @param string
543 * @return string
544 */
Andrey Andreevc123e112012-01-08 00:17:34 +0200545 public function slash_rsegment($n, $where = 'trailing')
Derek Allard2067d1a2008-11-13 22:59:24 +0000546 {
547 return $this->_slash_segment($n, $where, 'rsegment');
548 }
549
550 // --------------------------------------------------------------------
551
552 /**
553 * Fetch a URI Segment and add a trailing slash - helper function
554 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000555 * @param integer
556 * @param string
557 * @param string
558 * @return string
559 */
Andrey Andreevc123e112012-01-08 00:17:34 +0200560 protected function _slash_segment($n, $where = 'trailing', $which = 'segment')
Derek Allard2067d1a2008-11-13 22:59:24 +0000561 {
Andrey Andreevc123e112012-01-08 00:17:34 +0200562 $leading = $trailing = '/';
Phil Sturgeon48c718c2010-12-30 23:40:02 +0000563
Andrey Andreevc123e112012-01-08 00:17:34 +0200564 if ($where === 'trailing')
Derek Allard2067d1a2008-11-13 22:59:24 +0000565 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000566 $leading = '';
567 }
Andrey Andreevc123e112012-01-08 00:17:34 +0200568 elseif ($where === 'leading')
Derek Allard2067d1a2008-11-13 22:59:24 +0000569 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000570 $trailing = '';
571 }
Phil Sturgeon48c718c2010-12-30 23:40:02 +0000572
Derek Allard2067d1a2008-11-13 22:59:24 +0000573 return $leading.$this->$which($n).$trailing;
574 }
575
576 // --------------------------------------------------------------------
577
578 /**
579 * Segment Array
580 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000581 * @return array
582 */
Andrey Andreevc123e112012-01-08 00:17:34 +0200583 public function segment_array()
Derek Allard2067d1a2008-11-13 22:59:24 +0000584 {
585 return $this->segments;
586 }
587
588 // --------------------------------------------------------------------
589
590 /**
591 * Routed Segment Array
592 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000593 * @return array
594 */
Andrey Andreevc123e112012-01-08 00:17:34 +0200595 public function rsegment_array()
Derek Allard2067d1a2008-11-13 22:59:24 +0000596 {
597 return $this->rsegments;
598 }
599
600 // --------------------------------------------------------------------
601
602 /**
603 * Total number of segments
604 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000605 * @return integer
606 */
Andrey Andreevc123e112012-01-08 00:17:34 +0200607 public function total_segments()
Derek Allard2067d1a2008-11-13 22:59:24 +0000608 {
609 return count($this->segments);
610 }
611
612 // --------------------------------------------------------------------
613
614 /**
615 * Total number of routed segments
616 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000617 * @return integer
618 */
Andrey Andreevc123e112012-01-08 00:17:34 +0200619 public function total_rsegments()
Derek Allard2067d1a2008-11-13 22:59:24 +0000620 {
621 return count($this->rsegments);
622 }
623
624 // --------------------------------------------------------------------
625
626 /**
627 * Fetch the entire URI string
628 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000629 * @return string
630 */
Andrey Andreevc123e112012-01-08 00:17:34 +0200631 public function uri_string()
Derek Allard2067d1a2008-11-13 22:59:24 +0000632 {
633 return $this->uri_string;
634 }
635
636
637 // --------------------------------------------------------------------
638
639 /**
640 * Fetch the entire Re-routed URI string
641 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000642 * @return string
643 */
Andrey Andreevc123e112012-01-08 00:17:34 +0200644 public function ruri_string()
Derek Allard2067d1a2008-11-13 22:59:24 +0000645 {
Eric Barnesffdc3922011-01-12 09:05:20 -0500646 return '/'.implode('/', $this->rsegment_array());
Derek Allard2067d1a2008-11-13 22:59:24 +0000647 }
648
649}
Derek Allard2067d1a2008-11-13 22:59:24 +0000650
651/* End of file URI.php */
Andrey Andreevc123e112012-01-08 00:17:34 +0200652/* Location: ./system/core/URI.php */