blob: c02074fcad1c4f7155dff6b9a42a260789b37a88 [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));
admin24dd7e72006-10-01 19:02:29 +000083
84 // Bug fix for backward compat.
85 // Kill this at some point in the future
86 if ($class == 'unit_test')
87 {
88 $class = 'unit';
89 }
admin33de9a12006-09-28 06:50:16 +000090
91 // Is this a class extension request?
92 if (substr($class, 0, 3) == 'my_')
93 {
94 $class = preg_replace("/my_(.+)/", "\\1", $class);
95 $extend = TRUE;
96 }
97 else
98 {
99 $extend = FALSE;
100 }
admin7981a9a2006-09-26 07:52:09 +0000101
102 // Does THIS file (Controller.php) contain an initialization
103 // function that maps to the requested class?
104
105 $method = '_ci_init_'.$class;
106
107 if (method_exists($this, $method))
108 {
109 if (is_null($params))
adminb0dd10f2006-08-25 17:25:49 +0000110 {
111 $this->$method();
112 }
113 else
114 {
115 $this->$method($params);
admin7981a9a2006-09-26 07:52:09 +0000116 }
117
118 // We're done...
119 return TRUE;
adminb0dd10f2006-08-25 17:25:49 +0000120 }
admin7981a9a2006-09-26 07:52:09 +0000121
admin33de9a12006-09-28 06:50:16 +0000122 // Are we extending one of the base classes?
123 if ($extend == TRUE)
admin7981a9a2006-09-26 07:52:09 +0000124 {
admin33de9a12006-09-28 06:50:16 +0000125 // Load the requested library from the main system/libraries folder
126 if (file_exists(BASEPATH.'libraries/'.ucfirst($class).EXT))
admin7981a9a2006-09-26 07:52:09 +0000127 {
admin33de9a12006-09-28 06:50:16 +0000128 include_once(BASEPATH.'libraries/'.ucfirst($class).EXT);
129 }
admin7981a9a2006-09-26 07:52:09 +0000130
admin33de9a12006-09-28 06:50:16 +0000131 // Now look for a matching library
132 foreach (array(ucfirst($class), $class) as $filename)
133 {
134 if (file_exists(APPPATH.'libraries/'.$filename.EXT))
admin7981a9a2006-09-26 07:52:09 +0000135 {
admin33de9a12006-09-28 06:50:16 +0000136 include_once(APPPATH.'libraries/'.$filename.EXT);
admin7981a9a2006-09-26 07:52:09 +0000137 }
138 }
admin33de9a12006-09-28 06:50:16 +0000139
140 return $this->_ci_init_class($filename, 'MY_', $params);
141 }
142 else
143 {
144 // Lets search for the requested library file and load it.
145 // For backward compatibility we'll test for filenames that are
146 // both uppercase and lower.
147 foreach (array(ucfirst($class), $class) as $filename)
148 {
149 for ($i = 1; $i < 3; $i++)
150 {
151 $path = ($i % 2) ? APPPATH : BASEPATH;
152
153 if (file_exists($path.'libraries/'.$filename.EXT))
154 {
155 include_once($path.'libraries/'.$filename.EXT);
156 return $this->_ci_init_class($filename, '', $params);
157 }
158 }
159 }
admin7981a9a2006-09-26 07:52:09 +0000160 }
161
162 // If we got this far we were unable to find the requested class
163 log_message('error', "Unable to load the requested class: ".$class);
164 show_error("Unable to load the class: ".$class);
adminb0dd10f2006-08-25 17:25:49 +0000165 }
admin33de9a12006-09-28 06:50:16 +0000166
167 // --------------------------------------------------------------------
168
169 /**
170 * Instantiates a class
171 *
172 * @access private
173 * @param string
174 * @param string
175 * @return null
176 */
177 function _ci_init_class($class, $prefix = '', $config = NULL)
admin24dd7e72006-10-01 19:02:29 +0000178 {
admin33de9a12006-09-28 06:50:16 +0000179 // Is there an associated config file for this class?
admin33de9a12006-09-28 06:50:16 +0000180 if ($config == NULL)
181 {
182 if (file_exists(APPPATH.'config/'.$class.EXT))
183 {
184 include_once(APPPATH.'config/'.$class.EXT);
185 }
186 }
187
188 if ($prefix == '')
189 {
190 $name = ( ! class_exists($class)) ? 'CI_'.$class : $class;
191 }
192 else
193 {
admin24dd7e72006-10-01 19:02:29 +0000194 $name = $prefix.$class;
admin33de9a12006-09-28 06:50:16 +0000195 }
admin33de9a12006-09-28 06:50:16 +0000196
197 $varname = ( ! isset($remap[$class])) ? $class : $remap[$class];
admin24dd7e72006-10-01 19:02:29 +0000198 $varname = strtolower($varname);
199
admin33de9a12006-09-28 06:50:16 +0000200 // Instantiate the class
201 if ($config !== NULL)
202 {
203 $this->$varname = new $name($config);
204 }
205 else
admin24dd7e72006-10-01 19:02:29 +0000206 {
admin33de9a12006-09-28 06:50:16 +0000207 $this->$varname = new $name;
208 }
209 }
adminb0dd10f2006-08-25 17:25:49 +0000210
211 // --------------------------------------------------------------------
212
213 /**
214 * Loads and instantiates the requested model class
215 *
216 * @access private
217 * @param string
218 * @return array
219 */
admin7981a9a2006-09-26 07:52:09 +0000220 function _ci_init_model($model, $name = '', $db_conn = FALSE)
adminb0dd10f2006-08-25 17:25:49 +0000221 {
admin4ce59da2006-09-28 07:45:59 +0000222 // Is the model in a sub-folder?
223 // If so, parse out the filename and path.
224 if (strpos($model, '/') === FALSE)
225 {
226 $path = '';
227 }
228 else
229 {
230 $x = explode('/', $model);
231 $model = end($x);
232 unset($x[count($x)-1]);
233 $path = implode('/', $x).'/';
234 }
235
adminb0dd10f2006-08-25 17:25:49 +0000236 if ($name == '')
237 {
238 $name = $model;
239 }
adminb4473d42006-08-27 15:46:31 +0000240
admin0d296052006-08-27 15:48:38 +0000241 $obj =& get_instance();
adminee54c112006-09-28 17:13:38 +0000242 if (in_array($name, $obj->_ci_models, TRUE))
adminb4473d42006-08-27 15:46:31 +0000243 {
244 return;
245 }
246
adminb0dd10f2006-08-25 17:25:49 +0000247 if (isset($this->$name))
248 {
249 show_error('The model name you are loading is the name of a resource that is already being used: '.$name);
250 }
251
252 $model = strtolower($model);
253
admin4ce59da2006-09-28 07:45:59 +0000254 if ( ! file_exists(APPPATH.'models/'.$path.$model.EXT))
adminb0dd10f2006-08-25 17:25:49 +0000255 {
256 show_error('Unable to locate the model you have specified: '.$model);
257 }
admin4ce59da2006-09-28 07:45:59 +0000258
adminb0dd10f2006-08-25 17:25:49 +0000259 if ($db_conn !== FALSE)
260 {
261 if ($db_conn === TRUE)
262 $db_conn = '';
263
264 $this->_ci_init_database($db_conn, FALSE, TRUE);
265 }
266
267 if ( ! class_exists('Model'))
268 {
269 require_once(BASEPATH.'libraries/Model'.EXT);
270 }
271
admin4ce59da2006-09-28 07:45:59 +0000272 require_once(APPPATH.'models/'.$path.$model.EXT);
adminb0dd10f2006-08-25 17:25:49 +0000273
274 $model = ucfirst($model);
275 $this->$name = new $model();
276 $this->_ci_models[] = $name;
277 $this->_ci_assign_to_models();
admin7981a9a2006-09-26 07:52:09 +0000278 }
adminb0dd10f2006-08-25 17:25:49 +0000279
280 // --------------------------------------------------------------------
281
282 /**
283 * Assign to Models
284 *
285 * Makes sure that anything loaded by the loader class (libraries, plugins, etc.)
286 * will be available to modles, if any exist.
287 *
288 * @access public
289 * @param object
290 * @return array
291 */
292 function _ci_assign_to_models()
293 {
294 $obj =& get_instance();
295 if (count($obj->_ci_models) == 0)
296 {
297 return;
298 }
299 foreach ($obj->_ci_models as $model)
300 {
301 $obj->$model->_assign_libraries();
302 }
admin7981a9a2006-09-26 07:52:09 +0000303 }
adminb0dd10f2006-08-25 17:25:49 +0000304
305 // --------------------------------------------------------------------
306
307 /**
308 * Auto-initialize Core Classes
309 *
310 * This initializes the core systems that are specified in the
311 * libraries/autoload.php file, as well as the systems specified in
312 * the $autoload class array above.
313 *
314 * It returns the "autoload" array so we can pass it to the Loader
315 * class since it needs to autoload plugins and helper files
316 *
317 * The config/autoload.php file contains an array that permits
318 * sub-systems to be loaded automatically.
319 *
320 * @access private
321 * @return array
322 */
323 function _ci_autoload()
324 {
325 include_once(APPPATH.'config/autoload'.EXT);
326
327 if ( ! isset($autoload))
328 {
329 return FALSE;
330 }
331
332 if (count($autoload['config']) > 0)
333 {
334 foreach ($autoload['config'] as $key => $val)
335 {
336 $this->config->load($val);
337 }
338 }
339 unset($autoload['config']);
340
admind48ef1c2006-09-21 06:22:05 +0000341 // A little tweak to remain backward compatible
342 // The $autoload['core'] item was deprecated
343 if ( ! isset($autoload['libraries']))
adminb0dd10f2006-08-25 17:25:49 +0000344 {
admind48ef1c2006-09-21 06:22:05 +0000345 $autoload['libraries'] = $autoload['core'];
346
adminb0dd10f2006-08-25 17:25:49 +0000347 }
348
admin6e00bab2006-09-26 08:13:06 +0000349 $exceptions = array('dbutil', 'dbexport');
350
admind48ef1c2006-09-21 06:22:05 +0000351 foreach ($autoload['libraries'] as $item)
adminb0dd10f2006-08-25 17:25:49 +0000352 {
adminee54c112006-09-28 17:13:38 +0000353 if ( ! in_array($item, $exceptions, TRUE))
admin6e00bab2006-09-26 08:13:06 +0000354 {
admin33de9a12006-09-28 06:50:16 +0000355 $this->_ci_load_class($item);
admin6e00bab2006-09-26 08:13:06 +0000356 }
357 else
358 {
359 $this->_ci_init_dbextra($item);
360 }
adminb0dd10f2006-08-25 17:25:49 +0000361 }
admind48ef1c2006-09-21 06:22:05 +0000362 unset($autoload['libraries']);
363
adminb0dd10f2006-08-25 17:25:49 +0000364 return $autoload;
365 }
adminb0dd10f2006-08-25 17:25:49 +0000366
367 // --------------------------------------------------------------------
368
369 /**
370 * Assign the core classes to the global $CI object
371 *
372 * By assigning all the classes instantiated by the front controller
373 * local class variables we enable everything to be accessible using
374 * $this->class->function()
375 *
376 * @access private
377 * @return void
378 */
379 function _ci_assign_core()
380 {
381 foreach (array('Config', 'Input', 'Benchmark', 'URI', 'Output') as $val)
382 {
383 $class = strtolower($val);
admin33de9a12006-09-28 06:50:16 +0000384 $this->$class =& _load_class($val);
adminb0dd10f2006-08-25 17:25:49 +0000385 }
386
admin33de9a12006-09-28 06:50:16 +0000387 $this->lang =& _load_class('Language');
adminb0dd10f2006-08-25 17:25:49 +0000388
389 // In PHP 4 the Controller class is a child of CI_Loader.
390 // In PHP 5 we run it as its own class.
391 if (floor(phpversion()) >= 5)
392 {
393 $this->load = new CI_Loader();
394 }
adminb0dd10f2006-08-25 17:25:49 +0000395 }
adminb0dd10f2006-08-25 17:25:49 +0000396
397 // --------------------------------------------------------------------
398
399 /**
400 * Initialize Scaffolding
401 *
402 * This initializing function works a bit different than the
403 * others. It doesn't load the class. Instead, it simply
404 * sets a flag indicating that scaffolding is allowed to be
405 * used. The actual scaffolding function below is
406 * called by the front controller based on whether the
407 * second segment of the URL matches the "secret" scaffolding
408 * word stored in the application/config/routes.php
409 *
410 * @access private
411 * @param string the table to scaffold
412 * @return void
413 */
414 function _ci_init_scaffolding($table = FALSE)
415 {
416 if ($table === FALSE)
417 {
418 show_error('You must include the name of the table you would like access when you initialize scaffolding');
419 }
420
421 $this->_ci_scaffolding = TRUE;
422 $this->_ci_scaff_table = $table;
423 }
adminb0dd10f2006-08-25 17:25:49 +0000424
425 // --------------------------------------------------------------------
426
427 /**
428 * Initialize Database
429 *
430 * @access private
431 * @param mixed database connection values
432 * @param bool whether to return the object for multiple connections
433 * @return void
434 */
435 function _ci_init_database($params = '', $return = FALSE, $active_record = FALSE)
admin7981a9a2006-09-26 07:52:09 +0000436 {
adminb0dd10f2006-08-25 17:25:49 +0000437 if ($this->_ci_is_loaded('db') == TRUE AND $return == FALSE AND $active_record == FALSE)
438 {
439 return;
440 }
441
442 // Load the DB config file if needed
443 if (is_string($params) AND strpos($params, '://') === FALSE)
444 {
445 include(APPPATH.'config/database'.EXT);
446
447 $group = ($params == '') ? $active_group : $params;
448
449 if ( ! isset($db[$group]))
450 {
451 show_error('You have specified an invalid database connection group: '.$group);
452 }
453
454 $params = $db[$group];
455 }
456
457 // No DB specified yet? Beat them senseless...
458 if ( ! isset($params['dbdriver']) OR $params['dbdriver'] == '')
459 {
460 show_error('You have not selected a database type to connect to.');
461 }
462
463 // Load the DB classes. Note: Since the active record class is optional
464 // we need to dynamically create a class that extends proper parent class
465 // based on whether we're using the active record class or not.
466 // Kudos to Paul for discovering this clever use of eval()
467
468 if ($active_record == TRUE)
469 {
470 $params['active_r'] = TRUE;
471 }
472
admin58083462006-09-24 17:58:27 +0000473 require_once(BASEPATH.'database/DB_driver'.EXT);
adminb0dd10f2006-08-25 17:25:49 +0000474
475 if ( ! isset($params['active_r']) OR $params['active_r'] == TRUE)
476 {
adminc9a8bab2006-09-24 20:28:33 +0000477 require_once(BASEPATH.'database/DB_active_rec'.EXT);
adminb0dd10f2006-08-25 17:25:49 +0000478
479 if ( ! class_exists('CI_DB'))
480 {
481 eval('class CI_DB extends CI_DB_active_record { }');
482 }
483 }
484 else
485 {
486 if ( ! class_exists('CI_DB'))
487 {
488 eval('class CI_DB extends CI_DB_driver { }');
489 }
490 }
adminc1fa0742006-09-21 23:50:23 +0000491
admin46563d52006-09-24 18:14:22 +0000492 require_once(BASEPATH.'database/drivers/'.$params['dbdriver'].'/'.$params['dbdriver'].'_driver'.EXT);
adminb0dd10f2006-08-25 17:25:49 +0000493
494 // Instantiate the DB adapter
admina5e812c2006-09-25 02:17:30 +0000495 $driver = 'CI_DB_'.$params['dbdriver'].'_driver';
adminb0dd10f2006-08-25 17:25:49 +0000496 $DB = new $driver($params);
497
498 if ($return === TRUE)
499 {
500 return $DB;
501 }
502
503 $obj =& get_instance();
adminb0dd10f2006-08-25 17:25:49 +0000504 $obj->db =& $DB;
505 }
admina5e812c2006-09-25 02:17:30 +0000506
adminb0dd10f2006-08-25 17:25:49 +0000507 // --------------------------------------------------------------------
508
509 /**
admin6e00bab2006-09-26 08:13:06 +0000510 * Initialize Database Ancillary Classes
511 *
512 * @access private
513 * @param str class name
514 * @return void
515 */
516 function _ci_init_dbextra($class)
517 {
admine5bb9362006-09-27 00:31:22 +0000518 if ( ! $this->_ci_is_loaded('db'))
519 {
admin3ed8c512006-09-29 23:26:28 +0000520 $this->_ci_init_database();
admine5bb9362006-09-27 00:31:22 +0000521 }
522
523 if ($class == 'dbutil')
524 {
525 require_once(BASEPATH.'database/DB_utility'.EXT);
526 require_once(BASEPATH.'database/drivers/'.$this->db->dbdriver.'/'.$this->db->dbdriver.'_utility'.EXT);
admin3ed8c512006-09-29 23:26:28 +0000527 $class = 'CI_DB_'.$this->db->dbdriver.'_utility';
528 $this->dbutil = new $class();
admine5bb9362006-09-27 00:31:22 +0000529 }
admin6e00bab2006-09-26 08:13:06 +0000530 }
531
532 // --------------------------------------------------------------------
533
534 /**
adminb0dd10f2006-08-25 17:25:49 +0000535 * Returns TRUE if a class is loaded, FALSE if not
536 *
537 * @access public
538 * @param string the class name
539 * @return bool
540 */
541 function _ci_is_loaded($class)
542 {
admine79dc712006-09-26 03:52:45 +0000543 return ( ! isset($this->$class) OR ! is_object($this->$class)) ? FALSE : TRUE;
adminb0dd10f2006-08-25 17:25:49 +0000544 }
admine79dc712006-09-26 03:52:45 +0000545
adminb0dd10f2006-08-25 17:25:49 +0000546 // --------------------------------------------------------------------
547
548 /**
549 * Scaffolding
550 *
551 * Initializes the scaffolding.
552 *
553 * @access private
554 * @return void
555 */
556 function _ci_scaffolding()
557 {
558 if ($this->_ci_scaffolding === FALSE OR $this->_ci_scaff_table === FALSE)
559 {
560 show_404('Scaffolding unavailable');
561 }
562
563 if (class_exists('Scaffolding')) return;
564
adminee54c112006-09-28 17:13:38 +0000565 if ( ! in_array($this->uri->segment(3), array('add', 'insert', 'edit', 'update', 'view', 'delete', 'do_delete'), TRUE))
adminb0dd10f2006-08-25 17:25:49 +0000566 {
567 $method = 'view';
568 }
569 else
570 {
571 $method = $this->uri->segment(3);
572 }
573
574 $this->_ci_init_database("", FALSE, TRUE);
admin33de9a12006-09-28 06:50:16 +0000575 $this->_ci_load_class('pagination');
adminb0dd10f2006-08-25 17:25:49 +0000576 require_once(BASEPATH.'scaffolding/Scaffolding'.EXT);
577 $this->scaff = new Scaffolding($this->_ci_scaff_table);
578 $this->scaff->$method();
579 }
adminb0dd10f2006-08-25 17:25:49 +0000580
581}
582// END _Controller class
583?>