PageRenderTime 47ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 1ms

/system/core/Loader.php

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