GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

CI_Loader::add_package_path()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 9
nc 1
nop 2
dl 0
loc 16
rs 9.4285
c 0
b 0
f 0
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 51 and the first side effect is on line 38.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/**
3
 * CodeIgniter
4
 *
5
 * An open source application development framework for PHP
6
 *
7
 * This content is released under the MIT License (MIT)
8
 *
9
 * Copyright (c) 2014 - 2015, British Columbia Institute of Technology
10
 *
11
 * Permission is hereby granted, free of charge, to any person obtaining a copy
12
 * of this software and associated documentation files (the "Software"), to deal
13
 * in the Software without restriction, including without limitation the rights
14
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
 * copies of the Software, and to permit persons to whom the Software is
16
 * furnished to do so, subject to the following conditions:
17
 *
18
 * The above copyright notice and this permission notice shall be included in
19
 * all copies or substantial portions of the Software.
20
 *
21
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27
 * THE SOFTWARE.
28
 *
29
 * @package	CodeIgniter
30
 * @author	EllisLab Dev Team
31
 * @copyright	Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
32
 * @copyright	Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
33
 * @license	http://opensource.org/licenses/MIT	MIT License
34
 * @link	http://codeigniter.com
35
 * @since	Version 1.0.0
36
 * @filesource
37
 */
38
defined('BASEPATH') OR exit('No direct script access allowed');
39
40
/**
41
 * Loader Class
42
 *
43
 * Loads framework components.
44
 *
45
 * @package		CodeIgniter
46
 * @subpackage	Libraries
47
 * @category	Loader
48
 * @author		EllisLab Dev Team
49
 * @link		http://codeigniter.com/user_guide/libraries/loader.html
50
 */
