Completed
Push — master ( 63f9e6...34eb4c )
by Kenji
10s
created

replacing/core/old/3.1.7-Loader.php (12 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
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 - 2018, 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. (https://ellislab.com/)
32
 * @copyright	Copyright (c) 2014 - 2018, British Columbia Institute of Technology (http://bcit.ca/)
33
 * @license	http://opensource.org/licenses/MIT	MIT License
34
 * @link	https://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 (Modified by ci-phpunit-test)
42
 *
43
 * Loads framework components.
44
 *
45
 * @package		CodeIgniter
46
 * @subpackage	Libraries
47
 * @category	Loader
48
 * @author		EllisLab Dev Team
49
 * @link		https://codeigniter.com/user_guide/libraries/loader.html
50
 */
51 View Code Duplication
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
	 * @codeCoverageIgnore
137
	 */
138
	public function __construct()
139
	{
140
		$this->_ci_ob_level = ob_get_level();
141
		$this->_ci_classes =& is_loaded();
142
143
		log_message('info', 'Loader Class Initialized');
144
	}
145
146
	// --------------------------------------------------------------------
147
148
	/**
149
	 * Initializer
150
	 *
151
	 * @todo	Figure out a way to move this to the constructor
152
	 *		without breaking *package_path*() methods.
153
	 * @uses	CI_Loader::_ci_autoloader()
154
	 * @used-by	CI_Controller::__construct()
155
	 * @return	void
156
	 *
157
	 * @codeCoverageIgnore
158
	 */
159
	public function initialize()
160
	{
161
		$this->_ci_autoloader();
162
	}
163
164
	// --------------------------------------------------------------------
165
166
	/**
167
	 * Is Loaded
168
	 *
169
	 * A utility method to test if a class is in the self::$_ci_classes array.
170
	 *
171
	 * @used-by	Mainly used by Form Helper function _get_validation_object().
172
	 *
173
	 * @param 	string		$class	Class name to check for
174
	 * @return 	string|bool	Class object name if loaded or FALSE
175
	 *
176
	 * @codeCoverageIgnore
177
	 */
178
	public function is_loaded($class)
179
	{
180
		return array_search(ucfirst($class), $this->_ci_classes, TRUE);
181
	}
182
183
	// --------------------------------------------------------------------
184
185
	/**
186
	 * Library Loader
187
	 *
188
	 * Loads and instantiates libraries.
189
	 * Designed to be called from application controllers.
190
	 *
191
	 * @param	mixed	$library	Library name
192
	 * @param	array	$params		Optional parameters to pass to the library class constructor
193
	 * @param	string	$object_name	An optional object name to assign to
194
	 * @return	object
195
	 *
196
	 * @codeCoverageIgnore
197
	 */
198
	public function library($library, $params = NULL, $object_name = NULL)
199
	{
200
		if (empty($library))
201
		{
202
			return $this;
203
		}
204
		elseif (is_array($library))
205
		{
206
			foreach ($library as $key => $value)
207
			{
208
				if (is_int($key))
209
				{
210
					$this->library($value, $params);
211
				}
212
				else
213
				{
214
					$this->library($key, $params, $value);
215
				}
216
			}
217
218
			return $this;
219
		}
220
221
		if ($params !== NULL && ! is_array($params))
222
		{
223
			$params = NULL;
224
		}
225
226
		$this->_ci_load_library($library, $params, $object_name);
227
		return $this;
228
	}
229
230
	// --------------------------------------------------------------------
231
232
	/**
233
	 * Model Loader
234
	 *
235
	 * Loads and instantiates models.
236
	 *
237
	 * @param	mixed	$model		Model name
238
	 * @param	string	$name		An optional object name to assign to
239
	 * @param	bool	$db_conn	An optional database connection configuration to initialize
240
	 * @return	object
241
	 *
242
	 * modified by ci-phpunit-test
243
	 */
244
	public function model($model, $name = '', $db_conn = FALSE)
245
	{
246
		if (empty($model))
247
		{
248
			return $this;
249
		}
250
		elseif (is_array($model))
251
		{
252
			foreach ($model as $key => $value)
253
			{
254
				is_int($key) ? $this->model($value, '', $db_conn) : $this->model($key, $value, $db_conn);
255
			}
256
257
			return $this;
258
		}
259
260
		$path = '';
261
262
		// Is the model in a sub-folder? If so, parse out the filename and path.
263
		if (($last_slash = strrpos($model, '/')) !== FALSE)
264
		{
265
			// The path is in front of the last slash
266
			$path = substr($model, 0, ++$last_slash);
267
268
			// And the model name behind it
269
			$model = substr($model, $last_slash);
270
		}
271
272
		if (empty($name))
273
		{
274
			$name = $model;
275
		}
276
277
		if (in_array($name, $this->_ci_models, TRUE))
278
		{
279
			return $this;
280
		}
281
282
		$CI =& get_instance();
283
		if (isset($CI->$name))
284
		{
285
			throw new RuntimeException('The model name you are loading is the name of a resource that is already being used: '.$name);
286
		}
287
288
		if ($db_conn !== FALSE && ! class_exists('CI_DB', FALSE))
289
		{
290
			if ($db_conn === TRUE)
291
			{
292
				$db_conn = '';
293
			}
294
295
			$this->database($db_conn, FALSE, TRUE);
296
		}
297
298
		// Note: All of the code under this condition used to be just:
299
		//
300
		//	   load_class('Model', 'core');
301
		//
302
		//	   However, load_class() instantiates classes
303
		//	   to cache them for later use and that prevents
304
		//	   MY_Model from being an abstract class and is
305
		//	   sub-optimal otherwise anyway.
306
//		if ( ! class_exists('CI_Model', FALSE))
307
//		{
308
			$app_path = APPPATH.'core'.DIRECTORY_SEPARATOR;
309
			if (file_exists($app_path.'Model.php'))
310
			{
311
				require_once($app_path.'Model.php');
312
				if ( ! class_exists('CI_Model', FALSE))
313
				{
314
					throw new RuntimeException($app_path."Model.php exists, but doesn't declare class CI_Model");
315
				}
316
317
				log_message('info', 'CI_Model class loaded');
318
			}
319
			elseif ( ! class_exists('CI_Model', FALSE))
320
			{
321
				require_once(BASEPATH.'core'.DIRECTORY_SEPARATOR.'Model.php');
322
			}
323
324
			$class = config_item('subclass_prefix').'Model';
325
			if (file_exists($app_path.$class.'.php'))
326
			{
327
				require_once($app_path.$class.'.php');
328
				if ( ! class_exists($class, FALSE))
329
				{
330
					throw new RuntimeException($app_path.$class.".php exists, but doesn't declare class ".$class);
331
				}
332
333
				log_message('info', config_item('subclass_prefix').'Model class loaded');
334
			}
335
//		}
336
337
		$model = ucfirst($model);
338
		if ( ! class_exists($model, FALSE))
339
		{
340
			foreach ($this->_ci_model_paths as $mod_path)
341
			{
342
				if ( ! file_exists($mod_path.'models/'.$path.$model.'.php'))
343
				{
344
					continue;
345
				}
346
347
				require_once($mod_path.'models/'.$path.$model.'.php');
348
				if ( ! class_exists($model, FALSE))
349
				{
350
					throw new RuntimeException($mod_path."models/".$path.$model.".php exists, but doesn't declare class ".$model);
351
				}
352
353
				break;
354
			}
355
356
			if ( ! class_exists($model, FALSE))
357
			{
358
				throw new RuntimeException('Unable to locate the model you have specified: '.$model);
359
			}
360
		}
361
//		elseif ( ! is_subclass_of($model, 'CI_Model'))
362
//		{
363
//			throw new RuntimeException("Class ".$model." already exists and doesn't extend CI_Model");
364
//		}
365
366
		$this->_ci_models[] = $name;
367
		$model = new $model();
368
		$CI->$name = $model;
369
		log_message('info', 'Model "'.get_class($model).'" initialized');
370
		return $this;
371
	}
372
373
	// --------------------------------------------------------------------
374
375
	/**
376
	 * Database Loader
377
	 *
378
	 * @param	mixed	$params		Database configuration options
379
	 * @param	bool	$return 	Whether to return the database object
380
	 * @param	bool	$query_builder	Whether to enable Query Builder
381
	 *					(overrides the configuration setting)
382
	 *
383
	 * @return	object|bool	Database object if $return is set to TRUE,
384
	 *					FALSE on failure, CI_Loader instance in any other case
385
	 *
386
	 * @codeCoverageIgnore
387
	 */
388
	public function database($params = '', $return = FALSE, $query_builder = NULL)
389
	{
390
		// Grab the super object
391
		$CI =& get_instance();
392
393
		// Do we even need to load the database class?
394
		if ($return === FALSE && $query_builder === NULL && isset($CI->db) && is_object($CI->db) && ! empty($CI->db->conn_id))
395
		{
396
			return FALSE;
397
		}
398
399
		require_once(BASEPATH.'database/DB.php');
400
401
		if ($return === TRUE)
402
		{
403
			return DB($params, $query_builder);
404
		}
405
406
		// Initialize the db variable. Needed to prevent
407
		// reference errors with some configurations
408
		$CI->db = '';
409
410
		// Load the DB class
411
		$CI->db =& DB($params, $query_builder);
412
		return $this;
413
	}
414
415
	// --------------------------------------------------------------------
416
417
	/**
418
	 * Load the Database Utilities Class
419
	 *
420
	 * @param	object	$db	Database object
421
	 * @param	bool	$return	Whether to return the DB Utilities class object or not
422
	 * @return	object
423
	 *
424
	 * @codeCoverageIgnore
425
	 */
426
	public function dbutil($db = NULL, $return = FALSE)
427
	{
428
		$CI =& get_instance();
429
430
		if ( ! is_object($db) OR ! ($db instanceof CI_DB))
0 ignored issues
show
The class CI_DB does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
431
		{
432
			class_exists('CI_DB', FALSE) OR $this->database();
433
			$db =& $CI->db;
434
		}
435
436
		require_once(BASEPATH.'database/DB_utility.php');
437
		require_once(BASEPATH.'database/drivers/'.$db->dbdriver.'/'.$db->dbdriver.'_utility.php');
438
		$class = 'CI_DB_'.$db->dbdriver.'_utility';
439
440
		if ($return === TRUE)
441
		{
442
			return new $class($db);
443
		}
444
445
		$CI->dbutil = new $class($db);
446
		return $this;
447
	}
448
449
	// --------------------------------------------------------------------
450
451
	/**
452
	 * Load the Database Forge Class
453
	 *
454
	 * @param	object	$db	Database object
455
	 * @param	bool	$return	Whether to return the DB Forge class object or not
456
	 * @return	object
457
	 *
458
	 * @codeCoverageIgnore
459
	 */
460
	public function dbforge($db = NULL, $return = FALSE)
461
	{
462
		$CI =& get_instance();
463
		if ( ! is_object($db) OR ! ($db instanceof CI_DB))
0 ignored issues
show
The class CI_DB does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
464
		{
465
			class_exists('CI_DB', FALSE) OR $this->database();
466
			$db =& $CI->db;
467
		}
468
469
		require_once(BASEPATH.'database/DB_forge.php');
470
		require_once(BASEPATH.'database/drivers/'.$db->dbdriver.'/'.$db->dbdriver.'_forge.php');
471
472
		if ( ! empty($db->subdriver))
473
		{
474
			$driver_path = BASEPATH.'database/drivers/'.$db->dbdriver.'/subdrivers/'.$db->dbdriver.'_'.$db->subdriver.'_forge.php';
475
			if (file_exists($driver_path))
476
			{
477
				require_once($driver_path);
478
				$class = 'CI_DB_'.$db->dbdriver.'_'.$db->subdriver.'_forge';
479
			}
480
		}
481
		else
482
		{
483
			$class = 'CI_DB_'.$db->dbdriver.'_forge';
484
		}
485
486
		if ($return === TRUE)
487
		{
488
			return new $class($db);
0 ignored issues
show
The variable $class does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
489
		}
490
491
		$CI->dbforge = new $class($db);
492
		return $this;
493
	}
494
495
	// --------------------------------------------------------------------
496
497
	/**
498
	 * View Loader
499
	 *
500
	 * Loads "view" files.
501
	 *
502
	 * @param	string	$view	View name
503
	 * @param	array	$vars	An associative array of data
504
	 *				to be extracted for use in the view
505
	 * @param	bool	$return	Whether to return the view output
506
	 *				or leave it to the Output class
507
	 * @return	object|string
508
	 *
509
	 * @codeCoverageIgnore
510
	 */
511
	public function view($view, $vars = array(), $return = FALSE)
512
	{
513
		return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_prepare_view_vars($vars), '_ci_return' => $return));
514
	}
515
516
	// --------------------------------------------------------------------
517
518
	/**
519
	 * Generic File Loader
520
	 *
521
	 * @param	string	$path	File path
522
	 * @param	bool	$return	Whether to return the file output
523
	 * @return	object|string
524
	 */
525
	public function file($path, $return = FALSE)
526
	{
527
		return $this->_ci_load(array('_ci_path' => $path, '_ci_return' => $return));
528
	}
529
530
	// --------------------------------------------------------------------
531
532
	/**
533
	 * Set Variables
534
	 *
535
	 * Once variables are set they become available within
536
	 * the controller class and its "view" files.
537
	 *
538
	 * @param	array|object|string	$vars
539
	 *					An associative array or object containing values
540
	 *					to be set, or a value's name if string
541
	 * @param 	string	$val	Value to set, only used if $vars is a string
542
	 * @return	object
543
	 *
544
	 * @codeCoverageIgnore
545
	 */
546
	public function vars($vars, $val = '')
547
	{
548
		$vars = is_string($vars)
549
			? array($vars => $val)
550
			: $this->_ci_prepare_view_vars($vars);
551
552
		foreach ($vars as $key => $val)
553
		{
554
			$this->_ci_cached_vars[$key] = $val;
555
		}
556
557
		return $this;
558
	}
559
560
	// --------------------------------------------------------------------
561
562
	/**
563
	 * Clear Cached Variables
564
	 *
565
	 * Clears the cached variables.
566
	 *
567
	 * @return	CI_Loader
568
	 *
569
	 * @codeCoverageIgnore
570
	 */
571
	public function clear_vars()
572
	{
573
		$this->_ci_cached_vars = array();
574
		return $this;
575
	}
576
577
	// --------------------------------------------------------------------
578
579
	/**
580
	 * Get Variable
581
	 *
582
	 * Check if a variable is set and retrieve it.
583
	 *
584
	 * @param	string	$key	Variable name
585
	 * @return	mixed	The variable or NULL if not found
586
	 *
587
	 * @codeCoverageIgnore
588
	 */
589
	public function get_var($key)
590
	{
591
		return isset($this->_ci_cached_vars[$key]) ? $this->_ci_cached_vars[$key] : NULL;
592
	}
593
594
	// --------------------------------------------------------------------
595
596
	/**
597
	 * Get Variables
598
	 *
599
	 * Retrieves all loaded variables.
600
	 *
601
	 * @return	array
602
	 *
603
	 * @codeCoverageIgnore
604
	 */
605
	public function get_vars()
606
	{
607
		return $this->_ci_cached_vars;
608
	}
609
610
	// --------------------------------------------------------------------
611
612
	/**
613
	 * Helper Loader
614
	 *
615
	 * @param	string|string[]	$helpers	Helper name(s)
616
	 * @return	object
617
	 *
618
	 * @codeCoverageIgnore
619
	 */
620
	public function helper($helpers = array())
621
	{
622
		is_array($helpers) OR $helpers = array($helpers);
623
		foreach ($helpers as &$helper)
624
		{
625
			$filename = basename($helper);
626
			$filepath = ($filename === $helper) ? '' : substr($helper, 0, strlen($helper) - strlen($filename));
627
			$filename = strtolower(preg_replace('#(_helper)?(\.php)?$#i', '', $filename)).'_helper';
628
			$helper   = $filepath.$filename;
629
630
			if (isset($this->_ci_helpers[$helper]))
631
			{
632
				continue;
633
			}
634
635
			// Is this a helper extension request?
636
			$ext_helper = config_item('subclass_prefix').$filename;
637
			$ext_loaded = FALSE;
638
			foreach ($this->_ci_helper_paths as $path)
639
			{
640
				if (file_exists($path.'helpers/'.$ext_helper.'.php'))
641
				{
642
					include_once($path.'helpers/'.$ext_helper.'.php');
643
					$ext_loaded = TRUE;
644
				}
645
			}
646
647
			// If we have loaded extensions - check if the base one is here
648
			if ($ext_loaded === TRUE)
649
			{
650
				$base_helper = BASEPATH.'helpers/'.$helper.'.php';
651
				if ( ! file_exists($base_helper))
652
				{
653
					show_error('Unable to load the requested file: helpers/'.$helper.'.php');
654
				}
655
656
				include_once($base_helper);
657
				$this->_ci_helpers[$helper] = TRUE;
658
				log_message('info', 'Helper loaded: '.$helper);
659
				continue;
660
			}
661
662
			// No extensions found ... try loading regular helpers and/or overrides
663
			foreach ($this->_ci_helper_paths as $path)
664
			{
665
				if (file_exists($path.'helpers/'.$helper.'.php'))
666
				{
667
					include_once($path.'helpers/'.$helper.'.php');
668
669
					$this->_ci_helpers[$helper] = TRUE;
670
					log_message('info', 'Helper loaded: '.$helper);
671
					break;
672
				}
673
			}
674
675
			// unable to load the helper
676
			if ( ! isset($this->_ci_helpers[$helper]))
677
			{
678
				show_error('Unable to load the requested file: helpers/'.$helper.'.php');
679
			}
680
		}
681
682
		return $this;
683
	}
684
685
	// --------------------------------------------------------------------
686
687
	/**
688
	 * Load Helpers
689
	 *
690
	 * An alias for the helper() method in case the developer has
691
	 * written the plural form of it.
692
	 *
693
	 * @uses	CI_Loader::helper()
694
	 * @param	string|string[]	$helpers	Helper name(s)
695
	 * @return	object
696
	 *
697
	 * @codeCoverageIgnore
698
	 */
699
	public function helpers($helpers = array())
700
	{
701
		return $this->helper($helpers);
702
	}
703
704
	// --------------------------------------------------------------------
705
706
	/**
707
	 * Language Loader
708
	 *
709
	 * Loads language files.
710
	 *
711
	 * @param	string|string[]	$files	List of language file names to load
712
	 * @param	string		Language name
713
	 * @return	object
714
	 *
715
	 * @codeCoverageIgnore
716
	 */
717
	public function language($files, $lang = '')
718
	{
719
		get_instance()->lang->load($files, $lang);
720
		return $this;
721
	}
722
723
	// --------------------------------------------------------------------
724
725
	/**
726
	 * Config Loader
727
	 *
728
	 * Loads a config file (an alias for CI_Config::load()).
729
	 *
730
	 * @uses	CI_Config::load()
731
	 * @param	string	$file			Configuration file name
732
	 * @param	bool	$use_sections		Whether configuration values should be loaded into their own section
733
	 * @param	bool	$fail_gracefully	Whether to just return FALSE or display an error message
734
	 * @return	bool	TRUE if the file was loaded correctly or FALSE on failure
735
	 *
736
	 * @codeCoverageIgnore
737
	 */
738
	public function config($file, $use_sections = FALSE, $fail_gracefully = FALSE)
739
	{
740
		return get_instance()->config->load($file, $use_sections, $fail_gracefully);
741
	}
742
743
	// --------------------------------------------------------------------
744
745
	/**
746
	 * Driver Loader
747
	 *
748
	 * Loads a driver library.
749
	 *
750
	 * @param	string|string[]	$library	Driver name(s)
751
	 * @param	array		$params		Optional parameters to pass to the driver
752
	 * @param	string		$object_name	An optional object name to assign to
753
	 *
754
	 * @return	object|bool	Object or FALSE on failure if $library is a string
755
	 *				and $object_name is set. CI_Loader instance otherwise.
756
	 *
757
	 * @codeCoverageIgnore
758
	 */
759
	public function driver($library, $params = NULL, $object_name = NULL)
760
	{
761
		if (is_array($library))
762
		{
763
			foreach ($library as $key => $value)
764
			{
765
				if (is_int($key))
766
				{
767
					$this->driver($value, $params);
768
				}
769
				else
770
				{
771
					$this->driver($key, $params, $value);
772
				}
773
			}
774
775
			return $this;
776
		}
777
		elseif (empty($library))
778
		{
779
			return FALSE;
780
		}
781
782
		if ( ! class_exists('CI_Driver_Library', FALSE))
783
		{
784
			// We aren't instantiating an object here, just making the base class available
785
			require BASEPATH.'libraries/Driver.php';
786
		}
787
788
		// We can save the loader some time since Drivers will *always* be in a subfolder,
789
		// and typically identically named to the library
790
		if ( ! strpos($library, '/'))
791
		{
792
			$library = ucfirst($library).'/'.$library;
793
		}
794
795
		return $this->library($library, $params, $object_name);
796
	}
797
798
	// --------------------------------------------------------------------
799
800
	/**
801
	 * Add Package Path
802
	 *
803
	 * Prepends a parent path to the library, model, helper and config
804
	 * path arrays.
805
	 *
806
	 * @see	CI_Loader::$_ci_library_paths
807
	 * @see	CI_Loader::$_ci_model_paths
808
	 * @see CI_Loader::$_ci_helper_paths
809
	 * @see CI_Config::$_config_paths
810
	 *
811
	 * @param	string	$path		Path to add
812
	 * @param 	bool	$view_cascade	(default: TRUE)
813
	 * @return	object
814
	 *
815
	 * @codeCoverageIgnore
816
	 */
817
	public function add_package_path($path, $view_cascade = TRUE)
818
	{
819
		$path = rtrim($path, '/').'/';
820
821
		array_unshift($this->_ci_library_paths, $path);
822
		array_unshift($this->_ci_model_paths, $path);
823
		array_unshift($this->_ci_helper_paths, $path);
824
825
		$this->_ci_view_paths = array($path.'views/' => $view_cascade) + $this->_ci_view_paths;
826
827
		// Add config file path
828
		$config =& $this->_ci_get_component('config');
829
		$config->_config_paths[] = $path;
830
831
		return $this;
832
	}
833
834
	// --------------------------------------------------------------------
835
836
	/**
837
	 * Get Package Paths
838
	 *
839
	 * Return a list of all package paths.
840
	 *
841
	 * @param	bool	$include_base	Whether to include BASEPATH (default: FALSE)
842
	 * @return	array
843
	 *
844
	 * @codeCoverageIgnore
845
	 */
846
	public function get_package_paths($include_base = FALSE)
847
	{
848
		return ($include_base === TRUE) ? $this->_ci_library_paths : $this->_ci_model_paths;
849
	}
850
851
	// --------------------------------------------------------------------
852
853
	/**
854
	 * Remove Package Path
855
	 *
856
	 * Remove a path from the library, model, helper and/or config
857
	 * path arrays if it exists. If no path is provided, the most recently
858
	 * added path will be removed removed.
859
	 *
860
	 * @param	string	$path	Path to remove
861
	 * @return	object
862
	 *
863
	 * @codeCoverageIgnore
864
	 */
865
	public function remove_package_path($path = '')
866
	{
867
		$config =& $this->_ci_get_component('config');
868
869
		if ($path === '')
870
		{
871
			array_shift($this->_ci_library_paths);
872
			array_shift($this->_ci_model_paths);
873
			array_shift($this->_ci_helper_paths);
874
			array_shift($this->_ci_view_paths);
875
			array_pop($config->_config_paths);
876
		}
877
		else
878
		{
879
			$path = rtrim($path, '/').'/';
880
			foreach (array('_ci_library_paths', '_ci_model_paths', '_ci_helper_paths') as $var)
881
			{
882
				if (($key = array_search($path, $this->{$var})) !== FALSE)
883
				{
884
					unset($this->{$var}[$key]);
885
				}
886
			}
887
888
			if (isset($this->_ci_view_paths[$path.'views/']))
889
			{
890
				unset($this->_ci_view_paths[$path.'views/']);
891
			}
892
893
			if (($key = array_search($path, $config->_config_paths)) !== FALSE)
894
			{
895
				unset($config->_config_paths[$key]);
896
			}
897
		}
898
899
		// make sure the application default paths are still in the array
900
		$this->_ci_library_paths = array_unique(array_merge($this->_ci_library_paths, array(APPPATH, BASEPATH)));
901
		$this->_ci_helper_paths = array_unique(array_merge($this->_ci_helper_paths, array(APPPATH, BASEPATH)));
902
		$this->_ci_model_paths = array_unique(array_merge($this->_ci_model_paths, array(APPPATH)));
903
		$this->_ci_view_paths = array_merge($this->_ci_view_paths, array(APPPATH.'views/' => TRUE));
904
		$config->_config_paths = array_unique(array_merge($config->_config_paths, array(APPPATH)));
905
906
		return $this;
907
	}
908
909
	// --------------------------------------------------------------------
910
911
	/**
912
	 * Internal CI Data Loader
913
	 *
914
	 * Used to load views and files.
915
	 *
916
	 * Variables are prefixed with _ci_ to avoid symbol collision with
917
	 * variables made available to view files.
918
	 *
919
	 * @used-by	CI_Loader::view()
920
	 * @used-by	CI_Loader::file()
921
	 * @param	array	$_ci_data	Data to load
922
	 * @return	object
923
	 *
924
	 * @codeCoverageIgnore
925
	 */
926
	protected function _ci_load($_ci_data)
927
	{
928
		// Set the default data variables
929
		foreach (array('_ci_view', '_ci_vars', '_ci_path', '_ci_return') as $_ci_val)
930
		{
931
			$$_ci_val = isset($_ci_data[$_ci_val]) ? $_ci_data[$_ci_val] : FALSE;
932
		}
933
934
		$file_exists = FALSE;
935
936
		// Set the path to the requested file
937
		if (is_string($_ci_path) && $_ci_path !== '')
0 ignored issues
show
The variable $_ci_path seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
938
		{
939
			$_ci_x = explode('/', $_ci_path);
0 ignored issues
show
The variable $_ci_path seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?

This error can happen if you refactor code and forget to move the variable initialization.

Let’s take a look at a simple example:

function someFunction() {
    $x = 5;
    echo $x;
}

The above code is perfectly fine. Now imagine that we re-order the statements:

function someFunction() {
    echo $x;
    $x = 5;
}

In that case, $x would be read before it is initialized. This was a very basic example, however the principle is the same for the found issue.

Loading history...
940
			$_ci_file = end($_ci_x);
941
		}
942
		else
943
		{
944
			$_ci_ext = pathinfo($_ci_view, PATHINFO_EXTENSION);
0 ignored issues
show
The variable $_ci_view does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
945
			$_ci_file = ($_ci_ext === '') ? $_ci_view.'.php' : $_ci_view;
946
947
			foreach ($this->_ci_view_paths as $_ci_view_file => $cascade)
948
			{
949
				if (file_exists($_ci_view_file.$_ci_file))
950
				{
951
					$_ci_path = $_ci_view_file.$_ci_file;
952
					$file_exists = TRUE;
953
					break;
954
				}
955
956
				if ( ! $cascade)
957
				{
958
					break;
959
				}
960
			}
961
		}
962
963
		if ( ! $file_exists && ! file_exists($_ci_path))
0 ignored issues
show
The variable $_ci_path does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
964
		{
965
			show_error('Unable to load the requested file: '.$_ci_file);
966
		}
967
968
		// This allows anything loaded using $this->load (views, files, etc.)
969
		// to become accessible from within the Controller and Model functions.
970
		$_ci_CI =& get_instance();
971
		foreach (get_object_vars($_ci_CI) as $_ci_key => $_ci_var)
972
		{
973
			if ( ! isset($this->$_ci_key))
974
			{
975
				$this->$_ci_key =& $_ci_CI->$_ci_key;
976
			}
977
		}
978
979
		/*
980
		 * Extract and cache variables
981
		 *
982
		 * You can either set variables using the dedicated $this->load->vars()
983
		 * function or via the second parameter of this function. We'll merge
984
		 * the two types and cache them so that views that are embedded within
985
		 * other views can have access to these variables.
986
		 */
987
		empty($_ci_vars) OR $this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars);
0 ignored issues
show
The variable $_ci_vars seems to never exist, and therefore empty should always return true. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
988
		extract($this->_ci_cached_vars);
989
990
		/*
991
		 * Buffer the output
992
		 *
993
		 * We buffer the output for two reasons:
994
		 * 1. Speed. You get a significant speed boost.
995
		 * 2. So that the final rendered template can be post-processed by
996
		 *	the output class. Why do we need post processing? For one thing,
997
		 *	in order to show the elapsed page load time. Unless we can
998
		 *	intercept the content right before it's sent to the browser and
999
		 *	then stop the timer it won't be accurate.
1000
		 */
1001
		ob_start();
1002
1003
		// If the PHP installation does not support short tags we'll
1004
		// do a little string replacement, changing the short tags
1005
		// to standard PHP echo statements.
1006
		if ( ! is_php('5.4') && ! ini_get('short_open_tag') && config_item('rewrite_short_tags') === TRUE)
1007
		{
1008
			echo eval('?>'.preg_replace('/;*\s*\?>/', '; ?>', str_replace('<?=', '<?php echo ', file_get_contents($_ci_path))));
1009
		}
1010
		else
1011
		{
1012
			include($_ci_path); // include() vs include_once() allows for multiple views with the same name
1013
		}
1014
1015
		log_message('info', 'File loaded: '.$_ci_path);
1016
1017
		// Return the file data if requested
1018
		if ($_ci_return === TRUE)
1019
		{
1020
			$buffer = ob_get_contents();
1021
			@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...
1022
			return $buffer;
1023
		}
1024
1025
		/*
1026
		 * Flush the buffer... or buff the flusher?
1027
		 *
1028
		 * In order to permit views to be nested within
1029
		 * other views, we need to flush the content back out whenever
1030
		 * we are beyond the first level of output buffering so that
1031
		 * it can be seen and included properly by the first included
1032
		 * template and any subsequent ones. Oy!
1033
		 */
1034
		if (ob_get_level() > $this->_ci_ob_level + 1)
1035
		{
1036
			ob_end_flush();
1037
		}
1038
		else
1039
		{
1040
			$_ci_CI->output->append_output(ob_get_contents());
1041
			@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...
1042
		}
1043
1044
		return $this;
1045
	}
