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

/core/libraries/codeigniter/core/Loader.php

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