blob: 2448d9c8c4792a5a56c159e70833f63ca24094bc [file] [log] [blame]
Andrey Andreevc5536aa2012-11-01 17:33:58 +02001<?php
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 Andreevba6c0412012-01-07 21:10:09 +02008 *
Derek Jonesf4a4bd82011-10-20 12:18:42 -05009 * Licensed under the Open Software License version 3.0
Andrey Andreevba6c0412012-01-07 21:10:09 +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
darwinel871754a2014-02-11 17:34:57 +010021 * @copyright Copyright (c) 2008 - 2014, 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
25 * @filesource
26 */
Andrey Andreevc5536aa2012-11-01 17:33:58 +020027defined('BASEPATH') OR exit('No direct script access allowed');
Derek Allard2067d1a2008-11-13 22:59:24 +000028
Derek Allard2067d1a2008-11-13 22:59:24 +000029/**
30 * Router Class
31 *
32 * Parses URIs and determines routing
33 *
34 * @package CodeIgniter
35 * @subpackage Libraries
Derek Allard2067d1a2008-11-13 22:59:24 +000036 * @category Libraries
Andrey Andreev92ebfb62012-05-17 12:49:24 +030037 * @author EllisLab Dev Team
Derek Allard2067d1a2008-11-13 22:59:24 +000038 * @link http://codeigniter.com/user_guide/general/routing.html
39 */
40class CI_Router {
41
David Behler07b53422011-08-15 00:25:06 +020042 /**
Andrey Andreevb9fe7e92012-10-27 18:45:59 +030043 * CI_Config class object
David Behler07b53422011-08-15 00:25:06 +020044 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +030045 * @var object
David Behler07b53422011-08-15 00:25:06 +020046 */
Andrey Andreevba6c0412012-01-07 21:10:09 +020047 public $config;
Andrey Andreev92ebfb62012-05-17 12:49:24 +030048
David Behler07b53422011-08-15 00:25:06 +020049 /**
50 * List of routes
51 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +030052 * @var array
David Behler07b53422011-08-15 00:25:06 +020053 */
Timothy Warren48a7fbb2012-04-23 11:58:16 -040054 public $routes = array();
Andrey Andreev92ebfb62012-05-17 12:49:24 +030055
David Behler07b53422011-08-15 00:25:06 +020056 /**
David Behler07b53422011-08-15 00:25:06 +020057 * Current class name
58 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +030059 * @var string
David Behler07b53422011-08-15 00:25:06 +020060 */
Andrey Andreev92ebfb62012-05-17 12:49:24 +030061 public $class = '';
62
David Behler07b53422011-08-15 00:25:06 +020063 /**
64 * Current method name
65 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +030066 * @var string
David Behler07b53422011-08-15 00:25:06 +020067 */
Timothy Warren48a7fbb2012-04-23 11:58:16 -040068 public $method = 'index';
Andrey Andreev92ebfb62012-05-17 12:49:24 +030069
David Behler07b53422011-08-15 00:25:06 +020070 /**
71 * Sub-directory that contains the requested controller class
72 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +030073 * @var string
David Behler07b53422011-08-15 00:25:06 +020074 */
Timothy Warren48a7fbb2012-04-23 11:58:16 -040075 public $directory = '';
Andrey Andreev92ebfb62012-05-17 12:49:24 +030076
David Behler07b53422011-08-15 00:25:06 +020077 /**
78 * Default controller (and method if specific)
79 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +030080 * @var string
David Behler07b53422011-08-15 00:25:06 +020081 */
Andrey Andreevba6c0412012-01-07 21:10:09 +020082 public $default_controller;
Barry Mienydd671972010-10-04 16:33:58 +020083
Derek Allard2067d1a2008-11-13 22:59:24 +000084 /**
Andrey Andreev08fec7b2013-07-19 16:25:51 +030085 * Translate URI dashes
86 *
87 * Determines whether dashes in controller & method segments
88 * should be automatically replaced by underscores.
89 *
90 * @var bool
91 */
92 public $translate_uri_dashes = FALSE;
93
Andrey Andreev30d53242014-01-16 14:41:46 +020094 /**
95 * Enable query strings flag
96 *
97 * Determines wether to use GET parameters or segment URIs
98 *
99 * @var bool
100 */
101 public $enable_query_strings = FALSE;
102
Andrey Andreev08fec7b2013-07-19 16:25:51 +0300103 // --------------------------------------------------------------------
104
105 /**
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300106 * Class constructor
Derek Allard2067d1a2008-11-13 22:59:24 +0000107 *
108 * Runs the route mapping function.
Andrey Andreev92ebfb62012-05-17 12:49:24 +0300109 *
110 * @return void
Derek Allard2067d1a2008-11-13 22:59:24 +0000111 */
Andrey Andreevc26b9eb2014-02-24 11:31:36 +0200112 public function __construct($routing = NULL)
Derek Allard2067d1a2008-11-13 22:59:24 +0000113 {
Derek Jonesc7738402010-03-02 13:55:13 -0600114 $this->config =& load_class('Config', 'core');
115 $this->uri =& load_class('URI', 'core');
Andrey Andreev30d53242014-01-16 14:41:46 +0200116
117 $this->enable_query_strings = ( ! is_cli() && $this->config->item('enable_query_strings') === TRUE);
Andrey Andreev08fec7b2013-07-19 16:25:51 +0300118 $this->_set_routing();
Andrey Andreev4e6c5282014-01-10 19:29:49 +0200119
120 // Set any routing overrides that may exist in the main index file
Andrey Andreevc26b9eb2014-02-24 11:31:36 +0200121 if (is_array($routing))
Andrey Andreev4e6c5282014-01-10 19:29:49 +0200122 {
123 if (isset($routing['directory']))
124 {
125 $this->set_directory($routing['directory']);
126 }
127
128 if ( ! empty($routing['controller']))
129 {
130 $this->set_class($routing['controller']);
131 }
132
133 if (isset($routing['function']))
134 {
135 $routing['function'] = empty($routing['function']) ? 'index' : $routing['function'];
136 $this->set_method($routing['function']);
137 }
138 }
139
Andrey Andreevba6c0412012-01-07 21:10:09 +0200140 log_message('debug', 'Router Class Initialized');
Derek Allard2067d1a2008-11-13 22:59:24 +0000141 }
Barry Mienydd671972010-10-04 16:33:58 +0200142
Derek Allard2067d1a2008-11-13 22:59:24 +0000143 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200144
Derek Allard2067d1a2008-11-13 22:59:24 +0000145 /**
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300146 * Set route mapping
Derek Allard2067d1a2008-11-13 22:59:24 +0000147 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300148 * Determines what should be served based on the URI request,
Derek Allard2067d1a2008-11-13 22:59:24 +0000149 * as well as any "routes" that have been set in the routing config file.
150 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000151 * @return void
152 */
Andrey Andreev08fec7b2013-07-19 16:25:51 +0300153 protected function _set_routing()
Barry Mienydd671972010-10-04 16:33:58 +0200154 {
Andrey Andreevba6c0412012-01-07 21:10:09 +0200155 // Are query strings enabled in the config file? Normally CI doesn't utilize query strings
Barry Mienydd671972010-10-04 16:33:58 +0200156 // since URI segments are more search-engine friendly, but they can optionally be used.
Derek Jonesc7738402010-03-02 13:55:13 -0600157 // If this feature is enabled, we will gather the directory/class/method a little differently
Andrey Andreev30d53242014-01-16 14:41:46 +0200158 if ($this->enable_query_strings)
Derek Allard2067d1a2008-11-13 22:59:24 +0000159 {
Andrey Andreev30d53242014-01-16 14:41:46 +0200160 $_d = $this->config->item('directory_trigger');
161 $_d = isset($_GET[$_d]) ? trim($_GET[$_d], " \t\n\r\0\x0B/") : '';
162 if ($_d !== '')
Derek Jonesc7738402010-03-02 13:55:13 -0600163 {
Andrey Andreev30d53242014-01-16 14:41:46 +0200164 $this->set_directory($this->uri->filter_uri($_d));
Derek Jonesc7738402010-03-02 13:55:13 -0600165 }
Barry Mienydd671972010-10-04 16:33:58 +0200166
Andrey Andreev30d53242014-01-16 14:41:46 +0200167 $_c = $this->config->item('controller_trigger');
168 if ( ! empty($_GET[$_c]))
Derek Allard2067d1a2008-11-13 22:59:24 +0000169 {
Andrey Andreev30d53242014-01-16 14:41:46 +0200170 $this->set_class(trim($this->uri->filter_uri(trim($_GET[$_c]))));
171
172 $_f = $this->config->item('function_trigger');
173 if ( ! empty($_GET[$_f]))
174 {
175 $this->set_method(trim($this->uri->filter_uri($_GET[$_f])));
176 }
177
178 $this->uri->rsegments = array(
179 1 => $this->class,
180 2 => $this->method
181 );
Derek Allard2067d1a2008-11-13 22:59:24 +0000182 }
Andrey Andreev30d53242014-01-16 14:41:46 +0200183 else
184 {
185 $this->_set_default_controller();
186 }
187
188 // Routing rules don't apply to query strings and we don't need to detect
189 // directories, so we're done here
190 return;
Derek Allard2067d1a2008-11-13 22:59:24 +0000191 }
Barry Mienydd671972010-10-04 16:33:58 +0200192
Derek Allard2067d1a2008-11-13 22:59:24 +0000193 // Load the routes.php file.
Andrey Andreev06879112013-01-29 15:05:02 +0200194 if (file_exists(APPPATH.'config/routes.php'))
Greg Akerd96f8822011-12-27 16:23:47 -0600195 {
196 include(APPPATH.'config/routes.php');
197 }
David Behler07b53422011-08-15 00:25:06 +0200198
Andrey Andreev06879112013-01-29 15:05:02 +0200199 if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/routes.php'))
200 {
201 include(APPPATH.'config/'.ENVIRONMENT.'/routes.php');
202 }
203
Andrey Andreev08fec7b2013-07-19 16:25:51 +0300204 // Validate & get reserved routes
205 if (isset($route) && is_array($route))
206 {
207 isset($route['default_controller']) && $this->default_controller = $route['default_controller'];
208 isset($route['translate_uri_dashes']) && $this->translate_uri_dashes = $route['translate_uri_dashes'];
209 unset($route['default_controller'], $route['translate_uri_dashes']);
210 $this->routes = $route;
211 }
Barry Mienydd671972010-10-04 16:33:58 +0200212
Andrey Andreev30d53242014-01-16 14:41:46 +0200213 // Is there anything to parse?
214 if ($this->uri->uri_string !== '')
Derek Jonesc7738402010-03-02 13:55:13 -0600215 {
Andrey Andreev30d53242014-01-16 14:41:46 +0200216 $this->_parse_routes();
217 }
218 else
219 {
220 $this->_set_default_controller();
221 }
222 }
223
224 // --------------------------------------------------------------------
225
226 /**
227 * Set request route
228 *
229 * Takes an array of URI segments as input and sets the class/method
230 * to be called.
231 *
232 * @used-by CI_Router::_parse_routes()
233 * @param array $segments URI segments
234 * @return void
235 */
236 protected function _set_request($segments = array())
237 {
238 $segments = $this->_validate_request($segments);
239 // If we don't have any segments left - try the default controller;
240 // WARNING: Directories get shifted out of the segments array!
241 if (empty($segments))
242 {
243 $this->_set_default_controller();
244 return;
Derek Jonesc7738402010-03-02 13:55:13 -0600245 }
Barry Mienydd671972010-10-04 16:33:58 +0200246
Andrey Andreev30d53242014-01-16 14:41:46 +0200247 if ($this->translate_uri_dashes === TRUE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000248 {
Andrey Andreev30d53242014-01-16 14:41:46 +0200249 $segments[0] = str_replace('-', '_', $segments[0]);
250 if (isset($segments[1]))
251 {
252 $segments[1] = str_replace('-', '_', $segments[1]);
253 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000254 }
Barry Mienydd671972010-10-04 16:33:58 +0200255
Andrey Andreev30d53242014-01-16 14:41:46 +0200256 $this->set_class($segments[0]);
257 if (isset($segments[1]))
258 {
259 $this->set_method($segments[1]);
260 }
261
262 array_unshift($segments, NULL);
263 unset($segments[0]);
264 $this->uri->rsegments = $segments;
Derek Allard2067d1a2008-11-13 22:59:24 +0000265 }
Derek Jonesc7738402010-03-02 13:55:13 -0600266
267 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200268
Derek Jonesc7738402010-03-02 13:55:13 -0600269 /**
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300270 * Set default controller
Derek Jonesc7738402010-03-02 13:55:13 -0600271 *
Derek Jonesc7738402010-03-02 13:55:13 -0600272 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200273 */
Andrey Andreevba6c0412012-01-07 21:10:09 +0200274 protected function _set_default_controller()
Derek Jonesc7738402010-03-02 13:55:13 -0600275 {
Andrey Andreev533bf2d2012-11-02 22:44:29 +0200276 if (empty($this->default_controller))
Derek Jonesc7738402010-03-02 13:55:13 -0600277 {
Andrey Andreevba6c0412012-01-07 21:10:09 +0200278 show_error('Unable to determine what should be displayed. A default route has not been specified in the routing file.');
Derek Jonesc7738402010-03-02 13:55:13 -0600279 }
Andrey Andreevd1097a12012-11-01 19:55:42 +0200280
Derek Jonesc7738402010-03-02 13:55:13 -0600281 // Is the method being specified?
Andrey Andreev533bf2d2012-11-02 22:44:29 +0200282 if (sscanf($this->default_controller, '%[^/]/%s', $class, $method) !== 2)
Derek Jonesc7738402010-03-02 13:55:13 -0600283 {
Andrey Andreev533bf2d2012-11-02 22:44:29 +0200284 $method = 'index';
Barry Mienydd671972010-10-04 16:33:58 +0200285 }
Andrey Andreev533bf2d2012-11-02 22:44:29 +0200286
Andrey Andreev30d53242014-01-16 14:41:46 +0200287 if ( ! file_exists(APPPATH.'controllers/'.$this->directory.ucfirst($class).'.php'))
288 {
289 // This will trigger 404 later
290 return;
291 }
Barry Mienydd671972010-10-04 16:33:58 +0200292
Andrey Andreev30d53242014-01-16 14:41:46 +0200293 $this->set_class($class);
294 $this->set_method($method);
295
296 // Assign routed segments, index starting from 1
297 $this->uri->rsegments = array(
298 1 => $class,
299 2 => $method
300 );
Barry Mienydd671972010-10-04 16:33:58 +0200301
Andrey Andreevba6c0412012-01-07 21:10:09 +0200302 log_message('debug', 'No URI present. Default controller set.');
Derek Jonesc7738402010-03-02 13:55:13 -0600303 }
Barry Mienydd671972010-10-04 16:33:58 +0200304
Derek Allard2067d1a2008-11-13 22:59:24 +0000305 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200306
Derek Allard2067d1a2008-11-13 22:59:24 +0000307 /**
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300308 * Validate request
Derek Allard2067d1a2008-11-13 22:59:24 +0000309 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300310 * Attempts validate the URI request and determine the controller path.
311 *
Andrey Andreev30d53242014-01-16 14:41:46 +0200312 * @used-by CI_Router::_set_request()
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300313 * @param array $segments URI segments
Andrey Andreev30d53242014-01-16 14:41:46 +0200314 * @return mixed URI segments
Barry Mienydd671972010-10-04 16:33:58 +0200315 */
Andrey Andreevba6c0412012-01-07 21:10:09 +0200316 protected function _validate_request($segments)
Derek Allard2067d1a2008-11-13 22:59:24 +0000317 {
Andrey Andreev30d53242014-01-16 14:41:46 +0200318 $c = count($segments);
319 // Loop through our segments and return as soon as a controller
320 // is found or when such a directory doesn't exist
321 while ($c-- > 0)
Derek Jonesc7738402010-03-02 13:55:13 -0600322 {
Andrey Andreev30d53242014-01-16 14:41:46 +0200323 $test = $this->directory
324 .ucfirst($this->translate_uri_dashes === TRUE ? str_replace('-', '_', $segments[0]) : $segments[0]);
Barry Mienydd671972010-10-04 16:33:58 +0200325
Andrey Andreev30d53242014-01-16 14:41:46 +0200326 if ( ! file_exists(APPPATH.'controllers/'.$test.'.php') && is_dir(APPPATH.'controllers/'.$this->directory.$segments[0]))
Derek Allard2067d1a2008-11-13 22:59:24 +0000327 {
Andrey Andreev30d53242014-01-16 14:41:46 +0200328 $this->set_directory(array_shift($segments), TRUE);
329 continue;
Derek Allard2067d1a2008-11-13 22:59:24 +0000330 }
Barry Mienydd671972010-10-04 16:33:58 +0200331
Derek Allard2067d1a2008-11-13 22:59:24 +0000332 return $segments;
333 }
Barry Mienydd671972010-10-04 16:33:58 +0200334
Andrey Andreev30d53242014-01-16 14:41:46 +0200335 // This means that all segments were actually directories
336 return $segments;
Derek Allard2067d1a2008-11-13 22:59:24 +0000337 }
Barry Mienydd671972010-10-04 16:33:58 +0200338
Derek Allard2067d1a2008-11-13 22:59:24 +0000339 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200340
Derek Allard2067d1a2008-11-13 22:59:24 +0000341 /**
Andrey Andreev7b53d042012-03-26 23:02:32 +0300342 * Parse Routes
Derek Allard2067d1a2008-11-13 22:59:24 +0000343 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300344 * Matches any routes that may exist in the config/routes.php file
345 * against the URI to determine if the class/method need to be remapped.
Derek Allard2067d1a2008-11-13 22:59:24 +0000346 *
Derek Allard2067d1a2008-11-13 22:59:24 +0000347 * @return void
348 */
Andrey Andreevba6c0412012-01-07 21:10:09 +0200349 protected function _parse_routes()
Jonatas Miguel59dbe852012-08-07 12:13:32 +0100350 {
351 // Turn the segment array into a URI string
352 $uri = implode('/', $this->uri->segments);
Barry Mienydd671972010-10-04 16:33:58 +0200353
Fatih Kalifa442b50b2013-11-01 02:44:56 +0700354 // Get HTTP verb
Andrey Andreevc761a202013-11-11 14:02:15 +0200355 $http_verb = isset($_SERVER['REQUEST_METHOD']) ? strtolower($_SERVER['REQUEST_METHOD']) : 'cli';
Fatih Kalifa442b50b2013-11-01 02:44:56 +0700356
Jonatas Miguel59dbe852012-08-07 12:13:32 +0100357 // Is there a literal match? If so we're done
Fatih Kalifa0b58b3c2013-11-05 15:36:40 +0700358 if (isset($this->routes[$uri]))
Fatih Kalifa442b50b2013-11-01 02:44:56 +0700359 {
Fatih Kalifa0b58b3c2013-11-05 15:36:40 +0700360 // Check default routes format
361 if (is_string($this->routes[$uri]))
362 {
Andrey Andreev30d53242014-01-16 14:41:46 +0200363 $this->_set_request(explode('/', $this->routes[$uri]));
364 return;
Fatih Kalifa0b58b3c2013-11-05 15:36:40 +0700365 }
Andrey Andreevc761a202013-11-11 14:02:15 +0200366 // Is there a matching http verb?
Fatih Kalifa0b58b3c2013-11-05 15:36:40 +0700367 elseif (is_array($this->routes[$uri]) && isset($this->routes[$uri][$http_verb]))
368 {
Andrey Andreev30d53242014-01-16 14:41:46 +0200369 $this->_set_request(explode('/', $this->routes[$uri][$http_verb]));
370 return;
Fatih Kalifa0b58b3c2013-11-05 15:36:40 +0700371 }
Jonatas Miguel59dbe852012-08-07 12:13:32 +0100372 }
Barry Mienydd671972010-10-04 16:33:58 +0200373
vlakoffc941d852013-08-06 14:44:40 +0200374 // Loop through the route array looking for wildcards
Jonatas Miguel59dbe852012-08-07 12:13:32 +0100375 foreach ($this->routes as $key => $val)
376 {
Fatih Kalifa0b58b3c2013-11-05 15:36:40 +0700377 // Check if route format is using http verb
Fatih Kalifa442b50b2013-11-01 02:44:56 +0700378 if (is_array($val))
379 {
Fatih Kalifa442b50b2013-11-01 02:44:56 +0700380 if (isset($val[$http_verb]))
381 {
382 $val = $val[$http_verb];
383 }
Fatih Kalifa442b50b2013-11-01 02:44:56 +0700384 else
385 {
Fatih Kalifa442b50b2013-11-01 02:44:56 +0700386 continue;
387 }
388 }
389
vlakoffc941d852013-08-06 14:44:40 +0200390 // Convert wildcards to RegEx
Andrey Andreev7676c2d2012-10-30 13:42:01 +0200391 $key = str_replace(array(':any', ':num'), array('[^/]+', '[0-9]+'), $key);
Derek Jonesc7738402010-03-02 13:55:13 -0600392
Jonatas Miguel59dbe852012-08-07 12:13:32 +0100393 // Does the RegEx match?
394 if (preg_match('#^'.$key.'$#', $uri, $matches))
395 {
Jonatas Miguel59dbe852012-08-07 12:13:32 +0100396 // Are we using callbacks to process back-references?
Andrey Andreevda5562a2012-11-08 12:34:38 +0200397 if ( ! is_string($val) && is_callable($val))
Jonatas Miguel59dbe852012-08-07 12:13:32 +0100398 {
399 // Remove the original string from the matches array.
400 array_shift($matches);
Derek Allard2067d1a2008-11-13 22:59:24 +0000401
Jonatas Miguel59dbe852012-08-07 12:13:32 +0100402 // Get the match count.
403 $match_count = count($matches);
Jonatas Miguelc0d98b22012-08-06 15:42:50 +0100404
Jonatas Miguel59dbe852012-08-07 12:13:32 +0100405 // Determine how many parameters the callback has.
406 $reflection = new ReflectionFunction($val);
407 $param_count = $reflection->getNumberOfParameters();
Jonatas Miguelc0d98b22012-08-06 15:42:50 +0100408
Jonatas Miguel59dbe852012-08-07 12:13:32 +0100409 // Are there more parameters than matches?
Jonatas Miguel24296ca2012-09-27 12:10:01 +0100410 if ($param_count > $match_count)
Jonatas Miguel59dbe852012-08-07 12:13:32 +0100411 {
412 // Any params without matches will be set to an empty string.
413 $matches = array_merge($matches, array_fill($match_count, $param_count - $match_count, ''));
Jonatas Miguelefb81662012-10-23 19:52:46 +0100414
415 $match_count = $param_count;
416 }
417
418 // Get the parameters so we can use their default values.
419 $params = $reflection->getParameters();
420
421 for ($m = 0; $m < $match_count; $m++)
422 {
423 // Is the match empty and does a default value exist?
424 if (empty($matches[$m]) && $params[$m]->isDefaultValueAvailable())
425 {
426 // Substitute the empty match for the default value.
427 $matches[$m] = $params[$m]->getDefaultValue();
428 }
Jonatas Miguel59dbe852012-08-07 12:13:32 +0100429 }
Jonatas Miguelc0d98b22012-08-06 15:42:50 +0100430
Jonatas Miguel59dbe852012-08-07 12:13:32 +0100431 // Execute the callback using the values in matches as its parameters.
432 $val = call_user_func_array($val, $matches);
433 }
Andrey Andreevda5562a2012-11-08 12:34:38 +0200434 // Are we using the default routing method for back-references?
435 elseif (strpos($val, '$') !== FALSE && strpos($key, '(') !== FALSE)
436 {
437 $val = preg_replace('#^'.$key.'$#', $val, $uri);
438 }
Jonatas Miguelc0d98b22012-08-06 15:42:50 +0100439
Andrey Andreev30d53242014-01-16 14:41:46 +0200440 $this->_set_request(explode('/', $val));
441 return;
Jonatas Miguel59dbe852012-08-07 12:13:32 +0100442 }
443 }
Jonatas Miguelc0d98b22012-08-06 15:42:50 +0100444
Jonatas Miguel59dbe852012-08-07 12:13:32 +0100445 // If we got this far it means we didn't encounter a
446 // matching route so we'll set the site default route
Andrey Andreeva9237cb2014-01-18 19:07:20 +0200447 $this->_set_request(array_values($this->uri->segments));
Jonatas Miguel59dbe852012-08-07 12:13:32 +0100448 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000449
450 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200451
Derek Allard2067d1a2008-11-13 22:59:24 +0000452 /**
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300453 * Set class name
Derek Allard2067d1a2008-11-13 22:59:24 +0000454 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300455 * @param string $class Class name
Derek Allard2067d1a2008-11-13 22:59:24 +0000456 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200457 */
Andrey Andreevba6c0412012-01-07 21:10:09 +0200458 public function set_class($class)
Derek Allard2067d1a2008-11-13 22:59:24 +0000459 {
Derek Jones2615e412010-10-06 17:51:16 -0500460 $this->class = str_replace(array('/', '.'), '', $class);
Derek Allard2067d1a2008-11-13 22:59:24 +0000461 }
Barry Mienydd671972010-10-04 16:33:58 +0200462
Derek Allard2067d1a2008-11-13 22:59:24 +0000463 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200464
Derek Allard2067d1a2008-11-13 22:59:24 +0000465 /**
466 * Fetch the current class
467 *
Andrey Andreev0e4237f2013-04-04 16:53:21 +0300468 * @deprecated 3.0.0 Read the 'class' property instead
Derek Allard2067d1a2008-11-13 22:59:24 +0000469 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200470 */
Andrey Andreevba6c0412012-01-07 21:10:09 +0200471 public function fetch_class()
Derek Allard2067d1a2008-11-13 22:59:24 +0000472 {
473 return $this->class;
474 }
Barry Mienydd671972010-10-04 16:33:58 +0200475
Derek Allard2067d1a2008-11-13 22:59:24 +0000476 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200477
Derek Allard2067d1a2008-11-13 22:59:24 +0000478 /**
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300479 * Set method name
Derek Allard2067d1a2008-11-13 22:59:24 +0000480 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300481 * @param string $method Method name
Derek Allard2067d1a2008-11-13 22:59:24 +0000482 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200483 */
Andrey Andreevba6c0412012-01-07 21:10:09 +0200484 public function set_method($method)
Derek Allard2067d1a2008-11-13 22:59:24 +0000485 {
486 $this->method = $method;
487 }
488
489 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200490
Derek Allard2067d1a2008-11-13 22:59:24 +0000491 /**
Andrey Andreev7b53d042012-03-26 23:02:32 +0300492 * Fetch the current method
Derek Allard2067d1a2008-11-13 22:59:24 +0000493 *
Andrey Andreev0e4237f2013-04-04 16:53:21 +0300494 * @deprecated 3.0.0 Read the 'method' property instead
Derek Allard2067d1a2008-11-13 22:59:24 +0000495 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200496 */
Andrey Andreevba6c0412012-01-07 21:10:09 +0200497 public function fetch_method()
Derek Allard2067d1a2008-11-13 22:59:24 +0000498 {
Andrey Andreev0e4237f2013-04-04 16:53:21 +0300499 return $this->method;
Derek Allard2067d1a2008-11-13 22:59:24 +0000500 }
501
502 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200503
Derek Allard2067d1a2008-11-13 22:59:24 +0000504 /**
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300505 * Set directory name
Derek Allard2067d1a2008-11-13 22:59:24 +0000506 *
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300507 * @param string $dir Directory name
Andrey Andreev30d53242014-01-16 14:41:46 +0200508 * @param bool $appent Whether we're appending rather then setting the full value
Derek Allard2067d1a2008-11-13 22:59:24 +0000509 * @return void
Barry Mienydd671972010-10-04 16:33:58 +0200510 */
Andrey Andreev30d53242014-01-16 14:41:46 +0200511 public function set_directory($dir, $append = FALSE)
Derek Allard2067d1a2008-11-13 22:59:24 +0000512 {
Andrey Andreev30d53242014-01-16 14:41:46 +0200513 if ($append !== TRUE OR empty($this->directory))
514 {
515 $this->directory = str_replace('.', '', trim($dir, '/')).'/';
516 }
517 else
518 {
519 $this->directory .= str_replace('.', '', trim($dir, '/')).'/';
520 }
Derek Allard2067d1a2008-11-13 22:59:24 +0000521 }
522
523 // --------------------------------------------------------------------
Barry Mienydd671972010-10-04 16:33:58 +0200524
Derek Allard2067d1a2008-11-13 22:59:24 +0000525 /**
Andrey Andreevb9fe7e92012-10-27 18:45:59 +0300526 * Fetch directory
527 *
528 * Feches the sub-directory (if any) that contains the requested
529 * controller class.
Derek Allard2067d1a2008-11-13 22:59:24 +0000530 *
Andrey Andreev0e4237f2013-04-04 16:53:21 +0300531 * @deprecated 3.0.0 Read the 'directory' property instead
Derek Allard2067d1a2008-11-13 22:59:24 +0000532 * @return string
Barry Mienydd671972010-10-04 16:33:58 +0200533 */
Andrey Andreevba6c0412012-01-07 21:10:09 +0200534 public function fetch_directory()
Derek Allard2067d1a2008-11-13 22:59:24 +0000535 {
536 return $this->directory;
537 }
538
539}
Derek Allard2067d1a2008-11-13 22:59:24 +0000540
541/* End of file Router.php */
Andrey Andreev7b53d042012-03-26 23:02:32 +0300542/* Location: ./system/core/Router.php */