51
class CI_Loader {
52
53
	// All these are set automatically. Don't mess with them.
54
	/**
55
	 * Nesting level of the output buffering mechanism
56
	 *
57
	 * @var	int
58
	 */
59
	protected $_ci_ob_level;
60
61
	/**
62
	 * List of paths to load views from
63
	 *
64
	 * @var	array
65
	 */
66
	protected $_ci_view_paths =	array(VIEWPATH	=> TRUE);
67
68
	/**
69
	 * List of paths to load libraries from
70
	 *
71
	 * @var	array
72
	 */
73
	protected $_ci_library_paths =	array(APPPATH, BASEPATH);
74
75
	/**
76
	 * List of paths to load models from
77
	 *
78
	 * @var	array
79
	 */
80
	protected $_ci_model_paths =	array(APPPATH);
81
82
	/**
83
	 * List of paths to load helpers from
84
	 *
85
	 * @var	array
86
	 */
87
	protected $_ci_helper_paths =	array(APPPATH, BASEPATH);
88
89
	/**
90
	 * List of cached variables
91
	 *
92
	 * @var	array
93
	 */
94
	protected $_ci_cached_vars =	array();
95
96
	/**
97
	 * List of loaded classes
98
	 *
99
	 * @var	array
100
	 */
101
	protected $_ci_classes =	array();
102
103
	/**
104
	 * List of loaded models
105
	 *
106
	 * @var	array
107
	 */
108
	protected $_ci_models =	array();
109
110
	/**
111
	 * List of loaded helpers
112
	 *
113
	 * @var	array
114
	 */
115
	protected $_ci_helpers =	array();
116
117
	/**
118
	 * List of class name mappings
119
	 *
120
	 * @var	array
121
	 */
122
	protected $_ci_varmap =	array(
123
		'unit_test' => 'unit',
124
		'user_agent' => 'agent'
125
	);
126
127
	// --------------------------------------------------------------------
128
129
	/**
130
	 * Class constructor
131
	 *
132
	 * Sets component load paths, gets the initial output buffering level.
133
	 *
134
	 * @return	void
135
	 */
136
	public function __construct()
137
	{
138
		$this->_ci_ob_level = ob_get_level();
139
		$this->_ci_classes =& is_loaded();
140
141
		log_message('info', 'Loader Class Initialized');
142
	}
143
144
	// --------------------------------------------------------------------
145
146
	/**
147
	 * Initializer
148
	 *
149
	 * @todo	Figure out a way to move this to the constructor
150
	 *		without breaking *package_path*() methods.
151
	 * @uses	CI_Loader::_ci_autoloader()
152
	 * @used-by	CI_Controller::__construct()
153
	 * @return	void
154
	 */
155
	public function initialize()
156
	{
157
		$this->_ci_autoloader();
158
	}
159
160
	// --------------------------------------------------------------------
161
162
	/**
163
	 * Is Loaded
164
	 *
165
	 * A utility method to test if a class is in the self::$_ci_classes array.
166
	 *
167
	 * @used-by	Mainly used by Form Helper function _get_validation_object().
168
	 *
169
	 * @param 	string		$class	Class name to check for
170
	 * @return 	string|bool	Class object name if loaded or FALSE
171
	 */
172
	public function is_loaded($class)
173
	{
174
		return array_search(ucfirst($class), $this->_ci_classes, TRUE);
175
	}
176
177
	// --------------------------------------------------------------------
178
179
	/**
180
	 * Library Loader
181
	 *
182
	 * Loads and instantiates libraries.
183
	 * Designed to be called from application controllers.
184
	 *
185
	 * @param	string	$library	Library name
186
	 * @param	array	$params		Optional parameters to pass to the library class constructor
187
	 * @param	string	$object_name	An optional object name to assign to
188
	 * @return	object
189
	 */
190
	public function library($library, $params = NULL, $object_name = NULL)
191
	{
192 View Code Duplication
		if (empty($library))
193
		{
194
			return $this;
195
		}
196
		elseif (is_array($library))
197
		{
198
			foreach ($library as $key => $value)
199
			{
200
				if (is_int($key))
201
				{
202
					$this->library($value, $params);
203
				}
204
				else
205
				{
206
					$this->library($key, $params, $value);
207
				}
208
			}
209
210
			return $this;
211
		}
212
213
		if ($params !== NULL && ! is_array($params))
214
		{
215
			$params = NULL;
216
		}
217
218
		$this->_ci_load_library($library, $params, $object_name);
219
		return $this;
220
	}
221
222
	// --------------------------------------------------------------------
223
224
	/**
225
	 * Model Loader
226
	 *
227
	 * Loads and instantiates models.
228
	 *
229
	 * @param	string	$model		Model name
230
	 * @param	string	$name		An optional object name to assign to
231
	 * @param	bool	$db_conn	An optional database connection configuration to initialize
232
	 * @return	object
233
	 */
234
	public function model($model, $name = '', $db_conn = FALSE)
235
	{
236 View Code Duplication
		if (empty($model))
237
		{
238
			return $this;
239
		}
240
		elseif (is_array($model))
241
		{
242
			foreach ($model as $key => $value)
243
			{
244
				is_int($key) ? $this->model($value, '', $db_conn) : $this->model($key, $value, $db_conn);
245
			}
246
247
			return $this;
248
		}
249
250
		$path = '';
251
252
		// Is the model in a sub-folder? If so, parse out the filename and path.
253 View Code Duplication
		if (($last_slash = strrpos($model, '/')) !== FALSE)
254
		{
255
			// The path is in front of the last slash
256
			$path = substr($model, 0, ++$last_slash);
257
258
			// And the model name behind it
259
			$model = substr($model, $last_slash);
260
		}
261
262
		if (empty($name))
263
		{
264
			$name = $model;
265
		}
266
267
		if (in_array($name, $this->_ci_models, TRUE))
268
		{
269
			return $this;
270
		}
271
272
		$CI =& get_instance();
273
		if (isset($CI->$name))
274
		{
275
			throw new RuntimeException('The model name you are loading is the name of a resource that is already being used: '.$name);
276
		}
277
278
		if ($db_conn !== FALSE && ! class_exists('CI_DB', FALSE))
279
		{
280
			if ($db_conn === TRUE)
281
			{
282
				$db_conn = '';
283
			}
284
285
			$this->database($db_conn, FALSE, TRUE);
286
		}
287
288
		// Note: All of the code under this condition used to be just:
289
		//
290
		//       load_class('Model', 'core');
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
291
		//
292
		//       However, load_class() instantiates classes
293
		//       to cache them for later use and that prevents
294
		//       MY_Model from being an abstract class and is
295
		//       sub-optimal otherwise anyway.
296
		if ( ! class_exists('CI_Model', FALSE))
297
		{
298
			$app_path = APPPATH.'core'.DIRECTORY_SEPARATOR;
299 View Code Duplication
			if (file_exists($app_path.'Model.php'))
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
300
			{
301
				require_once($app_path.'Model.php');
302
				if ( ! class_exists('CI_Model', FALSE))
303
				{
304
					throw new RuntimeException($app_path."Model.php exists, but doesn't declare class CI_Model");
305
				}
306
			}
307
			elseif ( ! class_exists('CI_Model', FALSE))
308
			{
309
				require_once(BASEPATH.'core'.DIRECTORY_SEPARATOR.'Model.php');
310
			}
311
312
			$class = config_item('subclass_prefix').'Model';
313
			if (file_exists($app_path.$class.'.php'))
314
			{
315
				require_once($app_path.$class.'.php');
316
				if ( ! class_exists($class, FALSE))
317
				{
318
					throw new RuntimeException($app_path.$class.".php exists, but doesn't declare class ".$class);
319
				}
320
			}
321
		}
322
323
		$model = ucfirst($model);
324
		if ( ! class_exists($model))
325
		{
326
			foreach ($this->_ci_model_paths as $mod_path)
327
			{
328
				if ( ! file_exists($mod_path.'models/'.$path.$model.'.php'))
329
				{
330
					continue;
331
				}
332
333
				require_once($mod_path.'models/'.$path.$model.'.php');
334
				if ( ! class_exists($model, FALSE))
335
				{
336
					throw new RuntimeException($mod_path."models/".$path.$model.".php exists, but doesn't declare class ".$model);
337
				}
338
339
				break;
340
			}
341
342
			if ( ! class_exists($model, FALSE))
343
			{
344
				throw new RuntimeException('Unable to locate the model you have specified: '.$model);
345
			}
346
		}
347
		elseif ( ! is_subclass_of($model, 'CI_Model'))
348
		{
349
			throw new RuntimeException("Class ".$model." already exists and doesn't extend CI_Model");
350
		}
351
352
		$this->_ci_models[] = $name;
353
		$CI->$name = new $model();
354
		return $this;
355
	}
356
357
	// --------------------------------------------------------------------
358
359
	/**
360
	 * Database Loader
361
	 *
362
	 * @param	mixed	$params		Database configuration options
363
	 * @param	bool	$return 	Whether to return the database object
364
	 * @param	bool	$query_builder	Whether to enable Query Builder
365
	 *					(overrides the configuration setting)
366
	 *
367
	 * @return	object|bool	Database object if $return is set to TRUE,
368
	 *					FALSE on failure, CI_Loader instance in any other case
369
	 */
370
	public function database($params = '', $return = FALSE, $query_builder = NULL)
371
	{
372
		// Grab the super object
373
		$CI =& get_instance();
374
375
		// Do we even need to load the database class?
376
		if ($return === FALSE && $query_builder === NULL && isset($CI->db) && is_object($CI->db) && ! empty($CI->db->conn_id))
377
		{
378
			return FALSE;
379
		}
380
381
		require_once(BASEPATH.'database/DB.php');
382
383
		if ($return === TRUE)
384
		{
385
			return DB($params, $query_builder);
386
		}
387
388
		// Initialize the db variable. Needed to prevent
389
		// reference errors with some configurations
390
		$CI->db = '';
391
392
		// Load the DB class
393
		$CI->db =& DB($params, $query_builder);
394
		return $this;
395
	}
396
397
	// --------------------------------------------------------------------
398
399
	/**
400
	 * Load the Database Utilities Class
401
	 *
402
	 * @param	object	$db	Database object
403
	 * @param	bool	$return	Whether to return the DB Utilities class object or not
404
	 * @return	object
405
	 */
406
	public function dbutil($db = NULL, $return = FALSE)
407
	{
408
		$CI =& get_instance();
409
410 View Code Duplication
		if ( ! is_object($db) OR ! ($db instanceof CI_DB))
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
411
		{
412
			class_exists('CI_DB', FALSE) OR $this->database();
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
413
			$db =& $CI->db;
414
		}
415
416
		require_once(BASEPATH.'database/DB_utility.php');
417
		require_once(BASEPATH.'database/drivers/'.$db->dbdriver.'/'.$db->dbdriver.'_utility.php');
418
		$class = 'CI_DB_'.$db->dbdriver.'_utility';
419
420
		if ($return === TRUE)
421
		{
422
			return new $class($db);
423
		}
424
425
		$CI->dbutil = new $class($db);
426
		return $this;
427
	}
428
429
	// --------------------------------------------------------------------
430
431
	/**
432
	 * Load the Database Forge Class
433
	 *
434
	 * @param	object	$db	Database object
435
	 * @param	bool	$return	Whether to return the DB Forge class object or not
436
	 * @return	object
437
	 */
438
	public function dbforge($db = NULL, $return = FALSE)
439
	{
440
		$CI =& get_instance();
441 View Code Duplication
		if ( ! is_object($db) OR ! ($db instanceof CI_DB))
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
442
		{
443
			class_exists('CI_DB', FALSE) OR $this->database();
0 ignored issues
show
Comprehensibility Best Practice introduced by
Using logical operators such as or instead of || is generally not recommended.

PHP has two types of connecting operators (logical operators, and boolean operators):

  Logical Operators Boolean Operator
AND - meaning and &&
OR - meaning or ||

The difference between these is the order in which they are executed. In most cases, you would want to use a boolean operator like &&, or ||.

Let’s take a look at a few examples:

// Logical operators have lower precedence:
$f = false or true;

// is executed like this:
($f = false) or true;


// Boolean operators have higher precedence:
$f = false || true;

// is executed like this:
$f = (false || true);

Logical Operators are used for Control-Flow

One case where you explicitly want to use logical operators is for control-flow such as this:

$x === 5
    or die('$x must be 5.');

// Instead of
if ($x !== 5) {
    die('$x must be 5.');
}

Since die introduces problems of its own, f.e. it makes our code hardly testable, and prevents any kind of more sophisticated error handling; you probably do not want to use this in real-world code. Unfortunately, logical operators cannot be combined with throw at this point:

// The following is currently a parse error.
$x === 5
    or throw new RuntimeException('$x must be 5.');

These limitations lead to logical operators rarely being of use in current PHP code.

Loading history...
444
			$db =& $CI->db;
445
		}
446
447
		require_once(BASEPATH.'database/DB_forge.php');
448
		require_once(BASEPATH.'database/drivers/'.$db->dbdriver.'/'.$db->dbdriver.'_forge.php');
449
450
		if ( ! empty($db->subdriver))
451
		{
452
			$driver_path = BASEPATH.'database/drivers/'.$db->dbdriver.'/subdrivers/'.$db->dbdriver.'_'.$db->subdriver.'_forge.php';
453
			if (file_exists($driver_path))
454
			{
455
				require_once($driver_path);
456
				$class = 'CI_DB_'.$db->dbdriver.'_'.$db->subdriver.'_forge';
457
			}
458
		}
459
		else
460
		{
461
			$class = 'CI_DB_'.$db->dbdriver.'_forge';
462
		}
463
464
		if ($return === TRUE)
465
		{
466
			return new $class($db);
467
		}
468
469
		$CI->dbforge = new $class($db);
470
		return $this;
471
	}
472
473
	// --------------------------------------------------------------------
474
475
	/**
476
	 * View Loader
477
	 *
478
	 * Loads "view" files.
479
	 *
480
	 * @param	string	$view	View name
481
	 * @param	array	$vars	An associative array of data
482
	 *				to be extracted for use in the view
483
	 * @param	bool	$return	Whether to return the view output
484
	 *				or leave it to the Output class
485
	 * @return	object|string
486
	 */
487
	public function view($view, $vars = array(), $return = FALSE)
488
	{
489
		return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_object_to_array($vars), '_ci_return' => $return));
