Subversion Repositories Applications.papyrus

Rev

Details | Last modification | View Log | RSS feed

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