blob: ff914d1311700f5814547734ea6778e334923d91 [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',
194 'Encryption' => 'encrypt',
195 'Unit_test' => 'unit'
196 );
197
198 $varname = ( ! isset($remap[$class])) ? $class : $remap[$class];
199
200 // Instantiate the class
201 if ($config !== NULL)
202 {
203 $this->$varname = new $name($config);
204 }
205 else
206 {
207 $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 {
520 $this->_init_database();
521 }
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);
527 $this->init_class('CI_DB_'.$this->db->dbdriver.'_utility', 'dbutil');
528 }
529 elseif ($class == 'dbexport')
530 {
531 require_once(BASEPATH.'database/DB_export'.EXT);
532 $this->init_class('CI_DB_export', 'dbexport');
533 }
admin6e00bab2006-09-26 08:13:06 +0000534 }
535
536 // --------------------------------------------------------------------
537
538 /**
adminb0dd10f2006-08-25 17:25:49 +0000539 * Returns TRUE if a class is loaded, FALSE if not
540 *
541 * @access public
542 * @param string the class name
543 * @return bool
544 */
545 function _ci_is_loaded($class)
546 {
admine79dc712006-09-26 03:52:45 +0000547 return ( ! isset($this->$class) OR ! is_object($this->$class)) ? FALSE : TRUE;
adminb0dd10f2006-08-25 17:25:49 +0000548 }
admine79dc712006-09-26 03:52:45 +0000549
adminb0dd10f2006-08-25 17:25:49 +0000550 // --------------------------------------------------------------------
551
552 /**
553 * Scaffolding
554 *
555 * Initializes the scaffolding.
556 *
557 * @access private
558 * @return void
559 */
560 function _ci_scaffolding()
561 {
562 if ($this->_ci_scaffolding === FALSE OR $this->_ci_scaff_table === FALSE)
563 {
564 show_404('Scaffolding unavailable');
565 }
566
567 if (class_exists('Scaffolding')) return;
568
adminee54c112006-09-28 17:13:38 +0000569 if ( ! in_array($this->uri->segment(3), array('add', 'insert', 'edit', 'update', 'view', 'delete', 'do_delete'), TRUE))
adminb0dd10f2006-08-25 17:25:49 +0000570 {
571 $method = 'view';
572 }
573 else
574 {
575 $method = $this->uri->segment(3);
576 }
577
578 $this->_ci_init_database("", FALSE, TRUE);
admin33de9a12006-09-28 06:50:16 +0000579 $this->_ci_load_class('pagination');
adminb0dd10f2006-08-25 17:25:49 +0000580 require_once(BASEPATH.'scaffolding/Scaffolding'.EXT);
581 $this->scaff = new Scaffolding($this->_ci_scaff_table);
582 $this->scaff->$method();
583 }
adminb0dd10f2006-08-25 17:25:49 +0000584
585}
586// END _Controller class
587?>