490
	}
491
492
	// --------------------------------------------------------------------
493
494
	/**
495
	 * Generic File Loader
496
	 *
497
	 * @param	string	$path	File path
498
	 * @param	bool	$return	Whether to return the file output
499
	 * @return	object|string
500
	 */
501
	public function file($path, $return = FALSE)
502
	{
503
		return $this->_ci_load(array('_ci_path' => $path, '_ci_return' => $return));
504
	}
505
506
	// --------------------------------------------------------------------
507
508
	/**
509
	 * Set Variables
510
	 *
511
	 * Once variables are set they become available within
512
	 * the controller class and its "view" files.
513
	 *
514
	 * @param	array|object|string	$vars
515
	 *					An associative array or object containing values
516
	 *					to be set, or a value's name if string
517
	 * @param 	string	$val	Value to set, only used if $vars is a string
518
	 * @return	object
519
	 */
520
	public function vars($vars, $val = '')
521
	{
522
		if (is_string($vars))
523
		{
524
			$vars = array($vars => $val);
525
		}
526
527
		$vars = $this->_ci_object_to_array($vars);
0 ignored issues
show
Bug introduced by
It seems like $vars defined by $this->_ci_object_to_array($vars) on line 527 can also be of type array; however, CI_Loader::_ci_object_to_array() does only seem to accept object, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
528
529
		if (is_array($vars) && count($vars) > 0)
530
		{
531
			foreach ($vars as $key => $val)
532
			{
533
				$this->_ci_cached_vars[$key] = $val;
534
			}
535
		}
536
537
		return $this;
538
	}
539
540
	// --------------------------------------------------------------------
