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
 * Router Class
20
 *
21
 * Parses URIs and determines routing
22
 *
23
 * @package		CodeIgniter
24
 * @subpackage	Libraries
25
 * @author		ExpressionEngine Dev Team
26
 * @category	Libraries
27
 * @link		http://codeigniter.com/user_guide/general/routing.html
28
 */
29
class CI_Router {
30
31
	var $config;
32
	var $routes 		= array();
33
	var $error_routes	= array();
34
	var $class			= '';
35
	var $method			= 'index';
36
	var $directory		= '';
37
	var $uri_protocol 	= 'auto';
38
	var $default_controller;
39
	var $scaffolding_request = FALSE; // Must be set to FALSE
40
41
	/**
42
	 * Constructor
43
	 *
44
	 * Runs the route mapping function.
45
	 */
46
	function CI_Router()
47
	{
48
		$this->config =& load_class('Config');
49
		$this->uri =& load_class('URI');
50
		$this->_set_routing();
51
		log_message('debug', "Router Class Initialized");
52
	}
53
54
	// --------------------------------------------------------------------
55
56
	/**
57
	 * Set the route mapping
58
	 *
59
	 * This function determines what should be served based on the URI request,
60
	 * as well as any "routes" that have been set in the routing config file.
61
	 *
62
	 * @access	private
63
	 * @return	void
64
	 */
65
	function _set_routing()
66
	{
67
		// Are query strings enabled in the config file?
68
		// If so, we're done since segment based URIs are not used with query strings.
69
		if ($this->config->item('enable_query_strings') === TRUE AND isset($_GET[$this->config->item('controller_trigger')]))
70
		{
71
			$this->set_class(trim($this->uri->_filter_uri($_GET[$this->config->item('controller_trigger')])));
72
73
			if (isset($_GET[$this->config->item('function_trigger')]))
74
			{
75
				$this->set_method(trim($this->uri->_filter_uri($_GET[$this->config->item('function_trigger')])));
76
			}
77
78
			return;
79
		}
80
81
		// Load the routes.php file.
82
		@include(APPPATH.'config/routes'.EXT);
83
		$this->routes = ( ! isset($route) OR ! is_array($route)) ? array() : $route;
84
		unset($route);
85
86
		// Set the default controller so we can display it in the event
87
		// the URI doesn't correlated to a valid controller.
88
		$this->default_controller = ( ! isset($this->routes['default_controller']) OR $this->routes['default_controller'] == '') ? FALSE : strtolower($this->routes['default_controller']);
89
90
		// Fetch the complete URI string
91
		$this->uri->_fetch_uri_string();
92
93
		// Is there a URI string? If not, the default controller specified in the "routes" file will be shown.
94
		if ($this->uri->uri_string == '')
95
		{
96
			if ($this->default_controller === FALSE)
97
			{
98
				show_error("Unable to determine what should be displayed. A default route has not been specified in the routing file.");
99
			}
100
101
			// Turn the default route into an array.  We explode it in the event that
102
			// the controller is located in a subfolder
103
			$segments = $this->_validate_request(explode('/', $this->default_controller));
104
105
			// Set the class and method
106
			$this->set_class($segments[0]);
107
			$this->set_method('index');
108
109
			// Assign the segments to the URI class
110
			$this->uri->rsegments = $segments;
111
112
			// re-index the routed segments array so it starts with 1 rather than 0
113
			$this->uri->_reindex_segments();
114
115
			log_message('debug', "No URI present. Default controller set.");
116
			return;
117
		}
118
		unset($this->routes['default_controller']);
119
120
		// Do we need to remove the URL suffix?
121
		$this->uri->_remove_url_suffix();
122
123
		// Compile the segments into an array
124
		$this->uri->_explode_segments();
125
126
		// Parse any custom routing that may exist
127
		$this->_parse_routes();
128
129
		// Re-index the segment array so that it starts with 1 rather than 0
130
		$this->uri->_reindex_segments();
131
	}
132
133
	// --------------------------------------------------------------------
134
135
	/**
136
	 * Set the Route
137
	 *
138
	 * This function takes an array of URI segments as
139
	 * input, and sets the current class/method
140
	 *
141
	 * @access	private
142
	 * @param	array
143
	 * @param	bool
144
	 * @return	void
145
	 */
146
	function _set_request($segments = array())
147
	{
148
		$segments = $this->_validate_request($segments);
149
150
		if (count($segments) == 0)
151
		{
152
			return;
153
		}
154
155
		$this->set_class($segments[0]);
156
157
		if (isset($segments[1]))
158
		{
159
			// A scaffolding request. No funny business with the URL
160
			if ($this->routes['scaffolding_trigger'] == $segments[1] AND $segments[1] != '_ci_scaffolding')
161
			{
162
				$this->scaffolding_request = TRUE;
163
				unset($this->routes['scaffolding_trigger']);
164
			}
165
			else
166
			{
167
				// A standard method request
168
				$this->set_method($segments[1]);
169
			}
170
		}
171
		else
172
		{
173
			// This lets the "routed" segment array identify that the default
174
			// index method is being used.
175
			$segments[1] = 'index';
176
		}
177
178
		// Update our "routed" segment array to contain the segments.
179
		// Note: If there is no custom routing, this array will be
180
		// identical to $this->uri->segments
181
		$this->uri->rsegments = $segments;
182
	}
183
184
	// --------------------------------------------------------------------
185
186
	/**
187
	 * Validates the supplied segments.  Attempts to determine the path to
188
	 * the controller.
189
	 *
190
	 * @access	private
191
	 * @param	array
192
	 * @return	array
193
	 */
194
	function _validate_request($segments)
195
	{
196
		// Does the requested controller exist in the root folder?
197
		if (file_exists(APPPATH.'controllers/'.$segments[0].EXT))
198
		{
199
			return $segments;
200
		}
201
202
		// Is the controller in a sub-folder?
203
		if (is_dir(APPPATH.'controllers/'.$segments[0]))
204
		{
205
			// Set the directory and remove it from the segment array
206
			$this->set_directory($segments[0]);
207
			$segments = array_slice($segments, 1);
208
209
			if (count($segments) > 0)
210
			{
211
				// Does the requested controller exist in the sub-folder?
212
				if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$segments[0].EXT))
213
				{
214
					show_404($this->fetch_directory().$segments[0]);
215
				}
216
			}
217
			else
218
			{
219
				$this->set_class($this->default_controller);
220
				$this->set_method('index');
221
222
				// Does the default controller exist in the sub-folder?
223
				if ( ! file_exists(APPPATH.'controllers/'.$this->fetch_directory().$this->default_controller.EXT))
224
				{
225
					$this->directory = '';
226
					return array();
227
				}
228
229
			}
230
231
			return $segments;
232
		}