1046
1047
	// --------------------------------------------------------------------
1048
1049
	/**
1050
	 * Internal CI Library Loader
1051
	 *
1052
	 * @used-by	CI_Loader::library()
1053
	 * @uses	CI_Loader::_ci_init_library()
1054
	 *
1055
	 * @param	string	$class		Class name to load
1056
	 * @param	mixed	$params		Optional parameters to pass to the class constructor
1057
	 * @param	string	$object_name	Optional object name to assign to
1058
	 * @return	void
1059
	 *
1060
	 * modified by ci-phpunit-test
1061
	 */
1062
	protected function _ci_load_library($class, $params = NULL, $object_name = NULL)
1063
	{
1064
		// Get the class name, and while we're at it trim any slashes.
1065
		// The directory path can be included as part of the class name,
1066
		// but we don't want a leading slash
1067
		$class = str_replace('.php', '', trim($class, '/'));
1068
1069
		// Was the path included with the class name?
1070
		// We look for a slash to determine this
1071
		if (($last_slash = strrpos($class, '/')) !== FALSE)
1072
		{
1073
			// Extract the path
1074
			$subdir = substr($class, 0, ++$last_slash);
1075
1076
			// Get the filename from the path
1077
			$class = substr($class, $last_slash);
1078
		}
1079
		else
1080
		{
1081
			$subdir = '';
1082
		}
1083
1084
		$class = ucfirst($class);
1085
1086
		// Replace library in ci-phpuni-test
1087
		if (file_exists(TESTPATH.'_ci_phpunit_test/replacing/libraries/'.$subdir.$class.'.php'))
1088
		{
1089
			return $this->_ci_load_stock_library($class, $subdir, $params, $object_name);
1090
		}
1091
1092
		// Is this a stock library? There are a few special conditions if so ...
1093
		if (file_exists(BASEPATH.'libraries/'.$subdir.$class.'.php'))
1094
		{
1095
			return $this->_ci_load_stock_library($class, $subdir, $params, $object_name);
1096
		}
1097
1098
		// Safety: Was the class already loaded by a previous call?
1099
		if (class_exists($class, FALSE))
1100
		{
1101
			$property = $object_name;
1102
			if (empty($property))
1103
			{
1104
				$property = strtolower($class);
1105
				isset($this->_ci_varmap[$property]) && $property = $this->_ci_varmap[$property];
1106
			}
1107
1108
			$CI =& get_instance();
1109
			if (isset($CI->$property))
1110
			{
1111
//				log_message('debug', $class.' class already loaded. Second attempt ignored.');
1112
//				return;
1113
			}
1114
1115
			return $this->_ci_init_library($class, '', $params, $object_name);
1116
		}
1117
1118
		// Let's search for the requested library file and load it.
1119
		foreach ($this->_ci_library_paths as $path)
1120
		{
1121
			// BASEPATH has already been checked for
1122
			if ($path === BASEPATH)
1123
			{
1124
				continue;
1125
			}
1126
1127
			$filepath = $path.'libraries/'.$subdir.$class.'.php';
1128
			// Does the file exist? No? Bummer...
1129
			if ( ! file_exists($filepath))
1130
			{
1131
				continue;
1132
			}
1133
1134
			include_once($filepath);
1135
			return $this->_ci_init_library($class, '', $params, $object_name);
1136
		}
1137
1138
		// One last attempt. Maybe the library is in a subdirectory, but it wasn't specified?
1139
		if ($subdir === '')
1140
		{
1141
			return $this->_ci_load_library($class.'/'.$class, $params, $object_name);
1142
		}
1143
1144
		// If we got this far we were unable to find the requested class.
1145
		log_message('error', 'Unable to load the requested class: '.$class);
1146
		show_error('Unable to load the requested class: '.$class);
1147
	}