541
542
	/**
543
	 * Clear Cached Variables
544
	 *
545
	 * Clears the cached variables.
546
	 *
547
	 * @return	CI_Loader
548
	 */
549
	public function clear_vars()
550
	{
551
		$this->_ci_cached_vars = array();
552
		return $this;
553
	}
554
555
	// --------------------------------------------------------------------
556
557
	/**
558
	 * Get Variable
559
	 *
560
	 * Check if a variable is set and retrieve it.
561
	 *
562
	 * @param	string	$key	Variable name
563
	 * @return	mixed	The variable or NULL if not found
564
	 */
565
	public function get_var($key)
566
	{
567
		return isset($this->_ci_cached_vars[$key]) ? $this->_ci_cached_vars[$key] : NULL;
568
	}
569
570
	// --------------------------------------------------------------------
571
572
	/**
573
	 * Get Variables
574
	 *
575
	 * Retrieves all loaded variables.
576
	 *
577
	 * @return	array
578
	 */
579
	public function get_vars()
580
	{
581
		return $this->_ci_cached_vars;
582
	}
583
584
	// --------------------------------------------------------------------
585
586
	/**
587
	 * Helper Loader
588
	 *
589
	 * @param	string|string[]	$helpers	Helper name(s)
590
	 * @return	object
591
	 */
592
	public function helper($helpers = array())
593
	{
594
		foreach ($this->_ci_prep_filename($helpers, '_helper') as $helper)
595
		{
596
			if (isset($this->_ci_helpers[$helper]))
597
			{
598
				continue;
599
			}
600
601
			// Is this a helper extension request?
602
			$ext_helper = config_item('subclass_prefix').$helper;
603
			$ext_loaded = FALSE;
604
			foreach ($this->_ci_helper_paths as $path)
605
			{
606
				if (file_exists($path.'helpers/'.$ext_helper.'.php'))
607
				{
608
					include_once($path.'helpers/'.$ext_helper.'.php');
609
					$ext_loaded = TRUE;
610
				}
611
			}
612
613
			// If we have loaded extensions - check if the base one is here
614
			if ($ext_loaded === TRUE)
615
			{
616
				$base_helper = BASEPATH.'helpers/'.$helper.'.php';
617
				if ( ! file_exists($base_helper))
618
				{
619
					show_error('Unable to load the requested file: helpers/'.$helper.'.php');
620
				}
621
622
				include_once($base_helper);
623
				$this->_ci_helpers[$helper] = TRUE;
624
				log_message('info', 'Helper loaded: '.$helper);
625
				continue;
626
			}
627
628
			// No extensions found ... try loading regular helpers and/or overrides
629
			foreach ($this->_ci_helper_paths as $path)
630
			{
631
				if (file_exists($path.'helpers/'.$helper.'.php'))
632
				{
633
					include_once($path.'helpers/'.$helper.'.php');
634
635
					$this->_ci_helpers[$helper] = TRUE;
636
					log_message('info', 'Helper loaded: '.$helper);
637
					break;
638
				}
639
			}
640
641
			// unable to load the helper
642
			if ( ! isset($this->_ci_helpers[$helper]))
643
			{
644
				show_error('Unable to load the requested file: helpers/'.$helper.'.php');
645
			}
646
		}
647
648
		return $this;
649
	}
650
651
	// --------------------------------------------------------------------
652
653
	/**
654
	 * Load Helpers
655
	 *
656
	 * An alias for the helper() method in case the developer has
657
	 * written the plural form of it.
658
	 *
659
	 * @uses	CI_Loader::helper()
660
	 * @param	string|string[]	$helpers	Helper name(s)
661
	 * @return	object
662
	 */
663
	public function helpers($helpers = array())
664
	{
665
		return $this->helper($helpers);
666
	}
667
668
	// --------------------------------------------------------------------
669
670
	/**
671
	 * Language Loader
672
	 *
673
	 * Loads language files.
674
	 *
675
	 * @param	string|string[]	$files	List of language file names to load
676
	 * @param	string		Language name
677
	 * @return	object
678
	 */
679
	public function language($files, $lang = '')
680
	{
681
		get_instance()->lang->load($files, $lang);
682
		return $this;
683
	}
684
685
	// --------------------------------------------------------------------
686
687
	/**
688
	 * Config Loader
689
	 *
690
	 * Loads a config file (an alias for CI_Config::load()).
691
	 *
692
	 * @uses	CI_Config::load()
693
	 * @param	string	$file			Configuration file name
694
	 * @param	bool	$use_sections		Whether configuration values should be loaded into their own section
695
	 * @param	bool	$fail_gracefully	Whether to just return FALSE or display an error message
696
	 * @return	bool	TRUE if the file was loaded correctly or FALSE on failure
697
	 */
698
	public function config($file, $use_sections = FALSE, $fail_gracefully = FALSE)
699
	{
700
		return get_instance()->config->load($file, $use_sections, $fail_gracefully);
701
	}
702
703
	// --------------------------------------------------------------------
704
705
	/**
706
	 * Driver Loader
707
	 *
708
	 * Loads a driver library.
709
	 *
710
	 * @param	string|string[]	$library	Driver name(s)
711
	 * @param	array		$params		Optional parameters to pass to the driver
712
	 * @param	string		$object_name	An optional object name to assign to
713
	 *
714
	 * @return	object|bool	Object or FALSE on failure if $library is a string
715
	 *				and $object_name is set. CI_Loader instance otherwise.
716
	 */
717
	public function driver($library, $params = NULL, $object_name = NULL)
718
	{
719
		if (is_array($library))
720
		{
721
			foreach ($library as $driver)
722
			{
723
				$this->driver($driver);
724
			}
725
726
			return $this;
727
		}
728
		elseif (empty($library))
729
		{
730
			return FALSE;
731
		}
732
733
		if ( ! class_exists('CI_Driver_Library', FALSE))
734
		{
735
			// We aren't instantiating an object here, just making the base class available
736
			require BASEPATH.'libraries/Driver.php';
737
		}
738
739
		// We can save the loader some time since Drivers will *always* be in a subfolder,
740
		// and typically identically named to the library
741
		if ( ! strpos($library, '/'))
742
		{
743
			$library = ucfirst($library).'/'.$library;
744
		}
745
746
		return $this->library($library, $params, $object_name);
747
	}
