source: sourcecode/system/core/Loader.php @ 1

Last change on this file since 1 was 1, checked in by dungnv, 11 years ago
File size: 29.9 KB
Line 
1<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
2/**
3 * CodeIgniter
4 *
5 * An open source application development framework for PHP 5.1.6 or newer
6 *
7 * @package             CodeIgniter
8 * @author              ExpressionEngine Dev Team
9 * @copyright   Copyright (c) 2008 - 2011, EllisLab, Inc.
10 * @license             http://codeigniter.com/user_guide/license.html
11 * @link                http://codeigniter.com
12 * @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
25 * @author              ExpressionEngine Dev Team
26 * @category    Loader
27 * @link                http://codeigniter.com/user_guide/libraries/loader.html
28 */
29class CI_Loader {
30
31        // All these are set automatically. Don't mess with them.
32        /**
33         * Nesting level of the output buffering mechanism
34         *
35         * @var int
36         * @access protected
37         */
38        protected $_ci_ob_level;
39        /**
40         * List of paths to load views from
41         *
42         * @var array
43         * @access protected
44         */
45        protected $_ci_view_paths               = array();
46        /**
47         * List of paths to load libraries from
48         *
49         * @var array
50         * @access protected
51         */
52        protected $_ci_library_paths    = array();
53        /**
54         * List of paths to load models from
55         *
56         * @var array
57         * @access protected
58         */
59        protected $_ci_model_paths              = array();
60        /**
61         * List of paths to load helpers from
62         *
63         * @var array
64         * @access protected
65         */
66        protected $_ci_helper_paths             = array();
67        /**
68         * List of loaded base classes
69         * Set by the controller class
70         *
71         * @var array
72         * @access protected
73         */
74        protected $_base_classes                = array(); // Set by the controller class
75        /**
76         * List of cached variables
77         *
78         * @var array
79         * @access protected
80         */
81        protected $_ci_cached_vars              = array();
82        /**
83         * List of loaded classes
84         *
85         * @var array
86         * @access protected
87         */
88        protected $_ci_classes                  = array();
89        /**
90         * List of loaded files
91         *
92         * @var array
93         * @access protected
94         */
95        protected $_ci_loaded_files             = array();
96        /**
97         * List of loaded models
98         *
99         * @var array
100         * @access protected
101         */
102        protected $_ci_models                   = array();
103        /**
104         * List of loaded helpers
105         *
106         * @var array
107         * @access protected
108         */
109        protected $_ci_helpers                  = array();
110        /**
111         * List of class name mappings
112         *
113         * @var array
114         * @access protected
115         */
116        protected $_ci_varmap                   = array('unit_test' => 'unit',
117                                                                                        'user_agent' => 'agent');
118
119        /**
120         * Constructor
121         *
122         * Sets the path to the view files and gets the initial output buffering level
123         */
124        public function __construct()
125        {
126                $this->_ci_ob_level  = ob_get_level();
127                $this->_ci_library_paths = array(APPPATH, BASEPATH);
128                $this->_ci_helper_paths = array(APPPATH, BASEPATH);
129                $this->_ci_model_paths = array(APPPATH);
130                $this->_ci_view_paths = array(APPPATH.'views/'  => TRUE);
131
132                log_message('debug', "Loader Class Initialized");
133        }
134
135        // --------------------------------------------------------------------
136
137        /**
138         * Initialize the Loader
139         *
140         * This method is called once in CI_Controller.
141         *
142         * @param       array
143         * @return      object
144         */
145        public function initialize()
146        {
147                $this->_ci_classes = array();
148                $this->_ci_loaded_files = array();
149                $this->_ci_models = array();
150                $this->_base_classes =& is_loaded();
151
152                $this->_ci_autoloader();
153
154                return $this;
155        }
156
157        // --------------------------------------------------------------------
158
159        /**
160         * Is Loaded
161         *
162         * A utility function to test if a class is in the self::$_ci_classes array.
163         * This function returns the object name if the class tested for is loaded,
164         * and returns FALSE if it isn't.
165         *
166         * It is mainly used in the form_helper -> _get_validation_object()
167         *
168         * @param       string  class being checked for
169         * @return      mixed   class object name on the CI SuperObject or FALSE
170         */
171        public function is_loaded($class)
172        {
173                if (isset($this->_ci_classes[$class]))
174                {
175                        return $this->_ci_classes[$class];
176                }
177
178                return FALSE;
179        }
180
181        // --------------------------------------------------------------------
182
183        /**
184         * Class Loader
185         *
186         * This function lets users load and instantiate classes.
187         * It is designed to be called from a user's app controllers.
188         *
189         * @param       string  the name of the class
190         * @param       mixed   the optional parameters
191         * @param       string  an optional object name
192         * @return      void
193         */
194        public function library($library = '', $params = NULL, $object_name = NULL)
195        {
196                if (is_array($library))
197                {
198                        foreach ($library as $class)
199                        {
200                                $this->library($class, $params);
201                        }
202
203                        return;
204                }
205
206                if ($library == '' OR isset($this->_base_classes[$library]))
207                {
208                        return FALSE;
209                }
210
211                if ( ! is_null($params) && ! is_array($params))
212                {
213                        $params = NULL;
214                }
215
216                $this->_ci_load_class($library, $params, $object_name);
217        }
218
219        // --------------------------------------------------------------------
220
221        /**
222         * Model Loader
223         *
224         * This function lets users load and instantiate models.
225         *
226         * @param       string  the name of the class
227         * @param       string  name for the model
228         * @param       bool    database connection
229         * @return      void
230         */
231        public function model($model, $name = '', $db_conn = FALSE)
232        {
233                if (is_array($model))
234                {
235                        foreach ($model as $babe)
236                        {
237                                $this->model($babe);
238                        }
239                        return;
240                }
241
242                if ($model == '')
243                {
244                        return;
245                }
246
247                $path = '';
248
249                // Is the model in a sub-folder? If so, parse out the filename and path.
250                if (($last_slash = strrpos($model, '/')) !== FALSE)
251                {
252                        // The path is in front of the last slash
253                        $path = substr($model, 0, $last_slash + 1);
254
255                        // And the model name behind it
256                        $model = substr($model, $last_slash + 1);
257                }
258
259                if ($name == '')
260                {
261                        $name = $model;
262                }
263
264                if (in_array($name, $this->_ci_models, TRUE))
265                {
266                        return;
267                }
268
269                $CI =& get_instance();
270                if (isset($CI->$name))
271                {
272                        show_error('The model name you are loading is the name of a resource that is already being used: '.$name);
273                }
274
275                $model = strtolower($model);
276
277                foreach ($this->_ci_model_paths as $mod_path)
278                {
279                        if ( ! file_exists($mod_path.'models/'.$path.$model.'.php'))
280                        {
281                                continue;
282                        }
283
284                        if ($db_conn !== FALSE AND ! class_exists('CI_DB'))
285                        {
286                                if ($db_conn === TRUE)
287                                {
288                                        $db_conn = '';
289                                }
290
291                                $CI->load->database($db_conn, FALSE, TRUE);
292                        }
293
294                        if ( ! class_exists('CI_Model'))
295                        {
296                                load_class('Model', 'core');
297                        }
298
299                        require_once($mod_path.'models/'.$path.$model.'.php');
300
301                        $model = ucfirst($model);
302
303                        $CI->$name = new $model();
304
305                        $this->_ci_models[] = $name;
306                        return;
307                }
308
309                // couldn't find the model
310                show_error('Unable to locate the model you have specified: '.$model);
311        }
312
313        // --------------------------------------------------------------------
314
315        /**
316         * Database Loader
317         *
318         * @param       string  the DB credentials
319         * @param       bool    whether to return the DB object
320         * @param       bool    whether to enable active record (this allows us to override the config setting)
321         * @return      object
322         */
323        public function database($params = '', $return = FALSE, $active_record = NULL)
324        {
325                // Grab the super object
326                $CI =& get_instance();
327
328                // Do we even need to load the database class?
329                if (class_exists('CI_DB') AND $return == FALSE AND $active_record == NULL AND isset($CI->db) AND is_object($CI->db))
330                {
331                        return FALSE;
332                }
333
334                require_once(BASEPATH.'database/DB.php');
335
336                if ($return === TRUE)
337                {
338                        return DB($params, $active_record);
339                }
340
341                // Initialize the db variable.  Needed to prevent
342                // reference errors with some configurations
343                $CI->db = '';
344
345                // Load the DB class
346                $CI->db =& DB($params, $active_record);
347        }
348
349        // --------------------------------------------------------------------
350
351        /**
352         * Load the Utilities Class
353         *
354         * @return      string
355         */
356        public function dbutil()
357        {
358                if ( ! class_exists('CI_DB'))
359                {
360                        $this->database();
361                }
362
363                $CI =& get_instance();
364
365                // for backwards compatibility, load dbforge so we can extend dbutils off it
366                // this use is deprecated and strongly discouraged
367                $CI->load->dbforge();
368
369                require_once(BASEPATH.'database/DB_utility.php');
370                require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_utility.php');
371                $class = 'CI_DB_'.$CI->db->dbdriver.'_utility';
372
373                $CI->dbutil = new $class();
374        }
375
376        // --------------------------------------------------------------------
377
378        /**
379         * Load the Database Forge Class
380         *
381         * @return      string
382         */
383        public function dbforge()
384        {
385                if ( ! class_exists('CI_DB'))
386                {
387                        $this->database();
388                }
389
390                $CI =& get_instance();
391
392                require_once(BASEPATH.'database/DB_forge.php');
393                require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_forge.php');
394                $class = 'CI_DB_'.$CI->db->dbdriver.'_forge';
395
396                $CI->dbforge = new $class();
397        }
398
399        // --------------------------------------------------------------------
400
401        /**
402         * Load View
403         *
404         * This function is used to load a "view" file.  It has three parameters:
405         *
406         * 1. The name of the "view" file to be included.
407         * 2. An associative array of data to be extracted for use in the view.
408         * 3. TRUE/FALSE - whether to return the data or load it.  In
409         * some cases it's advantageous to be able to return data so that
410         * a developer can process it in some way.
411         *
412         * @param       string
413         * @param       array
414         * @param       bool
415         * @return      void
416         */
417        public function view($view, $vars = array(), $return = FALSE)
418        {
419                return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_object_to_array($vars), '_ci_return' => $return));
420        }
421
422        // --------------------------------------------------------------------
423
424        /**
425         * Load File
426         *
427         * This is a generic file loader
428         *
429         * @param       string
430         * @param       bool
431         * @return      string
432         */
433        public function file($path, $return = FALSE)
434        {
435                return $this->_ci_load(array('_ci_path' => $path, '_ci_return' => $return));
436        }
437
438        // --------------------------------------------------------------------
439
440        /**
441         * Set Variables
442         *
443         * Once variables are set they become available within
444         * the controller class and its "view" files.
445         *
446         * @param       array
447         * @param       string
448         * @return      void
449         */
450        public function vars($vars = array(), $val = '')
451        {
452                if ($val != '' AND is_string($vars))
453                {
454                        $vars = array($vars => $val);
455                }
456
457                $vars = $this->_ci_object_to_array($vars);
458
459                if (is_array($vars) AND count($vars) > 0)
460                {
461                        foreach ($vars as $key => $val)
462                        {
463                                $this->_ci_cached_vars[$key] = $val;
464                        }
465                }
466        }
467
468        // --------------------------------------------------------------------
469
470        /**
471         * Get Variable
472         *
473         * Check if a variable is set and retrieve it.
474         *
475         * @param       array
476         * @return      void
477         */
478        public function get_var($key)
479        {
480                return isset($this->_ci_cached_vars[$key]) ? $this->_ci_cached_vars[$key] : NULL;
481        }
482
483        // --------------------------------------------------------------------
484
485        /**
486         * Load Helper
487         *
488         * This function loads the specified helper file.
489         *
490         * @param       mixed
491         * @return      void
492         */
493        public function helper($helpers = array())
494        {
495                foreach ($this->_ci_prep_filename($helpers, '_helper') as $helper)
496                {
497                        if (isset($this->_ci_helpers[$helper]))
498                        {
499                                continue;
500                        }
501
502                        $ext_helper = APPPATH.'helpers/'.config_item('subclass_prefix').$helper.'.php';
503
504                        // Is this a helper extension request?
505                        if (file_exists($ext_helper))
506                        {
507                                $base_helper = BASEPATH.'helpers/'.$helper.'.php';
508
509                                if ( ! file_exists($base_helper))
510                                {
511                                        show_error('Unable to load the requested file: helpers/'.$helper.'.php');
512                                }
513
514                                include_once($ext_helper);
515                                include_once($base_helper);
516
517                                $this->_ci_helpers[$helper] = TRUE;
518                                log_message('debug', 'Helper loaded: '.$helper);
519                                continue;
520                        }
521
522                        // Try to load the helper
523                        foreach ($this->_ci_helper_paths as $path)
524                        {
525                                if (file_exists($path.'helpers/'.$helper.'.php'))
526                                {
527                                        include_once($path.'helpers/'.$helper.'.php');
528
529                                        $this->_ci_helpers[$helper] = TRUE;
530                                        log_message('debug', 'Helper loaded: '.$helper);
531                                        break;
532                                }
533                        }
534
535                        // unable to load the helper
536                        if ( ! isset($this->_ci_helpers[$helper]))
537                        {
538                                show_error('Unable to load the requested file: helpers/'.$helper.'.php');
539                        }
540                }
541        }
542
543        // --------------------------------------------------------------------
544
545        /**
546         * Load Helpers
547         *
548         * This is simply an alias to the above function in case the
549         * user has written the plural form of this function.
550         *
551         * @param       array
552         * @return      void
553         */
554        public function helpers($helpers = array())
555        {
556                $this->helper($helpers);
557        }
558
559        // --------------------------------------------------------------------
560
561        /**
562         * Loads a language file
563         *
564         * @param       array
565         * @param       string
566         * @return      void
567         */
568        public function language($file = array(), $lang = '')
569        {
570                $CI =& get_instance();
571
572                if ( ! is_array($file))
573                {
574                        $file = array($file);
575                }
576
577                foreach ($file as $langfile)
578                {
579                        $CI->lang->load($langfile, $lang);
580                }
581        }
582
583        // --------------------------------------------------------------------
584
585        /**
586         * Loads a config file
587         *
588         * @param       string
589         * @param       bool
590         * @param       bool
591         * @return      void
592         */
593        public 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         * Driver
603         *
604         * Loads a driver library
605         *
606         * @param       string  the name of the class
607         * @param       mixed   the optional parameters
608         * @param       string  an optional object name
609         * @return      void
610         */
611        public function driver($library = '', $params = NULL, $object_name = NULL)
612        {
613                if ( ! class_exists('CI_Driver_Library'))
614                {
615                        // we aren't instantiating an object here, that'll be done by the Library itself
616                        require BASEPATH.'libraries/Driver.php';
617                }
618
619                if ($library == '')
620                {
621                        return FALSE;
622                }
623
624                // We can save the loader some time since Drivers will *always* be in a subfolder,
625                // and typically identically named to the library
626                if ( ! strpos($library, '/'))
627                {
628                        $library = ucfirst($library).'/'.$library;
629                }
630
631                return $this->library($library, $params, $object_name);
632        }
633
634        // --------------------------------------------------------------------
635
636        /**
637         * Add Package Path
638         *
639         * Prepends a parent path to the library, model, helper, and config path arrays
640         *
641         * @param       string
642         * @param       boolean
643         * @return      void
644         */
645        public function add_package_path($path, $view_cascade=TRUE)
646        {
647                $path = rtrim($path, '/').'/';
648
649                array_unshift($this->_ci_library_paths, $path);
650                array_unshift($this->_ci_model_paths, $path);
651                array_unshift($this->_ci_helper_paths, $path);
652
653                $this->_ci_view_paths = array($path.'views/' => $view_cascade) + $this->_ci_view_paths;
654
655                // Add config file path
656                $config =& $this->_ci_get_component('config');
657                array_unshift($config->_config_paths, $path);
658        }
659
660        // --------------------------------------------------------------------
661
662        /**
663         * Get Package Paths
664         *
665         * Return a list of all package paths, by default it will ignore BASEPATH.
666         *
667         * @param       string
668         * @return      void
669         */
670        public function get_package_paths($include_base = FALSE)
671        {
672                return $include_base === TRUE ? $this->_ci_library_paths : $this->_ci_model_paths;
673        }
674
675        // --------------------------------------------------------------------
676
677        /**
678         * Remove Package Path
679         *
680         * Remove a path from the library, model, and helper path arrays if it exists
681         * If no path is provided, the most recently added path is removed.
682         *
683         * @param       type
684         * @param       bool
685         * @return      type
686         */
687        public function remove_package_path($path = '', $remove_config_path = TRUE)
688        {
689                $config =& $this->_ci_get_component('config');
690
691                if ($path == '')
692                {
693                        $void = array_shift($this->_ci_library_paths);
694                        $void = array_shift($this->_ci_model_paths);
695                        $void = array_shift($this->_ci_helper_paths);
696                        $void = array_shift($this->_ci_view_paths);
697                        $void = array_shift($config->_config_paths);
698                }
699                else
700                {
701                        $path = rtrim($path, '/').'/';
702                        foreach (array('_ci_library_paths', '_ci_model_paths', '_ci_helper_paths') as $var)
703                        {
704                                if (($key = array_search($path, $this->{$var})) !== FALSE)
705                                {
706                                        unset($this->{$var}[$key]);
707                                }
708                        }
709
710                        if (isset($this->_ci_view_paths[$path.'views/']))
711                        {
712                                unset($this->_ci_view_paths[$path.'views/']);
713                        }
714
715                        if (($key = array_search($path, $config->_config_paths)) !== FALSE)
716                        {
717                                unset($config->_config_paths[$key]);
718                        }
719                }
720
721                // make sure the application default paths are still in the array
722                $this->_ci_library_paths = array_unique(array_merge($this->_ci_library_paths, array(APPPATH, BASEPATH)));
723                $this->_ci_helper_paths = array_unique(array_merge($this->_ci_helper_paths, array(APPPATH, BASEPATH)));
724                $this->_ci_model_paths = array_unique(array_merge($this->_ci_model_paths, array(APPPATH)));
725                $this->_ci_view_paths = array_merge($this->_ci_view_paths, array(APPPATH.'views/' => TRUE));
726                $config->_config_paths = array_unique(array_merge($config->_config_paths, array(APPPATH)));
727        }
728
729        // --------------------------------------------------------------------
730
731        /**
732         * Loader
733         *
734         * This function is used to load views and files.
735         * Variables are prefixed with _ci_ to avoid symbol collision with
736         * variables made available to view files
737         *
738         * @param       array
739         * @return      void
740         */
741        protected function _ci_load($_ci_data)
742        {
743                // Set the default data variables
744                foreach (array('_ci_view', '_ci_vars', '_ci_path', '_ci_return') as $_ci_val)
745                {
746                        $$_ci_val = ( ! isset($_ci_data[$_ci_val])) ? FALSE : $_ci_data[$_ci_val];
747                }
748
749                $file_exists = FALSE;
750
751                // Set the path to the requested file
752                if ($_ci_path != '')
753                {
754                        $_ci_x = explode('/', $_ci_path);
755                        $_ci_file = end($_ci_x);
756                }
757                else
758                {
759                        $_ci_ext = pathinfo($_ci_view, PATHINFO_EXTENSION);
760                        $_ci_file = ($_ci_ext == '') ? $_ci_view.'.php' : $_ci_view;
761
762                        foreach ($this->_ci_view_paths as $view_file => $cascade)
763                        {
764                                if (file_exists($view_file.$_ci_file))
765                                {
766                                        $_ci_path = $view_file.$_ci_file;
767                                        $file_exists = TRUE;
768                                        break;
769                                }
770
771                                if ( ! $cascade)
772                                {
773                                        break;
774                                }
775                        }
776                }
777
778                if ( ! $file_exists && ! file_exists($_ci_path))
779                {
780                        show_error('Unable to load the requested file: '.$_ci_file);
781                }
782
783                // This allows anything loaded using $this->load (views, files, etc.)
784                // to become accessible from within the Controller and Model functions.
785
786                $_ci_CI =& get_instance();
787                foreach (get_object_vars($_ci_CI) as $_ci_key => $_ci_var)
788                {
789                        if ( ! isset($this->$_ci_key))
790                        {
791                                $this->$_ci_key =& $_ci_CI->$_ci_key;
792                        }
793                }
794
795                /*
796                 * Extract and cache variables
797                 *
798                 * You can either set variables using the dedicated $this->load_vars()
799                 * function or via the second parameter of this function. We'll merge
800                 * the two types and cache them so that views that are embedded within
801                 * other views can have access to these variables.
802                 */
803                if (is_array($_ci_vars))
804                {
805                        $this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars);
806                }
807                extract($this->_ci_cached_vars);
808
809                /*
810                 * Buffer the output
811                 *
812                 * We buffer the output for two reasons:
813                 * 1. Speed. You get a significant speed boost.
814                 * 2. So that the final rendered template can be
815                 * post-processed by the output class.  Why do we
816                 * need post processing?  For one thing, in order to
817                 * show the elapsed page load time.  Unless we
818                 * can intercept the content right before it's sent to
819                 * the browser and then stop the timer it won't be accurate.
820                 */
821                ob_start();
822
823                // If the PHP installation does not support short tags we'll
824                // do a little string replacement, changing the short tags
825                // to standard PHP echo statements.
826
827                if ((bool) @ini_get('short_open_tag') === FALSE AND config_item('rewrite_short_tags') == TRUE)
828                {
829                        echo eval('?>'.preg_replace("/;*\s*\?>/", "; ?>", str_replace('<?=', '<?php echo ', file_get_contents($_ci_path))));
830                }
831                else
832                {
833                        include($_ci_path); // include() vs include_once() allows for multiple views with the same name
834                }
835
836                log_message('debug', 'File loaded: '.$_ci_path);
837
838                // Return the file data if requested
839                if ($_ci_return === TRUE)
840                {
841                        $buffer = ob_get_contents();
842                        @ob_end_clean();
843                        return $buffer;
844                }
845
846                /*
847                 * Flush the buffer... or buff the flusher?
848                 *
849                 * In order to permit views to be nested within
850                 * other views, we need to flush the content back out whenever
851                 * we are beyond the first level of output buffering so that
852                 * it can be seen and included properly by the first included
853                 * template and any subsequent ones. Oy!
854                 *
855                 */
856                if (ob_get_level() > $this->_ci_ob_level + 1)
857                {
858                        ob_end_flush();
859                }
860                else
861                {
862                        $_ci_CI->output->append_output(ob_get_contents());
863                        @ob_end_clean();
864                }
865        }
866
867        // --------------------------------------------------------------------
868
869        /**
870         * Load class
871         *
872         * This function loads the requested class.
873         *
874         * @param       string  the item that is being loaded
875         * @param       mixed   any additional parameters
876         * @param       string  an optional object name
877         * @return      void
878         */
879        protected function _ci_load_class($class, $params = NULL, $object_name = NULL)
880        {
881                // Get the class name, and while we're at it trim any slashes.
882                // The directory path can be included as part of the class name,
883                // but we don't want a leading slash
884                $class = str_replace('.php', '', trim($class, '/'));
885
886                // Was the path included with the class name?
887                // We look for a slash to determine this
888                $subdir = '';
889                if (($last_slash = strrpos($class, '/')) !== FALSE)
890                {
891                        // Extract the path
892                        $subdir = substr($class, 0, $last_slash + 1);
893
894                        // Get the filename from the path
895                        $class = substr($class, $last_slash + 1);
896                }
897
898                // We'll test for both lowercase and capitalized versions of the file name
899                foreach (array(ucfirst($class), strtolower($class)) as $class)
900                {
901                        $subclass = APPPATH.'libraries/'.$subdir.config_item('subclass_prefix').$class.'.php';
902
903                        // Is this a class extension request?
904                        if (file_exists($subclass))
905                        {
906                                $baseclass = BASEPATH.'libraries/'.ucfirst($class).'.php';
907
908                                if ( ! file_exists($baseclass))
909                                {
910                                        log_message('error', "Unable to load the requested class: ".$class);
911                                        show_error("Unable to load the requested class: ".$class);
912                                }
913
914                                // Safety:  Was the class already loaded by a previous call?
915                                if (in_array($subclass, $this->_ci_loaded_files))
916                                {
917                                        // Before we deem this to be a duplicate request, let's see
918                                        // if a custom object name is being supplied.  If so, we'll
919                                        // return a new instance of the object
920                                        if ( ! is_null($object_name))
921                                        {
922                                                $CI =& get_instance();
923                                                if ( ! isset($CI->$object_name))
924                                                {
925                                                        return $this->_ci_init_class($class, config_item('subclass_prefix'), $params, $object_name);
926                                                }
927                                        }
928
929                                        $is_duplicate = TRUE;
930                                        log_message('debug', $class." class already loaded. Second attempt ignored.");
931                                        return;
932                                }
933
934                                include_once($baseclass);
935                                include_once($subclass);
936                                $this->_ci_loaded_files[] = $subclass;
937
938                                return $this->_ci_init_class($class, config_item('subclass_prefix'), $params, $object_name);
939                        }
940
941                        // Lets search for the requested library file and load it.
942                        $is_duplicate = FALSE;
943                        foreach ($this->_ci_library_paths as $path)
944                        {
945                                $filepath = $path.'libraries/'.$subdir.$class.'.php';
946
947                                // Does the file exist?  No?  Bummer...
948                                if ( ! file_exists($filepath))
949                                {
950                                        continue;
951                                }
952
953                                // Safety:  Was the class already loaded by a previous call?
954                                if (in_array($filepath, $this->_ci_loaded_files))
955                                {
956                                        // Before we deem this to be a duplicate request, let's see
957                                        // if a custom object name is being supplied.  If so, we'll
958                                        // return a new instance of the object
959                                        if ( ! is_null($object_name))
960                                        {
961                                                $CI =& get_instance();
962                                                if ( ! isset($CI->$object_name))
963                                                {
964                                                        return $this->_ci_init_class($class, '', $params, $object_name);
965                                                }
966                                        }
967
968                                        $is_duplicate = TRUE;
969                                        log_message('debug', $class." class already loaded. Second attempt ignored.");
970                                        return;
971                                }
972
973                                include_once($filepath);
974                                $this->_ci_loaded_files[] = $filepath;
975                                return $this->_ci_init_class($class, '', $params, $object_name);
976                        }
977
978                } // END FOREACH
979
980                // One last attempt.  Maybe the library is in a subdirectory, but it wasn't specified?
981                if ($subdir == '')
982                {
983                        $path = strtolower($class).'/'.$class;
984                        return $this->_ci_load_class($path, $params);
985                }
986
987                // If we got this far we were unable to find the requested class.
988                // We do not issue errors if the load call failed due to a duplicate request
989                if ($is_duplicate == FALSE)
990                {
991                        log_message('error', "Unable to load the requested class: ".$class);
992                        show_error("Unable to load the requested class: ".$class);
993                }
994        }
995
996        // --------------------------------------------------------------------
997
998        /**
999         * Instantiates a class
1000         *
1001         * @param       string
1002         * @param       string
1003         * @param       bool
1004         * @param       string  an optional object name
1005         * @return      null
1006         */
1007        protected function _ci_init_class($class, $prefix = '', $config = FALSE, $object_name = NULL)
1008        {
1009                // Is there an associated config file for this class?  Note: these should always be lowercase
1010                if ($config === NULL)
1011                {
1012                        // Fetch the config paths containing any package paths
1013                        $config_component = $this->_ci_get_component('config');
1014
1015                        if (is_array($config_component->_config_paths))
1016                        {
1017                                // Break on the first found file, thus package files
1018                                // are not overridden by default paths
1019                                foreach ($config_component->_config_paths as $path)
1020                                {
1021                                        // We test for both uppercase and lowercase, for servers that
1022                                        // are case-sensitive with regard to file names. Check for environment
1023                                        // first, global next
1024                                        if (defined('ENVIRONMENT') AND file_exists($path .'config/'.ENVIRONMENT.'/'.strtolower($class).'.php'))
1025                                        {
1026                                                include($path .'config/'.ENVIRONMENT.'/'.strtolower($class).'.php');
1027                                                break;
1028                                        }
1029                                        elseif (defined('ENVIRONMENT') AND file_exists($path .'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php'))
1030                                        {
1031                                                include($path .'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php');
1032                                                break;
1033                                        }
1034                                        elseif (file_exists($path .'config/'.strtolower($class).'.php'))
1035                                        {
1036                                                include($path .'config/'.strtolower($class).'.php');
1037                                                break;
1038                                        }
1039                                        elseif (file_exists($path .'config/'.ucfirst(strtolower($class)).'.php'))
1040                                        {
1041                                                include($path .'config/'.ucfirst(strtolower($class)).'.php');
1042                                                break;
1043                                        }
1044                                }
1045                        }
1046                }
1047
1048                if ($prefix == '')
1049                {
1050                        if (class_exists('CI_'.$class))
1051                        {
1052                                $name = 'CI_'.$class;
1053                        }
1054                        elseif (class_exists(config_item('subclass_prefix').$class))
1055                        {
1056                                $name = config_item('subclass_prefix').$class;
1057                        }
1058                        else
1059                        {
1060                                $name = $class;
1061                        }
1062                }
1063                else
1064                {
1065                        $name = $prefix.$class;
1066                }
1067
1068                // Is the class name valid?
1069                if ( ! class_exists($name))
1070                {
1071                        log_message('error', "Non-existent class: ".$name);
1072                        show_error("Non-existent class: ".$class);
1073                }
1074
1075                // Set the variable name we will assign the class to
1076                // Was a custom class name supplied?  If so we'll use it
1077                $class = strtolower($class);
1078
1079                if (is_null($object_name))
1080                {
1081                        $classvar = ( ! isset($this->_ci_varmap[$class])) ? $class : $this->_ci_varmap[$class];
1082                }
1083                else
1084                {
1085                        $classvar = $object_name;
1086                }
1087
1088                // Save the class name and object name
1089                $this->_ci_classes[$class] = $classvar;
1090
1091                // Instantiate the class
1092                $CI =& get_instance();
1093                if ($config !== NULL)
1094                {
1095                        $CI->$classvar = new $name($config);
1096                }
1097                else
1098                {
1099                        $CI->$classvar = new $name;
1100                }
1101        }
1102
1103        // --------------------------------------------------------------------
1104
1105        /**
1106         * Autoloader
1107         *
1108         * The config/autoload.php file contains an array that permits sub-systems,
1109         * libraries, and helpers to be loaded automatically.
1110         *
1111         * @param       array
1112         * @return      void
1113         */
1114        private function _ci_autoloader()
1115        {
1116                if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/autoload.php'))
1117                {
1118                        include(APPPATH.'config/'.ENVIRONMENT.'/autoload.php');
1119                }
1120                else
1121                {
1122                        include(APPPATH.'config/autoload.php');
1123                }
1124
1125                if ( ! isset($autoload))
1126                {
1127                        return FALSE;
1128                }
1129
1130                // Autoload packages
1131                if (isset($autoload['packages']))
1132                {
1133                        foreach ($autoload['packages'] as $package_path)
1134                        {
1135                                $this->add_package_path($package_path);
1136                        }
1137                }
1138
1139                // Load any custom config file
1140                if (count($autoload['config']) > 0)
1141                {
1142                        $CI =& get_instance();
1143                        foreach ($autoload['config'] as $key => $val)
1144                        {
1145                                $CI->config->load($val);
1146                        }
1147                }
1148
1149                // Autoload helpers and languages
1150                foreach (array('helper', 'language') as $type)
1151                {
1152                        if (isset($autoload[$type]) AND count($autoload[$type]) > 0)
1153                        {
1154                                $this->$type($autoload[$type]);
1155                        }
1156                }
1157
1158                // A little tweak to remain backward compatible
1159                // The $autoload['core'] item was deprecated
1160                if ( ! isset($autoload['libraries']) AND isset($autoload['core']))
1161                {
1162                        $autoload['libraries'] = $autoload['core'];
1163                }
1164
1165                // Load libraries
1166                if (isset($autoload['libraries']) AND count($autoload['libraries']) > 0)
1167                {
1168                        // Load the database driver.
1169                        if (in_array('database', $autoload['libraries']))
1170                        {
1171                                $this->database();
1172                                $autoload['libraries'] = array_diff($autoload['libraries'], array('database'));
1173                        }
1174
1175                        // Load all other libraries
1176                        foreach ($autoload['libraries'] as $item)
1177                        {
1178                                $this->library($item);
1179                        }
1180                }
1181
1182                // Autoload models
1183                if (isset($autoload['model']))
1184                {
1185                        $this->model($autoload['model']);
1186                }
1187        }
1188
1189        // --------------------------------------------------------------------
1190
1191        /**
1192         * Object to Array
1193         *
1194         * Takes an object as input and converts the class variables to array key/vals
1195         *
1196         * @param       object
1197         * @return      array
1198         */
1199        protected function _ci_object_to_array($object)
1200        {
1201                return (is_object($object)) ? get_object_vars($object) : $object;
1202        }
1203
1204        // --------------------------------------------------------------------
1205
1206        /**
1207         * Get a reference to a specific library or model
1208         *
1209         * @param       string
1210         * @return      bool
1211         */
1212        protected function &_ci_get_component($component)
1213        {
1214                $CI =& get_instance();
1215                return $CI->$component;
1216        }
1217
1218        // --------------------------------------------------------------------
1219
1220        /**
1221         * Prep filename
1222         *
1223         * This function preps the name of various items to make loading them more reliable.
1224         *
1225         * @param       mixed
1226         * @param       string
1227         * @return      array
1228         */
1229        protected function _ci_prep_filename($filename, $extension)
1230        {
1231                if ( ! is_array($filename))
1232                {
1233                        return array(strtolower(str_replace('.php', '', str_replace($extension, '', $filename)).$extension));
1234                }
1235                else
1236                {
1237                        foreach ($filename as $key => $val)
1238                        {
1239                                $filename[$key] = strtolower(str_replace('.php', '', str_replace($extension, '', $val)).$extension);
1240                        }
1241
1242                        return $filename;
1243                }
1244        }
1245}
1246
1247/* End of file Loader.php */
1248/* Location: ./system/core/Loader.php */
Note: See TracBrowser for help on using the repository browser.