1148
1149
	// --------------------------------------------------------------------
1150
1151
	/**
1152
	 * Internal CI Stock Library Loader
1153
	 *
1154
	 * @used-by	CI_Loader::_ci_load_library()
1155
	 * @uses	CI_Loader::_ci_init_library()
1156
	 *
1157
	 * @param	string	$library_name	Library name to load
1158
	 * @param	string	$file_path	Path to the library filename, relative to libraries/
1159
	 * @param	mixed	$params		Optional parameters to pass to the class constructor
1160
	 * @param	string	$object_name	Optional object name to assign to
1161
	 * @return	void
1162
	 *
1163
	 * modified by ci-phpunit-test
1164
	 */
1165
	protected function _ci_load_stock_library($library_name, $file_path, $params, $object_name)
1166
	{
1167
		$prefix = 'CI_';
1168
1169
		if (class_exists($prefix.$library_name, FALSE))
1170
		{
1171
			if (class_exists(config_item('subclass_prefix').$library_name, FALSE))
1172
			{
1173
				$prefix = config_item('subclass_prefix');
1174
			}
1175
1176
			$property = $object_name;
1177
			if (empty($property))
1178
			{
1179
				$property = strtolower($library_name);
1180
				isset($this->_ci_varmap[$property]) && $property = $this->_ci_varmap[$property];
1181
			}
1182
1183
			$CI =& get_instance();
1184
			if ( ! isset($CI->$property))
1185
			{
1186
				return $this->_ci_init_library($library_name, $prefix, $params, $object_name);
1187
			}
1188
1189
			log_message('debug', $library_name.' class already loaded. Second attempt ignored.');
1190
			return;
1191
		}
1192
1193
		$paths = $this->_ci_library_paths;
1194
		array_pop($paths); // BASEPATH
1195
		array_pop($paths); // APPPATH (needs to be the first path checked)
1196
		array_unshift($paths, APPPATH);
1197
1198
		foreach ($paths as $path)
1199
		{
1200
			if (file_exists($path = $path.'libraries/'.$file_path.$library_name.'.php'))
1201
			{
1202
				// Override
1203
				include_once($path);
1204
//				if (class_exists($prefix.$library_name, FALSE))
1205
				{
1206
					return $this->_ci_init_library($library_name, $prefix, $params, $object_name);
1207
				}
1208
1209
				log_message('debug', $path.' exists, but does not declare '.$prefix.$library_name);
0 ignored issues
show
log_message('debug', $pa...refix . $library_name); does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
1210
			}
1211
		}
1212
1213
		// Replace library in ci-phpuni-test
1214
		if (file_exists(TESTPATH.'_ci_phpunit_test/replacing/libraries/'.$file_path.$library_name.'.php'))
1215
		{
1216
			include_once(TESTPATH.'_ci_phpunit_test/replacing/libraries/'.$file_path.$library_name.'.php');
1217
		}
1218
		else
1219
		{
1220
			include_once(BASEPATH.'libraries/'.$file_path.$library_name.'.php');
1221
		}
1222
1223
		// Check for extensions
1224
		$subclass = config_item('subclass_prefix').$library_name;
1225
		foreach ($paths as $path)
1226
		{
1227
			if (file_exists($path = $path.'libraries/'.$file_path.$subclass.'.php'))
1228
			{
1229
				include_once($path);
1230
				if (class_exists($subclass, FALSE))
1231
				{
1232
					$prefix = config_item('subclass_prefix');
1233
					break;
1234
				}
1235
1236
				log_message('debug', $path.' exists, but does not declare '.$subclass);
1237
			}
1238
		}
1239
1240
		return $this->_ci_init_library($library_name, $prefix, $params, $object_name);
1241
	}
