PageRenderTime 151ms CodeModel.GetById 61ms app.highlight 47ms RepoModel.GetById 33ms app.codeStats 1ms

/system/core/Loader.php

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