PageRenderTime 54ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/system/core/Loader.php

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