blob: 51f455023d8bb08b5eed52600a398a604f41c833 [file] [log] [blame]
adminb0dd10f2006-08-25 17:25:49 +00001<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
2/**
3 * Code Igniter
4 *
5 * An open source application development framework for PHP 4.3.2 or newer
6 *
7 * @package CodeIgniter
8 * @author Rick Ellis
9 * @copyright Copyright (c) 2006, pMachine, Inc.
10 * @license http://www.codeignitor.com/user_guide/license.html
11 * @link http://www.codeigniter.com
12 * @since Version 1.0
13 * @filesource
14 */
15
16// ------------------------------------------------------------------------
17
18/**
19 * Code Igniter Application Controller Class
20 *
21 * This class object is the the super class the every library in
22 * Code Igniter will be assigned to.
23 *
24 * @package CodeIgniter
25 * @subpackage Libraries
26 * @category Libraries
27 * @author Rick Ellis
28 * @link http://www.codeigniter.com/user_guide/general/controllers.html
29 */
30class Controller extends CI_Base {
31
adminb0dd10f2006-08-25 17:25:49 +000032 var $_ci_models = array();
33 var $_ci_scaffolding = FALSE;
34 var $_ci_scaff_table = FALSE;
35
36 /**
37 * Constructor
38 *
39 * Loads the base classes needed to run CI, and runs the "autoload"
40 * routine which loads the systems specified in the "autoload" config file.
41 */
42 function Controller()
43 {
44 parent::CI_Base();
45
46 // Assign all the class objects that were instantiated by the
47 // front controller to local class variables so that CI can be
48 // run as one big super object.
49 $this->_ci_assign_core();
50
51 // Load everything specified in the autoload.php file
52 $this->load->_ci_autoloader($this->_ci_autoload());
53
54 // This allows anything loaded using $this->load (viwes, files, etc.)
55 // to become accessible from within the Controller class functions.
admine79dc712006-09-26 03:52:45 +000056 foreach (get_object_vars($this) as $key => $var)
adminb0dd10f2006-08-25 17:25:49 +000057 {
admine79dc712006-09-26 03:52:45 +000058 if (is_object($var))
59 {
60 $this->load->$key =& $this->$key;
61 }
adminb0dd10f2006-08-25 17:25:49 +000062 }
admine79dc712006-09-26 03:52:45 +000063
adminb0dd10f2006-08-25 17:25:49 +000064 log_message('debug', "Controller Class Initialized");
65 }
admine79dc712006-09-26 03:52:45 +000066
adminb0dd10f2006-08-25 17:25:49 +000067 // --------------------------------------------------------------------
68
69 /**
70 * Initialization Handler
71 *
admin7981a9a2006-09-26 07:52:09 +000072 * This function loads the requested class.
adminb0dd10f2006-08-25 17:25:49 +000073 *
74 * @access private
75 * @param string the item that is being loaded
76 * @param mixed any additional parameters
77 * @return void
78 */
admin33de9a12006-09-28 06:50:16 +000079 function _ci_load_class($class, $params = NULL)
admin7981a9a2006-09-26 07:52:09 +000080 {
81 // Prep the class name
admine79dc712006-09-26 03:52:45 +000082 $class = strtolower(str_replace(EXT, '', $class));
admin33de9a12006-09-28 06:50:16 +000083
84 // Is this a class extension request?
85 if (substr($class, 0, 3) == 'my_')
86 {
87 $class = preg_replace("/my_(.+)/", "\\1", $class);
88 $extend = TRUE;
89 }
90 else
91 {
92 $extend = FALSE;
93 }
admin7981a9a2006-09-26 07:52:09 +000094
95 // Does THIS file (Controller.php) contain an initialization
96 // function that maps to the requested class?
97
98 $method = '_ci_init_'.$class;
99
100 if (method_exists($this, $method))
101 {
102 if (is_null($params))
adminb0dd10f2006-08-25 17:25:49 +0000103 {
104 $this->$method();
105 }
106 else
107 {
108 $this->$method($params);
admin7981a9a2006-09-26 07:52:09 +0000109 }
110
111 // We're done...
112 return TRUE;
adminb0dd10f2006-08-25 17:25:49 +0000113 }
admin7981a9a2006-09-26 07:52:09 +0000114
admin33de9a12006-09-28 06:50:16 +0000115 // Are we extending one of the base classes?
116 if ($extend == TRUE)
admin7981a9a2006-09-26 07:52:09 +0000117 {
admin33de9a12006-09-28 06:50:16 +0000118 // Load the requested library from the main system/libraries folder
119 if (file_exists(BASEPATH.'libraries/'.ucfirst($class).EXT))
admin7981a9a2006-09-26 07:52:09 +0000120 {
admin33de9a12006-09-28 06:50:16 +0000121 include_once(BASEPATH.'libraries/'.ucfirst($class).EXT);
122 }
admin7981a9a2006-09-26 07:52:09 +0000123
admin33de9a12006-09-28 06:50:16 +0000124 // Now look for a matching library
125 foreach (array(ucfirst($class), $class) as $filename)
126 {
127 if (file_exists(APPPATH.'libraries/'.$filename.EXT))
admin7981a9a2006-09-26 07:52:09 +0000128 {
admin33de9a12006-09-28 06:50:16 +0000129 include_once(APPPATH.'libraries/'.$filename.EXT);
admin7981a9a2006-09-26 07:52:09 +0000130 }
131 }
admin33de9a12006-09-28 06:50:16 +0000132
133 return $this->_ci_init_class($filename, 'MY_', $params);
134 }
135 else
136 {
137 // Lets search for the requested library file and load it.
138 // For backward compatibility we'll test for filenames that are
139 // both uppercase and lower.
140 foreach (array(ucfirst($class), $class) as $filename)
141 {
142 for ($i = 1; $i < 3; $i++)
143 {
144 $path = ($i % 2) ? APPPATH : BASEPATH;
145
146 if (file_exists($path.'libraries/'.$filename.EXT))
147 {
148 include_once($path.'libraries/'.$filename.EXT);
149 return $this->_ci_init_class($filename, '', $params);
150 }
151 }
152 }
admin7981a9a2006-09-26 07:52:09 +0000153 }
154
155 // If we got this far we were unable to find the requested class
156 log_message('error', "Unable to load the requested class: ".$class);
157 show_error("Unable to load the class: ".$class);
adminb0dd10f2006-08-25 17:25:49 +0000158 }
admin33de9a12006-09-28 06:50:16 +0000159
160 // --------------------------------------------------------------------
161
162 /**
163 * Instantiates a class
164 *
165 * @access private
166 * @param string
167 * @param string
168 * @return null
169 */
170 function _ci_init_class($class, $prefix = '', $config = NULL)
171 {
172 // Is there an associated config file for this class?
173
174 if ($config == NULL)
175 {
176 if (file_exists(APPPATH.'config/'.$class.EXT))
177 {
178 include_once(APPPATH.'config/'.$class.EXT);
179 }
180 }
181
182 if ($prefix == '')
183 {
184 $name = ( ! class_exists($class)) ? 'CI_'.$class : $class;
185 }
186 else
187 {
188 $name = $prefix.ucfirst($class);
189 }
190
191 $remap = array(
admin33de9a12006-09-28 06:50:16 +0000192 'Unit_test' => 'unit'
193 );
194
195 $varname = ( ! isset($remap[$class])) ? $class : $remap[$class];
196
197 // Instantiate the class
198 if ($config !== NULL)
199 {
200 $this->$varname = new $name($config);
201 }
202 else
203 {
204 $this->$varname = new $name;
205 }
206 }
adminb0dd10f2006-08-25 17:25:49 +0000207
208 // --------------------------------------------------------------------
209
210 /**
211 * Loads and instantiates the requested model class
212 *
213 * @access private
214 * @param string
215 * @return array
216 */
admin7981a9a2006-09-26 07:52:09 +0000217 function _ci_init_model($model, $name = '', $db_conn = FALSE)
adminb0dd10f2006-08-25 17:25:49 +0000218 {
admin4ce59da2006-09-28 07:45:59 +0000219 // Is the model in a sub-folder?
220 // If so, parse out the filename and path.
221 if (strpos($model, '/') === FALSE)
222 {
223 $path = '';
224 }
225 else
226 {
227 $x = explode('/', $model);
228 $model = end($x);
229 unset($x[count($x)-1]);
230 $path = implode('/', $x).'/';
231 }
232
adminb0dd10f2006-08-25 17:25:49 +0000233 if ($name == '')
234 {
235 $name = $model;
236 }
adminb4473d42006-08-27 15:46:31 +0000237
admin0d296052006-08-27 15:48:38 +0000238 $obj =& get_instance();
adminee54c112006-09-28 17:13:38 +0000239 if (in_array($name, $obj->_ci_models, TRUE))
adminb4473d42006-08-27 15:46:31 +0000240 {
241 return;
242 }
243
adminb0dd10f2006-08-25 17:25:49 +0000244 if (isset($this->$name))
245 {
246 show_error('The model name you are loading is the name of a resource that is already being used: '.$name);
247 }
248
249 $model = strtolower($model);
250
admin4ce59da2006-09-28 07:45:59 +0000251 if ( ! file_exists(APPPATH.'models/'.$path.$model.EXT))
adminb0dd10f2006-08-25 17:25:49 +0000252 {
253 show_error('Unable to locate the model you have specified: '.$model);
254 }
admin4ce59da2006-09-28 07:45:59 +0000255
adminb0dd10f2006-08-25 17:25:49 +0000256 if ($db_conn !== FALSE)
257 {
258 if ($db_conn === TRUE)
259 $db_conn = '';
260
261 $this->_ci_init_database($db_conn, FALSE, TRUE);
262 }
263
264 if ( ! class_exists('Model'))
265 {
266 require_once(BASEPATH.'libraries/Model'.EXT);
267 }
268
admin4ce59da2006-09-28 07:45:59 +0000269 require_once(APPPATH.'models/'.$path.$model.EXT);
adminb0dd10f2006-08-25 17:25:49 +0000270
271 $model = ucfirst($model);
272 $this->$name = new $model();
273 $this->_ci_models[] = $name;
274 $this->_ci_assign_to_models();
admin7981a9a2006-09-26 07:52:09 +0000275 }
adminb0dd10f2006-08-25 17:25:49 +0000276
277 // --------------------------------------------------------------------
278
279 /**
280 * Assign to Models
281 *
282 * Makes sure that anything loaded by the loader class (libraries, plugins, etc.)
283 * will be available to modles, if any exist.
284 *
285 * @access public
286 * @param object
287 * @return array
288 */
289 function _ci_assign_to_models()
290 {
291 $obj =& get_instance();
292 if (count($obj->_ci_models) == 0)
293 {
294 return;
295 }
296 foreach ($obj->_ci_models as $model)
297 {
298 $obj->$model->_assign_libraries();
299 }
admin7981a9a2006-09-26 07:52:09 +0000300 }
adminb0dd10f2006-08-25 17:25:49 +0000301
302 // --------------------------------------------------------------------
303
304 /**
305 * Auto-initialize Core Classes
306 *
307 * This initializes the core systems that are specified in the
308 * libraries/autoload.php file, as well as the systems specified in
309 * the $autoload class array above.
310 *
311 * It returns the "autoload" array so we can pass it to the Loader
312 * class since it needs to autoload plugins and helper files
313 *
314 * The config/autoload.php file contains an array that permits
315 * sub-systems to be loaded automatically.
316 *
317 * @access private
318 * @return array
319 */
320 function _ci_autoload()
321 {
322 include_once(APPPATH.'config/autoload'.EXT);
323
324 if ( ! isset($autoload))
325 {
326 return FALSE;
327 }
328
329 if (count($autoload['config']) > 0)
330 {
331 foreach ($autoload['config'] as $key => $val)
332 {
333 $this->config->load($val);
334 }
335 }
336 unset($autoload['config']);
337
admind48ef1c2006-09-21 06:22:05 +0000338 // A little tweak to remain backward compatible
339 // The $autoload['core'] item was deprecated
340 if ( ! isset($autoload['libraries']))
adminb0dd10f2006-08-25 17:25:49 +0000341 {
admind48ef1c2006-09-21 06:22:05 +0000342 $autoload['libraries'] = $autoload['core'];
343
adminb0dd10f2006-08-25 17:25:49 +0000344 }
345
admin6e00bab2006-09-26 08:13:06 +0000346 $exceptions = array('dbutil', 'dbexport');
347
admind48ef1c2006-09-21 06:22:05 +0000348 foreach ($autoload['libraries'] as $item)
adminb0dd10f2006-08-25 17:25:49 +0000349 {
adminee54c112006-09-28 17:13:38 +0000350 if ( ! in_array($item, $exceptions, TRUE))
admin6e00bab2006-09-26 08:13:06 +0000351 {
admin33de9a12006-09-28 06:50:16 +0000352 $this->_ci_load_class($item);
admin6e00bab2006-09-26 08:13:06 +0000353 }
354 else
355 {
356 $this->_ci_init_dbextra($item);
357 }
adminb0dd10f2006-08-25 17:25:49 +0000358 }
admind48ef1c2006-09-21 06:22:05 +0000359 unset($autoload['libraries']);
360
adminb0dd10f2006-08-25 17:25:49 +0000361 return $autoload;
362 }
adminb0dd10f2006-08-25 17:25:49 +0000363
364 // --------------------------------------------------------------------
365
366 /**
367 * Assign the core classes to the global $CI object
368 *
369 * By assigning all the classes instantiated by the front controller
370 * local class variables we enable everything to be accessible using
371 * $this->class->function()
372 *
373 * @access private
374 * @return void
375 */
376 function _ci_assign_core()
377 {
378 foreach (array('Config', 'Input', 'Benchmark', 'URI', 'Output') as $val)
379 {
380 $class = strtolower($val);
admin33de9a12006-09-28 06:50:16 +0000381 $this->$class =& _load_class($val);
adminb0dd10f2006-08-25 17:25:49 +0000382 }
383
admin33de9a12006-09-28 06:50:16 +0000384 $this->lang =& _load_class('Language');
adminb0dd10f2006-08-25 17:25:49 +0000385
386 // In PHP 4 the Controller class is a child of CI_Loader.
387 // In PHP 5 we run it as its own class.
388 if (floor(phpversion()) >= 5)
389 {
390 $this->load = new CI_Loader();
391 }
adminb0dd10f2006-08-25 17:25:49 +0000392 }
adminb0dd10f2006-08-25 17:25:49 +0000393
394 // --------------------------------------------------------------------
395
396 /**
397 * Initialize Scaffolding
398 *
399 * This initializing function works a bit different than the
400 * others. It doesn't load the class. Instead, it simply
401 * sets a flag indicating that scaffolding is allowed to be
402 * used. The actual scaffolding function below is
403 * called by the front controller based on whether the
404 * second segment of the URL matches the "secret" scaffolding
405 * word stored in the application/config/routes.php
406 *
407 * @access private
408 * @param string the table to scaffold
409 * @return void
410 */
411 function _ci_init_scaffolding($table = FALSE)
412 {
413 if ($table === FALSE)
414 {
415 show_error('You must include the name of the table you would like access when you initialize scaffolding');
416 }
417
418 $this->_ci_scaffolding = TRUE;
419 $this->_ci_scaff_table = $table;
420 }
adminb0dd10f2006-08-25 17:25:49 +0000421
422 // --------------------------------------------------------------------
423
424 /**
425 * Initialize Database
426 *
427 * @access private
428 * @param mixed database connection values
429 * @param bool whether to return the object for multiple connections
430 * @return void
431 */
432 function _ci_init_database($params = '', $return = FALSE, $active_record = FALSE)
admin7981a9a2006-09-26 07:52:09 +0000433 {
adminb0dd10f2006-08-25 17:25:49 +0000434 if ($this->_ci_is_loaded('db') == TRUE AND $return == FALSE AND $active_record == FALSE)
435 {
436 return;
437 }
438
439 // Load the DB config file if needed
440 if (is_string($params) AND strpos($params, '://') === FALSE)
441 {
442 include(APPPATH.'config/database'.EXT);
443
444 $group = ($params == '') ? $active_group : $params;
445
446 if ( ! isset($db[$group]))
447 {
448 show_error('You have specified an invalid database connection group: '.$group);
449 }
450
451 $params = $db[$group];
452 }
453
454 // No DB specified yet? Beat them senseless...
455 if ( ! isset($params['dbdriver']) OR $params['dbdriver'] == '')
456 {
457 show_error('You have not selected a database type to connect to.');
458 }
459
460 // Load the DB classes. Note: Since the active record class is optional
461 // we need to dynamically create a class that extends proper parent class
462 // based on whether we're using the active record class or not.
463 // Kudos to Paul for discovering this clever use of eval()
464
465 if ($active_record == TRUE)
466 {
467 $params['active_r'] = TRUE;
468 }
469
admin58083462006-09-24 17:58:27 +0000470 require_once(BASEPATH.'database/DB_driver'.EXT);
adminb0dd10f2006-08-25 17:25:49 +0000471
472 if ( ! isset($params['active_r']) OR $params['active_r'] == TRUE)
473 {
adminc9a8bab2006-09-24 20:28:33 +0000474 require_once(BASEPATH.'database/DB_active_rec'.EXT);
adminb0dd10f2006-08-25 17:25:49 +0000475
476 if ( ! class_exists('CI_DB'))
477 {
478 eval('class CI_DB extends CI_DB_active_record { }');
479 }
480 }
481 else
482 {
483 if ( ! class_exists('CI_DB'))
484 {
485 eval('class CI_DB extends CI_DB_driver { }');
486 }
487 }
adminc1fa0742006-09-21 23:50:23 +0000488
admin46563d52006-09-24 18:14:22 +0000489 require_once(BASEPATH.'database/drivers/'.$params['dbdriver'].'/'.$params['dbdriver'].'_driver'.EXT);
adminb0dd10f2006-08-25 17:25:49 +0000490
491 // Instantiate the DB adapter
admina5e812c2006-09-25 02:17:30 +0000492 $driver = 'CI_DB_'.$params['dbdriver'].'_driver';
adminb0dd10f2006-08-25 17:25:49 +0000493 $DB = new $driver($params);
494
495 if ($return === TRUE)
496 {
497 return $DB;
498 }
499
500 $obj =& get_instance();
adminb0dd10f2006-08-25 17:25:49 +0000501 $obj->db =& $DB;
502 }
admina5e812c2006-09-25 02:17:30 +0000503
adminb0dd10f2006-08-25 17:25:49 +0000504 // --------------------------------------------------------------------
505
506 /**
admin6e00bab2006-09-26 08:13:06 +0000507 * Initialize Database Ancillary Classes
508 *
509 * @access private
510 * @param str class name
511 * @return void
512 */
513 function _ci_init_dbextra($class)
514 {
admine5bb9362006-09-27 00:31:22 +0000515 if ( ! $this->_ci_is_loaded('db'))
516 {
admin3ed8c512006-09-29 23:26:28 +0000517 $this->_ci_init_database();
admine5bb9362006-09-27 00:31:22 +0000518 }
519
520 if ($class == 'dbutil')
521 {
522 require_once(BASEPATH.'database/DB_utility'.EXT);
523 require_once(BASEPATH.'database/drivers/'.$this->db->dbdriver.'/'.$this->db->dbdriver.'_utility'.EXT);
admin3ed8c512006-09-29 23:26:28 +0000524 $class = 'CI_DB_'.$this->db->dbdriver.'_utility';
525 $this->dbutil = new $class();
admine5bb9362006-09-27 00:31:22 +0000526 }
admin6e00bab2006-09-26 08:13:06 +0000527 }
528
529 // --------------------------------------------------------------------
530
531 /**
adminb0dd10f2006-08-25 17:25:49 +0000532 * Returns TRUE if a class is loaded, FALSE if not
533 *
534 * @access public
535 * @param string the class name
536 * @return bool
537 */
538 function _ci_is_loaded($class)
539 {
admine79dc712006-09-26 03:52:45 +0000540 return ( ! isset($this->$class) OR ! is_object($this->$class)) ? FALSE : TRUE;
adminb0dd10f2006-08-25 17:25:49 +0000541 }
admine79dc712006-09-26 03:52:45 +0000542
adminb0dd10f2006-08-25 17:25:49 +0000543 // --------------------------------------------------------------------
544
545 /**
546 * Scaffolding
547 *
548 * Initializes the scaffolding.
549 *
550 * @access private
551 * @return void
552 */
553 function _ci_scaffolding()
554 {
555 if ($this->_ci_scaffolding === FALSE OR $this->_ci_scaff_table === FALSE)
556 {
557 show_404('Scaffolding unavailable');
558 }
559
560 if (class_exists('Scaffolding')) return;
561
adminee54c112006-09-28 17:13:38 +0000562 if ( ! in_array($this->uri->segment(3), array('add', 'insert', 'edit', 'update', 'view', 'delete', 'do_delete'), TRUE))
adminb0dd10f2006-08-25 17:25:49 +0000563 {
564 $method = 'view';
565 }
566 else
567 {
568 $method = $this->uri->segment(3);
569 }
570
571 $this->_ci_init_database("", FALSE, TRUE);
admin33de9a12006-09-28 06:50:16 +0000572 $this->_ci_load_class('pagination');
adminb0dd10f2006-08-25 17:25:49 +0000573 require_once(BASEPATH.'scaffolding/Scaffolding'.EXT);
574 $this->scaff = new Scaffolding($this->_ci_scaff_table);
575 $this->scaff->$method();
576 }
adminb0dd10f2006-08-25 17:25:49 +0000577
578}
579// END _Controller class
580?>