233
234
		// Can't find the requested controller...
235
		show_404($segments[0]);
236
	}
237
238
	// --------------------------------------------------------------------
239
240
	/**
241
	 *  Parse Routes
242
	 *
243
	 * This function matches any routes that may exist in
244
	 * the config/routes.php file against the URI to
245
	 * determine if the class/method need to be remapped.
246
	 *
247
	 * @access	private
248
	 * @return	void
249
	 */
250
	function _parse_routes()
251
	{
252
		// Do we even have any custom routing to deal with?
253
		// There is a default scaffolding trigger, so we'll look just for 1
254
		if (count($this->routes) == 1)
255
		{
256
			$this->_set_request($this->uri->segments);
257
			return;
258
		}
259
260
		// Turn the segment array into a URI string
261
		$uri = implode('/', $this->uri->segments);
262
263
		// Is there a literal match?  If so we're done
264
		if (isset($this->routes[$uri]))
265
		{
266
			$this->_set_request(explode('/', $this->routes[$uri]));
267
			return;
268
		}
269
270
		// Loop through the route array looking for wild-cards
271
		foreach ($this->routes as $key => $val)
272
		{
273
			// Convert wild-cards to RegEx
274
			$key = str_replace(':any', '.+', str_replace(':num', '[0-9]+', $key));
275
276
			// Does the RegEx match?
277
			if (preg_match('#^'.$key.'$#', $uri))
278
			{
279
				// Do we have a back-reference?
280
				if (strpos($val, '$') !== FALSE AND strpos($key, '(') !== FALSE)
281
				{
282
					$val = preg_replace('#^'.$key.'$#', $val, $uri);
283
				}
284
285
				$this->_set_request(explode('/', $val));
286
				return;
287
			}
288
		}
289
290
		// If we got this far it means we didn't encounter a
291
		// matching route so we'll set the site default route
292
		$this->_set_request($this->uri->segments);
293
	}
294
295
	// --------------------------------------------------------------------
296
297
	/**
298
	 * Set the class name
299
	 *
300
	 * @access	public
301
	 * @param	string
302
	 * @return	void
303
	 */
304
	function set_class($class)
305
	{
306
		$this->class = $class;
307
	}
308
309
	// --------------------------------------------------------------------
310
311
	/**
312
	 * Fetch the current class
313
	 *
314
	 * @access	public
315
	 * @return	string
316
	 */
317
	function fetch_class()
318
	{
319
		return $this->class;
320
	}
321
322
	// --------------------------------------------------------------------
323
324
	/**
325
	 *  Set the method name
326
	 *
327
	 * @access	public
328
	 * @param	string
329
	 * @return	void
330
	 */
331
	function set_method($method)
332
	{
333
		$this->method = $method;
334
	}
335
336
	// --------------------------------------------------------------------
337
338
	/**
339
	 *  Fetch the current method
340
	 *
341
	 * @access	public
342
	 * @return	string
343
	 */
344
	function fetch_method()
345
	{
346
		if ($this->method == $this->fetch_class())
347
		{
348
			return 'index';
349
		}
350
351
		return $this->method;
352
	}
353
354
	// --------------------------------------------------------------------
355
356
	/**
357
	 *  Set the directory name
358
	 *
359
	 * @access	public
360
	 * @param	string
361
	 * @return	void
362
	 */
363
	function set_directory($dir)
364
	{
365
		$this->directory = $dir.'/';
366
	}
367
368
	// --------------------------------------------------------------------
369
370
	/**
371
	 *  Fetch the sub-directory (if any) that contains the requested controller class
372
	 *
373
	 * @access	public
374
	 * @return	string
375
	 */
376
	function fetch_directory()
377
	{
378
		return $this->directory;
379
	}
380
381
}
382
// END Router Class
383
384
/* End of file Router.php */
385
/* Location: ./system/libraries/Router.php */