PageRenderTime 46ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/system/core/Loader.php

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