1242
1243
	// --------------------------------------------------------------------
1244
1245
	/**
1246
	 * Internal CI Library Instantiator
1247
	 *
1248
	 * @used-by	CI_Loader::_ci_load_stock_library()
1249
	 * @used-by	CI_Loader::_ci_load_library()
1250
	 *
1251
	 * @param	string		$class		Class name
1252
	 * @param	string		$prefix		Class name prefix
1253
	 * @param	array|null|bool	$config		Optional configuration to pass to the class constructor:
1254
	 *						FALSE to skip;
1255
	 *						NULL to search in config paths;
1256
	 *						array containing configuration data
1257
	 * @param	string		$object_name	Optional object name to assign to
1258
	 * @return	void
1259
	 *
1260
	 * @codeCoverageIgnore
1261
	 */
1262
	protected function _ci_init_library($class, $prefix, $config = FALSE, $object_name = NULL)
1263
	{
1264
		// Is there an associated config file for this class? Note: these should always be lowercase
1265
		if ($config === NULL)
1266
		{
1267
			// Fetch the config paths containing any package paths
1268
			$config_component = $this->_ci_get_component('config');
1269
1270
			if (is_array($config_component->_config_paths))
1271
			{
1272
				$found = FALSE;
1273
				foreach ($config_component->_config_paths as $path)
1274
				{
1275
					// We test for both uppercase and lowercase, for servers that
1276
					// are case-sensitive with regard to file names. Load global first,
1277
					// override with environment next
1278
					if (file_exists($path.'config/'.strtolower($class).'.php'))
1279
					{
1280
						include($path.'config/'.strtolower($class).'.php');
1281
						$found = TRUE;
1282
					}
1283
					elseif (file_exists($path.'config/'.ucfirst(strtolower($class)).'.php'))
1284
					{
1285
						include($path.'config/'.ucfirst(strtolower($class)).'.php');
1286
						$found = TRUE;
1287
					}
1288
1289
					if (file_exists($path.'config/'.ENVIRONMENT.'/'.strtolower($class).'.php'))
1290
					{
1291
						include($path.'config/'.ENVIRONMENT.'/'.strtolower($class).'.php');
1292
						$found = TRUE;
1293
					}
1294
					elseif (file_exists($path.'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php'))
1295
					{
1296
						include($path.'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php');
1297
						$found = TRUE;
1298
					}
1299
1300
					// Break on the first found configuration, thus package
1301
					// files are not overridden by default paths
1302
					if ($found === TRUE)
1303
					{
1304
						break;
1305
					}
1306
				}
1307
			}
1308
		}
1309
1310
		$class_name = $prefix.$class;
1311
1312
		// Is the class name valid?
1313
		if ( ! class_exists($class_name, FALSE))
1314
		{
1315
			log_message('error', 'Non-existent class: '.$class_name);
1316
			show_error('Non-existent class: '.$class_name);
1317
		}
1318
1319
		// Set the variable name we will assign the class to
1320
		// Was a custom class name supplied? If so we'll use it
1321
		if (empty($object_name))
1322
		{
1323
			$object_name = strtolower($class);
1324
			if (isset($this->_ci_varmap[$object_name]))
1325
			{
1326
				$object_name = $this->_ci_varmap[$object_name];
1327
			}
1328
		}
1329
1330
		// Don't overwrite existing properties
1331
		$CI =& get_instance();
1332
		if (isset($CI->$object_name))
1333
		{
1334
			if ($CI->$object_name instanceof $class_name)
1335
			{
1336
				log_message('debug', $class_name." has already been instantiated as '".$object_name."'. Second attempt aborted.");
1337
				return;
1338
			}
1339
1340
			show_error("Resource '".$object_name."' already exists and is not a ".$class_name." instance.");
1341
		}
1342
1343
		// Save the class name and object name
1344
		$this->_ci_classes[$object_name] = $class;
1345
1346
		// Instantiate the class
1347
		$CI->$object_name = isset($config)
1348
			? new $class_name($config)
1349
			: new $class_name();
1350
	}
