Loader.php

Go to the documentation of this file.
00001 <?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
00002 /**
00003  * CodeIgniter
00004  *
00005  * An open source application development framework for PHP 4.3.2 or newer
00006  *
00007  * @package             CodeIgniter
00008  * @author              ExpressionEngine Dev Team
00009  * @copyright   Copyright (c) 2008, EllisLab, Inc.
00010  * @license             http://codeigniter.com/user_guide/license.html
00011  * @link                http://codeigniter.com
00012  * @since               Version 1.0
00013  * @filesource
00014  */
00015 
00016 // ------------------------------------------------------------------------
00017 
00018 /**
00019  * Loader Class
00020  *
00021  * Loads views and files
00022  *
00023  * @package             CodeIgniter
00024  * @subpackage  Libraries
00025  * @author              ExpressionEngine Dev Team
00026  * @category    Loader
00027  * @link                http://codeigniter.com/user_guide/libraries/loader.html
00028  */
00029 class CI_Loader {
00030 
00031         // All these are set automatically. Don't mess with them.
00032         var $_ci_ob_level;
00033         var $_ci_view_path              = '';
00034         var $_ci_is_php5                = FALSE;
00035         var $_ci_is_instance    = FALSE; // Whether we should use $this or $CI =& get_instance()
00036         var $_ci_cached_vars    = array();
00037         var $_ci_classes                = array();
00038         var $_ci_loaded_files   = array();
00039         var $_ci_models                 = array();
00040         var $_ci_helpers                = array();
00041         var $_ci_plugins                = array();
00042         var $_ci_varmap                 = array('unit_test' => 'unit', 'user_agent' => 'agent');
00043         
00044 
00045         /**
00046          * Constructor
00047          *
00048          * Sets the path to the view files and gets the initial output buffering level
00049          *
00050          * @access      public
00051          */
00052         function CI_Loader()
00053         {       
00054                 $this->_ci_is_php5 = (floor(phpversion()) >= 5) ? TRUE : FALSE;
00055                 $this->_ci_view_path = APPPATH.'views/';
00056                 $this->_ci_ob_level  = ob_get_level();
00057                                 
00058                 log_message('debug', "Loader Class Initialized");
00059         }
00060         
00061         // --------------------------------------------------------------------
00062         
00063         /**
00064          * Class Loader
00065          *
00066          * This function lets users load and instantiate classes.
00067          * It is designed to be called from a user's app controllers.
00068          *
00069          * @access      public
00070          * @param       string  the name of the class
00071          * @param       mixed   the optional parameters
00072          * @param       string  an optional object name
00073          * @return      void
00074          */     
00075         function library($library = '', $params = NULL, $object_name = NULL)
00076         {
00077                 if ($library == '')
00078                 {
00079                         return FALSE;
00080                 }
00081 
00082                 if ( ! is_null($params) AND ! is_array($params))
00083                 {
00084                         $params = NULL;
00085                 }
00086 
00087                 if (is_array($library))
00088                 {
00089                         foreach ($library as $class)
00090                         {
00091                                 $this->_ci_load_class($class, $params, $object_name);
00092                         }
00093                 }
00094                 else
00095                 {
00096                         $this->_ci_load_class($library, $params, $object_name);
00097                 }
00098                 
00099                 $this->_ci_assign_to_models();
00100         }
00101 
00102         // --------------------------------------------------------------------
00103         
00104         /**
00105          * Model Loader
00106          *
00107          * This function lets users load and instantiate models.
00108          *
00109          * @access      public
00110          * @param       string  the name of the class
00111          * @param       string  name for the model
00112          * @param       bool    database connection
00113          * @return      void
00114          */     
00115         function model($model, $name = '', $db_conn = FALSE)
00116         {               
00117                 if (is_array($model))
00118                 {
00119                         foreach($model as $babe)
00120                         {
00121                                 $this->model($babe);    
00122                         }
00123                         return;
00124                 }
00125 
00126                 if ($model == '')
00127                 {
00128                         return;
00129                 }
00130         
00131                 // Is the model in a sub-folder? If so, parse out the filename and path.
00132                 if (strpos($model, '/') === FALSE)
00133                 {
00134                         $path = '';
00135                 }
00136                 else
00137                 {
00138                         $x = explode('/', $model);
00139                         $model = end($x);                       
00140                         unset($x[count($x)-1]);
00141                         $path = implode('/', $x).'/';
00142                 }
00143         
00144                 if ($name == '')
00145                 {
00146                         $name = $model;
00147                 }
00148                 
00149                 if (in_array($name, $this->_ci_models, TRUE))
00150                 {
00151                         return;
00152                 }
00153                 
00154                 $CI =& get_instance();
00155                 if (isset($CI->$name))
00156                 {
00157                         show_error('The model name you are loading is the name of a resource that is already being used: '.$name);
00158                 }
00159         
00160                 $model = strtolower($model);
00161                 
00162                 if ( ! file_exists(APPPATH.'models/'.$path.$model.EXT))
00163                 {
00164                         show_error('Unable to locate the model you have specified: '.$model);
00165                 }
00166                                 
00167                 if ($db_conn !== FALSE AND ! class_exists('CI_DB'))
00168                 {
00169                         if ($db_conn === TRUE)
00170                                 $db_conn = '';
00171                 
00172                         $CI->load->database($db_conn, FALSE, TRUE);
00173                 }
00174         
00175                 if ( ! class_exists('Model'))
00176                 {
00177                         load_class('Model', FALSE);
00178                 }
00179 
00180                 require_once(APPPATH.'models/'.$path.$model.EXT);
00181 
00182                 $model = ucfirst($model);
00183                                 
00184                 $CI->$name = new $model();
00185                 $CI->$name->_assign_libraries();
00186                 
00187                 $this->_ci_models[] = $name;    
00188         }
00189                 
00190         // --------------------------------------------------------------------
00191         
00192         /**
00193          * Database Loader
00194          *
00195          * @access      public
00196          * @param       string  the DB credentials
00197          * @param       bool    whether to return the DB object
00198          * @param       bool    whether to enable active record (this allows us to override the config setting)
00199          * @return      object
00200          */     
00201         function database($params = '', $return = FALSE, $active_record = FALSE)
00202         {
00203                 // Grab the super object
00204                 $CI =& get_instance();
00205                 
00206                 // Do we even need to load the database class?
00207                 if (class_exists('CI_DB') AND $return == FALSE AND $active_record == FALSE AND isset($CI->db) AND is_object($CI->db))
00208                 {
00209                         return FALSE;
00210                 }       
00211         
00212                 require_once(BASEPATH.'database/DB'.EXT);
00213 
00214                 if ($return === TRUE)
00215                 {
00216                         return DB($params, $active_record);
00217                 }
00218                 
00219                 // Initialize the db variable.  Needed to prevent   
00220                 // reference errors with some configurations
00221                 $CI->db = '';
00222                 
00223                 // Load the DB class
00224                 $CI->db =& DB($params, $active_record); 
00225                 
00226                 // Assign the DB object to any existing models
00227                 $this->_ci_assign_to_models();
00228         }
00229         
00230         // --------------------------------------------------------------------
00231 
00232         /**
00233          * Load the Utilities Class
00234          *
00235          * @access      public
00236          * @return      string          
00237          */             
00238         function dbutil()
00239         {
00240                 if ( ! class_exists('CI_DB'))
00241                 {
00242                         $this->database();
00243                 }
00244                 
00245                 $CI =& get_instance();
00246 
00247                 // for backwards compatibility, load dbforge so we can extend dbutils off it
00248                 // this use is deprecated and strongly discouraged
00249                 $CI->load->dbforge();
00250         
00251                 require_once(BASEPATH.'database/DB_utility'.EXT);
00252                 require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_utility'.EXT);
00253                 $class = 'CI_DB_'.$CI->db->dbdriver.'_utility';
00254 
00255                 $CI->dbutil =& new $class();
00256 
00257                 $CI->load->_ci_assign_to_models();
00258         }
00259         
00260         // --------------------------------------------------------------------
00261 
00262         /**
00263          * Load the Database Forge Class
00264          *
00265          * @access      public
00266          * @return      string          
00267          */             
00268         function dbforge()
00269         {
00270                 if ( ! class_exists('CI_DB'))
00271                 {
00272                         $this->database();
00273                 }
00274                 
00275                 $CI =& get_instance();
00276         
00277                 require_once(BASEPATH.'database/DB_forge'.EXT);
00278                 require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_forge'.EXT);
00279                 $class = 'CI_DB_'.$CI->db->dbdriver.'_forge';
00280 
00281                 $CI->dbforge = new $class();
00282                 
00283                 $CI->load->_ci_assign_to_models();
00284         }
00285         
00286         // --------------------------------------------------------------------
00287         
00288         /**
00289          * Load View
00290          *
00291          * This function is used to load a "view" file.  It has three parameters:
00292          *
00293          * 1. The name of the "view" file to be included.
00294          * 2. An associative array of data to be extracted for use in the view.
00295          * 3. TRUE/FALSE - whether to return the data or load it.  In
00296          * some cases it's advantageous to be able to return data so that
00297          * a developer can process it in some way.
00298          *
00299          * @access      public
00300          * @param       string
00301          * @param       array
00302          * @param       bool
00303          * @return      void
00304          */
00305         function view($view, $vars = array(), $return = FALSE)
00306         {
00307                 return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_object_to_array($vars), '_ci_return' => $return));
00308         }
00309         
00310         // --------------------------------------------------------------------
00311         
00312         /**
00313          * Load File
00314          *
00315          * This is a generic file loader
00316          *
00317          * @access      public
00318          * @param       string
00319          * @param       bool
00320          * @return      string
00321          */
00322         function file($path, $return = FALSE)
00323         {
00324                 return $this->_ci_load(array('_ci_path' => $path, '_ci_return' => $return));
00325         }
00326         
00327         // --------------------------------------------------------------------
00328         
00329         /**
00330          * Set Variables
00331          *
00332          * Once variables are set they become available within
00333          * the controller class and its "view" files.
00334          *
00335          * @access      public
00336          * @param       array
00337          * @return      void
00338          */
00339         function vars($vars = array(), $val = '')
00340         {
00341                 if ($val != '' AND is_string($vars))
00342                 {
00343                         $vars = array($vars => $val);
00344                 }
00345         
00346                 $vars = $this->_ci_object_to_array($vars);
00347         
00348                 if (is_array($vars) AND count($vars) > 0)
00349                 {
00350                         foreach ($vars as $key => $val)
00351                         {
00352                                 $this->_ci_cached_vars[$key] = $val;
00353                         }
00354                 }
00355         }
00356         
00357         // --------------------------------------------------------------------
00358         
00359         /**
00360          * Load Helper
00361          *
00362          * This function loads the specified helper file.
00363          *
00364          * @access      public
00365          * @param       mixed
00366          * @return      void
00367          */
00368         function helper($helpers = array())
00369         {
00370                 if ( ! is_array($helpers))
00371                 {
00372                         $helpers = array($helpers);
00373                 }
00374         
00375                 foreach ($helpers as $helper)
00376                 {               
00377                         $helper = strtolower(str_replace(EXT, '', str_replace('_helper', '', $helper)).'_helper');
00378 
00379                         if (isset($this->_ci_helpers[$helper]))
00380                         {
00381                                 continue;
00382                         }
00383                         
00384                         $ext_helper = APPPATH.'helpers/'.config_item('subclass_prefix').$helper.EXT;
00385 
00386                         // Is this a helper extension request?                  
00387                         if (file_exists($ext_helper))
00388                         {
00389                                 $base_helper = BASEPATH.'helpers/'.$helper.EXT;
00390                                 
00391                                 if ( ! file_exists($base_helper))
00392                                 {
00393                                         show_error('Unable to load the requested file: helpers/'.$helper.EXT);
00394                                 }
00395                                 
00396                                 include_once($ext_helper);
00397                                 include_once($base_helper);
00398                         }
00399                         elseif (file_exists(APPPATH.'helpers/'.$helper.EXT))
00400                         { 
00401                                 include_once(APPPATH.'helpers/'.$helper.EXT);
00402                         }
00403                         else
00404                         {               
00405                                 if (file_exists(BASEPATH.'helpers/'.$helper.EXT))
00406                                 {
00407                                         include_once(BASEPATH.'helpers/'.$helper.EXT);
00408                                 }
00409                                 else
00410                                 {
00411                                         show_error('Unable to load the requested file: helpers/'.$helper.EXT);
00412                                 }
00413                         }
00414 
00415                         $this->_ci_helpers[$helper] = TRUE;
00416                         log_message('debug', 'Helper loaded: '.$helper);        
00417                 }               
00418         }
00419         
00420         // --------------------------------------------------------------------
00421         
00422         /**
00423          * Load Helpers
00424          *
00425          * This is simply an alias to the above function in case the
00426          * user has written the plural form of this function.
00427          *
00428          * @access      public
00429          * @param       array
00430          * @return      void
00431          */
00432         function helpers($helpers = array())
00433         {
00434                 $this->helper($helpers);
00435         }
00436         
00437         // --------------------------------------------------------------------
00438         
00439         /**
00440          * Load Plugin
00441          *
00442          * This function loads the specified plugin.
00443          *
00444          * @access      public
00445          * @param       array
00446          * @return      void
00447          */
00448         function plugin($plugins = array())
00449         {
00450                 if ( ! is_array($plugins))
00451                 {
00452                         $plugins = array($plugins);
00453                 }
00454         
00455                 foreach ($plugins as $plugin)
00456                 {       
00457                         $plugin = strtolower(str_replace(EXT, '', str_replace('_pi', '', $plugin)).'_pi');              
00458 
00459                         if (isset($this->_ci_plugins[$plugin]))
00460                         {
00461                                 continue;
00462                         }
00463 
00464                         if (file_exists(APPPATH.'plugins/'.$plugin.EXT))
00465                         {
00466                                 include_once(APPPATH.'plugins/'.$plugin.EXT);   
00467                         }
00468                         else
00469                         {
00470                                 if (file_exists(BASEPATH.'plugins/'.$plugin.EXT))
00471                                 {
00472                                         include_once(BASEPATH.'plugins/'.$plugin.EXT);  
00473                                 }
00474                                 else
00475                                 {
00476                                         show_error('Unable to load the requested file: plugins/'.$plugin.EXT);
00477                                 }
00478                         }
00479                         
00480                         $this->_ci_plugins[$plugin] = TRUE;
00481                         log_message('debug', 'Plugin loaded: '.$plugin);
00482                 }               
00483         }
00484 
00485         // --------------------------------------------------------------------
00486         
00487         /**
00488          * Load Plugins
00489          *
00490          * This is simply an alias to the above function in case the
00491          * user has written the plural form of this function.
00492          *
00493          * @access      public
00494          * @param       array
00495          * @return      void
00496          */
00497         function plugins($plugins = array())
00498         {
00499                 $this->plugin($plugins);
00500         }
00501                 
00502         // --------------------------------------------------------------------
00503         
00504         /**
00505          * Loads a language file
00506          *
00507          * @access      public
00508          * @param       array
00509          * @param       string
00510          * @return      void
00511          */
00512         function language($file = array(), $lang = '')
00513         {
00514                 $CI =& get_instance();
00515 
00516                 if ( ! is_array($file))
00517                 {
00518                         $file = array($file);
00519                 }
00520 
00521                 foreach ($file as $langfile)
00522                 {       
00523                         $CI->lang->load($langfile, $lang);
00524                 }
00525         }
00526 
00527         /**
00528          * Loads language files for scaffolding
00529          *
00530          * @access      public
00531          * @param       string
00532          * @return      arra
00533          */
00534         function scaffold_language($file = '', $lang = '', $return = FALSE)
00535         {
00536                 $CI =& get_instance();
00537                 return $CI->lang->load($file, $lang, $return);
00538         }
00539         
00540         // --------------------------------------------------------------------
00541         
00542         /**
00543          * Loads a config file
00544          *
00545          * @access      public
00546          * @param       string
00547          * @return      void
00548          */
00549         function config($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)
00550         {                       
00551                 $CI =& get_instance();
00552                 $CI->config->load($file, $use_sections, $fail_gracefully);
00553         }
00554 
00555         // --------------------------------------------------------------------
00556         
00557         /**
00558          * Scaffolding Loader
00559          *
00560          * This initializing function works a bit different than the
00561          * others. It doesn't load the class.  Instead, it simply
00562          * sets a flag indicating that scaffolding is allowed to be
00563          * used.  The actual scaffolding function below is
00564          * called by the front controller based on whether the
00565          * second segment of the URL matches the "secret" scaffolding
00566          * word stored in the application/config/routes.php
00567          *
00568          * @access      public
00569          * @param       string
00570          * @return      void
00571          */     
00572         function scaffolding($table = '')
00573         {               
00574                 if ($table === FALSE)
00575                 {
00576                         show_error('You must include the name of the table you would like to access when you initialize scaffolding');
00577                 }
00578                 
00579                 $CI =& get_instance();
00580                 $CI->_ci_scaffolding = TRUE;
00581                 $CI->_ci_scaff_table = $table;
00582         }
00583 
00584         // --------------------------------------------------------------------
00585                 
00586         /**
00587          * Loader
00588          *
00589          * This function is used to load views and files.
00590          * Variables are prefixed with _ci_ to avoid symbol collision with
00591          * variables made available to view files
00592          *
00593          * @access      private
00594          * @param       array
00595          * @return      void
00596          */
00597         function _ci_load($_ci_data)
00598         {
00599                 // Set the default data variables
00600                 foreach (array('_ci_view', '_ci_vars', '_ci_path', '_ci_return') as $_ci_val)
00601                 {
00602                         $$_ci_val = ( ! isset($_ci_data[$_ci_val])) ? FALSE : $_ci_data[$_ci_val];
00603                 }
00604 
00605                 // Set the path to the requested file
00606                 if ($_ci_path == '')
00607                 {
00608                         $_ci_ext = pathinfo($_ci_view, PATHINFO_EXTENSION);
00609                         $_ci_file = ($_ci_ext == '') ? $_ci_view.EXT : $_ci_view;
00610                         $_ci_path = $this->_ci_view_path.$_ci_file;
00611                 }
00612                 else
00613                 {
00614                         $_ci_x = explode('/', $_ci_path);
00615                         $_ci_file = end($_ci_x);
00616                 }
00617                 
00618                 if ( ! file_exists($_ci_path))
00619                 {
00620                         show_error('Unable to load the requested file: '.$_ci_file);
00621                 }
00622         
00623                 // This allows anything loaded using $this->load (views, files, etc.)
00624                 // to become accessible from within the Controller and Model functions.
00625                 // Only needed when running PHP 5
00626                 
00627                 if ($this->_ci_is_instance())
00628                 {
00629                         $_ci_CI =& get_instance();
00630                         foreach (get_object_vars($_ci_CI) as $_ci_key => $_ci_var)
00631                         {
00632                                 if ( ! isset($this->$_ci_key))
00633                                 {
00634                                         $this->$_ci_key =& $_ci_CI->$_ci_key;
00635                                 }
00636                         }
00637                 }
00638 
00639                 /*
00640                  * Extract and cache variables
00641                  *
00642                  * You can either set variables using the dedicated $this->load_vars()
00643                  * function or via the second parameter of this function. We'll merge
00644                  * the two types and cache them so that views that are embedded within
00645                  * other views can have access to these variables.
00646                  */     
00647                 if (is_array($_ci_vars))
00648                 {
00649                         $this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars);
00650                 }
00651                 extract($this->_ci_cached_vars);
00652                                 
00653                 /*
00654                  * Buffer the output
00655                  *
00656                  * We buffer the output for two reasons:
00657                  * 1. Speed. You get a significant speed boost.
00658                  * 2. So that the final rendered template can be
00659                  * post-processed by the output class.  Why do we
00660                  * need post processing?  For one thing, in order to
00661                  * show the elapsed page load time.  Unless we
00662                  * can intercept the content right before it's sent to
00663                  * the browser and then stop the timer it won't be accurate.
00664                  */
00665                 ob_start();
00666                                 
00667                 // If the PHP installation does not support short tags we'll
00668                 // do a little string replacement, changing the short tags
00669                 // to standard PHP echo statements.
00670                 
00671                 if ((bool) @ini_get('short_open_tag') === FALSE AND config_item('rewrite_short_tags') == TRUE)
00672                 {
00673                         echo eval('?>'.preg_replace("/;*\s*\?>/", "; ?>", str_replace('<?=', '<?php echo ', file_get_contents($_ci_path))));
00674                 }
00675                 else
00676                 {
00677                         include($_ci_path); // include() vs include_once() allows for multiple views with the same name
00678                 }
00679                 
00680                 log_message('debug', 'File loaded: '.$_ci_path);
00681                 
00682                 // Return the file data if requested
00683                 if ($_ci_return === TRUE)
00684                 {               
00685                         $buffer = ob_get_contents();
00686                         @ob_end_clean();
00687                         return $buffer;
00688                 }
00689 
00690                 /*
00691                  * Flush the buffer... or buff the flusher?
00692                  *
00693                  * In order to permit views to be nested within
00694                  * other views, we need to flush the content back out whenever
00695                  * we are beyond the first level of output buffering so that
00696                  * it can be seen and included properly by the first included
00697                  * template and any subsequent ones. Oy!
00698                  *
00699                  */     
00700                 if (ob_get_level() > $this->_ci_ob_level + 1)
00701                 {
00702                         ob_end_flush();
00703                 }
00704                 else
00705                 {
00706                         // PHP 4 requires that we use a global
00707                         global $OUT;
00708                         $OUT->append_output(ob_get_contents());
00709                         @ob_end_clean();
00710                 }
00711         }
00712 
00713         // --------------------------------------------------------------------
00714 
00715         /**
00716          * Load class
00717          *
00718          * This function loads the requested class.
00719          *
00720          * @access      private
00721          * @param       string  the item that is being loaded
00722          * @param       mixed   any additional parameters
00723          * @param       string  an optional object name
00724          * @return      void
00725          */
00726         function _ci_load_class($class, $params = NULL, $object_name = NULL)
00727         {       
00728                 // Get the class name, and while we're at it trim any slashes.  
00729                 // The directory path can be included as part of the class name, 
00730                 // but we don't want a leading slash
00731                 $class = str_replace(EXT, '', trim($class, '/'));
00732         
00733                 // Was the path included with the class name?
00734                 // We look for a slash to determine this
00735                 $subdir = '';
00736                 if (strpos($class, '/') !== FALSE)
00737                 {
00738                         // explode the path so we can separate the filename from the path
00739                         $x = explode('/', $class);      
00740                         
00741                         // Reset the $class variable now that we know the actual filename
00742                         $class = end($x);
00743                         
00744                         // Kill the filename from the array
00745                         unset($x[count($x)-1]);
00746                         
00747                         // Glue the path back together, sans filename
00748                         $subdir = implode($x, '/').'/';
00749                 }
00750 
00751                 // We'll test for both lowercase and capitalized versions of the file name
00752                 foreach (array(ucfirst($class), strtolower($class)) as $class)
00753                 {
00754                         $subclass = APPPATH.'libraries/'.$subdir.config_item('subclass_prefix').$class.EXT;
00755 
00756                         // Is this a class extension request?                   
00757                         if (file_exists($subclass))
00758                         {
00759                                 $baseclass = BASEPATH.'libraries/'.ucfirst($class).EXT;
00760                                 
00761                                 if ( ! file_exists($baseclass))
00762                                 {
00763                                         log_message('error', "Unable to load the requested class: ".$class);
00764                                         show_error("Unable to load the requested class: ".$class);
00765                                 }
00766 
00767                                 // Safety:  Was the class already loaded by a previous call?
00768                                 if (in_array($subclass, $this->_ci_loaded_files))
00769                                 {
00770                                         // Before we deem this to be a duplicate request, let's see
00771                                         // if a custom object name is being supplied.  If so, we'll
00772                                         // return a new instance of the object
00773                                         if ( ! is_null($object_name))
00774                                         {
00775                                                 $CI =& get_instance();
00776                                                 if ( ! isset($CI->$object_name))
00777                                                 {
00778                                                         return $this->_ci_init_class($class, config_item('subclass_prefix'), $params, $object_name);                    
00779                                                 }
00780                                         }
00781                                         
00782                                         $is_duplicate = TRUE;
00783                                         log_message('debug', $class." class already loaded. Second attempt ignored.");
00784                                         return;
00785                                 }
00786         
00787                                 include_once($baseclass);                               
00788                                 include_once($subclass);
00789                                 $this->_ci_loaded_files[] = $subclass;
00790         
00791                                 return $this->_ci_init_class($class, config_item('subclass_prefix'), $params, $object_name);                    
00792                         }
00793                 
00794                         // Lets search for the requested library file and load it.
00795                         $is_duplicate = FALSE;          
00796                         for ($i = 1; $i < 3; $i++)
00797                         {
00798                                 $path = ($i % 2) ? APPPATH : BASEPATH;  
00799                                 $filepath = $path.'libraries/'.$subdir.$class.EXT;
00800                                 
00801                                 // Does the file exist?  No?  Bummer...
00802                                 if ( ! file_exists($filepath))
00803                                 {
00804                                         continue;
00805                                 }
00806                                 
00807                                 // Safety:  Was the class already loaded by a previous call?
00808                                 if (in_array($filepath, $this->_ci_loaded_files))
00809                                 {
00810                                         // Before we deem this to be a duplicate request, let's see
00811                                         // if a custom object name is being supplied.  If so, we'll
00812                                         // return a new instance of the object
00813                                         if ( ! is_null($object_name))
00814                                         {
00815                                                 $CI =& get_instance();
00816                                                 if ( ! isset($CI->$object_name))
00817                                                 {
00818                                                         return $this->_ci_init_class($class, '', $params, $object_name);
00819                                                 }
00820                                         }
00821                                 
00822                                         $is_duplicate = TRUE;
00823                                         log_message('debug', $class." class already loaded. Second attempt ignored.");
00824                                         return;
00825                                 }
00826                                 
00827                                 include_once($filepath);
00828                                 $this->_ci_loaded_files[] = $filepath;
00829                                 return $this->_ci_init_class($class, '', $params, $object_name);
00830                         }
00831                 } // END FOREACH
00832 
00833                 // One last attempt.  Maybe the library is in a subdirectory, but it wasn't specified?
00834                 if ($subdir == '')
00835                 {
00836                         $path = strtolower($class).'/'.$class;
00837                         return $this->_ci_load_class($path, $params);
00838                 }
00839                 
00840                 // If we got this far we were unable to find the requested class.
00841                 // We do not issue errors if the load call failed due to a duplicate request
00842                 if ($is_duplicate == FALSE)
00843                 {
00844                         log_message('error', "Unable to load the requested class: ".$class);
00845                         show_error("Unable to load the requested class: ".$class);
00846                 }
00847         }
00848         
00849         // --------------------------------------------------------------------
00850 
00851         /**
00852          * Instantiates a class
00853          *
00854          * @access      private
00855          * @param       string
00856          * @param       string
00857          * @param       string  an optional object name
00858          * @return      null
00859          */
00860         function _ci_init_class($class, $prefix = '', $config = FALSE, $object_name = NULL)
00861         {       
00862                 // Is there an associated config file for this class?
00863                 if ($config === NULL)
00864                 {
00865                         // We test for both uppercase and lowercase, for servers that
00866                         // are case-sensitive with regard to file names
00867                         if (file_exists(APPPATH.'config/'.strtolower($class).EXT))
00868                         {
00869                                 include_once(APPPATH.'config/'.strtolower($class).EXT);
00870                         }                       
00871                         else
00872                         {
00873                                 if (file_exists(APPPATH.'config/'.ucfirst(strtolower($class)).EXT))
00874                                 {
00875                                         include_once(APPPATH.'config/'.ucfirst(strtolower($class)).EXT);
00876                                 }                       
00877                         }
00878                 }
00879                 
00880                 if ($prefix == '')
00881                 {                       
00882                         if (class_exists('CI_'.$class)) 
00883                         {
00884                                 $name = 'CI_'.$class;
00885                         }
00886                         elseif (class_exists(config_item('subclass_prefix').$class)) 
00887                         {
00888                                 $name = config_item('subclass_prefix').$class;
00889                         }
00890                         else
00891                         {
00892                                 $name = $class;
00893                         }
00894                 }
00895                 else
00896                 {
00897                         $name = $prefix.$class;
00898                 }
00899                 
00900                 // Is the class name valid?
00901                 if ( ! class_exists($name))
00902                 {
00903                         log_message('error', "Non-existent class: ".$name);
00904                         show_error("Non-existent class: ".$class);
00905                 }
00906                 
00907                 // Set the variable name we will assign the class to
00908                 // Was a custom class name supplied?  If so we'll use it
00909                 $class = strtolower($class);
00910                 
00911                 if (is_null($object_name))
00912                 {
00913                         $classvar = ( ! isset($this->_ci_varmap[$class])) ? $class : $this->_ci_varmap[$class];
00914                 }
00915                 else
00916                 {
00917                         $classvar = $object_name;
00918                 }
00919 
00920                 // Save the class name and object name          
00921                 $this->_ci_classes[$class] = $classvar;
00922 
00923                 // Instantiate the class                
00924                 $CI =& get_instance();
00925                 if ($config !== NULL)
00926                 {
00927                         $CI->$classvar = new $name($config);
00928                 }
00929                 else
00930                 {               
00931                         $CI->$classvar = new $name;
00932                 }       
00933         }       
00934         
00935         // --------------------------------------------------------------------
00936         
00937         /**
00938          * Autoloader
00939          *
00940          * The config/autoload.php file contains an array that permits sub-systems,
00941          * libraries, plugins, and helpers to be loaded automatically.
00942          *
00943          * @access      private
00944          * @param       array
00945          * @return      void
00946          */
00947         function _ci_autoloader()
00948         {       
00949                 include_once(APPPATH.'config/autoload'.EXT);
00950                 
00951                 if ( ! isset($autoload))
00952                 {
00953                         return FALSE;
00954                 }
00955                 
00956                 // Load any custom config file
00957                 if (count($autoload['config']) > 0)
00958                 {                       
00959                         $CI =& get_instance();
00960                         foreach ($autoload['config'] as $key => $val)
00961                         {
00962                                 $CI->config->load($val);
00963                         }
00964                 }               
00965 
00966                 // Autoload plugins, helpers and languages
00967                 foreach (array('helper', 'plugin', 'language') as $type)
00968                 {                       
00969                         if (isset($autoload[$type]) AND count($autoload[$type]) > 0)
00970                         {
00971                                 $this->$type($autoload[$type]);
00972                         }               
00973                 }
00974 
00975                 // A little tweak to remain backward compatible
00976                 // The $autoload['core'] item was deprecated
00977                 if ( ! isset($autoload['libraries']))
00978                 {
00979                         $autoload['libraries'] = $autoload['core'];
00980                 }
00981                 
00982                 // Load libraries
00983                 if (isset($autoload['libraries']) AND count($autoload['libraries']) > 0)
00984                 {
00985                         // Load the database driver.
00986                         if (in_array('database', $autoload['libraries']))
00987                         {
00988                                 $this->database();
00989                                 $autoload['libraries'] = array_diff($autoload['libraries'], array('database'));
00990                         }
00991 
00992                         // Load scaffolding
00993                         if (in_array('scaffolding', $autoload['libraries']))
00994                         {
00995                                 $this->scaffolding();
00996                                 $autoload['libraries'] = array_diff($autoload['libraries'], array('scaffolding'));
00997                         }
00998                 
00999                         // Load all other libraries
01000                         foreach ($autoload['libraries'] as $item)
01001                         {
01002                                 $this->library($item);
01003                         }
01004                 }               
01005 
01006                 // Autoload models
01007                 if (isset($autoload['model']))
01008                 {
01009                         $this->model($autoload['model']);
01010                 }
01011 
01012         }
01013         
01014         // --------------------------------------------------------------------
01015 
01016         /**
01017          * Assign to Models
01018          *
01019          * Makes sure that anything loaded by the loader class (libraries, plugins, etc.)
01020          * will be available to models, if any exist.
01021          *
01022          * @access      private
01023          * @param       object
01024          * @return      array
01025          */
01026         function _ci_assign_to_models()
01027         {
01028                 if (count($this->_ci_models) == 0)
01029                 {
01030                         return;
01031                 }
01032         
01033                 if ($this->_ci_is_instance())
01034                 {
01035                         $CI =& get_instance();
01036                         foreach ($this->_ci_models as $model)
01037                         {                       
01038                                 $CI->$model->_assign_libraries();
01039                         }
01040                 }
01041                 else
01042                 {               
01043                         foreach ($this->_ci_models as $model)
01044                         {                       
01045                                 $this->$model->_assign_libraries();
01046                         }
01047                 }
01048         }       
01049 
01050         // --------------------------------------------------------------------
01051 
01052         /**
01053          * Object to Array
01054          *
01055          * Takes an object as input and converts the class variables to array key/vals
01056          *
01057          * @access      private
01058          * @param       object
01059          * @return      array
01060          */
01061         function _ci_object_to_array($object)
01062         {
01063                 return (is_object($object)) ? get_object_vars($object) : $object;
01064         }
01065 
01066         // --------------------------------------------------------------------
01067 
01068         /**
01069          * Determines whether we should use the CI instance or $this
01070          *
01071          * @access      private
01072          * @return      bool
01073          */
01074         function _ci_is_instance()
01075         {
01076                 if ($this->_ci_is_php5 == TRUE)
01077                 {
01078                         return TRUE;
01079                 }
01080         
01081                 global $CI;
01082                 return (is_object($CI)) ? TRUE : FALSE;
01083         }
01084 
01085 }
01086 
01087 /* End of file Loader.php */
01088 /* Location: ./system/libraries/Loader.php */