/lenasys/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/lenasys/trunk
20.1.1 by galaxyAbstractor
* Added an simple admin panel to the codeviewer-cmssy stuff
1
<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
2
/**
3
 * CodeIgniter
4
 *
5
 * An open source application development framework for PHP 5.1.6 or newer
6
 *
7
 * @package		CodeIgniter
8
 * @author		ExpressionEngine Dev Team
9
 * @copyright	Copyright (c) 2008 - 2011, 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
	/**
32
	 * List of cached uri segments
33
	 *
34
	 * @var array
35
	 * @access public
36
	 */
37
	var	$keyval			= array();
38
	/**
39
	 * Current uri string
40
	 *
41
	 * @var string
42
	 * @access public
43
	 */
44
	var $uri_string;
45
	/**
46
	 * List of uri segments
47
	 *
48
	 * @var array
49
	 * @access public
50
	 */
51
	var $segments		= array();
52
	/**
53
	 * Re-indexed list of uri segments
54
	 * Starts at 1 instead of 0
55
	 *
56
	 * @var array
57
	 * @access public
58
	 */
59
	var $rsegments		= array();
60
61
	/**
62
	 * Constructor
63
	 *
64
	 * Simply globalizes the $RTR object.  The front
65
	 * loads the Router class early on so it's not available
66
	 * normally as other classes are.
67
	 *
68
	 * @access	public
69
	 */
70
	function __construct()
71
	{
72
		$this->config =& load_class('Config', 'core');
73
		log_message('debug', "URI Class Initialized");
74
	}
75
76
77
	// --------------------------------------------------------------------
78
79
	/**
80
	 * Get the URI String
81
	 *
82
	 * @access	private
83
	 * @return	string
84
	 */
85
	function _fetch_uri_string()
