PageRenderTime 60ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/system/core/Loader.php

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