748
749
	// --------------------------------------------------------------------
750
751
	/**
752
	 * Add Package Path
753
	 *
754
	 * Prepends a parent path to the library, model, helper and config
755
	 * path arrays.
756
	 *
757
	 * @see	CI_Loader::$_ci_library_paths
758
	 * @see	CI_Loader::$_ci_model_paths
759
	 * @see CI_Loader::$_ci_helper_paths
760
	 * @see CI_Config::$_config_paths
761
	 *
762
	 * @param	string	$path		Path to add
763
	 * @param 	bool	$view_cascade	(default: TRUE)
764
	 * @return	object
765
	 */
766
	public function add_package_path($path, $view_cascade = TRUE)
767
	{
768
		$path = rtrim($path, '/').'/';
769
770
		array_unshift($this->_ci_library_paths, $path);
771
		array_unshift($this->_ci_model_paths, $path);
772
		array_unshift($this->_ci_helper_paths, $path);
773
774
		$this->_ci_view_paths = array($path.'views/' => $view_cascade) + $this->_ci_view_paths;
775
776
		// Add config file path
777
		$config =& $this->_ci_get_component('config');
778
		$config->_config_paths[] = $path;
779
780
		return $this;
781
	}
782
783
	// --------------------------------------------------------------------
784
785
	/**
786
	 * Get Package Paths
787
	 *
788
	 * Return a list of all package paths.
789
	 *
790
	 * @param	bool	$include_base	Whether to include BASEPATH (default: FALSE)
791
	 * @return	array
792
	 */
793
	public function get_package_paths($include_base = FALSE)
794
	{
795
		return ($include_base === TRUE) ? $this->_ci_library_paths : $this->_ci_model_paths;
796
	}
797
798
	// --------------------------------------------------------------------
799
800
	/**
801
	 * Remove Package Path
802
	 *
803
	 * Remove a path from the library, model, helper and/or config
804
	 * path arrays if it exists. If no path is provided, the most recently
805
	 * added path will be removed removed.
806
	 *
807
	 * @param	string	$path	Path to remove
808
	 * @return	object
809
	 */
810
	public function remove_package_path($path = '')
811
	{
812
		$config =& $this->_ci_get_component('config');
813
814
		if ($path === '')
815
		{
816
			array_shift($this->_ci_library_paths);
817
			array_shift($this->_ci_model_paths);
818
			array_shift($this->_ci_helper_paths);
819
			array_shift($this->_ci_view_paths);
820
			array_pop($config->_config_paths);
821
		}
822
		else
823
		{
824
			$path = rtrim($path, '/').'/';
825
			foreach (array('_ci_library_paths', '_ci_model_paths', '_ci_helper_paths') as $var)
826
			{
827
				if (($key = array_search($path, $this->{$var})) !== FALSE)
828
				{
829
					unset($this->{$var}[$key]);
830
				}
831
			}
832
833
			if (isset($this->_ci_view_paths[$path.'views/']))
834
			{
835
				unset($this->_ci_view_paths[$path.'views/']);
836
			}
837
838
			if (($key = array_search($path, $config->_config_paths)) !== FALSE)
839
			{
840
				unset($config->_config_paths[$key]);
841
			}
842
		}
843
844
		// make sure the application default paths are still in the array
845
		$this->_ci_library_paths = array_unique(array_merge($this->_ci_library_paths, array(APPPATH, BASEPATH)));
846
		$this->_ci_helper_paths = array_unique(array_merge($this->_ci_helper_paths, array(APPPATH, BASEPATH)));
847
		$this->_ci_model_paths = array_unique(array_merge($this->_ci_model_paths, array(APPPATH)));
848
		$this->_ci_view_paths = array_merge($this->_ci_view_paths, array(APPPATH.'views/' => TRUE));
849
		$config->_config_paths = array_unique(array_merge($config->_config_paths, array(APPPATH)));
850
851
		return $this;
852
	}
853
854
	// --------------------------------------------------------------------
855
856
	/**
857
	 * Internal CI Data Loader
858
	 *
859
	 * Used to load views and files.
860
	 *
861
	 * Variables are prefixed with _ci_ to avoid symbol collision with
862
	 * variables made available to view files.
863
	 *
864
	 * @used-by	CI_Loader::view()
865
	 * @used-by	CI_Loader::file()
866
	 * @param	array	$_ci_data	Data to load
867
	 * @return	object
868
	 */
869
	protected function _ci_load($_ci_data)
870
	{
871
		// Set the default data variables
872
		foreach (array('_ci_view', '_ci_vars', '_ci_path', '_ci_return') as $_ci_val)
873
		{
874
			$$_ci_val = isset($_ci_data[$_ci_val]) ? $_ci_data[$_ci_val] : FALSE;
875
		}
876
877
		$file_exists = FALSE;
878
879
		// Set the path to the requested file
880
		if (is_string($_ci_path) && $_ci_path !== '')
881
		{
882
			$_ci_x = explode('/', $_ci_path);
883
			$_ci_file = end($_ci_x);
884
		}
885
		else
886
		{
887
			$_ci_ext = pathinfo($_ci_view, PATHINFO_EXTENSION);
888
			$_ci_file = ($_ci_ext === '') ? $_ci_view.'.php' : $_ci_view;
889
890
			foreach ($this->_ci_view_paths as $_ci_view_file => $cascade)
891
			{
892
				if (file_exists($_ci_view_file.$_ci_file))
893
				{
894
					$_ci_path = $_ci_view_file.$_ci_file;
895
					$file_exists = TRUE;
896
					break;
897
				}
898
899
				if ( ! $cascade)
900
				{
901
					break;
902
				}
903
			}
904
		}
905
906
		if ( ! $file_exists && ! file_exists($_ci_path))
907
		{
908
			show_error('Unable to load the requested file: '.$_ci_file);
909
		}
910
911
		// This allows anything loaded using $this->load (views, files, etc.)
912
		// to become accessible from within the Controller and Model functions.
913
		$_ci_CI =& get_instance();
914
		foreach (get_object_vars($_ci_CI) as $_ci_key => $_ci_var)
915
		{
916
			if ( ! isset($this->$_ci_key))
917
			{
918
				$this->$_ci_key =& $_ci_CI->$_ci_key;
919
			}
920
		}
921
922
		/*
923
		 * Extract and cache variables
924
		 *
925
		 * You can either set variables using the dedicated $this->load->vars()
926
		 * function or via the second parameter of this function. We'll merge
927
		 * the two types and cache them so that views that are embedded within
928
		 * other views can have access to these variables.
929
		 */
930
		if (is_array($_ci_vars))
931
		{
932
			$this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars);
933
		}
