CI_Loader::model()   C
last analyzed

Complexity

Conditions 14
Paths 71

Size

Total Lines 81
Code Lines 34

Duplication

Lines 17
Ratio 20.99 %

Importance

Changes 0
Metric Value
cc 14
eloc 34
nc 71
nop 3
dl 17
loc 81
rs 5.0042
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php  if ( ! defined('BASEPATH')) {
2
	exit('No direct script access allowed');
3
}
4
/**
5
 * CodeIgniter
6
 *
7
 * An open source application development framework for PHP 5.1.6 or newer
8
 *
9
 * @package		CodeIgniter
10
 * @author		ExpressionEngine Dev Team
11
 * @copyright	Copyright (c) 2008 - 2011, EllisLab, Inc.
12
 * @license		http://codeigniter.com/user_guide/license.html
13
 * @link		http://codeigniter.com
14
 * @since		Version 1.0
15
 * @filesource
16
 */
17
18
// ------------------------------------------------------------------------
19
20
/**
21
 * Loader Class
22
 *
23
 * Loads views and files
24
 *
25
 * @package		CodeIgniter
26
 * @subpackage	Libraries
27
 * @author		ExpressionEngine Dev Team
28
 * @category	Loader
29
 * @link		http://codeigniter.com/user_guide/libraries/loader.html
30
 */
