blob: 48bb7ae3cb87bca001d9db07201866969a9b5d8e [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 *
Phil Sturgeon07c1ac82012-03-09 17:03:37 +00005 * An open source application development framework for PHP 5.2.4 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
Michiel Vugteveen0609d582012-01-08 13:26:17 +0100188 $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 }
Michiel Vugteveen0609d582012-01-08 13:26:17 +0100193 elseif (strpos($uri, dirname($_SERVER['SCRIPT_NAME'])) === 0)
Dan Horriganfea45ad2011-01-19 00:54:12 -0500194 {
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 Andreev1ae65162012-03-10 16:11:34 +0200461 return array_fill_keys($default, FALSE);
Derek Allard2067d1a2008-11-13 22:59:24 +0000462 }
463
464 $segments = array_slice($this->$segment_array(), ($n - 1));
Derek Allard2067d1a2008-11-13 22:59:24 +0000465 $i = 0;
466 $lastval = '';
Derek Jones37f4b9c2011-07-01 17:56:50 -0500467 $retval = array();
Derek Allard2067d1a2008-11-13 22:59:24 +0000468 foreach ($segments as $seg)
469 {
470 if ($i % 2)
471 {
472 $retval[$lastval] = $seg;
473 }
474 else
475 {
476 $retval[$seg] = FALSE;
477 $lastval = $seg;
478 }
479
480 $i++;
481 }
482
483 if (count($default) > 0)
484 {
485 foreach ($default as $val)
486 {
487 if ( ! array_key_exists($val, $retval))
488 {
489 $retval[$val] = FALSE;
490 }
491 }
492 }
493
494 // Cache the array for reuse
495 $this->keyval[$n] = $retval;
496 return $retval;
497 }
498
499 // --------------------------------------------------------------------
500
501 /**
502 * Generate a URI string from an associative array
503 *
504 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000505 * @param array an associative array of key/values
506 * @return array
507 */
Andrey Andreevc123e112012-01-08 00:17:34 +0200508 public function assoc_to_uri($array)
Derek Allard2067d1a2008-11-13 22:59:24 +0000509 {
510 $temp = array();
511 foreach ((array)$array as $key => $val)
512 {
Andrey Andreeva798fdb2012-01-08 00:20:49 +0200513 $temp[] = $key;
Derek Allard2067d1a2008-11-13 22:59:24 +0000514 $temp[] = $val;
515 }
516
517 return implode('/', $temp);
518 }
519
520 // --------------------------------------------------------------------
521
522 /**
523 * Fetch a URI Segment and add a trailing slash
524 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000525 * @param integer
526 * @param string
527 * @return string
528 */
Andrey Andreevc123e112012-01-08 00:17:34 +0200529 public function slash_segment($n, $where = 'trailing')
Derek Allard2067d1a2008-11-13 22:59:24 +0000530 {
531 return $this->_slash_segment($n, $where, 'segment');
532 }
533
534 // --------------------------------------------------------------------
535
536 /**
537 * Fetch a URI Segment and add a trailing slash
538 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000539 * @param integer
540 * @param string
541 * @return string
542 */
Andrey Andreevc123e112012-01-08 00:17:34 +0200543 public function slash_rsegment($n, $where = 'trailing')
Derek Allard2067d1a2008-11-13 22:59:24 +0000544 {
545 return $this->_slash_segment($n, $where, 'rsegment');
546 }
547
548 // --------------------------------------------------------------------
549
550 /**
551 * Fetch a URI Segment and add a trailing slash - helper function
552 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000553 * @param integer
554 * @param string
555 * @param string
556 * @return string
557 */
Andrey Andreevc123e112012-01-08 00:17:34 +0200558 protected function _slash_segment($n, $where = 'trailing', $which = 'segment')
Derek Allard2067d1a2008-11-13 22:59:24 +0000559 {
Andrey Andreevc123e112012-01-08 00:17:34 +0200560 $leading = $trailing = '/';
Phil Sturgeon48c718c2010-12-30 23:40:02 +0000561
Andrey Andreevc123e112012-01-08 00:17:34 +0200562 if ($where === 'trailing')
Derek Allard2067d1a2008-11-13 22:59:24 +0000563 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000564 $leading = '';
565 }
Andrey Andreevc123e112012-01-08 00:17:34 +0200566 elseif ($where === 'leading')
Derek Allard2067d1a2008-11-13 22:59:24 +0000567 {
Derek Allard2067d1a2008-11-13 22:59:24 +0000568 $trailing = '';
569 }
Phil Sturgeon48c718c2010-12-30 23:40:02 +0000570
Derek Allard2067d1a2008-11-13 22:59:24 +0000571 return $leading.$this->$which($n).$trailing;
572 }
573
574 // --------------------------------------------------------------------
575
576 /**
577 * Segment Array
578 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000579 * @return array
580 */
Andrey Andreevc123e112012-01-08 00:17:34 +0200581 public function segment_array()
Derek Allard2067d1a2008-11-13 22:59:24 +0000582 {
583 return $this->segments;
584 }
585
586 // --------------------------------------------------------------------
587
588 /**
589 * Routed Segment Array
590 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000591 * @return array
592 */
Andrey Andreevc123e112012-01-08 00:17:34 +0200593 public function rsegment_array()
Derek Allard2067d1a2008-11-13 22:59:24 +0000594 {
595 return $this->rsegments;
596 }
597
598 // --------------------------------------------------------------------
599
600 /**
601 * Total number of segments
602 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000603 * @return integer
604 */
Andrey Andreevc123e112012-01-08 00:17:34 +0200605 public function total_segments()
Derek Allard2067d1a2008-11-13 22:59:24 +0000606 {
607 return count($this->segments);
608 }
609
610 // --------------------------------------------------------------------
611
612 /**
613 * Total number of routed segments
614 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000615 * @return integer
616 */
Andrey Andreevc123e112012-01-08 00:17:34 +0200617 public function total_rsegments()
Derek Allard2067d1a2008-11-13 22:59:24 +0000618 {
619 return count($this->rsegments);
620 }
621
622 // --------------------------------------------------------------------
623
624 /**
625 * Fetch the entire URI string
626 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000627 * @return string
628 */
Andrey Andreevc123e112012-01-08 00:17:34 +0200629 public function uri_string()
Derek Allard2067d1a2008-11-13 22:59:24 +0000630 {
631 return $this->uri_string;
632 }
633
634
635 // --------------------------------------------------------------------
636
637 /**
638 * Fetch the entire Re-routed URI string
639 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000640 * @return string
641 */
Andrey Andreevc123e112012-01-08 00:17:34 +0200642 public function ruri_string()
Derek Allard2067d1a2008-11-13 22:59:24 +0000643 {
Eric Barnesffdc3922011-01-12 09:05:20 -0500644 return '/'.implode('/', $this->rsegment_array());
Derek Allard2067d1a2008-11-13 22:59:24 +0000645 }
646
647}
Derek Allard2067d1a2008-11-13 22:59:24 +0000648
649/* End of file URI.php */
Andrey Andreevc123e112012-01-08 00:17:34 +0200650/* Location: ./system/core/URI.php */