934
		extract($this->_ci_cached_vars);
935
936
		/*
937
		 * Buffer the output
938
		 *
939
		 * We buffer the output for two reasons:
940
		 * 1. Speed. You get a significant speed boost.
941
		 * 2. So that the final rendered template can be post-processed by
942
		 *	the output class. Why do we need post processing? For one thing,
943
		 *	in order to show the elapsed page load time. Unless we can
944
		 *	intercept the content right before it's sent to the browser and
945
		 *	then stop the timer it won't be accurate.
946
		 */
947
		ob_start();
948
949
		// If the PHP installation does not support short tags we'll
950
		// do a little string replacement, changing the short tags
951
		// to standard PHP echo statements.
952
		if ( ! is_php('5.4') && ! ini_get('short_open_tag') && config_item('rewrite_short_tags') === TRUE)
953
		{
954
			echo eval('?>'.preg_replace('/;*\s*\?>/', '; ?>', str_replace('<?=', '<?php echo ', file_get_contents($_ci_path))));
955
		}
956
		else
957
		{
958
			include($_ci_path); // include() vs include_once() allows for multiple views with the same name
959
		}
960
961
		log_message('info', 'File loaded: '.$_ci_path);
962
963
		// Return the file data if requested
964
		if ($_ci_return === TRUE)
965
		{
966
			$buffer = ob_get_contents();
967
			@ob_end_clean();
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
968
			return $buffer;
969
		}
970
971
		/*
972
		 * Flush the buffer... or buff the flusher?
973
		 *
974
		 * In order to permit views to be nested within
975
		 * other views, we need to flush the content back out whenever
976
		 * we are beyond the first level of output buffering so that
977
		 * it can be seen and included properly by the first included
978
		 * template and any subsequent ones. Oy!
979
		 */
980
		if (ob_get_level() > $this->_ci_ob_level + 1)
981
		{
982
			ob_end_flush();
983
		}
984
		else
985
		{
986
			$_ci_CI->output->append_output(ob_get_contents());
987
			@ob_end_clean();
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
988
		}
989
990
		return $this;
991
	}
992
993
	// --------------------------------------------------------------------
994
995
	/**
996
	 * Internal CI Library Loader
997
	 *
998
	 * @used-by	CI_Loader::library()
999
	 * @uses	CI_Loader::_ci_init_library()
1000
	 *
1001
	 * @param	string	$class		Class name to load
1002
	 * @param	mixed	$params		Optional parameters to pass to the class constructor
1003
	 * @param	string	$object_name	Optional object name to assign to
1004
	 * @return	void
1005
	 */
1006
	protected function _ci_load_library($class, $params = NULL, $object_name = NULL)
1007
	{
1008
		// Get the class name, and while we're at it trim any slashes.
1009
		// The directory path can be included as part of the class name,
1010
		// but we don't want a leading slash
1011
		$class = str_replace('.php', '', trim($class, '/'));
1012
1013
		// Was the path included with the class name?
1014
		// We look for a slash to determine this
1015 View Code Duplication
		if (($last_slash = strrpos($class, '/')) !== FALSE)
1016
		{
1017
			// Extract the path
1018
			$subdir = substr($class, 0, ++$last_slash);
1019
1020
			// Get the filename from the path
1021
			$class = substr($class, $last_slash);
1022
		}
1023
		else
1024
		{
1025
			$subdir = '';
1026
		}
1027
1028
		$class = ucfirst($class);
1029
1030
		// Is this a stock library? There are a few special conditions if so ...
1031
		if (file_exists(BASEPATH.'libraries/'.$subdir.$class.'.php'))
1032
		{
1033
			return $this->_ci_load_stock_library($class, $subdir, $params, $object_name);
1034
		}
1035
1036
		// Let's search for the requested library file and load it.
1037
		foreach ($this->_ci_library_paths as $path)
1038
		{
1039
			// BASEPATH has already been checked for
1040
			if ($path === BASEPATH)
1041
			{
1042
				continue;
1043
			}
1044
1045
			$filepath = $path.'libraries/'.$subdir.$class.'.php';
1046
1047
			// Safety: Was the class already loaded by a previous call?
1048
			if (class_exists($class, FALSE))
1049
			{
1050
				// Before we deem this to be a duplicate request, let's see
1051
				// if a custom object name is being supplied. If so, we'll
1052
				// return a new instance of the object
1053 View Code Duplication
				if ($object_name !== NULL)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1054
				{
1055
					$CI =& get_instance();
1056
					if ( ! isset($CI->$object_name))
1057
					{
1058
						return $this->_ci_init_library($class, '', $params, $object_name);
1059
					}
1060
				}
1061
1062
				log_message('debug', $class.' class already loaded. Second attempt ignored.');
1063
				return;
1064
			}
1065
			// Does the file exist? No? Bummer...
1066
			elseif ( ! file_exists($filepath))
1067
			{
1068
				continue;
1069
			}
1070
1071
			include_once($filepath);
1072
			return $this->_ci_init_library($class, '', $params, $object_name);
1073
		}
1074
1075
		// One last attempt. Maybe the library is in a subdirectory, but it wasn't specified?
1076
		if ($subdir === '')
1077
		{
1078
			return $this->_ci_load_library($class.'/'.$class, $params, $object_name);
1079
		}
1080
1081
		// If we got this far we were unable to find the requested class.
1082
		log_message('error', 'Unable to load the requested class: '.$class);
1083
		show_error('Unable to load the requested class: '.$class);
1084
	}