86
	{
87
		if (strtoupper($this->config->item('uri_protocol')) == 'AUTO')
88
		{
89
			// Is the request coming from the command line?
90
			if (php_sapi_name() == 'cli' or defined('STDIN'))
91
			{
92
				$this->_set_uri_string($this->_parse_cli_args());
93
				return;
94
			}
95
96
			// Let's try the REQUEST_URI first, this will work in most situations
97
			if ($uri = $this->_detect_uri())
98
			{
99
				$this->_set_uri_string($uri);
100
				return;
101
			}
102
103
			// Is there a PATH_INFO variable?
104
			// Note: some servers seem to have trouble with getenv() so we'll test it two ways
105
			$path = (isset($_SERVER['PATH_INFO'])) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO');
106
			if (trim($path, '/') != '' && $path != "/".SELF)
107
			{
108
				$this->_set_uri_string($path);
109
				return;
110
			}
111
112
			// No PATH_INFO?... What about QUERY_STRING?
113
			$path =  (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING');
114
			if (trim($path, '/') != '')
115
			{
116
				$this->_set_uri_string($path);
117
				return;
118
			}
119
120
			// As a last ditch effort lets try using the $_GET array
121
			if (is_array($_GET) && count($_GET) == 1 && trim(key($_GET), '/') != '')
122
			{
123
				$this->_set_uri_string(key($_GET));
124
				return;
125
			}
126
127
			// We've exhausted all our options...
128
			$this->uri_string = '';
129
			return;
130
		}
131
132
		$uri = strtoupper($this->config->item('uri_protocol'));
133
134
		if ($uri == 'REQUEST_URI')
135
		{
136
			$this->_set_uri_string($this->_detect_uri());
137
			return;
138
		}
139
		elseif ($uri == 'CLI')
140
		{
141
			$this->_set_uri_string($this->_parse_cli_args());
142
			return;
143
		}
144
145
		$path = (isset($_SERVER[$uri])) ? $_SERVER[$uri] : @getenv($uri);
146
		$this->_set_uri_string($path);
147
	}
148
149
	// --------------------------------------------------------------------
150
151
	/**
152
	 * Set the URI String
153
	 *
154
	 * @access	public
155
	 * @param 	string
156
	 * @return	string
157
	 */
158
	function _set_uri_string($str)
159
	{
160
		// Filter out control characters
161
		$str = remove_invisible_characters($str, FALSE);
162
163
		// If the URI contains only a slash we'll kill it
164
		$this->uri_string = ($str == '/') ? '' : $str;
165
	}
166
167
	// --------------------------------------------------------------------
168
169
	/**
170
	 * Detects the URI
171
	 *
172
	 * This function will detect the URI automatically and fix the query string
173
	 * if necessary.
174
	 *
175
	 * @access	private
176
	 * @return	string
177
	 */
178
	private function _detect_uri()
179
	{
180
		if ( ! isset($_SERVER['REQUEST_URI']) OR ! isset($_SERVER['SCRIPT_NAME']))
181
		{
182
			return '';
183
		}
184
185
		$uri = $_SERVER['REQUEST_URI'];
186
		if (strpos($uri, $_SERVER['SCRIPT_NAME']) === 0)
187
		{
188
			$uri = substr($uri, strlen($_SERVER['SCRIPT_NAME']));
189
		}
190
		elseif (strpos($uri, dirname($_SERVER['SCRIPT_NAME'])) === 0)
191
		{
192
			$uri = substr($uri, strlen(dirname($_SERVER['SCRIPT_NAME'])));
193
		}
194
195
		// This section ensures that even on servers that require the URI to be in the query string (Nginx) a correct
196
		// URI is found, and also fixes the QUERY_STRING server var and $_GET array.
197
		if (strncmp($uri, '?/', 2) === 0)
198
		{
199
			$uri = substr($uri, 2);
200
		}
201
		$parts = preg_split('#\?#i', $uri, 2);
202
		$uri = $parts[0];
203
		if (isset($parts[1]))
204
		{
205
			$_SERVER['QUERY_STRING'] = $parts[1];
206
			parse_str($_SERVER['QUERY_STRING'], $_GET);
207
		}
208
		else
209
		{
210
			$_SERVER['QUERY_STRING'] = '';
211
			$_GET = array();
212
		}
213
214
		if ($uri == '/' || empty($uri))
215
		{
216
			return '/';
217
		}
218
219
		$uri = parse_url($uri, PHP_URL_PATH);
220
221
		// Do some final cleaning of the URI and return it
222
		return str_replace(array('//', '../'), '/', trim($uri, '/'));
223
	}
224
225
	// --------------------------------------------------------------------
226
227
	/**
228
	 * Parse cli arguments
229
	 *
230
	 * Take each command line argument and assume it is a URI segment.
231
	 *
232
	 * @access	private
233
	 * @return	string
234
	 */
235
	private function _parse_cli_args()
236
	{
237
		$args = array_slice($_SERVER['argv'], 1);
238
239
		return $args ? '/' . implode('/', $args) : '';
240
	}
241
242
	// --------------------------------------------------------------------
243
244
	/**
245
	 * Filter segments for malicious characters
246
	 *
247
	 * @access	private
248
	 * @param	string
249
	 * @return	string
250
	 */
251
	function _filter_uri($str)
252
	{
253
		if ($str != '' && $this->config->item('permitted_uri_chars') != '' && $this->config->item('enable_query_strings') == FALSE)
254
		{
255
			// preg_quote() in PHP 5.3 escapes -, so the str_replace() and addition of - to preg_quote() is to maintain backwards
256
			// compatibility as many are unaware of how characters in the permitted_uri_chars will be parsed as a regex pattern
257
			if ( ! preg_match("|^[".str_replace(array('\\-', '\-'), '-', preg_quote($this->config->item('permitted_uri_chars'), '-'))."]+$|i", $str))
258
			{
259
				show_error('The URI you submitted has disallowed characters.', 400);
260
			}
261
		}
262
263
		// Convert programatic characters to entities
264
		$bad	= array('$',		'(',		')',		'%28',		'%29');
265
		$good	= array('&#36;',	'&#40;',	'&#41;',	'&#40;',	'&#41;');
266
267
		return str_replace($bad, $good, $str);
268
	}
269
270
	// --------------------------------------------------------------------
271
272
	/**
273
	 * Remove the suffix from the URL if needed
274
	 *
275
	 * @access	private
276
	 * @return	void
277
	 */
278
	function _remove_url_suffix()
279
	{
280
		if  ($this->config->item('url_suffix') != "")
281
		{
282
			$this->uri_string = preg_replace("|".preg_quote($this->config->item('url_suffix'))."$|", "", $this->uri_string);
283
		}
284
	}
285
286
	// --------------------------------------------------------------------
287
288
	/**
289
	 * Explode the URI Segments. The individual segments will
290
	 * be stored in the $this->segments array.
291
	 *
292
	 * @access	private
293
	 * @return	void
294
	 */
295
	function _explode_segments()
296
	{
297
		foreach (explode("/", preg_replace("|/*(.+?)/*$|", "\\1", $this->uri_string)) as $val)
298
		{
299
			// Filter segments for security
300
			$val = trim($this->_filter_uri($val));
301
302
			if ($val != '')
303
			{
304
				$this->segments[] = $val;
305
			}
306
		}
307
	}
308
309
	// --------------------------------------------------------------------
310
	/**
311
	 * Re-index Segments
312
	 *
313
	 * This function re-indexes the $this->segment array so that it
314
	 * starts at 1 rather than 0.  Doing so makes it simpler to
315
	 * use functions like $this->uri->segment(n) since there is
316
	 * a 1:1 relationship between the segment array and the actual segments.
317
	 *
318
	 * @access	private
319
	 * @return	void
320
	 */
321
	function _reindex_segments()
322
	{
323
		array_unshift($this->segments, NULL);
324
		array_unshift($this->rsegments, NULL);
325
		unset($this->segments[0]);
326
		unset($this->rsegments[0]);
327
	}
328
329
	// --------------------------------------------------------------------
330
331
	/**
332
	 * Fetch a URI Segment
333
	 *
334
	 * This function returns the URI segment based on the number provided.
335
	 *
336
	 * @access	public
337
	 * @param	integer
338
	 * @param	bool
339
	 * @return	string
340
	 */
341
	function segment($n, $no_result = FALSE)
342
	{
343
		return ( ! isset($this->segments[$n])) ? $no_result : $this->segments[$n];
344
	}
345
346
	// --------------------------------------------------------------------
347
348
	/**
349
	 * Fetch a URI "routed" Segment
350
	 *
351
	 * This function returns the re-routed URI segment (assuming routing rules are used)
352
	 * based on the number provided.  If there is no routing this function returns the
353
	 * same result as $this->segment()
354
	 *
355
	 * @access	public
356
	 * @param	integer
357
	 * @param	bool
358
	 * @return	string
359
	 */
360
	function rsegment($n, $no_result = FALSE)
361
	{
362
		return ( ! isset($this->rsegments[$n])) ? $no_result : $this->rsegments[$n];
363
	}
364
365
	// --------------------------------------------------------------------
366
367
	/**
368
	 * Generate a key value pair from the URI string
369
	 *
370
	 * This function generates and associative array of URI data starting
371
	 * at the supplied segment. For example, if this is your URI:
372
	 *
373
	 *	example.com/user/search/name/joe/location/UK/gender/male
374
	 *
375
	 * You can use this function to generate an array with this prototype:
376
	 *
377
	 * array (
378
	 *			name => joe
379
	 *			location => UK
380
	 *			gender => male
381
	 *		 )
382
	 *
383
	 * @access	public
384
	 * @param	integer	the starting segment number
385
	 * @param	array	an array of default values
386
	 * @return	array
387
	 */
388
	function uri_to_assoc($n = 3, $default = array())
389
	{
390
		return $this->_uri_to_assoc($n, $default, 'segment');
391
	}
392
	/**
393
	 * Identical to above only it uses the re-routed segment array
394
	 *
395
	 * @access 	public
396
	 * @param 	integer	the starting segment number
397
	 * @param 	array	an array of default values
398
	 * @return 	array
399
	 *
400
	 */
401
	function ruri_to_assoc($n = 3, $default = array())
402
	{
403
		return $this->_uri_to_assoc($n, $default, 'rsegment');
404
	}
405
406
	// --------------------------------------------------------------------
407
408
	/**
409
	 * Generate a key value pair from the URI string or Re-routed URI string
410
	 *
411
	 * @access	private
412
	 * @param	integer	the starting segment number
413
	 * @param	array	an array of default values
414
	 * @param	string	which array we should use
415
	 * @return	array
416
	 */
417
	function _uri_to_assoc($n = 3, $default = array(), $which = 'segment')
418
	{
419
		if ($which == 'segment')
420
		{
421
			$total_segments = 'total_segments';
422
			$segment_array = 'segment_array';
423
		}
424
		else
425
		{
426
			$total_segments = 'total_rsegments';
427
			$segment_array = 'rsegment_array';
428
		}
429
430
		if ( ! is_numeric($n))
431
		{
432
			return $default;
433
		}
434
435
		if (isset($this->keyval[$n]))
436
		{
437
			return $this->keyval[$n];
438
		}
439
440
		if ($this->$total_segments() < $n)
441
		{
442
			if (count($default) == 0)
443
			{
444
				return array();
445
			}
446
447
			$retval = array();
448
			foreach ($default as $val)
449
			{
450
				$retval[$val] = FALSE;
451
			}
452
			return $retval;
453
		}
454
455
		$segments = array_slice($this->$segment_array(), ($n - 1));
456
457
		$i = 0;
458
		$lastval = '';
459
		$retval  = array();
460
		foreach ($segments as $seg)
461
		{
462
			if ($i % 2)
463
			{
464
				$retval[$lastval] = $seg;
465
			}
466
			else
467
			{
468
				$retval[$seg] = FALSE;
469
				$lastval = $seg;
470
			}
471
472
			$i++;
473
		}
474
475
		if (count($default) > 0)
476
		{
477
			foreach ($default as $val)
478
			{
479
				if ( ! array_key_exists($val, $retval))
480
				{
481
					$retval[$val] = FALSE;
482
				}
483
			}
484
		}
485
486
		// Cache the array for reuse
487
		$this->keyval[$n] = $retval;
488
		return $retval;
489
	}
490
491
	// --------------------------------------------------------------------
492
493
	/**
494
	 * Generate a URI string from an associative array
495
	 *
496
	 *
497
	 * @access	public
498
	 * @param	array	an associative array of key/values
499
	 * @return	array
500
	 */
501
	function assoc_to_uri($array)
502
	{
503
		$temp = array();
504
		foreach ((array)$array as $key => $val)
505
		{
506
			$temp[] = $key;
507
			$temp[] = $val;
508
		}
509
510
		return implode('/', $temp);
511
	}
512
513
	// --------------------------------------------------------------------
514
515
	/**
516
	 * Fetch a URI Segment and add a trailing slash
517
	 *
518
	 * @access	public
519
	 * @param	integer
520
	 * @param	string
521
	 * @return	string
522
	 */
523
	function slash_segment($n, $where = 'trailing')
524
	{
525
		return $this->_slash_segment($n, $where, 'segment');
526
	}
527
528
	// --------------------------------------------------------------------
529
530
	/**
531
	 * Fetch a URI Segment and add a trailing slash
532
	 *
533
	 * @access	public
534
	 * @param	integer
535
	 * @param	string
536
	 * @return	string
537
	 */
538
	function slash_rsegment($n, $where = 'trailing')
539
	{
540
		return $this->_slash_segment($n, $where, 'rsegment');
541
	}
542
543
	// --------------------------------------------------------------------
544
545
	/**
546
	 * Fetch a URI Segment and add a trailing slash - helper function
547
	 *
548
	 * @access	private
549
	 * @param	integer
550
	 * @param	string
551
	 * @param	string
552
	 * @return	string
553
	 */
554
	function _slash_segment($n, $where = 'trailing', $which = 'segment')
555
	{
556
		$leading	= '/';
557
		$trailing	= '/';
558
559
		if ($where == 'trailing')
560
		{
561
			$leading	= '';
562
		}
563
		elseif ($where == 'leading')
564
		{
565
			$trailing	= '';
566
		}
567
568
		return $leading.$this->$which($n).$trailing;
569
	}
570
571
	// --------------------------------------------------------------------
572
573
	/**
574
	 * Segment Array
575
	 *
576
	 * @access	public
577
	 * @return	array
578
	 */
579
	function segment_array()
580
	{
581
		return $this->segments;
582
	}
583
584
	// --------------------------------------------------------------------
585
586
	/**
587
	 * Routed Segment Array
588
	 *
589
	 * @access	public
590
	 * @return	array
591
	 */
592
	function rsegment_array()
593
	{
594
		return $this->rsegments;
595
	}
596
597
	// --------------------------------------------------------------------
598
599
	/**
600
	 * Total number of segments
601
	 *
602
	 * @access	public
603
	 * @return	integer
604
	 */
605
	function total_segments()
606
	{
607
		return count($this->segments);
608
	}
609
610
	// --------------------------------------------------------------------
611
612
	/**
613
	 * Total number of routed segments
614
	 *
615
	 * @access	public
616
	 * @return	integer
617
	 */
618
	function total_rsegments()
619
	{
620
		return count($this->rsegments);
621
	}
622
623
	// --------------------------------------------------------------------
624
625
	/**
626
	 * Fetch the entire URI string
627
	 *
628
	 * @access	public
629
	 * @return	string
630
	 */
631
	function uri_string()
632
	{
633
		return $this->uri_string;
634
	}
635
636
637
	// --------------------------------------------------------------------
638
639
	/**
640
	 * Fetch the entire Re-routed URI string
641
	 *
642
	 * @access	public
643
	 * @return	string
644
	 */
645
	function ruri_string()
646
	{
647
		return '/'.implode('/', $this->rsegment_array());
648
	}
649
650
}
651
// END URI Class
652
653
/* End of file URI.php */
654
/* Location: ./system/core/URI.php */