31
class CI_Loader {
32
33
	// All these are set automatically. Don't mess with them.
34
	/**
35
	 * Nesting level of the output buffering mechanism
36
	 *
37
	 * @var int
38
	 * @access protected
39
	 */
40
	protected $_ci_ob_level;
41
	/**
42
	 * List of paths to load views from
43
	 *
44
	 * @var array
45
	 * @access protected
46
	 */
47
	protected $_ci_view_paths = array();
48
	/**
49
	 * List of paths to load libraries from
50
	 *
51
	 * @var array
52
	 * @access protected
53
	 */
54
	protected $_ci_library_paths = array();
55
	/**
56
	 * List of paths to load models from
57
	 *
58
	 * @var array
59
	 * @access protected
60
	 */
61
	protected $_ci_model_paths = array();
62
	/**
63
	 * List of paths to load helpers from
64
	 *
65
	 * @var array
66
	 * @access protected
67
	 */
68
	protected $_ci_helper_paths = array();
69
	/**
70
	 * List of loaded base classes
71
	 * Set by the controller class
72
	 *
73
	 * @var array
74
	 * @access protected
75
	 */
76
	protected $_base_classes = array(); // Set by the controller class
77
	/**
78
	 * List of cached variables
79
	 *
80
	 * @var array
81
	 * @access protected
82
	 */
83
	protected $_ci_cached_vars = array();
84
	/**
85
	 * List of loaded classes
86
	 *
87
	 * @var array
88
	 * @access protected
89
	 */
90
	protected $_ci_classes = array();
91
	/**
92
	 * List of loaded files
93
	 *
94
	 * @var array
95
	 * @access protected
96
	 */
97
	protected $_ci_loaded_files = array();
98
	/**
99
	 * List of loaded models
100
	 *
101
	 * @var array
102
	 * @access protected
103
	 */
104
	protected $_ci_models = array();
105
	/**
106
	 * List of loaded helpers
107
	 *
108
	 * @var array
109
	 * @access protected
110
	 */
111
	protected $_ci_helpers = array();
112
	/**
113
	 * List of class name mappings
114
	 *
115
	 * @var array
116
	 * @access protected
117
	 */
118
	protected $_ci_varmap = array('unit_test' => 'unit',
119
											'user_agent' => 'agent');
120
121
	/**
122
	 * Constructor
123
	 *
124
	 * Sets the path to the view files and gets the initial output buffering level
125
	 */
126
	public function __construct()
127
	{
128
		$this->_ci_ob_level = ob_get_level();
129
		$this->_ci_library_paths = array(APPPATH, BASEPATH);
130
		$this->_ci_helper_paths = array(APPPATH, BASEPATH);
131
		$this->_ci_model_paths = array(APPPATH);
132
		$this->_ci_view_paths = array(APPPATH.'views/'	=> TRUE);
133
134
		log_message('debug', "Loader Class Initialized");
135
	}
136
137
	// --------------------------------------------------------------------
138
139
	/**
140
	 * Initialize the Loader
141
	 *
142
	 * This method is called once in CI_Controller.
143
	 *
144
	 * @param 	array
145
	 * @return 	CI_Loader
146
	 */
147
	public function initialize()
148
	{
149
		$this->_ci_classes = array();
150
		$this->_ci_loaded_files = array();
151
		$this->_ci_models = array();
152
		$this->_base_classes = & is_loaded();
153
154
		$this->_ci_autoloader();
155
156
		return $this;
157
	}
158
159
	// --------------------------------------------------------------------
160
161
	/**
162
	 * Is Loaded
163
	 *
164
	 * A utility function to test if a class is in the self::$_ci_classes array.
165
	 * This function returns the object name if the class tested for is loaded,
166
	 * and returns FALSE if it isn't.
167
	 *
168
	 * It is mainly used in the form_helper -> _get_validation_object()
169
	 *
170
	 * @param 	string	class being checked for
171
	 * @return 	mixed	class object name on the CI SuperObject or FALSE
172
	 */
173
	public function is_loaded($class)
174
	{
175
		if (isset($this->_ci_classes[$class]))
176
		{
177
			return $this->_ci_classes[$class];
178
		}
179
180
		return FALSE;
181
	}
182
183
	// --------------------------------------------------------------------
184
185
	/**
186
	 * Class Loader
187
	 *
188
	 * This function lets users load and instantiate classes.
189
	 * It is designed to be called from a user's app controllers.
190
	 *
191
	 * @param	string	the name of the class
192
	 * @param	mixed	the optional parameters
193
	 * @param	string	an optional object name
194
	 * @return	null|false
195
	 */
196
	public function library($library = '', $params = NULL, $object_name = NULL)
197
	{
198
		if (is_array($library))
199
		{
200
			foreach ($library as $class)
201
			{
202
				$this->library($class, $params);
203
			}
204
205
			return;
206
		}
207
208
		if ($library == '' OR isset($this->_base_classes[$library]))
209
		{
210
			return FALSE;
211
		}
212
213
		if ( ! is_null($params) && ! is_array($params))
214
		{
215
			$params = NULL;
216
		}
217
218
		$this->_ci_load_class($library, $params, $object_name);
219
	}
220
221
	// --------------------------------------------------------------------
222
223
	/**
224
	 * Model Loader
225
	 *
226
	 * This function lets users load and instantiate models.
227
	 *
228
	 * @param	string	the name of the class
229
	 * @param	string	name for the model
230
	 * @param	bool	database connection
231
	 * @return	void
232
	 */
233
	public function model($model, $name = '', $db_conn = FALSE)
234
	{
235
		if (is_array($model))
236
		{
237
			foreach ($model as $babe)
238
			{
239
				$this->model($babe);
240
			}
241
			return;
242
		}
243
244
		if ($model == '')
245
		{
246
			return;
247
		}
248
249
		$path = '';
250
251
		// Is the model in a sub-folder? If so, parse out the filename and path.
252 View Code Duplication
		if (($last_slash = strrpos($model, '/')) !== FALSE)
253
		{
254
			// The path is in front of the last slash
255
			$path = substr($model, 0, $last_slash + 1);
256
257
			// And the model name behind it
258
			$model = substr($model, $last_slash + 1);
259
		}
260
261
		if ($name == '')
262
		{
263
			$name = $model;
264
		}
265
266
		if (in_array($name, $this->_ci_models, TRUE))
267
		{
268
			return;
269
		}
270
271
		$CI = & get_instance();
272
		if (isset($CI->$name))
273
		{
274
			show_error('The model name you are loading is the name of a resource that is already being used: '.$name);
275
		}
276
277
		$model = strtolower($model);
278
279
		foreach ($this->_ci_model_paths as $mod_path)
280
		{
281
			if ( ! file_exists($mod_path.'models/'.$path.$model.'.php'))
282
			{
283
				continue;
284
			}
285
286 View Code Duplication
			if ($db_conn !== FALSE AND ! class_exists('CI_DB'))
287
			{
288
				if ($db_conn === TRUE)
289
				{
290
					$db_conn = '';
291
				}
292
293
				$CI->load->database($db_conn, FALSE, TRUE);
294
			}
295
296
			if ( ! class_exists('CI_Model'))
297
			{
298
				load_class('Model', 'core');
299
			}
300
301
			require_once($mod_path.'models/'.$path.$model.'.php');
302
303
			$model = ucfirst($model);
304
305
			$CI->$name = new $model();
306
307
			$this->_ci_models[] = $name;
308
			return;
309
		}
310
311
		// couldn't find the model
312
		show_error('Unable to locate the model you have specified: '.$model);
313
	}
314
315
	// --------------------------------------------------------------------
316
317
	/**
318
	 * Database Loader
319
	 *
320
	 * @param	string	the DB credentials
321
	 * @param	bool	whether to return the DB object
322
	 * @param	bool	whether to enable active record (this allows us to override the config setting)
323
	 * @return	object
324
	 */
325
	public function database($params = '', $return = FALSE, $active_record = NULL)
326
	{
327
		// Grab the super object
328
		$CI = & get_instance();
329
330
		// Do we even need to load the database class?
331
		if (class_exists('CI_DB') AND $return == FALSE AND $active_record == NULL AND isset($CI->db) AND is_object($CI->db))
0 ignored issues
show
Bug introduced by
The property db does not seem to exist in CI_Controller.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
332
		{
333
			return FALSE;
334
		}
335
336
		require_once(BASEPATH.'database/DB.php');
337
338
		if ($return === TRUE)
339
		{
340
			return DB($params, $active_record);
341
		}
342
343
		// Initialize the db variable.  Needed to prevent
344
		// reference errors with some configurations
345
		$CI->db = '';
346
347
		// Load the DB class
348
		$CI->db = & DB($params, $active_record);
349
	}
350
351
	// --------------------------------------------------------------------
352
353
	/**
354
	 * Load the Utilities Class
355
	 *
356
	 * @return	string
357
	 */
358 View Code Duplication
	public function dbutil()
359
	{
360
		if ( ! class_exists('CI_DB'))
361
		{
362
			$this->database();
363
		}
364
365
		$CI = & get_instance();
366
367
		// for backwards compatibility, load dbforge so we can extend dbutils off it
368
		// this use is deprecated and strongly discouraged
369
		$CI->load->dbforge();
370
371
		require_once(BASEPATH.'database/DB_utility.php');
372
		require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_utility.php');
373
		$class = 'CI_DB_'.$CI->db->dbdriver.'_utility';
0 ignored issues
show
Bug introduced by
The property db does not seem to exist in CI_Controller.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
374
375
		$CI->dbutil = new $class();
0 ignored issues
show
Bug introduced by
The property dbutil does not seem to exist in CI_Controller.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
376
	}
377
378
	// --------------------------------------------------------------------
379
380
	/**
381
	 * Load the Database Forge Class
382
	 *
383
	 * @return	string
384
	 */
385 View Code Duplication
	public function dbforge()
386
	{
387
		if ( ! class_exists('CI_DB'))
388
		{
389
			$this->database();
390
		}
391
392
		$CI = & get_instance();
393
394
		require_once(BASEPATH.'database/DB_forge.php');
395
		require_once(BASEPATH.'database/drivers/'.$CI->db->dbdriver.'/'.$CI->db->dbdriver.'_forge.php');
396
		$class = 'CI_DB_'.$CI->db->dbdriver.'_forge';
0 ignored issues
show
Bug introduced by
The property db does not seem to exist in CI_Controller.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
397
398
		$CI->dbforge = new $class();
0 ignored issues
show
Bug introduced by
The property dbforge does not seem to exist in CI_Controller.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
399
	}
400
401
	// --------------------------------------------------------------------
402
403
	/**
404
	 * Load View
405
	 *
406
	 * This function is used to load a "view" file.  It has three parameters:
407
	 *
408
	 * 1. The name of the "view" file to be included.
409
	 * 2. An associative array of data to be extracted for use in the view.
410
	 * 3. TRUE/FALSE - whether to return the data or load it.  In
411
	 * some cases it's advantageous to be able to return data so that
412
	 * a developer can process it in some way.
413
	 *
414
	 * @param	string
415
	 * @param	array
416
	 * @param	bool
417
	 * @return	string|null
418
	 */
419
	public function view($view, $vars = array(), $return = FALSE)
420
	{
421
		return $this->_ci_load(array('_ci_view' => $view, '_ci_vars' => $this->_ci_object_to_array($vars), '_ci_return' => $return));
422
	}
423
424
	// --------------------------------------------------------------------
425
426
	/**
427
	 * Load File
428
	 *
429
	 * This is a generic file loader
430
	 *
431
	 * @param	string
432
	 * @param	bool
433
	 * @return	string
434
	 */
435
	public function file($path, $return = FALSE)
436
	{
437
		return $this->_ci_load(array('_ci_path' => $path, '_ci_return' => $return));
438
	}
439
440
	// --------------------------------------------------------------------
441
442
	/**
443
	 * Set Variables
444
	 *
445
	 * Once variables are set they become available within
446
	 * the controller class and its "view" files.
447
	 *
448
	 * @param	array
449
	 * @param 	string
450
	 * @return	void
451
	 */
452
	public function vars($vars = array(), $val = '')
453
	{
454
		if ($val != '' AND is_string($vars))
455
		{
456
			$vars = array($vars => $val);
457
		}
458
459
		$vars = $this->_ci_object_to_array($vars);
460
461
		if (is_array($vars) AND count($vars) > 0)
462
		{
463
			foreach ($vars as $key => $val)
464
			{
465
				$this->_ci_cached_vars[$key] = $val;
466
			}
467
		}
468
	}
469
470
	// --------------------------------------------------------------------
471
472
	/**
473
	 * Get Variable
474
	 *
475
	 * Check if a variable is set and retrieve it.
476
	 *
477
	 * @param	array
478
	 * @return	void
479
	 */
480
	public function get_var($key)
481
	{
482
		return isset($this->_ci_cached_vars[$key]) ? $this->_ci_cached_vars[$key] : NULL;
483
	}
484
485
	// --------------------------------------------------------------------
486
487
	/**
488
	 * Load Helper
489
	 *
490
	 * This function loads the specified helper file.
491
	 *
492
	 * @param	mixed
493
	 * @return	void
494
	 */
495
	public function helper($helpers = array())
496
	{
497
		foreach ($this->_ci_prep_filename($helpers, '_helper') as $helper)
498
		{
499
			if (isset($this->_ci_helpers[$helper]))
500
			{
501
				continue;
502
			}
503
504
			$ext_helper = APPPATH.'helpers/'.config_item('subclass_prefix').$helper.'.php';
505
506
			// Is this a helper extension request?
507
			if (file_exists($ext_helper))
508
			{
509
				$base_helper = BASEPATH.'helpers/'.$helper.'.php';
510
511
				if ( ! file_exists($base_helper))
512
				{
513
					show_error('Unable to load the requested file: helpers/'.$helper.'.php');
514
				}
515
516
				include_once($ext_helper);
517
				include_once($base_helper);
518
519
				$this->_ci_helpers[$helper] = TRUE;
520
				log_message('debug', 'Helper loaded: '.$helper);
521
				continue;
522
			}
523
524
			// Try to load the helper
525
			foreach ($this->_ci_helper_paths as $path)
526
			{
527
				if (file_exists($path.'helpers/'.$helper.'.php'))
528
				{
529
					include_once($path.'helpers/'.$helper.'.php');
530
531
					$this->_ci_helpers[$helper] = TRUE;
532
					log_message('debug', 'Helper loaded: '.$helper);
533
					break;
534
				}
535
			}
536
537
			// unable to load the helper
538
			if ( ! isset($this->_ci_helpers[$helper]))
539
			{
540
				show_error('Unable to load the requested file: helpers/'.$helper.'.php');
541
			}
542
		}
543
	}
544
545
	// --------------------------------------------------------------------
546
547
	/**
548
	 * Load Helpers
549
	 *
550
	 * This is simply an alias to the above function in case the
551
	 * user has written the plural form of this function.
552
	 *
553
	 * @param	array
554
	 * @return	void
555
	 */
556
	public function helpers($helpers = array())
557
	{
558
		$this->helper($helpers);
559
	}
560
561
	// --------------------------------------------------------------------
562
563
	/**
564
	 * Loads a language file
565
	 *
566
	 * @param	array
567
	 * @param	string
568
	 * @return	void
569
	 */
570
	public function language($file = array(), $lang = '')
571
	{
572
		$CI = & get_instance();
573
574
		if ( ! is_array($file))
575
		{
576
			$file = array($file);
577
		}
578
579
		foreach ($file as $langfile)
580
		{
581
			$CI->lang->load($langfile, $lang);
0 ignored issues
show
Bug introduced by
The property lang does not seem to exist in CI_Controller.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
582
		}
583
	}
584
585
	// --------------------------------------------------------------------
586
587
	/**
588
	 * Loads a config file
589
	 *
590
	 * @param	string
591
	 * @param	bool
592
	 * @param 	bool
593
	 * @return	void
594
	 */
595
	public function config($file = '', $use_sections = FALSE, $fail_gracefully = FALSE)
596
	{
597
		$CI = & get_instance();
598
		$CI->config->load($file, $use_sections, $fail_gracefully);
0 ignored issues
show
Bug introduced by
The property config does not seem to exist in CI_Controller.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
599
	}
600
601
	// --------------------------------------------------------------------
602
603
	/**
604
	 * Driver
605
	 *
606
	 * Loads a driver library
607
	 *
608
	 * @param	string	the name of the class
609
	 * @param	mixed	the optional parameters
610
	 * @param	string	an optional object name
611
	 * @return	false|null
612
	 */
613
	public function driver($library = '', $params = NULL, $object_name = NULL)
614
	{
615
		if ( ! class_exists('CI_Driver_Library'))
616
		{
617
			// we aren't instantiating an object here, that'll be done by the Library itself
618
			require BASEPATH.'libraries/Driver.php';
619
		}
620
621
		if ($library == '')
622
		{
623
			return FALSE;
624
		}
625
626
		// We can save the loader some time since Drivers will *always* be in a subfolder,
627
		// and typically identically named to the library
628
		if ( ! strpos($library, '/'))
629
		{
630
			$library = ucfirst($library).'/'.$library;
631
		}
632
633
		return $this->library($library, $params, $object_name);
634
	}
635
636
	// --------------------------------------------------------------------
637
638
	/**
639
	 * Add Package Path
640
	 *
641
	 * Prepends a parent path to the library, model, helper, and config path arrays
642
	 *
643
	 * @param	string
644
	 * @param 	boolean
645
	 * @return	void
646
	 */
647
	public function add_package_path($path, $view_cascade = TRUE)
648
	{
649
		$path = rtrim($path, '/').'/';
650
651
		array_unshift($this->_ci_library_paths, $path);
652
		array_unshift($this->_ci_model_paths, $path);
653
		array_unshift($this->_ci_helper_paths, $path);
654
655
		$this->_ci_view_paths = array($path.'views/' => $view_cascade) + $this->_ci_view_paths;
656
657
		// Add config file path
658
		$config = & $this->_ci_get_component('config');
659
		array_unshift($config->_config_paths, $path);
660
	}
661
662
	// --------------------------------------------------------------------
663
664
	/**
665
	 * Get Package Paths
666
	 *
667
	 * Return a list of all package paths, by default it will ignore BASEPATH.
668
	 *
669
	 * @param	string
670
	 * @return	void
671
	 */
672
	public function get_package_paths($include_base = FALSE)
673
	{
674
		return $include_base === TRUE ? $this->_ci_library_paths : $this->_ci_model_paths;
675
	}
676
677
	// --------------------------------------------------------------------
678
679
	/**
680
	 * Remove Package Path
681
	 *
682
	 * Remove a path from the library, model, and helper path arrays if it exists
683
	 * If no path is provided, the most recently added path is removed.
684
	 *
685
	 * @param	type
686
	 * @param 	bool
687
	 * @return	type
688
	 */
689
	public function remove_package_path($path = '', $remove_config_path = TRUE)
0 ignored issues
show
Unused Code introduced by
The parameter $remove_config_path is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
690
	{
691
		$config = & $this->_ci_get_component('config');
692
693
		if ($path == '')
694
		{
695
			$void = array_shift($this->_ci_library_paths);
696
			$void = array_shift($this->_ci_model_paths);
697
			$void = array_shift($this->_ci_helper_paths);
698
			$void = array_shift($this->_ci_view_paths);
699
			$void = array_shift($config->_config_paths);
700
		} else
701
		{
702
			$path = rtrim($path, '/').'/';
703
			foreach (array('_ci_library_paths', '_ci_model_paths', '_ci_helper_paths') as $var)
704
			{
705
				if (($key = array_search($path, $this->{$var})) !== FALSE)
706
				{
707
					unset($this->{$var}[$key]);
708
				}
709
			}
710
711
			if (isset($this->_ci_view_paths[$path.'views/']))
712
			{
713
				unset($this->_ci_view_paths[$path.'views/']);
714
			}
715
716
			if (($key = array_search($path, $config->_config_paths)) !== FALSE)
717
			{
718
				unset($config->_config_paths[$key]);
719
			}
720
		}
721
722
		// make sure the application default paths are still in the array
723
		$this->_ci_library_paths = array_unique(array_merge($this->_ci_library_paths, array(APPPATH, BASEPATH)));
724
		$this->_ci_helper_paths = array_unique(array_merge($this->_ci_helper_paths, array(APPPATH, BASEPATH)));
725
		$this->_ci_model_paths = array_unique(array_merge($this->_ci_model_paths, array(APPPATH)));
726
		$this->_ci_view_paths = array_merge($this->_ci_view_paths, array(APPPATH.'views/' => TRUE));
727
		$config->_config_paths = array_unique(array_merge($config->_config_paths, array(APPPATH)));
728
	}
729
730
	// --------------------------------------------------------------------
731
732
	/**
733
	 * Loader
734
	 *
735
	 * This function is used to load views and files.
736
	 * Variables are prefixed with _ci_ to avoid symbol collision with
737
	 * variables made available to view files
738
	 *
739
	 * @param	array
740
	 * @return	string|null
741
	 */
742
	protected function _ci_load($_ci_data)
743
	{
744
		// Set the default data variables
745
		foreach (array('_ci_view', '_ci_vars', '_ci_path', '_ci_return') as $_ci_val)
746
		{
747
			$$_ci_val = ( ! isset($_ci_data[$_ci_val])) ? FALSE : $_ci_data[$_ci_val];
748
		}
749
750
		$file_exists = FALSE;
751
752
		// Set the path to the requested file
753
		if ($_ci_path != '')
0 ignored issues
show
Bug introduced by
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...
754
		{
755
			$_ci_x = explode('/', $_ci_path);
0 ignored issues
show
Bug introduced by
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...
756
			$_ci_file = end($_ci_x);
757
		} else
758
		{
759
			$_ci_ext = pathinfo($_ci_view, PATHINFO_EXTENSION);
0 ignored issues
show
Bug introduced by
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...
760
			$_ci_file = ($_ci_ext == '') ? $_ci_view.'.php' : $_ci_view;
761
762 View Code Duplication
			foreach ($this->_ci_view_paths as $view_file => $cascade)
763
			{
764
				if (file_exists($view_file.$_ci_file))
765
				{
766
					$_ci_path = $view_file.$_ci_file;
767
					$file_exists = TRUE;
768
					break;
769
				}
770
771
				if ( ! $cascade)
772
				{
773
					break;
774
				}
775
			}
776
		}
777
778
		if ( ! $file_exists && ! file_exists($_ci_path))
0 ignored issues
show
Bug introduced by
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...
779
		{
780
			show_error('Unable to load the requested file: '.$_ci_file);
781
		}
782
783
		// This allows anything loaded using $this->load (views, files, etc.)
784
		// to become accessible from within the Controller and Model functions.
785
786
		$_ci_CI = & get_instance();
787
		foreach (get_object_vars($_ci_CI) as $_ci_key => $_ci_var)
788
		{
789
			if ( ! isset($this->$_ci_key))
790
			{
791
				$this->$_ci_key = & $_ci_CI->$_ci_key;
792
			}
793
		}
794
795
		/*
796
		 * Extract and cache variables
797
		 *
798
		 * You can either set variables using the dedicated $this->load_vars()
799
		 * function or via the second parameter of this function. We'll merge
800
		 * the two types and cache them so that views that are embedded within
801
		 * other views can have access to these variables.
802
		 */
803
		if (is_array($_ci_vars))
804
		{
805
			$this->_ci_cached_vars = array_merge($this->_ci_cached_vars, $_ci_vars);
0 ignored issues
show
Bug introduced by
The variable $_ci_vars 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...
806
		}
807
		extract($this->_ci_cached_vars);
808
809
		/*
810
		 * Buffer the output
811
		 *
812
		 * We buffer the output for two reasons:
813
		 * 1. Speed. You get a significant speed boost.
814
		 * 2. So that the final rendered template can be
815
		 * post-processed by the output class.  Why do we
816
		 * need post processing?  For one thing, in order to
817
		 * show the elapsed page load time.  Unless we
818
		 * can intercept the content right before it's sent to
819
		 * the browser and then stop the timer it won't be accurate.
820
		 */
821
		ob_start();
822
823
		// If the PHP installation does not support short tags we'll
824
		// do a little string replacement, changing the short tags
825
		// to standard PHP echo statements.
826
827 View Code Duplication
		if ((bool)@ini_get('short_open_tag') === FALSE AND config_item('rewrite_short_tags') == TRUE)
828
		{
829
			echo eval('?>'.preg_replace("/;*\s*\?>/", "; ?>", str_replace('<?=', '<?php echo ', file_get_contents($_ci_path))));
0 ignored issues
show
Coding Style introduced by
It is generally not recommended to use eval unless absolutely required.

On one hand, eval might be exploited by malicious users if they somehow manage to inject dynamic content. On the other hand, with the emergence of faster PHP runtimes like the HHVM, eval prevents some optimization that they perform.

Loading history...
830
		} else
831
		{
832
			include($_ci_path); // include() vs include_once() allows for multiple views with the same name
833
		}
834
835
		log_message('debug', 'File loaded: '.$_ci_path);
836
837
		// Return the file data if requested
838
		if ($_ci_return === TRUE)
839
		{
840
			$buffer = ob_get_contents();
841
			@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...
842
			return $buffer;
843
		}
844
845
		/*
846
		 * Flush the buffer... or buff the flusher?
847
		 *
848
		 * In order to permit views to be nested within
849
		 * other views, we need to flush the content back out whenever
850
		 * we are beyond the first level of output buffering so that
851
		 * it can be seen and included properly by the first included
852
		 * template and any subsequent ones. Oy!
853
		 *
854
		 */
855
		if (ob_get_level() > $this->_ci_ob_level + 1)
856
		{
857
			ob_end_flush();
858
		} else
859
		{
860
			$_ci_CI->output->append_output(ob_get_contents());
0 ignored issues
show
Bug introduced by
The property output does not seem to exist in CI_Controller.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
861
			@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...
862
		}
863
	}
864
865
	// --------------------------------------------------------------------
866
867
	/**
868
	 * Load class
869
	 *
870
	 * This function loads the requested class.
871
	 *
872
	 * @param	string	the item that is being loaded
873
	 * @param	mixed	any additional parameters
874
	 * @param	string	an optional object name
875
	 * @param string $class
876
	 * @return	void
877
	 */
878
	protected function _ci_load_class($class, $params = NULL, $object_name = NULL)
879
	{
880
		// Get the class name, and while we're at it trim any slashes.
881
		// The directory path can be included as part of the class name,
882
		// but we don't want a leading slash
883
		$class = str_replace('.php', '', trim($class, '/'));
884
885
		// Was the path included with the class name?
886
		// We look for a slash to determine this
887
		$subdir = '';
888 View Code Duplication
		if (($last_slash = strrpos($class, '/')) !== FALSE)
889
		{
890
			// Extract the path
891
			$subdir = substr($class, 0, $last_slash + 1);
892
893
			// Get the filename from the path
894
			$class = substr($class, $last_slash + 1);
895
		}
896
897
		// We'll test for both lowercase and capitalized versions of the file name
898
		foreach (array(ucfirst($class), strtolower($class)) as $class)
899
		{
900
			$subclass = APPPATH.'libraries/'.$subdir.config_item('subclass_prefix').$class.'.php';
901
902
			// Is this a class extension request?
903
			if (file_exists($subclass))
904
			{
905
				$baseclass = BASEPATH.'libraries/'.ucfirst($class).'.php';
906
907
				if ( ! file_exists($baseclass))
908
				{
909
					log_message('error', "Unable to load the requested class: ".$class);
910
					show_error("Unable to load the requested class: ".$class);
911
				}
912
913
				// Safety:  Was the class already loaded by a previous call?
914 View Code Duplication
				if (in_array($subclass, $this->_ci_loaded_files))
915
				{
916
					// Before we deem this to be a duplicate request, let's see
917
					// if a custom object name is being supplied.  If so, we'll
918
					// return a new instance of the object
919
					if ( ! is_null($object_name))
920
					{
921
						$CI = & get_instance();
922
						if ( ! isset($CI->$object_name))
923
						{
924
							return $this->_ci_init_class($class, config_item('subclass_prefix'), $params, $object_name);
925
						}
926
					}
927
928
					$is_duplicate = TRUE;
929
					log_message('debug', $class." class already loaded. Second attempt ignored.");
930
					return;
931
				}
932
933
				include_once($baseclass);
934
				include_once($subclass);
935
				$this->_ci_loaded_files[] = $subclass;
936
937
				return $this->_ci_init_class($class, config_item('subclass_prefix'), $params, $object_name);
938
			}
939
940
			// Lets search for the requested library file and load it.
941
			$is_duplicate = FALSE;
942
			foreach ($this->_ci_library_paths as $path)
943
			{
944
				$filepath = $path.'libraries/'.$subdir.$class.'.php';
945
946
				// Does the file exist?  No?  Bummer...
947
				if ( ! file_exists($filepath))
948
				{
949
					continue;
950
				}
951
952
				// Safety:  Was the class already loaded by a previous call?
953 View Code Duplication
				if (in_array($filepath, $this->_ci_loaded_files))
954
				{
955
					// Before we deem this to be a duplicate request, let's see
956
					// if a custom object name is being supplied.  If so, we'll
957
					// return a new instance of the object
958
					if ( ! is_null($object_name))
959
					{
960
						$CI = & get_instance();
961
						if ( ! isset($CI->$object_name))
962
						{
963
							return $this->_ci_init_class($class, '', $params, $object_name);
964
						}
965
					}
966
967
					$is_duplicate = TRUE;
968
					log_message('debug', $class." class already loaded. Second attempt ignored.");
969
					return;
970
				}
971
972
				include_once($filepath);
973
				$this->_ci_loaded_files[] = $filepath;
974
				return $this->_ci_init_class($class, '', $params, $object_name);
975
			}
976
977
		} // END FOREACH
978
979
		// One last attempt.  Maybe the library is in a subdirectory, but it wasn't specified?
980
		if ($subdir == '')
981
		{
982
			$path = strtolower($class).'/'.$class;
983
			return $this->_ci_load_class($path, $params);
984
		}
985
986
		// If we got this far we were unable to find the requested class.
987
		// We do not issue errors if the load call failed due to a duplicate request
988
		if ($is_duplicate == FALSE)
0 ignored issues
show
Bug introduced by
The variable $is_duplicate 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...
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
989
		{
990
			log_message('error', "Unable to load the requested class: ".$class);
991
			show_error("Unable to load the requested class: ".$class);
992
		}
993
	}
994
995
	// --------------------------------------------------------------------
996
997
	/**
998
	 * Instantiates a class
999
	 *
1000
	 * @param	string
1001
	 * @param	string
1002
	 * @param	bool
1003
	 * @param	string	an optional object name
1004
	 * @param string $class
1005
	 * @return	null
1006
	 */
1007
	protected function _ci_init_class($class, $prefix = '', $config = FALSE, $object_name = NULL)
1008
	{
1009
		// Is there an associated config file for this class?  Note: these should always be lowercase
1010
		if ($config === NULL)
1011
		{
1012
			// Fetch the config paths containing any package paths
1013
			$config_component = $this->_ci_get_component('config');
1014
1015
			if (is_array($config_component->_config_paths))
1016
			{
1017
				// Break on the first found file, thus package files
1018
				// are not overridden by default paths
1019
				foreach ($config_component->_config_paths as $path)
1020
				{
1021
					// We test for both uppercase and lowercase, for servers that
1022
					// are case-sensitive with regard to file names. Check for environment
1023
					// first, global next
1024
					if (defined('ENVIRONMENT') AND file_exists($path.'config/'.ENVIRONMENT.'/'.strtolower($class).'.php'))
1025
					{
1026
						include($path.'config/'.ENVIRONMENT.'/'.strtolower($class).'.php');
1027
						break;
1028
					}
1029
					elseif (defined('ENVIRONMENT') AND file_exists($path.'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php'))
1030
					{
1031
						include($path.'config/'.ENVIRONMENT.'/'.ucfirst(strtolower($class)).'.php');
1032
						break;
1033
					}
1034 View Code Duplication
					elseif (file_exists($path.'config/'.strtolower($class).'.php'))
1035
					{
1036
						include($path.'config/'.strtolower($class).'.php');
1037
						break;
1038
					}
1039 View Code Duplication
					elseif (file_exists($path.'config/'.ucfirst(strtolower($class)).'.php'))
1040
					{
1041
						include($path.'config/'.ucfirst(strtolower($class)).'.php');
1042
						break;
1043
					}
1044
				}
1045
			}
1046
		}
1047
1048
		if ($prefix == '')
1049
		{
1050
			if (class_exists('CI_'.$class))
1051
			{
1052
				$name = 'CI_'.$class;
1053
			} elseif (class_exists(config_item('subclass_prefix').$class))
1054
			{
1055
				$name = config_item('subclass_prefix').$class;
1056
			} else
1057
			{
1058
				$name = $class;
1059
			}
1060
		} else
1061
		{
1062
			$name = $prefix.$class;
1063
		}
1064
1065
		// Is the class name valid?
1066
		if ( ! class_exists($name))
1067
		{
1068
			log_message('error', "Non-existent class: ".$name);
1069
			show_error("Non-existent class: ".$class);
1070
		}
1071
1072
		// Set the variable name we will assign the class to
1073
		// Was a custom class name supplied?  If so we'll use it
1074
		$class = strtolower($class);
1075
1076
		if (is_null($object_name))
1077
		{
1078
			$classvar = ( ! isset($this->_ci_varmap[$class])) ? $class : $this->_ci_varmap[$class];
1079
		} else
1080
		{
1081
			$classvar = $object_name;
1082
		}
1083
1084
		// Save the class name and object name
1085
		$this->_ci_classes[$class] = $classvar;
1086
1087
		// Instantiate the class
1088
		$CI = & get_instance();
1089
		if ($config !== NULL)
1090
		{
1091
			$CI->$classvar = new $name($config);
1092
		} else
1093
		{
1094
			$CI->$classvar = new $name;
1095
		}
1096
	}
1097
1098
	// --------------------------------------------------------------------
1099
1100
	/**
1101
	 * Autoloader
1102
	 *
1103
	 * The config/autoload.php file contains an array that permits sub-systems,
1104
	 * libraries, and helpers to be loaded automatically.
1105
	 *
1106
	 * @param	array
1107
	 * @return	false|null
1108
	 */
1109
	private function _ci_autoloader()
1110
	{
1111 View Code Duplication
		if (defined('ENVIRONMENT') AND file_exists(APPPATH.'config/'.ENVIRONMENT.'/autoload.php'))
1112
		{
1113
			include(APPPATH.'config/'.ENVIRONMENT.'/autoload.php');
1114
		} else
1115
		{
1116
			include(APPPATH.'config/autoload.php');
1117
		}
1118
1119
		if ( ! isset($autoload))
0 ignored issues
show
Bug introduced by
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...
1120
		{
1121
			return FALSE;
1122
		}
1123
1124
		// Autoload packages
1125
		if (isset($autoload['packages']))
1126
		{
1127
			foreach ($autoload['packages'] as $package_path)
1128
			{
1129
				$this->add_package_path($package_path);
1130
			}
1131
		}
1132
1133
		// Load any custom config file
1134
		if (count($autoload['config']) > 0)
1135
		{
1136
			$CI = & get_instance();
1137
			foreach ($autoload['config'] as $key => $val)
1138
			{
1139
				$CI->config->load($val);
0 ignored issues
show
Bug introduced by
The property config does not seem to exist in CI_Controller.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1140
			}
1141
		}
1142
1143
		// Autoload helpers and languages
1144 View Code Duplication
		foreach (array('helper', 'language') as $type)
1145
		{
1146
			if (isset($autoload[$type]) AND count($autoload[$type]) > 0)
1147
			{
1148
				$this->$type($autoload[$type]);
1149
			}
1150
		}
1151
1152
		// A little tweak to remain backward compatible
1153
		// The $autoload['core'] item was deprecated
1154
		if ( ! isset($autoload['libraries']) AND isset($autoload['core']))
1155
		{
1156
			$autoload['libraries'] = $autoload['core'];
1157
		}
1158
1159
		// Load libraries
1160
		if (isset($autoload['libraries']) AND count($autoload['libraries']) > 0)
1161
		{
1162
			// Load the database driver.
1163
			if (in_array('database', $autoload['libraries']))
1164
			{
1165
				$this->database();
1166
				$autoload['libraries'] = array_diff($autoload['libraries'], array('database'));
1167
			}
1168
1169
			// Load all other libraries
1170
			foreach ($autoload['libraries'] as $item)
1171
			{
1172
				$this->library($item);
1173
			}
1174
		}
1175
1176
		// Autoload models
1177
		if (isset($autoload['model']))
1178
		{
1179
			$this->model($autoload['model']);
1180
		}
1181
	}
1182
1183
	// --------------------------------------------------------------------
1184
1185
	/**
1186
	 * Object to Array
1187
	 *
1188
	 * Takes an object as input and converts the class variables to array key/vals
1189
	 *
1190
	 * @param	object
1191
	 * @return	array
1192
	 */
1193
	protected function _ci_object_to_array($object)
1194
	{
1195
		return (is_object($object)) ? get_object_vars($object) : $object;
1196
	}
1197
1198
	// --------------------------------------------------------------------
1199
1200
	/**
1201
	 * Get a reference to a specific library or model
1202
	 *
1203
	 * @param 	string
1204
	 * @param string $component
1205
	 * @return	bool
1206
	 */
1207
	protected function &_ci_get_component($component)
1208
	{
1209
		$CI = & get_instance();
1210
		return $CI->$component;
1211
	}
1212
1213
	// --------------------------------------------------------------------
1214
1215
	/**
1216
	 * Prep filename
1217
	 *
1218
	 * This function preps the name of various items to make loading them more reliable.
1219
	 *
1220
	 * @param	mixed
1221
	 * @param 	string
1222
	 * @param string $extension
1223
	 * @return	array
1224
	 */
1225
	protected function _ci_prep_filename($filename, $extension)
1226
	{
1227
		if ( ! is_array($filename))
1228
		{
1229
			return array(strtolower(str_replace('.php', '', str_replace($extension, '', $filename)).$extension));
1230
		} else
1231
		{
1232
			foreach ($filename as $key => $val)
1233
			{
1234
				$filename[$key] = strtolower(str_replace('.php', '', str_replace($extension, '', $val)).$extension);
1235
			}
1236
1237
			return $filename;
1238
		}
1239
	}
1240
}
1241
1242
/* End of file Loader.php */
1243
/* Location: ./system/core/Loader.php */