1085
1086
	// --------------------------------------------------------------------
1087
1088
	/**
1089
	 * Internal CI Stock Library Loader
1090
	 *
1091
	 * @used-by	CI_Loader::_ci_load_library()
1092
	 * @uses	CI_Loader::_ci_init_library()
1093
	 *
1094
	 * @param	string	$library	Library name to load
1095
	 * @param	string	$file_path	Path to the library filename, relative to libraries/
1096
	 * @param	mixed	$params		Optional parameters to pass to the class constructor
1097
	 * @param	string	$object_name	Optional object name to assign to
1098
	 * @return	void
1099
	 */
1100
	protected function _ci_load_stock_library($library_name, $file_path, $params, $object_name)
1101
	{
1102
		$prefix = 'CI_';
1103
1104
		if (class_exists($prefix.$library_name, FALSE))
1105
		{
1106
			if (class_exists(config_item('subclass_prefix').$library_name, FALSE))
1107
			{
1108
				$prefix = config_item('subclass_prefix');
1109
			}
1110
1111
			// Before we deem this to be a duplicate request, let's see
1112
			// if a custom object name is being supplied. If so, we'll
1113
			// return a new instance of the object
1114 View Code Duplication
			if ($object_name !== NULL)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1115
			{
1116
				$CI =& get_instance();
1117
				if ( ! isset($CI->$object_name))
1118
				{
1119
					return $this->_ci_init_library($library_name, $prefix, $params, $object_name);
1120
				}
1121
			}
1122
1123
			log_message('debug', $library_name.' class already loaded. Second attempt ignored.');
1124
			return;
1125
		}
1126
1127
		$paths = $this->_ci_library_paths;
1128
		array_pop($paths); // BASEPATH
1129
		array_pop($paths); // APPPATH (needs to be the first path checked)
1130
		array_unshift($paths, APPPATH);
1131
1132
		foreach ($paths as $path)
1133
		{
1134
			if (file_exists($path = $path.'libraries/'.$file_path.$library_name.'.php'))
1135
			{
1136
				// Override
1137
				include_once($path);
1138
				if (class_exists($prefix.$library_name, FALSE))
1139
				{
1140
					return $this->_ci_init_library($library_name, $prefix, $params, $object_name);
1141
				}
1142
				else
1143
				{
1144
					log_message('debug', $path.' exists, but does not declare '.$prefix.$library_name);
1145
				}
1146
			}
1147
		}
1148
1149
		include_once(BASEPATH.'libraries/'.$file_path.$library_name.'.php');
1150
1151
		// Check for extensions
1152
		$subclass = config_item('subclass_prefix').$library_name;
1153
		foreach ($paths as $path)
1154
		{
1155
			if (file_exists($path = $path.'libraries/'.$file_path.$subclass.'.php'))
1156
			{
1157
				include_once($path);
1158
				if (class_exists($subclass, FALSE))
1159
				{
1160
					$prefix = config_item('subclass_prefix');
1161
					break;
1162
				}
1163
				else
1164
				{
1165
					log_message('debug', $path.' exists, but does not declare '.$subclass);
1166
				}
1167
			}
1168
		}
1169
1170
		return $this->_ci_init_library($library_name, $prefix, $params, $object_name);
1171
	}
1172
1173
	// --------------------------------------------------------------------
1174
1175
	/**
1176
	 * Internal CI Library Instantiator
1177
	 *
1178
	 * @used-by	CI_Loader::_ci_load_stock_library()
1179
	 * @used-by	CI_Loader::_ci_load_library()
1180
	 *
1181
	 * @param	string		$class		Class name
1182
	 * @param	string		$prefix		Class name prefix
1183
	 * @param	array|null|bool	$config		Optional configuration to pass to the class constructor:
1184
	 *						FALSE to skip;
1185
	 *						NULL to search in config paths;
1186
	 *						array containing configuration data
1187
	 * @param	string		$object_name	Optional object name to assign to
1188
	 * @return	void
1189
	 */
1190
	protected function _ci_init_library($class, $prefix, $config = FALSE, $object_name = NULL)
