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