blob: aa7b87b00b59f04de388eb63970c905ffe3dc1b1 [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 {
222 if ($name == '')
223 {
224 $name = $model;
225 }
adminb4473d42006-08-27 15:46:31 +0000226
admin0d296052006-08-27 15:48:38 +0000227 $obj =& get_instance();
228 if (in_array($name, $obj->_ci_models))
adminb4473d42006-08-27 15:46:31 +0000229 {
230 return;
231 }
232
adminb0dd10f2006-08-25 17:25:49 +0000233 if (isset($this->$name))
234 {
235 show_error('The model name you are loading is the name of a resource that is already being used: '.$name);
236 }
237
238 $model = strtolower($model);
239
240 if ( ! file_exists(APPPATH.'models/'.$model.EXT))
241 {
242 show_error('Unable to locate the model you have specified: '.$model);
243 }
244
245 if ($db_conn !== FALSE)
246 {
247 if ($db_conn === TRUE)
248 $db_conn = '';
249
250 $this->_ci_init_database($db_conn, FALSE, TRUE);
251 }
252
253 if ( ! class_exists('Model'))
254 {
255 require_once(BASEPATH.'libraries/Model'.EXT);
256 }
257
258 require_once(APPPATH.'models/'.$model.EXT);
259
260 $model = ucfirst($model);
261 $this->$name = new $model();
262 $this->_ci_models[] = $name;
263 $this->_ci_assign_to_models();
admin7981a9a2006-09-26 07:52:09 +0000264 }
adminb0dd10f2006-08-25 17:25:49 +0000265
266 // --------------------------------------------------------------------
267
268 /**
269 * Assign to Models
270 *
271 * Makes sure that anything loaded by the loader class (libraries, plugins, etc.)
272 * will be available to modles, if any exist.
273 *
274 * @access public
275 * @param object
276 * @return array
277 */
278 function _ci_assign_to_models()
279 {
280 $obj =& get_instance();
281 if (count($obj->_ci_models) == 0)
282 {
283 return;
284 }
285 foreach ($obj->_ci_models as $model)
286 {
287 $obj->$model->_assign_libraries();
288 }
admin7981a9a2006-09-26 07:52:09 +0000289 }
adminb0dd10f2006-08-25 17:25:49 +0000290
291 // --------------------------------------------------------------------
292
293 /**
294 * Auto-initialize Core Classes
295 *
296 * This initializes the core systems that are specified in the
297 * libraries/autoload.php file, as well as the systems specified in
298 * the $autoload class array above.
299 *
300 * It returns the "autoload" array so we can pass it to the Loader
301 * class since it needs to autoload plugins and helper files
302 *
303 * The config/autoload.php file contains an array that permits
304 * sub-systems to be loaded automatically.
305 *
306 * @access private
307 * @return array
308 */
309 function _ci_autoload()
310 {
311 include_once(APPPATH.'config/autoload'.EXT);
312
313 if ( ! isset($autoload))
314 {
315 return FALSE;
316 }
317
318 if (count($autoload['config']) > 0)
319 {
320 foreach ($autoload['config'] as $key => $val)
321 {
322 $this->config->load($val);
323 }
324 }
325 unset($autoload['config']);
326
admind48ef1c2006-09-21 06:22:05 +0000327 // A little tweak to remain backward compatible
328 // The $autoload['core'] item was deprecated
329 if ( ! isset($autoload['libraries']))
adminb0dd10f2006-08-25 17:25:49 +0000330 {
admind48ef1c2006-09-21 06:22:05 +0000331 $autoload['libraries'] = $autoload['core'];
332
adminb0dd10f2006-08-25 17:25:49 +0000333 }
334
admin6e00bab2006-09-26 08:13:06 +0000335 $exceptions = array('dbutil', 'dbexport');
336
admind48ef1c2006-09-21 06:22:05 +0000337 foreach ($autoload['libraries'] as $item)
adminb0dd10f2006-08-25 17:25:49 +0000338 {
admin6e00bab2006-09-26 08:13:06 +0000339 if ( ! in_array($item, $exceptions))
340 {
admin33de9a12006-09-28 06:50:16 +0000341 $this->_ci_load_class($item);
admin6e00bab2006-09-26 08:13:06 +0000342 }
343 else
344 {
345 $this->_ci_init_dbextra($item);
346 }
adminb0dd10f2006-08-25 17:25:49 +0000347 }
admind48ef1c2006-09-21 06:22:05 +0000348 unset($autoload['libraries']);
349
adminb0dd10f2006-08-25 17:25:49 +0000350 return $autoload;
351 }
adminb0dd10f2006-08-25 17:25:49 +0000352
353 // --------------------------------------------------------------------
354
355 /**
356 * Assign the core classes to the global $CI object
357 *
358 * By assigning all the classes instantiated by the front controller
359 * local class variables we enable everything to be accessible using
360 * $this->class->function()
361 *
362 * @access private
363 * @return void
364 */
365 function _ci_assign_core()
366 {
367 foreach (array('Config', 'Input', 'Benchmark', 'URI', 'Output') as $val)
368 {
369 $class = strtolower($val);
admin33de9a12006-09-28 06:50:16 +0000370 $this->$class =& _load_class($val);
adminb0dd10f2006-08-25 17:25:49 +0000371 }
372
admin33de9a12006-09-28 06:50:16 +0000373 $this->lang =& _load_class('Language');
adminb0dd10f2006-08-25 17:25:49 +0000374
375 // In PHP 4 the Controller class is a child of CI_Loader.
376 // In PHP 5 we run it as its own class.
377 if (floor(phpversion()) >= 5)
378 {
379 $this->load = new CI_Loader();
380 }
adminb0dd10f2006-08-25 17:25:49 +0000381 }
adminb0dd10f2006-08-25 17:25:49 +0000382
383 // --------------------------------------------------------------------
384
385 /**
386 * Initialize Scaffolding
387 *
388 * This initializing function works a bit different than the
389 * others. It doesn't load the class. Instead, it simply
390 * sets a flag indicating that scaffolding is allowed to be
391 * used. The actual scaffolding function below is
392 * called by the front controller based on whether the
393 * second segment of the URL matches the "secret" scaffolding
394 * word stored in the application/config/routes.php
395 *
396 * @access private
397 * @param string the table to scaffold
398 * @return void
399 */
400 function _ci_init_scaffolding($table = FALSE)
401 {
402 if ($table === FALSE)
403 {
404 show_error('You must include the name of the table you would like access when you initialize scaffolding');
405 }
406
407 $this->_ci_scaffolding = TRUE;
408 $this->_ci_scaff_table = $table;
409 }
adminb0dd10f2006-08-25 17:25:49 +0000410
411 // --------------------------------------------------------------------
412
413 /**
414 * Initialize Database
415 *
416 * @access private
417 * @param mixed database connection values
418 * @param bool whether to return the object for multiple connections
419 * @return void
420 */
421 function _ci_init_database($params = '', $return = FALSE, $active_record = FALSE)
admin7981a9a2006-09-26 07:52:09 +0000422 {
adminb0dd10f2006-08-25 17:25:49 +0000423 if ($this->_ci_is_loaded('db') == TRUE AND $return == FALSE AND $active_record == FALSE)
424 {
425 return;
426 }
427
428 // Load the DB config file if needed
429 if (is_string($params) AND strpos($params, '://') === FALSE)
430 {
431 include(APPPATH.'config/database'.EXT);
432
433 $group = ($params == '') ? $active_group : $params;
434
435 if ( ! isset($db[$group]))
436 {
437 show_error('You have specified an invalid database connection group: '.$group);
438 }
439
440 $params = $db[$group];
441 }
442
443 // No DB specified yet? Beat them senseless...
444 if ( ! isset($params['dbdriver']) OR $params['dbdriver'] == '')
445 {
446 show_error('You have not selected a database type to connect to.');
447 }
448
449 // Load the DB classes. Note: Since the active record class is optional
450 // we need to dynamically create a class that extends proper parent class
451 // based on whether we're using the active record class or not.
452 // Kudos to Paul for discovering this clever use of eval()
453
454 if ($active_record == TRUE)
455 {
456 $params['active_r'] = TRUE;
457 }
458
admin58083462006-09-24 17:58:27 +0000459 require_once(BASEPATH.'database/DB_driver'.EXT);
adminb0dd10f2006-08-25 17:25:49 +0000460
461 if ( ! isset($params['active_r']) OR $params['active_r'] == TRUE)
462 {
adminc9a8bab2006-09-24 20:28:33 +0000463 require_once(BASEPATH.'database/DB_active_rec'.EXT);
adminb0dd10f2006-08-25 17:25:49 +0000464
465 if ( ! class_exists('CI_DB'))
466 {
467 eval('class CI_DB extends CI_DB_active_record { }');
468 }
469 }
470 else
471 {
472 if ( ! class_exists('CI_DB'))
473 {
474 eval('class CI_DB extends CI_DB_driver { }');
475 }
476 }
adminc1fa0742006-09-21 23:50:23 +0000477
admin46563d52006-09-24 18:14:22 +0000478 require_once(BASEPATH.'database/drivers/'.$params['dbdriver'].'/'.$params['dbdriver'].'_driver'.EXT);
adminb0dd10f2006-08-25 17:25:49 +0000479
480 // Instantiate the DB adapter
admina5e812c2006-09-25 02:17:30 +0000481 $driver = 'CI_DB_'.$params['dbdriver'].'_driver';
adminb0dd10f2006-08-25 17:25:49 +0000482 $DB = new $driver($params);
483
484 if ($return === TRUE)
485 {
486 return $DB;
487 }
488
489 $obj =& get_instance();
adminb0dd10f2006-08-25 17:25:49 +0000490 $obj->db =& $DB;
491 }
admina5e812c2006-09-25 02:17:30 +0000492
adminb0dd10f2006-08-25 17:25:49 +0000493 // --------------------------------------------------------------------
494
495 /**
admin6e00bab2006-09-26 08:13:06 +0000496 * Initialize Database Ancillary Classes
497 *
498 * @access private
499 * @param str class name
500 * @return void
501 */
502 function _ci_init_dbextra($class)
503 {
admine5bb9362006-09-27 00:31:22 +0000504 if ( ! $this->_ci_is_loaded('db'))
505 {
506 $this->_init_database();
507 }
508
509 if ($class == 'dbutil')
510 {
511 require_once(BASEPATH.'database/DB_utility'.EXT);
512 require_once(BASEPATH.'database/drivers/'.$this->db->dbdriver.'/'.$this->db->dbdriver.'_utility'.EXT);
513 $this->init_class('CI_DB_'.$this->db->dbdriver.'_utility', 'dbutil');
514 }
515 elseif ($class == 'dbexport')
516 {
517 require_once(BASEPATH.'database/DB_export'.EXT);
518 $this->init_class('CI_DB_export', 'dbexport');
519 }
admin6e00bab2006-09-26 08:13:06 +0000520 }
521
522 // --------------------------------------------------------------------
523
524 /**
adminb0dd10f2006-08-25 17:25:49 +0000525 * Returns TRUE if a class is loaded, FALSE if not
526 *
527 * @access public
528 * @param string the class name
529 * @return bool
530 */
531 function _ci_is_loaded($class)
532 {
admine79dc712006-09-26 03:52:45 +0000533 return ( ! isset($this->$class) OR ! is_object($this->$class)) ? FALSE : TRUE;
adminb0dd10f2006-08-25 17:25:49 +0000534 }
admine79dc712006-09-26 03:52:45 +0000535
adminb0dd10f2006-08-25 17:25:49 +0000536 // --------------------------------------------------------------------
537
538 /**
539 * Scaffolding
540 *
541 * Initializes the scaffolding.
542 *
543 * @access private
544 * @return void
545 */
546 function _ci_scaffolding()
547 {
548 if ($this->_ci_scaffolding === FALSE OR $this->_ci_scaff_table === FALSE)
549 {
550 show_404('Scaffolding unavailable');
551 }
552
553 if (class_exists('Scaffolding')) return;
554
555 if ( ! in_array($this->uri->segment(3), array('add', 'insert', 'edit', 'update', 'view', 'delete', 'do_delete')))
556 {
557 $method = 'view';
558 }
559 else
560 {
561 $method = $this->uri->segment(3);
562 }
563
564 $this->_ci_init_database("", FALSE, TRUE);
admin33de9a12006-09-28 06:50:16 +0000565 $this->_ci_load_class('pagination');
adminb0dd10f2006-08-25 17:25:49 +0000566 require_once(BASEPATH.'scaffolding/Scaffolding'.EXT);
567 $this->scaff = new Scaffolding($this->_ci_scaff_table);
568 $this->scaff->$method();
569 }
adminb0dd10f2006-08-25 17:25:49 +0000570
571}
572// END _Controller class
573?>