1191
	{
1192
		// Is there an associated config file for this class? Note: these should always be lowercase
1193
		if ($config === NULL)
1194
		{
1195
			// Fetch the config paths containing any package paths
1196
			$config_component = $this->_ci_get_component('config');
1197
1198
			if (is_array($config_component->_config_paths))
1199
			{
1200
				$found = FALSE;
1201
				foreach ($config_component->_config_paths as $path)
1202
				{
1203
					// We test for both uppercase and lowercase, for servers that
1204
					// are case-sensitive with regard to file names. Load global first,
1205
					// override with environment next
1206
					if (file_exists($path.'config/'.strtolower($class).'.php'))
1207
					{
1208
						include($path.'config/'.strtolower($class).'.php');
1209
						$found = TRUE;
1210
					}
1211
					elseif (file_exists($path.'config/'.ucfirst(strtolower($class)).'.php'))
1212
					{
1213
						include($path.'config/'.ucfirst(strtolower($class)).'.php');
1214
						$found = TRUE;
1215
					}
1216
1217
					if (file_exists($path.'config/'.ENVIRONMENT.'/'.strtolower($class).'.php'))
1218
					{
1219
						include($path.'config/'.ENVIRONMENT.'/'.strtolower($class).'.php');
1220
						$found = TRUE;
1221
					}
1222
					elseif (file_exists($path.'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php'))
1223
					{
1224
						include($path.'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php');
1225
						$found = TRUE;
1226
					}
1227
1228
					// Break on the first found configuration, thus package
1229
					// files are not overridden by default paths
1230
					if ($found === TRUE)
1231
					{
1232
						break;
1233
					}
1234
				}
1235
			}
1236
		}
1237
1238
		$class_name = $prefix.$class;
1239
1240
		// Is the class name valid?
1241
		if ( ! class_exists($class_name, FALSE))
1242
		{
1243
			log_message('error', 'Non-existent class: '.$class_name);
1244
			show_error('Non-existent class: '.$class_name);
1245
		}
1246
1247
		// Set the variable name we will assign the class to
1248
		// Was a custom class name supplied? If so we'll use it
1249
		if (empty($object_name))
1250
		{
1251
			$object_name = strtolower($class);
1252
			if (isset($this->_ci_varmap[$object_name]))
1253
			{
1254
				$object_name = $this->_ci_varmap[$object_name];
1255
			}
1256
		}
1257
1258
		// Don't overwrite existing properties
1259
		$CI =& get_instance();
1260
		if (isset($CI->$object_name))
1261
		{
1262
			if ($CI->$object_name instanceof $class_name)
1263
			{
1264
				log_message('debug', $class_name." has already been instantiated as '".$object_name."'. Second attempt aborted.");
1265
				return;
1266
			}
1267
1268
			show_error("Resource '".$object_name."' already exists and is not a ".$class_name." instance.");
1269
		}
1270
1271
		// Save the class name and object name
1272
		$this->_ci_classes[$object_name] = $class;
1273
1274
		// Instantiate the class
1275
		$CI->$object_name = isset($config)
1276
			? new $class_name($config)
1277
			: new $class_name();
1278
	}
1279
1280
	// --------------------------------------------------------------------
1281
1282
	/**
1283
	 * CI Autoloader
1284
	 *
1285
	 * Loads component listed in the config/autoload.php file.
1286
	 *
1287
	 * @used-by	CI_Loader::initialize()
1288
	 * @return	void
1289
	 */
1290
	protected function _ci_autoloader()
1291
	{
1292
		if (file_exists(APPPATH.'config/autoload.php'))
1293
		{
1294
			include(APPPATH.'config/autoload.php');
1295
		}
1296
1297
		if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/autoload.php'))
1298
		{
1299
			include(APPPATH.'config/'.ENVIRONMENT.'/autoload.php');
1300
		}
1301
1302
		if ( ! isset($autoload))
1303
		{
1304
			return;
1305
		}
1306
1307
		// Autoload packages
1308
		if (isset($autoload['packages']))
1309
		{
1310
			foreach ($autoload['packages'] as $package_path)
1311
			{
1312
				$this->add_package_path($package_path);
1313
			}
1314
		}
1315
1316
		// Load any custom config file
1317
		if (count($autoload['config']) > 0)
1318
		{
1319
			foreach ($autoload['config'] as $val)
1320
			{
1321
				$this->config($val);
1322
			}
1323
		}
1324
1325
		// Autoload helpers and languages
1326
		foreach (array('helper', 'language') as $type)
1327
		{
1328
			if (isset($autoload[$type]) && count($autoload[$type]) > 0)
1329
			{
1330
				$this->$type($autoload[$type]);
1331
			}
1332
		}
1333
1334
		// Autoload drivers
1335
		if (isset($autoload['drivers']))
1336
		{
1337
			foreach ($autoload['drivers'] as $item)
1338
			{
1339
				$this->driver($item);
1340
			}
1341
		}
1342
1343
		// Load libraries
1344
		if (isset($autoload['libraries']) && count($autoload['libraries']) > 0)
1345
		{
1346
			// Load the database driver.
1347
			if (in_array('database', $autoload['libraries']))
1348
			{
1349
				$this->database();
1350
				$autoload['libraries'] = array_diff($autoload['libraries'], array('database'));
1351
			}
1352
1353
			// Load all other libraries
1354
			$this->library($autoload['libraries']);
1355
		}
1356
1357
		// Autoload models
1358
		if (isset($autoload['model']))
1359
		{
1360
			$this->model($autoload['model']);
1361
		}
1362
	}
1363
1364
	// --------------------------------------------------------------------
1365
1366
	/**
1367
	 * CI Object to Array translator
1368
	 *
1369
	 * Takes an object as input and converts the class variables to
1370
	 * an associative array with key/value pairs.
1371
	 *
1372
	 * @param	object	$object	Object data to translate
1373
	 * @return	array
1374
	 */
1375
	protected function _ci_object_to_array($object)
1376
	{
1377
		return is_object($object) ? get_object_vars($object) : $object;
1378
	}
1379
1380
	// --------------------------------------------------------------------
1381
1382
	/**
1383
	 * CI Component getter
1384
	 *
1385
	 * Get a reference to a specific library or model.
1386
	 *
1387
	 * @param 	string	$component	Component name
1388
	 * @return	bool
1389
	 */
1390
	protected function &_ci_get_component($component)
1391
	{
1392
		$CI =& get_instance();
1393
		return $CI->$component;
1394
	}
1395
1396
	// --------------------------------------------------------------------
1397
1398
	/**
1399
	 * Prep filename
1400
	 *
1401
	 * This function prepares filenames of various items to
1402
	 * make their loading more reliable.
1403
	 *
1404
	 * @param	string|string[]	$filename	Filename(s)
1405
	 * @param 	string		$extension	Filename extension
1406
	 * @return	array
1407
	 */
1408
	protected function _ci_prep_filename($filename, $extension)
1409
	{
1410
		if ( ! is_array($filename))
1411
		{
1412
			return array(strtolower(str_replace(array($extension, '.php'), '', $filename).$extension));
1413
		}
1414
		else
1415
		{
1416
			foreach ($filename as $key => $val)
1417
			{
1418
				$filename[$key] = strtolower(str_replace(array($extension, '.php'), '', $val).$extension);
1419
			}
1420
1421
			return $filename;
1422
		}
1423
	}
1424
1425
}
1426