blob: 1d88841ddd284b5c6f042a1b682de85259340bea [file] [log] [blame]
Derek Jones0b59f272008-05-13 04:22:33 +00001<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
Derek Allard02658572007-12-20 14:00:50 +00002/**
3 * CodeIgniter
4 *
5 * An open source application development framework for PHP 4.3.2 or newer
6 *
7 * @package CodeIgniter
Derek Allard3d879d52008-01-18 19:41:32 +00008 * @author ExpressionEngine Dev Team
Derek Allard02658572007-12-20 14:00:50 +00009 * @copyright Copyright (c) 2006, EllisLab, Inc.
Derek Jones7a9193a2008-01-21 18:39:20 +000010 * @license http://codeigniter.com/user_guide/license.html
11 * @link http://codeigniter.com
Derek Allard02658572007-12-20 14:00:50 +000012 * @since Version 1.0
13 * @filesource
14 */
15
16// ------------------------------------------------------------------------
17
18/**
19 * Loader Class
20 *
21 * Loads views and files
22 *
23 * @package CodeIgniter
24 * @subpackage Libraries
Derek Allard3d879d52008-01-18 19:41:32 +000025 * @author ExpressionEngine Dev Team
Derek Allard02658572007-12-20 14:00:50 +000026 * @category Loader
Derek Jones7a9193a2008-01-21 18:39:20 +000027 * @link http://codeigniter.com/user_guide/libraries/loader.html
Derek Allard02658572007-12-20 14:00:50 +000028 */
29class CI_Loader {
30
31 // All these are set automatically. Don't mess with them.
32 var $_ci_ob_level;
33 var $_ci_view_path = '';
34 var $_ci_is_php5 = FALSE;
35 var $_ci_is_instance = FALSE; // Whether we should use $this or $CI =& get_instance()
36 var $_ci_cached_vars = array();
37 var $_ci_classes = array();
38 var $_ci_models = array();
39 var $_ci_helpers = array();
40 var $_ci_plugins = array();
41 var $_ci_scripts = array();
42 var $_ci_varmap = array('unit_test' => 'unit', 'user_agent' => 'agent');
43
44
45 /**
46 * Constructor
47 *
48 * Sets the path to the view files and gets the initial output buffering level
49 *
50 * @access public
51 */
52 function CI_Loader()
53 {
54 $this->_ci_is_php5 = (floor(phpversion()) >= 5) ? TRUE : FALSE;
55 $this->_ci_view_path = APPPATH.'views/';
56 $this->_ci_ob_level = ob_get_level();
57
58 log_message('debug', "Loader Class Initialized");
59 }
60
61 // --------------------------------------------------------------------
62
63 /**
64 * Class Loader
65 *
66 * This function lets users load and instantiate classes.
67 * It is designed to be called from a user's app controllers.
68 *
69 * @access public
70 * @param string the name of the class
71 * @param mixed the optional parameters
Rick Ellis6ad53292008-08-21 18:31:28 +000072 * @param string an optional object name
Derek Allard02658572007-12-20 14:00:50 +000073 * @return void
74 */
Rick Ellis6ad53292008-08-21 18:31:28 +000075 function library($library = '', $params = NULL, $object_name = NULL)
Derek Allard02658572007-12-20 14:00:50 +000076 {
77 if ($library == '')
78 {
79 return FALSE;
80 }
81
Rick Ellis65f46062008-08-21 18:55:09 +000082 if ( ! is_null($params) AND ! is_array($params))
83 {
84 $params = NULL;
85 }
86
Derek Allard02658572007-12-20 14:00:50 +000087 if (is_array($library))
88 {
89 foreach ($library as $class)
90 {
91 $this->_ci_load_class($class, $params);
92 }
93 }
94 else
95 {
Rick Ellis6ad53292008-08-21 18:31:28 +000096 $this->_ci_load_class($library, $params, $object_name);
Derek Allard02658572007-12-20 14:00:50 +000097 }
98
99 $this->_ci_assign_to_models();
100 }
101
102 // --------------------------------------------------------------------
103
104 /**
105 * Model Loader
106 *
107 * This function lets users load and instantiate models.
108 *
Derek Allard02658572007-12-20 14:00:50 +0000109 * @param string the name of the class
Derek Allard9736d3f2008-06-16 21:36:01 +0000110 * @param string name for the model
111 * @param bool database connection
Derek Allard02658572007-12-20 14:00:50 +0000112 * @return void
113 */
114 function model($model, $name = '', $db_conn = FALSE)
115 {
116 if (is_array($model))
117 {
118 foreach($model as $babe)
119 {
120 $this->model($babe);
121 }
122 return;
123 }
124
125 if ($model == '')
126 {
127 return;
128 }
129
130 // Is the model in a sub-folder? If so, parse out the filename and path.
131 if (strpos($model, '/') === FALSE)
132 {
133 $path = '';
134 }
135 else
136 {
137 $x = explode('/', $model);
138 $model = end($x);
139 unset($x[count($x)-1]);
140 $path = implode('/', $x).'/';
141 }
142
143 if ($name == '')
144 {
145 $name = $model;
146 }
147
148 if (in_array($name, $this->_ci_models, TRUE))
149 {
150 return;
151 }
152
153 $CI =& get_instance();
154 if (isset($CI->$name))
155 {
156 show_error('The model name you are loading is the name of a resource that is already being used: '.$name);
157 }
158
159 $model = strtolower($model);
160
Derek Jones0b59f272008-05-13 04:22:33 +0000161 if ( ! file_exists(APPPATH.'models/'.$path.$model.EXT))
Derek Allard02658572007-12-20 14:00:50 +0000162 {
163 show_error('Unable to locate the model you have specified: '.$model);
164 }
165
166 if ($db_conn !== FALSE AND ! class_exists('CI_DB'))
167 {
168 if ($db_conn === TRUE)
169 $db_conn = '';
170
171 $CI->load->database($db_conn, FALSE, TRUE);
172 }
173
Derek Jones0b59f272008-05-13 04:22:33 +0000174 if ( ! class_exists('Model'))
Derek Allard02658572007-12-20 14:00:50 +0000175 {
Derek Allardff943eb2008-01-22 18:08:10 +0000176 load_class('Model', FALSE);
Derek Allard02658572007-12-20 14:00:50 +0000177 }
178
179 require_once(APPPATH.'models/'.$path.$model.EXT);
180
181 $model = ucfirst($model);
182
183 $CI->$name = new $model();
184 $CI->$name->_assign_libraries();
185
186 $this->_ci_models[] = $name;
187 }
188
189 // --------------------------------------------------------------------
190
191 /**
192 * Database Loader
193 *
194 * @access public
195 * @param string the DB credentials
196 * @param bool whether to return the DB object
197 * @param bool whether to enable active record (this allows us to override the config setting)
198 * @return object
199 */
200 function database($params = '', $return = FALSE, $active_record = FALSE)
201 {
Derek Jones72d61332008-01-30 20:52:22 +0000202 // Grab the super object
203 $CI =& get_instance();
204
Derek Allard02658572007-12-20 14:00:50 +0000205 // Do we even need to load the database class?
Derek Jones72d61332008-01-30 20:52:22 +0000206 if (class_exists('CI_DB') AND $return == FALSE AND $active_record == FALSE AND isset($CI->db) AND is_object($CI->db))
Derek Allard02658572007-12-20 14:00:50 +0000207 {
208 return FALSE;
209 }
210
211 require_once(BASEPATH.'database/DB'.EXT);
212
213 if ($return === TRUE)
214 {
215 return DB($params, $active_record);
216 }
Derek Allard02658572007-12-20 14:00:50 +0000217
218 // Initialize the db variable. Needed to prevent
219 // reference errors with some configurations
220 $CI->db = '';
221
222 // Load the DB class
223 $CI->db =& DB($params, $active_record);
224
225 // Assign the DB object to any existing models
226 $this->_ci_assign_to_models();
227 }
228
229 // --------------------------------------------------------------------
230
231 /**
232 * Load the Utilities Class
233 *
234 * @access public
235 * @return string
236 */
237 function dbutil()
238 {
Derek Jones0b59f272008-05-13 04:22:33 +0000239 if ( ! class_exists('CI_DB'))
Derek Allard02658572007-12-20 14:00:50 +0000240 {
241 $this->database();
242 }
243
244 $CI =& get_instance();
Derek Allard39b622d2008-01-16 21:10:09 +0000245
246 // for backwards compatibility, load dbforge so we can extend dbutils off it
247 // this use is deprecated and strongly discouraged
248 $CI->load->dbforge();
Derek Allard02658572007-12-20 14:00:50 +0000249
250 require_once(BASEPATH.'database/DB_utility'.EXT);
251 require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_utility'.EXT);
252 $class = 'CI_DB_'.$CI->db->dbdriver.'_utility';
253
Derek Allard39b622d2008-01-16 21:10:09 +0000254 $CI->dbutil =& new $class();
255
Derek Allard02658572007-12-20 14:00:50 +0000256 $CI->load->_ci_assign_to_models();
257 }
258
259 // --------------------------------------------------------------------
Derek Allard39b622d2008-01-16 21:10:09 +0000260
261 /**
262 * Load the Database Forge Class
263 *
264 * @access public
265 * @return string
266 */
267 function dbforge()
268 {
Derek Jones0b59f272008-05-13 04:22:33 +0000269 if ( ! class_exists('CI_DB'))
Derek Allard39b622d2008-01-16 21:10:09 +0000270 {
271 $this->database();
272 }
273
274 $CI =& get_instance();
275
276 require_once(BASEPATH.'database/DB_forge'.EXT);
277 require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_forge'.EXT);
278 $class = 'CI_DB_'.$CI->db->dbdriver.'_forge';
279
280 $CI->dbforge = new $class();
Derek Allardff390bd2008-05-06 00:37:12 +0000281
282 $CI->load->_ci_assign_to_models();
Derek Allard39b622d2008-01-16 21:10:09 +0000283 }
284
285 // --------------------------------------------------------------------
Derek Allard02658572007-12-20 14:00:50 +0000286
287 /**
288 * Load View
289 *
290 * This function is used to load a "view" file. It has three parameters:
291 *
292 * 1. The name of the "view" file to be included.
293 * 2. An associative array of data to be extracted for use in the view.
294 * 3. TRUE/FALSE - whether to return the data or load it. In
295 * some cases it's advantageous to be able to return data so that
296 * a developer can process it in some way.
297 *
298 * @access public
299 * @param string
300 * @param array
301 * @param bool
302 * @return void
303 */
304 function view($view, $vars = array(), $return = FALSE)
305 {
Derek Jones47845f22008-01-16 23:23:02 +0000306 return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_object_to_array($vars), '_ci_return' => $return));
Derek Allard02658572007-12-20 14:00:50 +0000307 }
308
309 // --------------------------------------------------------------------
310
311 /**
312 * Load File
313 *
314 * This is a generic file loader
315 *
316 * @access public
317 * @param string
318 * @param bool
319 * @return string
320 */
321 function file($path, $return = FALSE)
322 {
Derek Jones47845f22008-01-16 23:23:02 +0000323 return $this->_ci_load(array('_ci_path' => $path, '_ci_return' => $return));
Derek Allard02658572007-12-20 14:00:50 +0000324 }
325
326 // --------------------------------------------------------------------
327
328 /**
329 * Set Variables
330 *
331 * Once variables are set they become available within
332 * the controller class and its "view" files.
333 *
334 * @access public
335 * @param array
336 * @return void
337 */
Rick Ellis6ad53292008-08-21 18:31:28 +0000338 function vars($vars = array(), $val = '')
Derek Allard02658572007-12-20 14:00:50 +0000339 {
Rick Ellis6ad53292008-08-21 18:31:28 +0000340 if ($val != '' AND is_string($vars))
341 {
342 $vars = array($vars => $val);
343 }
344
Derek Allard02658572007-12-20 14:00:50 +0000345 $vars = $this->_ci_object_to_array($vars);
346
347 if (is_array($vars) AND count($vars) > 0)
348 {
349 foreach ($vars as $key => $val)
350 {
351 $this->_ci_cached_vars[$key] = $val;
352 }
353 }
354 }
355
356 // --------------------------------------------------------------------
357
358 /**
359 * Load Helper
360 *
361 * This function loads the specified helper file.
362 *
363 * @access public
364 * @param mixed
365 * @return void
366 */
367 function helper($helpers = array())
368 {
Derek Jones0b59f272008-05-13 04:22:33 +0000369 if ( ! is_array($helpers))
Derek Allard02658572007-12-20 14:00:50 +0000370 {
371 $helpers = array($helpers);
372 }
373
374 foreach ($helpers as $helper)
375 {
376 $helper = strtolower(str_replace(EXT, '', str_replace('_helper', '', $helper)).'_helper');
377
378 if (isset($this->_ci_helpers[$helper]))
379 {
380 continue;
381 }
Derek Jones269b9422008-01-28 21:00:20 +0000382
383 $ext_helper = APPPATH.'helpers/'.config_item('subclass_prefix').$helper.EXT;
Derek Allard02658572007-12-20 14:00:50 +0000384
Derek Jones269b9422008-01-28 21:00:20 +0000385 // Is this a helper extension request?
386 if (file_exists($ext_helper))
387 {
388 $base_helper = BASEPATH.'helpers/'.$helper.EXT;
389
Derek Jones0b59f272008-05-13 04:22:33 +0000390 if ( ! file_exists($base_helper))
Derek Jones269b9422008-01-28 21:00:20 +0000391 {
392 show_error('Unable to load the requested file: helpers/'.$helper.EXT);
393 }
394
395 include_once($ext_helper);
396 include_once($base_helper);
397 }
398 elseif (file_exists(APPPATH.'helpers/'.$helper.EXT))
Derek Allard02658572007-12-20 14:00:50 +0000399 {
400 include_once(APPPATH.'helpers/'.$helper.EXT);
401 }
402 else
403 {
404 if (file_exists(BASEPATH.'helpers/'.$helper.EXT))
405 {
Derek Allardd888c352008-03-18 04:04:33 +0000406 include_once(BASEPATH.'helpers/'.$helper.EXT);
Derek Allard02658572007-12-20 14:00:50 +0000407 }
408 else
409 {
410 show_error('Unable to load the requested file: helpers/'.$helper.EXT);
411 }
412 }
413
414 $this->_ci_helpers[$helper] = TRUE;
415
416 }
417
418 log_message('debug', 'Helpers loaded: '.implode(', ', $helpers));
419 }
420
421 // --------------------------------------------------------------------
422
423 /**
424 * Load Helpers
425 *
426 * This is simply an alias to the above function in case the
427 * user has written the plural form of this function.
428 *
429 * @access public
430 * @param array
431 * @return void
432 */
433 function helpers($helpers = array())
434 {
435 $this->helper($helpers);
436 }
437
438 // --------------------------------------------------------------------
439
440 /**
441 * Load Plugin
442 *
443 * This function loads the specified plugin.
444 *
445 * @access public
446 * @param array
447 * @return void
448 */
449 function plugin($plugins = array())
450 {
Derek Jones0b59f272008-05-13 04:22:33 +0000451 if ( ! is_array($plugins))
Derek Allard02658572007-12-20 14:00:50 +0000452 {
453 $plugins = array($plugins);
454 }
455
456 foreach ($plugins as $plugin)
457 {
Derek Allard17f74062008-01-16 01:22:44 +0000458 $plugin = strtolower(str_replace(EXT, '', str_replace('_pi', '', $plugin)).'_pi');
Derek Allard02658572007-12-20 14:00:50 +0000459
460 if (isset($this->_ci_plugins[$plugin]))
461 {
462 continue;
463 }
464
465 if (file_exists(APPPATH.'plugins/'.$plugin.EXT))
466 {
Derek Allardd888c352008-03-18 04:04:33 +0000467 include_once(APPPATH.'plugins/'.$plugin.EXT);
Derek Allard02658572007-12-20 14:00:50 +0000468 }
469 else
470 {
471 if (file_exists(BASEPATH.'plugins/'.$plugin.EXT))
472 {
Derek Allardd888c352008-03-18 04:04:33 +0000473 include_once(BASEPATH.'plugins/'.$plugin.EXT);
Derek Allard02658572007-12-20 14:00:50 +0000474 }
475 else
476 {
477 show_error('Unable to load the requested file: plugins/'.$plugin.EXT);
478 }
479 }
480
481 $this->_ci_plugins[$plugin] = TRUE;
482 }
483
484 log_message('debug', 'Plugins loaded: '.implode(', ', $plugins));
485 }
486
487 // --------------------------------------------------------------------
488
489 /**
490 * Load Plugins
491 *
492 * This is simply an alias to the above function in case the
493 * user has written the plural form of this function.
494 *
495 * @access public
496 * @param array
497 * @return void
498 */
499 function plugins($plugins = array())
500 {
501 $this->plugin($plugins);
502 }
503
504 // --------------------------------------------------------------------
505
506 /**
507 * Load Script
508 *
509 * This function loads the specified include file from the
510 * application/scripts/ folder.
511 *
512 * NOTE: This feature has been deprecated but it will remain available
513 * for legacy users.
514 *
515 * @access public
516 * @param array
517 * @return void
518 */
519 function script($scripts = array())
520 {
Derek Jones0b59f272008-05-13 04:22:33 +0000521 if ( ! is_array($scripts))
Derek Allard02658572007-12-20 14:00:50 +0000522 {
523 $scripts = array($scripts);
524 }
525
526 foreach ($scripts as $script)
527 {
528 $script = strtolower(str_replace(EXT, '', $script));
529
530 if (isset($this->_ci_scripts[$script]))
531 {
532 continue;
533 }
534
Derek Jones0b59f272008-05-13 04:22:33 +0000535 if ( ! file_exists(APPPATH.'scripts/'.$script.EXT))
Derek Allard02658572007-12-20 14:00:50 +0000536 {
537 show_error('Unable to load the requested script: scripts/'.$script.EXT);
538 }
539
Derek Allardd888c352008-03-18 04:04:33 +0000540 include_once(APPPATH.'scripts/'.$script.EXT);
Derek Allard02658572007-12-20 14:00:50 +0000541 }
542
543 log_message('debug', 'Scripts loaded: '.implode(', ', $scripts));
544 }
545
546 // --------------------------------------------------------------------
547
548 /**
549 * Loads a language file
550 *
551 * @access public
552 * @param array
553 * @param string
554 * @return void
555 */
556 function language($file = array(), $lang = '')
557 {
558 $CI =& get_instance();
559
Derek Jones0b59f272008-05-13 04:22:33 +0000560 if ( ! is_array($file))
Derek Allard02658572007-12-20 14:00:50 +0000561 {
562 $file = array($file);
563 }
564
565 foreach ($file as $langfile)
566 {
567 $CI->lang->load($langfile, $lang);
568 }
569 }
570
571 /**
572 * Loads language files for scaffolding
573 *
574 * @access public
575 * @param string
576 * @return arra
577 */
578 function scaffold_language($file = '', $lang = '', $return = FALSE)
579 {
580 $CI =& get_instance();
581 return $CI->lang->load($file, $lang, $return);
582 }
583
584 // --------------------------------------------------------------------
585
586 /**
587 * Loads a config file
588 *
589 * @access public
590 * @param string
591 * @return void
592 */
593 function config($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)
594 {
595 $CI =& get_instance();
596 $CI->config->load($file, $use_sections, $fail_gracefully);
597 }
598
599 // --------------------------------------------------------------------
600
601 /**
602 * Scaffolding Loader
603 *
604 * This initializing function works a bit different than the
605 * others. It doesn't load the class. Instead, it simply
606 * sets a flag indicating that scaffolding is allowed to be
607 * used. The actual scaffolding function below is
608 * called by the front controller based on whether the
609 * second segment of the URL matches the "secret" scaffolding
610 * word stored in the application/config/routes.php
611 *
612 * @access public
613 * @param string
614 * @return void
615 */
616 function scaffolding($table = '')
617 {
618 if ($table === FALSE)
619 {
620 show_error('You must include the name of the table you would like to access when you initialize scaffolding');
621 }
622
623 $CI =& get_instance();
624 $CI->_ci_scaffolding = TRUE;
625 $CI->_ci_scaff_table = $table;
626 }
627
628 // --------------------------------------------------------------------
629
630 /**
631 * Loader
632 *
633 * This function is used to load views and files.
Derek Jonesca0e7fa2008-01-22 16:42:13 +0000634 * Variables are prefixed with _ci_ to avoid symbol collision with
635 * variables made available to view files
Derek Allard02658572007-12-20 14:00:50 +0000636 *
637 * @access private
638 * @param array
639 * @return void
640 */
Derek Jonesca0e7fa2008-01-22 16:42:13 +0000641 function _ci_load($_ci_data)
Derek Allard02658572007-12-20 14:00:50 +0000642 {
643 // Set the default data variables
Derek Jonesca0e7fa2008-01-22 16:42:13 +0000644 foreach (array('_ci_view', '_ci_vars', '_ci_path', '_ci_return') as $_ci_val)
Derek Allard02658572007-12-20 14:00:50 +0000645 {
Derek Jones0b59f272008-05-13 04:22:33 +0000646 $$_ci_val = ( ! isset($_ci_data[$_ci_val])) ? FALSE : $_ci_data[$_ci_val];
Derek Allard02658572007-12-20 14:00:50 +0000647 }
648
649 // Set the path to the requested file
Derek Jones47845f22008-01-16 23:23:02 +0000650 if ($_ci_path == '')
Derek Allard02658572007-12-20 14:00:50 +0000651 {
Derek Jonesca0e7fa2008-01-22 16:42:13 +0000652 $_ci_ext = pathinfo($_ci_view, PATHINFO_EXTENSION);
653 $_ci_file = ($_ci_ext == '') ? $_ci_view.EXT : $_ci_view;
654 $_ci_path = $this->_ci_view_path.$_ci_file;
Derek Allard02658572007-12-20 14:00:50 +0000655 }
656 else
657 {
Derek Jonesca0e7fa2008-01-22 16:42:13 +0000658 $_ci_x = explode('/', $_ci_path);
659 $_ci_file = end($_ci_x);
Derek Allard02658572007-12-20 14:00:50 +0000660 }
661
Derek Jones0b59f272008-05-13 04:22:33 +0000662 if ( ! file_exists($_ci_path))
Derek Allard02658572007-12-20 14:00:50 +0000663 {
Derek Jonesca0e7fa2008-01-22 16:42:13 +0000664 show_error('Unable to load the requested file: '.$_ci_file);
Derek Allard02658572007-12-20 14:00:50 +0000665 }
666
667 // This allows anything loaded using $this->load (views, files, etc.)
668 // to become accessible from within the Controller and Model functions.
669 // Only needed when running PHP 5
670
671 if ($this->_ci_is_instance())
672 {
Derek Jonesca0e7fa2008-01-22 16:42:13 +0000673 $_ci_CI =& get_instance();
674 foreach (get_object_vars($_ci_CI) as $_ci_key => $_ci_var)
Derek Allard02658572007-12-20 14:00:50 +0000675 {
Derek Jones0b59f272008-05-13 04:22:33 +0000676 if ( ! isset($this->$_ci_key))
Derek Allard02658572007-12-20 14:00:50 +0000677 {
Derek Jonesca0e7fa2008-01-22 16:42:13 +0000678 $this->$_ci_key =& $_ci_CI->$_ci_key;
Derek Allard02658572007-12-20 14:00:50 +0000679 }
680 }
681 }
Derek Jonesca0e7fa2008-01-22 16:42:13 +0000682
Derek Allard02658572007-12-20 14:00:50 +0000683 /*
684 * Extract and cache variables
685 *
686 * You can either set variables using the dedicated $this->load_vars()
687 * function or via the second parameter of this function. We'll merge
688 * the two types and cache them so that views that are embedded within
689 * other views can have access to these variables.
690 */
Derek Jones47845f22008-01-16 23:23:02 +0000691 if (is_array($_ci_vars))
Derek Allard02658572007-12-20 14:00:50 +0000692 {
Derek Jones47845f22008-01-16 23:23:02 +0000693 $this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars);
Derek Allard02658572007-12-20 14:00:50 +0000694 }
695 extract($this->_ci_cached_vars);
696
697 /*
698 * Buffer the output
699 *
700 * We buffer the output for two reasons:
701 * 1. Speed. You get a significant speed boost.
702 * 2. So that the final rendered template can be
703 * post-processed by the output class. Why do we
704 * need post processing? For one thing, in order to
705 * show the elapsed page load time. Unless we
706 * can intercept the content right before it's sent to
707 * the browser and then stop the timer it won't be accurate.
708 */
709 ob_start();
710
711 // If the PHP installation does not support short tags we'll
712 // do a little string replacement, changing the short tags
713 // to standard PHP echo statements.
714
715 if ((bool) @ini_get('short_open_tag') === FALSE AND config_item('rewrite_short_tags') == TRUE)
716 {
Derek Jones454fa7e2008-05-13 22:26:09 +0000717 echo eval('?>'.preg_replace("/;*\s*\?>/", "; ?>", str_replace('<?=', '<?php echo ', file_get_contents($_ci_path))));
Derek Allard02658572007-12-20 14:00:50 +0000718 }
719 else
720 {
Derek Allard72c82c12008-04-04 11:34:58 +0000721 include($_ci_path); // include() vs include_once() allows for multiple views with the same name
Derek Allard02658572007-12-20 14:00:50 +0000722 }
723
Derek Jones47845f22008-01-16 23:23:02 +0000724 log_message('debug', 'File loaded: '.$_ci_path);
Derek Allard02658572007-12-20 14:00:50 +0000725
726 // Return the file data if requested
Derek Jones47845f22008-01-16 23:23:02 +0000727 if ($_ci_return === TRUE)
Derek Allard02658572007-12-20 14:00:50 +0000728 {
729 $buffer = ob_get_contents();
730 @ob_end_clean();
731 return $buffer;
732 }
733
734 /*
735 * Flush the buffer... or buff the flusher?
736 *
737 * In order to permit views to be nested within
738 * other views, we need to flush the content back out whenever
739 * we are beyond the first level of output buffering so that
740 * it can be seen and included properly by the first included
741 * template and any subsequent ones. Oy!
742 *
743 */
744 if (ob_get_level() > $this->_ci_ob_level + 1)
745 {
746 ob_end_flush();
747 }
748 else
749 {
750 // PHP 4 requires that we use a global
751 global $OUT;
Derek Allard66f07242008-01-18 22:36:14 +0000752 $OUT->append_output(ob_get_contents());
Derek Allard02658572007-12-20 14:00:50 +0000753 @ob_end_clean();
754 }
755 }
756
757 // --------------------------------------------------------------------
758
759 /**
760 * Load class
761 *
762 * This function loads the requested class.
763 *
764 * @access private
765 * @param string the item that is being loaded
766 * @param mixed any additional parameters
Rick Ellis6ad53292008-08-21 18:31:28 +0000767 * @param string an optional object name
Derek Allard02658572007-12-20 14:00:50 +0000768 * @return void
769 */
Rick Ellis6ad53292008-08-21 18:31:28 +0000770 function _ci_load_class($class, $params = NULL, $object_name = NULL)
Derek Allard02658572007-12-20 14:00:50 +0000771 {
Rick Ellis0ea8f982008-08-12 00:39:10 +0000772 // Get the class name, and while we're at it trim any slashes.
773 // The directory path can be included as part of the class name,
774 // but we don't want a leading slash
775 $class = str_replace(EXT, '', trim($class, '/'));
776
777 // Was the path included with the class name?
778 // We look for a slash to determine this
779 $subdir = '';
780 if (strpos($class, '/') !== FALSE)
781 {
782 // explode the path so we can separate the filename from the path
783 $x = explode('/', $class);
784
785 // Reset the $class variable now that we know the actual filename
786 $class = end($x);
787
788 // Kill the filename from the array
789 unset($x[count($x)-1]);
790
791 // Glue the path back together, sans filename
792 $subdir = implode($x, '/').'/';
793 }
Derek Allard02658572007-12-20 14:00:50 +0000794
795 // We'll test for both lowercase and capitalized versions of the file name
796 foreach (array(ucfirst($class), strtolower($class)) as $class)
797 {
Rick Ellisafb056a2008-08-12 00:44:25 +0000798 $subclass = APPPATH.'libraries/'.$subdir.config_item('subclass_prefix').$class.EXT;
Derek Allard02658572007-12-20 14:00:50 +0000799
800 // Is this a class extension request?
801 if (file_exists($subclass))
802 {
803 $baseclass = BASEPATH.'libraries/'.ucfirst($class).EXT;
804
Derek Jones0b59f272008-05-13 04:22:33 +0000805 if ( ! file_exists($baseclass))
Derek Allard02658572007-12-20 14:00:50 +0000806 {
807 log_message('error', "Unable to load the requested class: ".$class);
808 show_error("Unable to load the requested class: ".$class);
809 }
810
811 // Safety: Was the class already loaded by a previous call?
812 if (in_array($subclass, $this->_ci_classes))
813 {
Rick Ellis6ad53292008-08-21 18:31:28 +0000814 // Before we deem this to be a duplicate request, let's see
815 // if a custom object name is being supplied. If so, we'll
816 // return a new instance of the object
817 if ( ! is_null($object_name))
818 {
819 $CI =& get_instance();
820 if ( ! isset($CI->$object_name))
821 {
822 return $this->_ci_init_class($class, config_item('subclass_prefix'), $params, $object_name);
823 }
824 }
825
Derek Allard02658572007-12-20 14:00:50 +0000826 $is_duplicate = TRUE;
827 log_message('debug', $class." class already loaded. Second attempt ignored.");
828 return;
829 }
830
Derek Allardd888c352008-03-18 04:04:33 +0000831 include_once($baseclass);
832 include_once($subclass);
Derek Allard02658572007-12-20 14:00:50 +0000833 $this->_ci_classes[] = $subclass;
834
Rick Ellis6ad53292008-08-21 18:31:28 +0000835 return $this->_ci_init_class($class, config_item('subclass_prefix'), $params, $object_name);
Derek Allard02658572007-12-20 14:00:50 +0000836 }
837
838 // Lets search for the requested library file and load it.
839 $is_duplicate = FALSE;
840 for ($i = 1; $i < 3; $i++)
841 {
842 $path = ($i % 2) ? APPPATH : BASEPATH;
Rick Ellisafb056a2008-08-12 00:44:25 +0000843 $filepath = $path.'libraries/'.$subdir.$class.EXT;
Derek Allard02658572007-12-20 14:00:50 +0000844
845 // Does the file exist? No? Bummer...
Derek Jones0b59f272008-05-13 04:22:33 +0000846 if ( ! file_exists($filepath))
Derek Allard02658572007-12-20 14:00:50 +0000847 {
848 continue;
849 }
850
851 // Safety: Was the class already loaded by a previous call?
852 if (in_array($filepath, $this->_ci_classes))
853 {
Rick Ellis6ad53292008-08-21 18:31:28 +0000854 // Before we deem this to be a duplicate request, let's see
855 // if a custom object name is being supplied. If so, we'll
856 // return a new instance of the object
857 if ( ! is_null($object_name))
858 {
859 $CI =& get_instance();
860 if ( ! isset($CI->$object_name))
861 {
862 return $this->_ci_init_class($class, '', $params, $object_name);
863 }
864 }
865
Derek Allard02658572007-12-20 14:00:50 +0000866 $is_duplicate = TRUE;
867 log_message('debug', $class." class already loaded. Second attempt ignored.");
868 return;
869 }
870
Derek Allardd888c352008-03-18 04:04:33 +0000871 include_once($filepath);
Derek Allard02658572007-12-20 14:00:50 +0000872 $this->_ci_classes[] = $filepath;
Rick Ellis6ad53292008-08-21 18:31:28 +0000873 return $this->_ci_init_class($class, '', $params, $object_name);
Derek Allard02658572007-12-20 14:00:50 +0000874 }
875 } // END FOREACH
Rick Ellis6ad53292008-08-21 18:31:28 +0000876
877 // One last attempt. Maybe the library is in a subdirectory, but it wasn't specified?
878 if ($subdir == '')
879 {
880 $path = strtolower($class).'/'.$class;
881 return $this->_ci_load_class($path, $params);
882 }
Derek Allard02658572007-12-20 14:00:50 +0000883
884 // If we got this far we were unable to find the requested class.
885 // We do not issue errors if the load call failed due to a duplicate request
886 if ($is_duplicate == FALSE)
887 {
888 log_message('error', "Unable to load the requested class: ".$class);
889 show_error("Unable to load the requested class: ".$class);
890 }
891 }
892
893 // --------------------------------------------------------------------
894
895 /**
896 * Instantiates a class
897 *
898 * @access private
899 * @param string
900 * @param string
Rick Ellis6ad53292008-08-21 18:31:28 +0000901 * @param string an optional object name
Derek Allard02658572007-12-20 14:00:50 +0000902 * @return null
903 */
Rick Ellis6ad53292008-08-21 18:31:28 +0000904 function _ci_init_class($class, $prefix = '', $config = FALSE, $object_name = NULL)
Derek Allard02658572007-12-20 14:00:50 +0000905 {
Derek Allard0796b8d2008-01-17 03:41:37 +0000906 $class = strtolower($class);
907
Derek Allard02658572007-12-20 14:00:50 +0000908 // Is there an associated config file for this class?
909 if ($config === NULL)
910 {
911 if (file_exists(APPPATH.'config/'.$class.EXT))
912 {
Derek Allardd888c352008-03-18 04:04:33 +0000913 include_once(APPPATH.'config/'.$class.EXT);
Derek Allard02658572007-12-20 14:00:50 +0000914 }
915 }
916
917 if ($prefix == '')
918 {
919 $name = (class_exists('CI_'.$class)) ? 'CI_'.$class : $class;
920 }
921 else
922 {
923 $name = $prefix.$class;
924 }
925
Rick Ellis6ad53292008-08-21 18:31:28 +0000926 // Set the variable name we will assign the class to
927 // Was a custom class name supplied? If so we'll use it
928 if (is_null($object_name))
929 {
930 $classvar = ( ! isset($this->_ci_varmap[$class])) ? $class : $this->_ci_varmap[$class];
931 }
932 else
933 {
934 $classvar = $object_name;
935 }
Derek Allard02658572007-12-20 14:00:50 +0000936
937 // Instantiate the class
938 $CI =& get_instance();
939 if ($config !== NULL)
940 {
941 $CI->$classvar = new $name($config);
942 }
943 else
944 {
945 $CI->$classvar = new $name;
946 }
947 }
948
949 // --------------------------------------------------------------------
950
951 /**
952 * Autoloader
953 *
954 * The config/autoload.php file contains an array that permits sub-systems,
955 * libraries, plugins, and helpers to be loaded automatically.
956 *
957 * @access private
958 * @param array
959 * @return void
960 */
961 function _ci_autoloader()
962 {
Derek Allardd888c352008-03-18 04:04:33 +0000963 include_once(APPPATH.'config/autoload'.EXT);
Derek Allard02658572007-12-20 14:00:50 +0000964
Derek Jones0b59f272008-05-13 04:22:33 +0000965 if ( ! isset($autoload))
Derek Allard02658572007-12-20 14:00:50 +0000966 {
967 return FALSE;
968 }
969
970 // Load any custom config file
971 if (count($autoload['config']) > 0)
972 {
973 $CI =& get_instance();
974 foreach ($autoload['config'] as $key => $val)
975 {
976 $CI->config->load($val);
977 }
978 }
979
Derek Allard15dcf492008-05-12 21:37:04 +0000980 // Autoload plugins, helpers and languages
981 foreach (array('helper', 'plugin', 'language') as $type)
Derek Allard02658572007-12-20 14:00:50 +0000982 {
983 if (isset($autoload[$type]) AND count($autoload[$type]) > 0)
984 {
985 $this->$type($autoload[$type]);
986 }
987 }
988
Derek Allard22259b52008-01-22 01:47:11 +0000989
Derek Allard02658572007-12-20 14:00:50 +0000990
991 // A little tweak to remain backward compatible
992 // The $autoload['core'] item was deprecated
Derek Jones0b59f272008-05-13 04:22:33 +0000993 if ( ! isset($autoload['libraries']))
Derek Allard02658572007-12-20 14:00:50 +0000994 {
995 $autoload['libraries'] = $autoload['core'];
996 }
997
998 // Load libraries
999 if (isset($autoload['libraries']) AND count($autoload['libraries']) > 0)
1000 {
1001 // Load the database driver.
1002 if (in_array('database', $autoload['libraries']))
1003 {
1004 $this->database();
1005 $autoload['libraries'] = array_diff($autoload['libraries'], array('database'));
1006 }
1007
1008 // Load scaffolding
1009 if (in_array('scaffolding', $autoload['libraries']))
1010 {
1011 $this->scaffolding();
1012 $autoload['libraries'] = array_diff($autoload['libraries'], array('scaffolding'));
1013 }
1014
1015 // Load all other libraries
1016 foreach ($autoload['libraries'] as $item)
1017 {
1018 $this->library($item);
1019 }
Derek Allard02658572007-12-20 14:00:50 +00001020 }
Derek Allard22259b52008-01-22 01:47:11 +00001021
1022 // Autoload models
1023 if (isset($autoload['model']))
1024 {
1025 $this->model($autoload['model']);
1026 }
1027
Derek Allard02658572007-12-20 14:00:50 +00001028 }
1029
1030 // --------------------------------------------------------------------
1031
1032 /**
1033 * Assign to Models
1034 *
1035 * Makes sure that anything loaded by the loader class (libraries, plugins, etc.)
1036 * will be available to models, if any exist.
1037 *
1038 * @access private
1039 * @param object
1040 * @return array
1041 */
1042 function _ci_assign_to_models()
1043 {
1044 if (count($this->_ci_models) == 0)
1045 {
1046 return;
1047 }
1048
1049 if ($this->_ci_is_instance())
1050 {
1051 $CI =& get_instance();
1052 foreach ($this->_ci_models as $model)
1053 {
1054 $CI->$model->_assign_libraries();
1055 }
1056 }
1057 else
1058 {
1059 foreach ($this->_ci_models as $model)
1060 {
1061 $this->$model->_assign_libraries();
1062 }
1063 }
1064 }
1065
1066 // --------------------------------------------------------------------
1067
1068 /**
1069 * Object to Array
1070 *
1071 * Takes an object as input and converts the class variables to array key/vals
1072 *
1073 * @access private
1074 * @param object
1075 * @return array
1076 */
1077 function _ci_object_to_array($object)
1078 {
1079 return (is_object($object)) ? get_object_vars($object) : $object;
1080 }
1081
1082 // --------------------------------------------------------------------
1083
1084 /**
1085 * Determines whether we should use the CI instance or $this
1086 *
1087 * @access private
1088 * @return bool
1089 */
1090 function _ci_is_instance()
1091 {
1092 if ($this->_ci_is_php5 == TRUE)
1093 {
1094 return TRUE;
1095 }
1096
1097 global $CI;
1098 return (is_object($CI)) ? TRUE : FALSE;
1099 }
1100
1101}
Derek Allard15dcf492008-05-12 21:37:04 +00001102
1103/* End of file Loader.php */
Derek Jonesa3ffbbb2008-05-11 18:18:29 +00001104/* Location: ./system/libraries/Loader.php */