1351
1352
	// --------------------------------------------------------------------
1353
1354
	/**
1355
	 * CI Autoloader
1356
	 *
1357
	 * Loads component listed in the config/autoload.php file.
1358
	 *
1359
	 * @used-by	CI_Loader::initialize()
1360
	 * @return	void
1361
	 *
1362
	 * @codeCoverageIgnore
1363
	 */
1364
	protected function _ci_autoloader()
1365
	{
1366
		if (file_exists(APPPATH.'config/autoload.php'))
1367
		{
1368
			include(APPPATH.'config/autoload.php');
1369
		}
1370
1371
		if (file_exists(APPPATH.'config/'.ENVIRONMENT.'/autoload.php'))
1372
		{
1373
			include(APPPATH.'config/'.ENVIRONMENT.'/autoload.php');
1374
		}
1375
1376
		if ( ! isset($autoload))
0 ignored issues
show
The variable $autoload seems only to be defined at a later point. As such the call to isset() seems to always evaluate to false.

This check marks calls to isset(...) or empty(...) that are found before the variable itself is defined. These will always have the same result.

This is likely the result of code being shifted around. Consider removing these calls.

Loading history...
1377
		{
1378
			return;
1379
		}
1380
1381
		// Autoload packages
1382
		if (isset($autoload['packages']))
1383
		{
1384
			foreach ($autoload['packages'] as $package_path)
1385
			{
1386
				$this->add_package_path($package_path);
1387
			}
1388
		}
1389
1390
		// Load any custom config file
1391
		if (count($autoload['config']) > 0)
1392
		{
1393
			foreach ($autoload['config'] as $val)
1394
			{
1395
				$this->config($val);
1396
			}
1397
		}
1398
1399
		// Autoload helpers and languages
1400
		foreach (array('helper', 'language') as $type)
1401
		{
1402
			if (isset($autoload[$type]) && count($autoload[$type]) > 0)
1403
			{
1404
				$this->$type($autoload[$type]);
1405
			}
1406
		}
1407
1408
		// Autoload drivers
1409
		if (isset($autoload['drivers']))
1410
		{
1411
			$this->driver($autoload['drivers']);
1412
		}
1413
1414
		// Load libraries
1415
		if (isset($autoload['libraries']) && count($autoload['libraries']) > 0)
1416
		{
1417
			// Load the database driver.
1418
			if (in_array('database', $autoload['libraries']))
1419
			{
1420
				$this->database();
1421
				$autoload['libraries'] = array_diff($autoload['libraries'], array('database'));
1422
			}
1423
1424
			// Load all other libraries
1425
			$this->library($autoload['libraries']);
1426
		}
1427
1428
		// Autoload models
1429
		if (isset($autoload['model']))
1430
		{
1431
			$this->model($autoload['model']);
1432
		}
1433
	}
