blob: be66b19b7366487badaee03c846c147f2d1911ca [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(
192 'DB_export' => 'dbexport',
193 'DB_utility' => 'dbutility',
admin33de9a12006-09-28 06:50:16 +0000194 'Unit_test' => 'unit'
195 );
196
197 $varname = ( ! isset($remap[$class])) ? $class : $remap[$class];
198
199 // Instantiate the class
200 if ($config !== NULL)
201 {
202 $this->$varname = new $name($config);
203 }
204 else
205 {
206 $this->$varname = new $name;
207 }
208 }
adminb0dd10f2006-08-25 17:25:49 +0000209
210 // --------------------------------------------------------------------
211
212 /**
213 * Loads and instantiates the requested model class
214 *
215 * @access private
216 * @param string
217 * @return array
218 */
admin7981a9a2006-09-26 07:52:09 +0000219 function _ci_init_model($model, $name = '', $db_conn = FALSE)
adminb0dd10f2006-08-25 17:25:49 +0000220 {
admin4ce59da2006-09-28 07:45:59 +0000221 // Is the model in a sub-folder?
222 // If so, parse out the filename and path.
223 if (strpos($model, '/') === FALSE)
224 {
225 $path = '';
226 }
227 else
228 {
229 $x = explode('/', $model);
230 $model = end($x);
231 unset($x[count($x)-1]);
232 $path = implode('/', $x).'/';
233 }
234
adminb0dd10f2006-08-25 17:25:49 +0000235 if ($name == '')
236 {
237 $name = $model;
238 }
adminb4473d42006-08-27 15:46:31 +0000239
admin0d296052006-08-27 15:48:38 +0000240 $obj =& get_instance();
adminee54c112006-09-28 17:13:38 +0000241 if (in_array($name, $obj->_ci_models, TRUE))
adminb4473d42006-08-27 15:46:31 +0000242 {
243 return;
244 }
245
adminb0dd10f2006-08-25 17:25:49 +0000246 if (isset($this->$name))
247 {
248 show_error('The model name you are loading is the name of a resource that is already being used: '.$name);
249 }
250
251 $model = strtolower($model);
252
admin4ce59da2006-09-28 07:45:59 +0000253 if ( ! file_exists(APPPATH.'models/'.$path.$model.EXT))
adminb0dd10f2006-08-25 17:25:49 +0000254 {
255 show_error('Unable to locate the model you have specified: '.$model);
256 }
admin4ce59da2006-09-28 07:45:59 +0000257
adminb0dd10f2006-08-25 17:25:49 +0000258 if ($db_conn !== FALSE)
259 {
260 if ($db_conn === TRUE)
261 $db_conn = '';
262
263 $this->_ci_init_database($db_conn, FALSE, TRUE);
264 }
265
266 if ( ! class_exists('Model'))
267 {
268 require_once(BASEPATH.'libraries/Model'.EXT);
269 }
270
admin4ce59da2006-09-28 07:45:59 +0000271 require_once(APPPATH.'models/'.$path.$model.EXT);
adminb0dd10f2006-08-25 17:25:49 +0000272
273 $model = ucfirst($model);
274 $this->$name = new $model();
275 $this->_ci_models[] = $name;
276 $this->_ci_assign_to_models();
admin7981a9a2006-09-26 07:52:09 +0000277 }
adminb0dd10f2006-08-25 17:25:49 +0000278
279 // --------------------------------------------------------------------
280
281 /**
282 * Assign to Models
283 *
284 * Makes sure that anything loaded by the loader class (libraries, plugins, etc.)
285 * will be available to modles, if any exist.
286 *
287 * @access public
288 * @param object
289 * @return array
290 */
291 function _ci_assign_to_models()
292 {
293 $obj =& get_instance();
294 if (count($obj->_ci_models) == 0)
295 {
296 return;
297 }
298 foreach ($obj->_ci_models as $model)
299 {
300 $obj->$model->_assign_libraries();
301 }
admin7981a9a2006-09-26 07:52:09 +0000302 }
adminb0dd10f2006-08-25 17:25:49 +0000303
304 // --------------------------------------------------------------------
305
306 /**
307 * Auto-initialize Core Classes
308 *
309 * This initializes the core systems that are specified in the
310 * libraries/autoload.php file, as well as the systems specified in
311 * the $autoload class array above.
312 *
313 * It returns the "autoload" array so we can pass it to the Loader
314 * class since it needs to autoload plugins and helper files
315 *
316 * The config/autoload.php file contains an array that permits
317 * sub-systems to be loaded automatically.
318 *
319 * @access private
320 * @return array
321 */
322 function _ci_autoload()
323 {
324 include_once(APPPATH.'config/autoload'.EXT);
325
326 if ( ! isset($autoload))
327 {
328 return FALSE;
329 }
330
331 if (count($autoload['config']) > 0)
332 {
333 foreach ($autoload['config'] as $key => $val)
334 {
335 $this->config->load($val);
336 }
337 }
338 unset($autoload['config']);
339
admind48ef1c2006-09-21 06:22:05 +0000340 // A little tweak to remain backward compatible
341 // The $autoload['core'] item was deprecated
342 if ( ! isset($autoload['libraries']))
adminb0dd10f2006-08-25 17:25:49 +0000343 {
admind48ef1c2006-09-21 06:22:05 +0000344 $autoload['libraries'] = $autoload['core'];
345
adminb0dd10f2006-08-25 17:25:49 +0000346 }
347
admin6e00bab2006-09-26 08:13:06 +0000348 $exceptions = array('dbutil', 'dbexport');
349
admind48ef1c2006-09-21 06:22:05 +0000350 foreach ($autoload['libraries'] as $item)
adminb0dd10f2006-08-25 17:25:49 +0000351 {
adminee54c112006-09-28 17:13:38 +0000352 if ( ! in_array($item, $exceptions, TRUE))
admin6e00bab2006-09-26 08:13:06 +0000353 {
admin33de9a12006-09-28 06:50:16 +0000354 $this->_ci_load_class($item);
admin6e00bab2006-09-26 08:13:06 +0000355 }
356 else
357 {
358 $this->_ci_init_dbextra($item);
359 }
adminb0dd10f2006-08-25 17:25:49 +0000360 }
admind48ef1c2006-09-21 06:22:05 +0000361 unset($autoload['libraries']);
362
adminb0dd10f2006-08-25 17:25:49 +0000363 return $autoload;
364 }
adminb0dd10f2006-08-25 17:25:49 +0000365
366 // --------------------------------------------------------------------
367
368 /**
369 * Assign the core classes to the global $CI object
370 *
371 * By assigning all the classes instantiated by the front controller
372 * local class variables we enable everything to be accessible using
373 * $this->class->function()
374 *
375 * @access private
376 * @return void
377 */
378 function _ci_assign_core()
379 {
380 foreach (array('Config', 'Input', 'Benchmark', 'URI', 'Output') as $val)
381 {
382 $class = strtolower($val);
admin33de9a12006-09-28 06:50:16 +0000383 $this->$class =& _load_class($val);
adminb0dd10f2006-08-25 17:25:49 +0000384 }
385
admin33de9a12006-09-28 06:50:16 +0000386 $this->lang =& _load_class('Language');
adminb0dd10f2006-08-25 17:25:49 +0000387
388 // In PHP 4 the Controller class is a child of CI_Loader.
389 // In PHP 5 we run it as its own class.
390 if (floor(phpversion()) >= 5)
391 {
392 $this->load = new CI_Loader();
393 }
adminb0dd10f2006-08-25 17:25:49 +0000394 }
adminb0dd10f2006-08-25 17:25:49 +0000395
396 // --------------------------------------------------------------------
397
398 /**
399 * Initialize Scaffolding
400 *
401 * This initializing function works a bit different than the
402 * others. It doesn't load the class. Instead, it simply
403 * sets a flag indicating that scaffolding is allowed to be
404 * used. The actual scaffolding function below is
405 * called by the front controller based on whether the
406 * second segment of the URL matches the "secret" scaffolding
407 * word stored in the application/config/routes.php
408 *
409 * @access private
410 * @param string the table to scaffold
411 * @return void
412 */
413 function _ci_init_scaffolding($table = FALSE)
414 {
415 if ($table === FALSE)
416 {
417 show_error('You must include the name of the table you would like access when you initialize scaffolding');
418 }
419
420 $this->_ci_scaffolding = TRUE;
421 $this->_ci_scaff_table = $table;
422 }
adminb0dd10f2006-08-25 17:25:49 +0000423
424 // --------------------------------------------------------------------
425
426 /**
427 * Initialize Database
428 *
429 * @access private
430 * @param mixed database connection values
431 * @param bool whether to return the object for multiple connections
432 * @return void
433 */
434 function _ci_init_database($params = '', $return = FALSE, $active_record = FALSE)
admin7981a9a2006-09-26 07:52:09 +0000435 {
adminb0dd10f2006-08-25 17:25:49 +0000436 if ($this->_ci_is_loaded('db') == TRUE AND $return == FALSE AND $active_record == FALSE)
437 {
438 return;
439 }
440
441 // Load the DB config file if needed
442 if (is_string($params) AND strpos($params, '://') === FALSE)
443 {
444 include(APPPATH.'config/database'.EXT);
445
446 $group = ($params == '') ? $active_group : $params;
447
448 if ( ! isset($db[$group]))
449 {
450 show_error('You have specified an invalid database connection group: '.$group);
451 }
452
453 $params = $db[$group];
454 }
455
456 // No DB specified yet? Beat them senseless...
457 if ( ! isset($params['dbdriver']) OR $params['dbdriver'] == '')
458 {
459 show_error('You have not selected a database type to connect to.');
460 }
461
462 // Load the DB classes. Note: Since the active record class is optional
463 // we need to dynamically create a class that extends proper parent class
464 // based on whether we're using the active record class or not.
465 // Kudos to Paul for discovering this clever use of eval()
466
467 if ($active_record == TRUE)
468 {
469 $params['active_r'] = TRUE;
470 }
471
admin58083462006-09-24 17:58:27 +0000472 require_once(BASEPATH.'database/DB_driver'.EXT);
adminb0dd10f2006-08-25 17:25:49 +0000473
474 if ( ! isset($params['active_r']) OR $params['active_r'] == TRUE)
475 {
adminc9a8bab2006-09-24 20:28:33 +0000476 require_once(BASEPATH.'database/DB_active_rec'.EXT);
adminb0dd10f2006-08-25 17:25:49 +0000477
478 if ( ! class_exists('CI_DB'))
479 {
480 eval('class CI_DB extends CI_DB_active_record { }');
481 }
482 }
483 else
484 {
485 if ( ! class_exists('CI_DB'))
486 {
487 eval('class CI_DB extends CI_DB_driver { }');
488 }
489 }
adminc1fa0742006-09-21 23:50:23 +0000490
admin46563d52006-09-24 18:14:22 +0000491 require_once(BASEPATH.'database/drivers/'.$params['dbdriver'].'/'.$params['dbdriver'].'_driver'.EXT);
adminb0dd10f2006-08-25 17:25:49 +0000492
493 // Instantiate the DB adapter
admina5e812c2006-09-25 02:17:30 +0000494 $driver = 'CI_DB_'.$params['dbdriver'].'_driver';
adminb0dd10f2006-08-25 17:25:49 +0000495 $DB = new $driver($params);
496
497 if ($return === TRUE)
498 {
499 return $DB;
500 }
501
502 $obj =& get_instance();
adminb0dd10f2006-08-25 17:25:49 +0000503 $obj->db =& $DB;
504 }
admina5e812c2006-09-25 02:17:30 +0000505
adminb0dd10f2006-08-25 17:25:49 +0000506 // --------------------------------------------------------------------
507
508 /**
admin6e00bab2006-09-26 08:13:06 +0000509 * Initialize Database Ancillary Classes
510 *
511 * @access private
512 * @param str class name
513 * @return void
514 */
515 function _ci_init_dbextra($class)
516 {
admine5bb9362006-09-27 00:31:22 +0000517 if ( ! $this->_ci_is_loaded('db'))
518 {
519 $this->_init_database();
520 }
521
522 if ($class == 'dbutil')
523 {
524 require_once(BASEPATH.'database/DB_utility'.EXT);
525 require_once(BASEPATH.'database/drivers/'.$this->db->dbdriver.'/'.$this->db->dbdriver.'_utility'.EXT);
526 $this->init_class('CI_DB_'.$this->db->dbdriver.'_utility', 'dbutil');
527 }
528 elseif ($class == 'dbexport')
529 {
530 require_once(BASEPATH.'database/DB_export'.EXT);
531 $this->init_class('CI_DB_export', 'dbexport');
532 }
admin6e00bab2006-09-26 08:13:06 +0000533 }
534
535 // --------------------------------------------------------------------
536
537 /**
adminb0dd10f2006-08-25 17:25:49 +0000538 * Returns TRUE if a class is loaded, FALSE if not
539 *
540 * @access public
541 * @param string the class name
542 * @return bool
543 */
544 function _ci_is_loaded($class)
545 {
admine79dc712006-09-26 03:52:45 +0000546 return ( ! isset($this->$class) OR ! is_object($this->$class)) ? FALSE : TRUE;
adminb0dd10f2006-08-25 17:25:49 +0000547 }
admine79dc712006-09-26 03:52:45 +0000548
adminb0dd10f2006-08-25 17:25:49 +0000549 // --------------------------------------------------------------------
550
551 /**
552 * Scaffolding
553 *
554 * Initializes the scaffolding.
555 *
556 * @access private
557 * @return void
558 */
559 function _ci_scaffolding()
560 {
561 if ($this->_ci_scaffolding === FALSE OR $this->_ci_scaff_table === FALSE)
562 {
563 show_404('Scaffolding unavailable');
564 }
565
566 if (class_exists('Scaffolding')) return;
567
adminee54c112006-09-28 17:13:38 +0000568 if ( ! in_array($this->uri->segment(3), array('add', 'insert', 'edit', 'update', 'view', 'delete', 'do_delete'), TRUE))
adminb0dd10f2006-08-25 17:25:49 +0000569 {
570 $method = 'view';
571 }
572 else
573 {
574 $method = $this->uri->segment(3);
575 }
576
577 $this->_ci_init_database("", FALSE, TRUE);
admin33de9a12006-09-28 06:50:16 +0000578 $this->_ci_load_class('pagination');
adminb0dd10f2006-08-25 17:25:49 +0000579 require_once(BASEPATH.'scaffolding/Scaffolding'.EXT);
580 $this->scaff = new Scaffolding($this->_ci_scaff_table);
581 $this->scaff->$method();
582 }
adminb0dd10f2006-08-25 17:25:49 +0000583
584}
585// END _Controller class
586?>