PageRenderTime 52ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/system/core/Loader.php

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