1434
1435
	// --------------------------------------------------------------------
1436
1437
	/**
1438
	 * Prepare variables for _ci_vars, to be later extract()-ed inside views
1439
	 *
1440
	 * Converts objects to associative arrays and filters-out internal
1441
	 * variable names (i.e. keys prefixed with '_ci_').
1442
	 *
1443
	 * @param	mixed	$vars
1444
	 * @return	array
1445
	 *
1446
	 * @codeCoverageIgnore
1447
	 */
1448
	protected function _ci_prepare_view_vars($vars)
1449
	{
1450
		if ( ! is_array($vars))
1451
		{
1452
			$vars = is_object($vars)
1453
				? get_object_vars($vars)
1454
				: array();
1455
		}
1456
1457
		foreach (array_keys($vars) as $key)
1458
		{
1459
			if (strncmp($key, '_ci_', 4) === 0)
1460
			{
1461
				unset($vars[$key]);
1462
			}
1463
		}
1464
1465
		return $vars;
1466
	}
1467
1468
	// --------------------------------------------------------------------
1469
1470
	/**
1471
	 * CI Component getter
1472
	 *
1473
	 * Get a reference to a specific library or model.
1474
	 *
1475
	 * @param 	string	$component	Component name
1476
	 * @return	bool
1477
	 *
1478
	 * @codeCoverageIgnore
1479
	 */
1480
	protected function &_ci_get_component($component)
1481
	{
1482
		$CI =& get_instance();
1483
		return $CI->$component;
1484
	}
1485
}
1486