blob: 644c493452b68605b2f17e1075d655decbbba0ad [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();
Rick Ellis7cdef032008-08-26 18:44:54 +000038 var $_ci_loaded_files = array();
Derek Allard02658572007-12-20 14:00:50 +000039 var $_ci_models = array();
40 var $_ci_helpers = array();
41 var $_ci_plugins = array();
42 var $_ci_scripts = array();
43 var $_ci_varmap = array('unit_test' => 'unit', 'user_agent' => 'agent');
44
45
46 /**
47 * Constructor
48 *
49 * Sets the path to the view files and gets the initial output buffering level
50 *
51 * @access public
52 */
53 function CI_Loader()
54 {
55 $this->_ci_is_php5 = (floor(phpversion()) >= 5) ? TRUE : FALSE;
56 $this->_ci_view_path = APPPATH.'views/';
57 $this->_ci_ob_level = ob_get_level();
58
59 log_message('debug', "Loader Class Initialized");
60 }
61
62 // --------------------------------------------------------------------
63
64 /**
65 * Class Loader
66 *
67 * This function lets users load and instantiate classes.
68 * It is designed to be called from a user's app controllers.
69 *
70 * @access public
71 * @param string the name of the class
72 * @param mixed the optional parameters
Rick Ellis6ad53292008-08-21 18:31:28 +000073 * @param string an optional object name
Derek Allard02658572007-12-20 14:00:50 +000074 * @return void
75 */
Rick Ellis6ad53292008-08-21 18:31:28 +000076 function library($library = '', $params = NULL, $object_name = NULL)
Derek Allard02658572007-12-20 14:00:50 +000077 {
78 if ($library == '')
79 {
80 return FALSE;
81 }
82
Rick Ellis65f46062008-08-21 18:55:09 +000083 if ( ! is_null($params) AND ! is_array($params))
84 {
85 $params = NULL;
86 }
87
Derek Allard02658572007-12-20 14:00:50 +000088 if (is_array($library))
89 {
90 foreach ($library as $class)
91 {
Rick Ellis69450972008-08-26 18:51:19 +000092 $this->_ci_load_class($class, $params, $object_name);
Derek Allard02658572007-12-20 14:00:50 +000093 }
94 }
95 else
96 {
Rick Ellis6ad53292008-08-21 18:31:28 +000097 $this->_ci_load_class($library, $params, $object_name);
Derek Allard02658572007-12-20 14:00:50 +000098 }
99
100 $this->_ci_assign_to_models();
101 }
102
103 // --------------------------------------------------------------------
104
105 /**
106 * Model Loader
107 *
108 * This function lets users load and instantiate models.
109 *
Derek Allard02658572007-12-20 14:00:50 +0000110 * @param string the name of the class
Derek Allard9736d3f2008-06-16 21:36:01 +0000111 * @param string name for the model
112 * @param bool database connection
Derek Allard02658572007-12-20 14:00:50 +0000113 * @return void
114 */
115 function model($model, $name = '', $db_conn = FALSE)
116 {
117 if (is_array($model))
118 {
119 foreach($model as $babe)
120 {
121 $this->model($babe);
122 }
123 return;
124 }
125
126 if ($model == '')
127 {
128 return;
129 }
130
131 // Is the model in a sub-folder? If so, parse out the filename and path.
132 if (strpos($model, '/') === FALSE)
133 {
134 $path = '';
135 }
136 else
137 {
138 $x = explode('/', $model);
139 $model = end($x);
140 unset($x[count($x)-1]);
141 $path = implode('/', $x).'/';
142 }
143
144 if ($name == '')
145 {
146 $name = $model;
147 }
148
149 if (in_array($name, $this->_ci_models, TRUE))
150 {
151 return;
152 }
153
154 $CI =& get_instance();
155 if (isset($CI->$name))
156 {
157 show_error('The model name you are loading is the name of a resource that is already being used: '.$name);
158 }
159
160 $model = strtolower($model);
161
Derek Jones0b59f272008-05-13 04:22:33 +0000162 if ( ! file_exists(APPPATH.'models/'.$path.$model.EXT))
Derek Allard02658572007-12-20 14:00:50 +0000163 {
164 show_error('Unable to locate the model you have specified: '.$model);
165 }
166
167 if ($db_conn !== FALSE AND ! class_exists('CI_DB'))
168 {
169 if ($db_conn === TRUE)
170 $db_conn = '';
171
172 $CI->load->database($db_conn, FALSE, TRUE);
173 }
174
Derek Jones0b59f272008-05-13 04:22:33 +0000175 if ( ! class_exists('Model'))
Derek Allard02658572007-12-20 14:00:50 +0000176 {
Derek Allardff943eb2008-01-22 18:08:10 +0000177 load_class('Model', FALSE);
Derek Allard02658572007-12-20 14:00:50 +0000178 }
179
180 require_once(APPPATH.'models/'.$path.$model.EXT);
181
182 $model = ucfirst($model);
183
184 $CI->$name = new $model();
185 $CI->$name->_assign_libraries();
186
187 $this->_ci_models[] = $name;
188 }
189
190 // --------------------------------------------------------------------
191
192 /**
193 * Database Loader
194 *
195 * @access public
196 * @param string the DB credentials
197 * @param bool whether to return the DB object
198 * @param bool whether to enable active record (this allows us to override the config setting)
199 * @return object
200 */
201 function database($params = '', $return = FALSE, $active_record = FALSE)
202 {
Derek Jones72d61332008-01-30 20:52:22 +0000203 // Grab the super object
204 $CI =& get_instance();
205
Derek Allard02658572007-12-20 14:00:50 +0000206 // Do we even need to load the database class?
Derek Jones72d61332008-01-30 20:52:22 +0000207 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 +0000208 {
209 return FALSE;
210 }
211
212 require_once(BASEPATH.'database/DB'.EXT);
213
214 if ($return === TRUE)
215 {
216 return DB($params, $active_record);
217 }
Derek Allard02658572007-12-20 14:00:50 +0000218
219 // Initialize the db variable. Needed to prevent
220 // reference errors with some configurations
221 $CI->db = '';
222
223 // Load the DB class
224 $CI->db =& DB($params, $active_record);
225
226 // Assign the DB object to any existing models
227 $this->_ci_assign_to_models();
228 }
229
230 // --------------------------------------------------------------------
231
232 /**
233 * Load the Utilities Class
234 *
235 * @access public
236 * @return string
237 */
238 function dbutil()
239 {
Derek Jones0b59f272008-05-13 04:22:33 +0000240 if ( ! class_exists('CI_DB'))
Derek Allard02658572007-12-20 14:00:50 +0000241 {
242 $this->database();
243 }
244
245 $CI =& get_instance();
Derek Allard39b622d2008-01-16 21:10:09 +0000246
247 // for backwards compatibility, load dbforge so we can extend dbutils off it
248 // this use is deprecated and strongly discouraged
249 $CI->load->dbforge();
Derek Allard02658572007-12-20 14:00:50 +0000250
251 require_once(BASEPATH.'database/DB_utility'.EXT);
252 require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_utility'.EXT);
253 $class = 'CI_DB_'.$CI->db->dbdriver.'_utility';
254
Derek Allard39b622d2008-01-16 21:10:09 +0000255 $CI->dbutil =& new $class();
256
Derek Allard02658572007-12-20 14:00:50 +0000257 $CI->load->_ci_assign_to_models();
258 }
259
260 // --------------------------------------------------------------------
Derek Allard39b622d2008-01-16 21:10:09 +0000261
262 /**
263 * Load the Database Forge Class
264 *
265 * @access public
266 * @return string
267 */
268 function dbforge()
269 {
Derek Jones0b59f272008-05-13 04:22:33 +0000270 if ( ! class_exists('CI_DB'))
Derek Allard39b622d2008-01-16 21:10:09 +0000271 {
272 $this->database();
273 }
274
275 $CI =& get_instance();
276
277 require_once(BASEPATH.'database/DB_forge'.EXT);
278 require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_forge'.EXT);
279 $class = 'CI_DB_'.$CI->db->dbdriver.'_forge';
280
281 $CI->dbforge = new $class();
Derek Allardff390bd2008-05-06 00:37:12 +0000282
283 $CI->load->_ci_assign_to_models();
Derek Allard39b622d2008-01-16 21:10:09 +0000284 }
285
286 // --------------------------------------------------------------------
Derek Allard02658572007-12-20 14:00:50 +0000287
288 /**
289 * Load View
290 *
291 * This function is used to load a "view" file. It has three parameters:
292 *
293 * 1. The name of the "view" file to be included.
294 * 2. An associative array of data to be extracted for use in the view.
295 * 3. TRUE/FALSE - whether to return the data or load it. In
296 * some cases it's advantageous to be able to return data so that
297 * a developer can process it in some way.
298 *
299 * @access public
300 * @param string
301 * @param array
302 * @param bool
303 * @return void
304 */
305 function view($view, $vars = array(), $return = FALSE)
306 {
Derek Jones47845f22008-01-16 23:23:02 +0000307 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 +0000308 }
309
310 // --------------------------------------------------------------------
311
312 /**
313 * Load File
314 *
315 * This is a generic file loader
316 *
317 * @access public
318 * @param string
319 * @param bool
320 * @return string
321 */
322 function file($path, $return = FALSE)
323 {
Derek Jones47845f22008-01-16 23:23:02 +0000324 return $this->_ci_load(array('_ci_path' => $path, '_ci_return' => $return));
Derek Allard02658572007-12-20 14:00:50 +0000325 }
326
327 // --------------------------------------------------------------------
328
329 /**
330 * Set Variables
331 *
332 * Once variables are set they become available within
333 * the controller class and its "view" files.
334 *
335 * @access public
336 * @param array
337 * @return void
338 */
Rick Ellis6ad53292008-08-21 18:31:28 +0000339 function vars($vars = array(), $val = '')
Derek Allard02658572007-12-20 14:00:50 +0000340 {
Rick Ellis6ad53292008-08-21 18:31:28 +0000341 if ($val != '' AND is_string($vars))
342 {
343 $vars = array($vars => $val);
344 }
345
Derek Allard02658572007-12-20 14:00:50 +0000346 $vars = $this->_ci_object_to_array($vars);
347
348 if (is_array($vars) AND count($vars) > 0)
349 {
350 foreach ($vars as $key => $val)
351 {
352 $this->_ci_cached_vars[$key] = $val;
353 }
354 }
355 }
356
357 // --------------------------------------------------------------------
358
359 /**
360 * Load Helper
361 *
362 * This function loads the specified helper file.
363 *
364 * @access public
365 * @param mixed
366 * @return void
367 */
368 function helper($helpers = array())
369 {
Derek Jones0b59f272008-05-13 04:22:33 +0000370 if ( ! is_array($helpers))
Derek Allard02658572007-12-20 14:00:50 +0000371 {
372 $helpers = array($helpers);
373 }
374
375 foreach ($helpers as $helper)
376 {
377 $helper = strtolower(str_replace(EXT, '', str_replace('_helper', '', $helper)).'_helper');
378
379 if (isset($this->_ci_helpers[$helper]))
380 {
381 continue;
382 }
Derek Jones269b9422008-01-28 21:00:20 +0000383
384 $ext_helper = APPPATH.'helpers/'.config_item('subclass_prefix').$helper.EXT;
Derek Allard02658572007-12-20 14:00:50 +0000385
Derek Jones269b9422008-01-28 21:00:20 +0000386 // Is this a helper extension request?
387 if (file_exists($ext_helper))
388 {
389 $base_helper = BASEPATH.'helpers/'.$helper.EXT;
390
Derek Jones0b59f272008-05-13 04:22:33 +0000391 if ( ! file_exists($base_helper))
Derek Jones269b9422008-01-28 21:00:20 +0000392 {
393 show_error('Unable to load the requested file: helpers/'.$helper.EXT);
394 }
395
396 include_once($ext_helper);
397 include_once($base_helper);
398 }
399 elseif (file_exists(APPPATH.'helpers/'.$helper.EXT))
Derek Allard02658572007-12-20 14:00:50 +0000400 {
401 include_once(APPPATH.'helpers/'.$helper.EXT);
402 }
403 else
404 {
405 if (file_exists(BASEPATH.'helpers/'.$helper.EXT))
406 {
Derek Allardd888c352008-03-18 04:04:33 +0000407 include_once(BASEPATH.'helpers/'.$helper.EXT);
Derek Allard02658572007-12-20 14:00:50 +0000408 }
409 else
410 {
411 show_error('Unable to load the requested file: helpers/'.$helper.EXT);
412 }
413 }
414
415 $this->_ci_helpers[$helper] = TRUE;
416
417 }
418
419 log_message('debug', 'Helpers loaded: '.implode(', ', $helpers));
420 }
421
422 // --------------------------------------------------------------------
423
424 /**
425 * Load Helpers
426 *
427 * This is simply an alias to the above function in case the
428 * user has written the plural form of this function.
429 *
430 * @access public
431 * @param array
432 * @return void
433 */
434 function helpers($helpers = array())
435 {
436 $this->helper($helpers);
437 }
438
439 // --------------------------------------------------------------------
440
441 /**
442 * Load Plugin
443 *
444 * This function loads the specified plugin.
445 *
446 * @access public
447 * @param array
448 * @return void
449 */
450 function plugin($plugins = array())
451 {
Derek Jones0b59f272008-05-13 04:22:33 +0000452 if ( ! is_array($plugins))
Derek Allard02658572007-12-20 14:00:50 +0000453 {
454 $plugins = array($plugins);
455 }
456
457 foreach ($plugins as $plugin)
458 {
Derek Allard17f74062008-01-16 01:22:44 +0000459 $plugin = strtolower(str_replace(EXT, '', str_replace('_pi', '', $plugin)).'_pi');
Derek Allard02658572007-12-20 14:00:50 +0000460
461 if (isset($this->_ci_plugins[$plugin]))
462 {
463 continue;
464 }
465
466 if (file_exists(APPPATH.'plugins/'.$plugin.EXT))
467 {
Derek Allardd888c352008-03-18 04:04:33 +0000468 include_once(APPPATH.'plugins/'.$plugin.EXT);
Derek Allard02658572007-12-20 14:00:50 +0000469 }
470 else
471 {
472 if (file_exists(BASEPATH.'plugins/'.$plugin.EXT))
473 {
Derek Allardd888c352008-03-18 04:04:33 +0000474 include_once(BASEPATH.'plugins/'.$plugin.EXT);
Derek Allard02658572007-12-20 14:00:50 +0000475 }
476 else
477 {
478 show_error('Unable to load the requested file: plugins/'.$plugin.EXT);
479 }
480 }
481
482 $this->_ci_plugins[$plugin] = TRUE;
483 }
484
485 log_message('debug', 'Plugins loaded: '.implode(', ', $plugins));
486 }
487
488 // --------------------------------------------------------------------
489
490 /**
491 * Load Plugins
492 *
493 * This is simply an alias to the above function in case the
494 * user has written the plural form of this function.
495 *
496 * @access public
497 * @param array
498 * @return void
499 */
500 function plugins($plugins = array())
501 {
502 $this->plugin($plugins);
503 }
504
505 // --------------------------------------------------------------------
506
507 /**
508 * Load Script
509 *
510 * This function loads the specified include file from the
511 * application/scripts/ folder.
512 *
513 * NOTE: This feature has been deprecated but it will remain available
514 * for legacy users.
515 *
516 * @access public
517 * @param array
518 * @return void
519 */
520 function script($scripts = array())
521 {
Derek Jones0b59f272008-05-13 04:22:33 +0000522 if ( ! is_array($scripts))
Derek Allard02658572007-12-20 14:00:50 +0000523 {
524 $scripts = array($scripts);
525 }
526
527 foreach ($scripts as $script)
528 {
529 $script = strtolower(str_replace(EXT, '', $script));
530
531 if (isset($this->_ci_scripts[$script]))
532 {
533 continue;
534 }
535
Derek Jones0b59f272008-05-13 04:22:33 +0000536 if ( ! file_exists(APPPATH.'scripts/'.$script.EXT))
Derek Allard02658572007-12-20 14:00:50 +0000537 {
538 show_error('Unable to load the requested script: scripts/'.$script.EXT);
539 }
540
Derek Allardd888c352008-03-18 04:04:33 +0000541 include_once(APPPATH.'scripts/'.$script.EXT);
Derek Allard02658572007-12-20 14:00:50 +0000542 }
543
544 log_message('debug', 'Scripts loaded: '.implode(', ', $scripts));
545 }
546
547 // --------------------------------------------------------------------
548
549 /**
550 * Loads a language file
551 *
552 * @access public
553 * @param array
554 * @param string
555 * @return void
556 */
557 function language($file = array(), $lang = '')
558 {
559 $CI =& get_instance();
560
Derek Jones0b59f272008-05-13 04:22:33 +0000561 if ( ! is_array($file))
Derek Allard02658572007-12-20 14:00:50 +0000562 {
563 $file = array($file);
564 }
565
566 foreach ($file as $langfile)
567 {
568 $CI->lang->load($langfile, $lang);
569 }
570 }
571
572 /**
573 * Loads language files for scaffolding
574 *
575 * @access public
576 * @param string
577 * @return arra
578 */
579 function scaffold_language($file = '', $lang = '', $return = FALSE)
580 {
581 $CI =& get_instance();
582 return $CI->lang->load($file, $lang, $return);
583 }
584
585 // --------------------------------------------------------------------
586
587 /**
588 * Loads a config file
589 *
590 * @access public
591 * @param string
592 * @return void
593 */
594 function config($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)
595 {
596 $CI =& get_instance();
597 $CI->config->load($file, $use_sections, $fail_gracefully);
598 }
599
600 // --------------------------------------------------------------------
601
602 /**
603 * Scaffolding Loader
604 *
605 * This initializing function works a bit different than the
606 * others. It doesn't load the class. Instead, it simply
607 * sets a flag indicating that scaffolding is allowed to be
608 * used. The actual scaffolding function below is
609 * called by the front controller based on whether the
610 * second segment of the URL matches the "secret" scaffolding
611 * word stored in the application/config/routes.php
612 *
613 * @access public
614 * @param string
615 * @return void
616 */
617 function scaffolding($table = '')
618 {
619 if ($table === FALSE)
620 {
621 show_error('You must include the name of the table you would like to access when you initialize scaffolding');
622 }
623
624 $CI =& get_instance();
625 $CI->_ci_scaffolding = TRUE;
626 $CI->_ci_scaff_table = $table;
627 }
628
629 // --------------------------------------------------------------------
630
631 /**
632 * Loader
633 *
634 * This function is used to load views and files.
Derek Jonesca0e7fa2008-01-22 16:42:13 +0000635 * Variables are prefixed with _ci_ to avoid symbol collision with
636 * variables made available to view files
Derek Allard02658572007-12-20 14:00:50 +0000637 *
638 * @access private
639 * @param array
640 * @return void
641 */
Derek Jonesca0e7fa2008-01-22 16:42:13 +0000642 function _ci_load($_ci_data)
Derek Allard02658572007-12-20 14:00:50 +0000643 {
644 // Set the default data variables
Derek Jonesca0e7fa2008-01-22 16:42:13 +0000645 foreach (array('_ci_view', '_ci_vars', '_ci_path', '_ci_return') as $_ci_val)
Derek Allard02658572007-12-20 14:00:50 +0000646 {
Derek Jones0b59f272008-05-13 04:22:33 +0000647 $$_ci_val = ( ! isset($_ci_data[$_ci_val])) ? FALSE : $_ci_data[$_ci_val];
Derek Allard02658572007-12-20 14:00:50 +0000648 }
649
650 // Set the path to the requested file
Derek Jones47845f22008-01-16 23:23:02 +0000651 if ($_ci_path == '')
Derek Allard02658572007-12-20 14:00:50 +0000652 {
Derek Jonesca0e7fa2008-01-22 16:42:13 +0000653 $_ci_ext = pathinfo($_ci_view, PATHINFO_EXTENSION);
654 $_ci_file = ($_ci_ext == '') ? $_ci_view.EXT : $_ci_view;
655 $_ci_path = $this->_ci_view_path.$_ci_file;
Derek Allard02658572007-12-20 14:00:50 +0000656 }
657 else
658 {
Derek Jonesca0e7fa2008-01-22 16:42:13 +0000659 $_ci_x = explode('/', $_ci_path);
660 $_ci_file = end($_ci_x);
Derek Allard02658572007-12-20 14:00:50 +0000661 }
662
Derek Jones0b59f272008-05-13 04:22:33 +0000663 if ( ! file_exists($_ci_path))
Derek Allard02658572007-12-20 14:00:50 +0000664 {
Derek Jonesca0e7fa2008-01-22 16:42:13 +0000665 show_error('Unable to load the requested file: '.$_ci_file);
Derek Allard02658572007-12-20 14:00:50 +0000666 }
667
668 // This allows anything loaded using $this->load (views, files, etc.)
669 // to become accessible from within the Controller and Model functions.
670 // Only needed when running PHP 5
671
672 if ($this->_ci_is_instance())
673 {
Derek Jonesca0e7fa2008-01-22 16:42:13 +0000674 $_ci_CI =& get_instance();
675 foreach (get_object_vars($_ci_CI) as $_ci_key => $_ci_var)
Derek Allard02658572007-12-20 14:00:50 +0000676 {
Derek Jones0b59f272008-05-13 04:22:33 +0000677 if ( ! isset($this->$_ci_key))
Derek Allard02658572007-12-20 14:00:50 +0000678 {
Derek Jonesca0e7fa2008-01-22 16:42:13 +0000679 $this->$_ci_key =& $_ci_CI->$_ci_key;
Derek Allard02658572007-12-20 14:00:50 +0000680 }
681 }
682 }
Derek Jonesca0e7fa2008-01-22 16:42:13 +0000683
Derek Allard02658572007-12-20 14:00:50 +0000684 /*
685 * Extract and cache variables
686 *
687 * You can either set variables using the dedicated $this->load_vars()
688 * function or via the second parameter of this function. We'll merge
689 * the two types and cache them so that views that are embedded within
690 * other views can have access to these variables.
691 */
Derek Jones47845f22008-01-16 23:23:02 +0000692 if (is_array($_ci_vars))
Derek Allard02658572007-12-20 14:00:50 +0000693 {
Derek Jones47845f22008-01-16 23:23:02 +0000694 $this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars);
Derek Allard02658572007-12-20 14:00:50 +0000695 }
696 extract($this->_ci_cached_vars);
697
698 /*
699 * Buffer the output
700 *
701 * We buffer the output for two reasons:
702 * 1. Speed. You get a significant speed boost.
703 * 2. So that the final rendered template can be
704 * post-processed by the output class. Why do we
705 * need post processing? For one thing, in order to
706 * show the elapsed page load time. Unless we
707 * can intercept the content right before it's sent to
708 * the browser and then stop the timer it won't be accurate.
709 */
710 ob_start();
711
712 // If the PHP installation does not support short tags we'll
713 // do a little string replacement, changing the short tags
714 // to standard PHP echo statements.
715
716 if ((bool) @ini_get('short_open_tag') === FALSE AND config_item('rewrite_short_tags') == TRUE)
717 {
Derek Jones454fa7e2008-05-13 22:26:09 +0000718 echo eval('?>'.preg_replace("/;*\s*\?>/", "; ?>", str_replace('<?=', '<?php echo ', file_get_contents($_ci_path))));
Derek Allard02658572007-12-20 14:00:50 +0000719 }
720 else
721 {
Derek Allard72c82c12008-04-04 11:34:58 +0000722 include($_ci_path); // include() vs include_once() allows for multiple views with the same name
Derek Allard02658572007-12-20 14:00:50 +0000723 }
724
Derek Jones47845f22008-01-16 23:23:02 +0000725 log_message('debug', 'File loaded: '.$_ci_path);
Derek Allard02658572007-12-20 14:00:50 +0000726
727 // Return the file data if requested
Derek Jones47845f22008-01-16 23:23:02 +0000728 if ($_ci_return === TRUE)
Derek Allard02658572007-12-20 14:00:50 +0000729 {
730 $buffer = ob_get_contents();
731 @ob_end_clean();
732 return $buffer;
733 }
734
735 /*
736 * Flush the buffer... or buff the flusher?
737 *
738 * In order to permit views to be nested within
739 * other views, we need to flush the content back out whenever
740 * we are beyond the first level of output buffering so that
741 * it can be seen and included properly by the first included
742 * template and any subsequent ones. Oy!
743 *
744 */
745 if (ob_get_level() > $this->_ci_ob_level + 1)
746 {
747 ob_end_flush();
748 }
749 else
750 {
751 // PHP 4 requires that we use a global
752 global $OUT;
Derek Allard66f07242008-01-18 22:36:14 +0000753 $OUT->append_output(ob_get_contents());
Derek Allard02658572007-12-20 14:00:50 +0000754 @ob_end_clean();
755 }
756 }
757
758 // --------------------------------------------------------------------
759
760 /**
761 * Load class
762 *
763 * This function loads the requested class.
764 *
765 * @access private
766 * @param string the item that is being loaded
767 * @param mixed any additional parameters
Rick Ellis6ad53292008-08-21 18:31:28 +0000768 * @param string an optional object name
Derek Allard02658572007-12-20 14:00:50 +0000769 * @return void
770 */
Rick Ellis6ad53292008-08-21 18:31:28 +0000771 function _ci_load_class($class, $params = NULL, $object_name = NULL)
Derek Allard02658572007-12-20 14:00:50 +0000772 {
Rick Ellis0ea8f982008-08-12 00:39:10 +0000773 // Get the class name, and while we're at it trim any slashes.
774 // The directory path can be included as part of the class name,
775 // but we don't want a leading slash
776 $class = str_replace(EXT, '', trim($class, '/'));
777
778 // Was the path included with the class name?
779 // We look for a slash to determine this
780 $subdir = '';
781 if (strpos($class, '/') !== FALSE)
782 {
783 // explode the path so we can separate the filename from the path
784 $x = explode('/', $class);
785
786 // Reset the $class variable now that we know the actual filename
787 $class = end($x);
788
789 // Kill the filename from the array
790 unset($x[count($x)-1]);
791
792 // Glue the path back together, sans filename
793 $subdir = implode($x, '/').'/';
794 }
Derek Allard02658572007-12-20 14:00:50 +0000795
796 // We'll test for both lowercase and capitalized versions of the file name
797 foreach (array(ucfirst($class), strtolower($class)) as $class)
798 {
Rick Ellisafb056a2008-08-12 00:44:25 +0000799 $subclass = APPPATH.'libraries/'.$subdir.config_item('subclass_prefix').$class.EXT;
Derek Allard02658572007-12-20 14:00:50 +0000800
801 // Is this a class extension request?
802 if (file_exists($subclass))
803 {
804 $baseclass = BASEPATH.'libraries/'.ucfirst($class).EXT;
805
Derek Jones0b59f272008-05-13 04:22:33 +0000806 if ( ! file_exists($baseclass))
Derek Allard02658572007-12-20 14:00:50 +0000807 {
808 log_message('error', "Unable to load the requested class: ".$class);
809 show_error("Unable to load the requested class: ".$class);
810 }
811
812 // Safety: Was the class already loaded by a previous call?
Rick Ellis7cdef032008-08-26 18:44:54 +0000813 if (in_array($subclass, $this->_ci_loaded_files))
Derek Allard02658572007-12-20 14:00:50 +0000814 {
Rick Ellis6ad53292008-08-21 18:31:28 +0000815 // Before we deem this to be a duplicate request, let's see
816 // if a custom object name is being supplied. If so, we'll
817 // return a new instance of the object
818 if ( ! is_null($object_name))
819 {
820 $CI =& get_instance();
821 if ( ! isset($CI->$object_name))
822 {
823 return $this->_ci_init_class($class, config_item('subclass_prefix'), $params, $object_name);
824 }
825 }
826
Derek Allard02658572007-12-20 14:00:50 +0000827 $is_duplicate = TRUE;
828 log_message('debug', $class." class already loaded. Second attempt ignored.");
829 return;
830 }
831
Derek Allardd888c352008-03-18 04:04:33 +0000832 include_once($baseclass);
833 include_once($subclass);
Rick Ellis7cdef032008-08-26 18:44:54 +0000834 $this->_ci_loaded_files[] = $subclass;
Derek Allard02658572007-12-20 14:00:50 +0000835
Rick Ellis6ad53292008-08-21 18:31:28 +0000836 return $this->_ci_init_class($class, config_item('subclass_prefix'), $params, $object_name);
Derek Allard02658572007-12-20 14:00:50 +0000837 }
838
839 // Lets search for the requested library file and load it.
840 $is_duplicate = FALSE;
841 for ($i = 1; $i < 3; $i++)
842 {
843 $path = ($i % 2) ? APPPATH : BASEPATH;
Rick Ellisafb056a2008-08-12 00:44:25 +0000844 $filepath = $path.'libraries/'.$subdir.$class.EXT;
Derek Allard02658572007-12-20 14:00:50 +0000845
846 // Does the file exist? No? Bummer...
Derek Jones0b59f272008-05-13 04:22:33 +0000847 if ( ! file_exists($filepath))
Derek Allard02658572007-12-20 14:00:50 +0000848 {
849 continue;
850 }
851
852 // Safety: Was the class already loaded by a previous call?
Rick Ellis7cdef032008-08-26 18:44:54 +0000853 if (in_array($filepath, $this->_ci_loaded_files))
Derek Allard02658572007-12-20 14:00:50 +0000854 {
Rick Ellis6ad53292008-08-21 18:31:28 +0000855 // Before we deem this to be a duplicate request, let's see
856 // if a custom object name is being supplied. If so, we'll
857 // return a new instance of the object
858 if ( ! is_null($object_name))
859 {
860 $CI =& get_instance();
861 if ( ! isset($CI->$object_name))
862 {
863 return $this->_ci_init_class($class, '', $params, $object_name);
864 }
865 }
866
Derek Allard02658572007-12-20 14:00:50 +0000867 $is_duplicate = TRUE;
868 log_message('debug', $class." class already loaded. Second attempt ignored.");
869 return;
870 }
871
Derek Allardd888c352008-03-18 04:04:33 +0000872 include_once($filepath);
Rick Ellis7cdef032008-08-26 18:44:54 +0000873 $this->_ci_loaded_files[] = $filepath;
Rick Ellis6ad53292008-08-21 18:31:28 +0000874 return $this->_ci_init_class($class, '', $params, $object_name);
Derek Allard02658572007-12-20 14:00:50 +0000875 }
876 } // END FOREACH
Rick Ellis6ad53292008-08-21 18:31:28 +0000877
878 // One last attempt. Maybe the library is in a subdirectory, but it wasn't specified?
879 if ($subdir == '')
880 {
881 $path = strtolower($class).'/'.$class;
882 return $this->_ci_load_class($path, $params);
883 }
Derek Allard02658572007-12-20 14:00:50 +0000884
885 // If we got this far we were unable to find the requested class.
886 // We do not issue errors if the load call failed due to a duplicate request
887 if ($is_duplicate == FALSE)
888 {
889 log_message('error', "Unable to load the requested class: ".$class);
890 show_error("Unable to load the requested class: ".$class);
891 }
892 }
893
894 // --------------------------------------------------------------------
895
896 /**
897 * Instantiates a class
898 *
899 * @access private
900 * @param string
901 * @param string
Rick Ellis6ad53292008-08-21 18:31:28 +0000902 * @param string an optional object name
Derek Allard02658572007-12-20 14:00:50 +0000903 * @return null
904 */
Rick Ellis6ad53292008-08-21 18:31:28 +0000905 function _ci_init_class($class, $prefix = '', $config = FALSE, $object_name = NULL)
Derek Allard02658572007-12-20 14:00:50 +0000906 {
Derek Allard0796b8d2008-01-17 03:41:37 +0000907 $class = strtolower($class);
908
Derek Allard02658572007-12-20 14:00:50 +0000909 // Is there an associated config file for this class?
910 if ($config === NULL)
911 {
912 if (file_exists(APPPATH.'config/'.$class.EXT))
913 {
Derek Allardd888c352008-03-18 04:04:33 +0000914 include_once(APPPATH.'config/'.$class.EXT);
Derek Allard02658572007-12-20 14:00:50 +0000915 }
916 }
917
918 if ($prefix == '')
919 {
920 $name = (class_exists('CI_'.$class)) ? 'CI_'.$class : $class;
921 }
922 else
923 {
924 $name = $prefix.$class;
925 }
926
Rick Ellis6ad53292008-08-21 18:31:28 +0000927 // Set the variable name we will assign the class to
928 // Was a custom class name supplied? If so we'll use it
929 if (is_null($object_name))
930 {
931 $classvar = ( ! isset($this->_ci_varmap[$class])) ? $class : $this->_ci_varmap[$class];
932 }
933 else
934 {
935 $classvar = $object_name;
936 }
Rick Ellis7cdef032008-08-26 18:44:54 +0000937
938 // Save the class name and object name
939 $this->_ci_classes[$class] = $object_name;
940
Derek Allard02658572007-12-20 14:00:50 +0000941 // Instantiate the class
942 $CI =& get_instance();
943 if ($config !== NULL)
944 {
945 $CI->$classvar = new $name($config);
946 }
947 else
948 {
949 $CI->$classvar = new $name;
950 }
951 }
952
953 // --------------------------------------------------------------------
954
955 /**
956 * Autoloader
957 *
958 * The config/autoload.php file contains an array that permits sub-systems,
959 * libraries, plugins, and helpers to be loaded automatically.
960 *
961 * @access private
962 * @param array
963 * @return void
964 */
965 function _ci_autoloader()
966 {
Derek Allardd888c352008-03-18 04:04:33 +0000967 include_once(APPPATH.'config/autoload'.EXT);
Derek Allard02658572007-12-20 14:00:50 +0000968
Derek Jones0b59f272008-05-13 04:22:33 +0000969 if ( ! isset($autoload))
Derek Allard02658572007-12-20 14:00:50 +0000970 {
971 return FALSE;
972 }
973
974 // Load any custom config file
975 if (count($autoload['config']) > 0)
976 {
977 $CI =& get_instance();
978 foreach ($autoload['config'] as $key => $val)
979 {
980 $CI->config->load($val);
981 }
982 }
983
Derek Allard15dcf492008-05-12 21:37:04 +0000984 // Autoload plugins, helpers and languages
985 foreach (array('helper', 'plugin', 'language') as $type)
Derek Allard02658572007-12-20 14:00:50 +0000986 {
987 if (isset($autoload[$type]) AND count($autoload[$type]) > 0)
988 {
989 $this->$type($autoload[$type]);
990 }
991 }
992
Derek Allard22259b52008-01-22 01:47:11 +0000993
Derek Allard02658572007-12-20 14:00:50 +0000994
995 // A little tweak to remain backward compatible
996 // The $autoload['core'] item was deprecated
Derek Jones0b59f272008-05-13 04:22:33 +0000997 if ( ! isset($autoload['libraries']))
Derek Allard02658572007-12-20 14:00:50 +0000998 {
999 $autoload['libraries'] = $autoload['core'];
1000 }
1001
1002 // Load libraries
1003 if (isset($autoload['libraries']) AND count($autoload['libraries']) > 0)
1004 {
1005 // Load the database driver.
1006 if (in_array('database', $autoload['libraries']))
1007 {
1008 $this->database();
1009 $autoload['libraries'] = array_diff($autoload['libraries'], array('database'));
1010 }
1011
1012 // Load scaffolding
1013 if (in_array('scaffolding', $autoload['libraries']))
1014 {
1015 $this->scaffolding();
1016 $autoload['libraries'] = array_diff($autoload['libraries'], array('scaffolding'));
1017 }
1018
1019 // Load all other libraries
1020 foreach ($autoload['libraries'] as $item)
1021 {
1022 $this->library($item);
1023 }
Derek Allard02658572007-12-20 14:00:50 +00001024 }
Derek Allard22259b52008-01-22 01:47:11 +00001025
1026 // Autoload models
1027 if (isset($autoload['model']))
1028 {
1029 $this->model($autoload['model']);
1030 }
1031
Derek Allard02658572007-12-20 14:00:50 +00001032 }
1033
1034 // --------------------------------------------------------------------
1035
1036 /**
1037 * Assign to Models
1038 *
1039 * Makes sure that anything loaded by the loader class (libraries, plugins, etc.)
1040 * will be available to models, if any exist.
1041 *
1042 * @access private
1043 * @param object
1044 * @return array
1045 */
1046 function _ci_assign_to_models()
1047 {
1048 if (count($this->_ci_models) == 0)
1049 {
1050 return;
1051 }
1052
1053 if ($this->_ci_is_instance())
1054 {
1055 $CI =& get_instance();
1056 foreach ($this->_ci_models as $model)
1057 {
1058 $CI->$model->_assign_libraries();
1059 }
1060 }
1061 else
1062 {
1063 foreach ($this->_ci_models as $model)
1064 {
1065 $this->$model->_assign_libraries();
1066 }
1067 }
1068 }
1069
1070 // --------------------------------------------------------------------
1071
1072 /**
1073 * Object to Array
1074 *
1075 * Takes an object as input and converts the class variables to array key/vals
1076 *
1077 * @access private
1078 * @param object
1079 * @return array
1080 */
1081 function _ci_object_to_array($object)
1082 {
1083 return (is_object($object)) ? get_object_vars($object) : $object;
1084 }
1085
1086 // --------------------------------------------------------------------
1087
1088 /**
1089 * Determines whether we should use the CI instance or $this
1090 *
1091 * @access private
1092 * @return bool
1093 */
1094 function _ci_is_instance()
1095 {
1096 if ($this->_ci_is_php5 == TRUE)
1097 {
1098 return TRUE;
1099 }
1100
1101 global $CI;
1102 return (is_object($CI)) ? TRUE : FALSE;
1103 }
1104
1105}
Derek Allard15dcf492008-05-12 21:37:04 +00001106
1107/* End of file Loader.php */
Derek Jonesa3ffbbb2008-05-11 18:18:29 +00001108/* Location: ./system/libraries/Loader.php */