Passed
Branch 1.0.0-dev (4efac2)
by nguereza
04:41
created

Loader::loadResourcesFromAutoloadConfig()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 25
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 13
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 25
rs 9.8333
1
<?php
2
	defined('ROOT_PATH') || exit('Access denied');
3
	/**
4
	 * TNH Framework
5
	 *
6
	 * A simple PHP framework using HMVC architecture
7
	 *
8
	 * This content is released under the GNU GPL License (GPL)
9
	 *
10
	 * Copyright (C) 2017 Tony NGUEREZA
11
	 *
12
	 * This program is free software; you can redistribute it and/or
13
	 * modify it under the terms of the GNU General Public License
14
	 * as published by the Free Software Foundation; either version 3
15
	 * of the License, or (at your option) any later version.
16
	 *
17
	 * This program is distributed in the hope that it will be useful,
18
	 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19
	 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
	 * GNU General Public License for more details.
21
	 *
22
	 * You should have received a copy of the GNU General Public License
23
	 * along with this program; if not, write to the Free Software
24
	 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25
	*/
26
	class Loader{
27
		
28
		/**
29
		 * List of loaded resources
30
		 * @var array
31
		 */
32
		public static $loaded = array();
33
		
34
		/**
35
		 * The logger instance
36
		 * @var Log
37
		 */
38
		private static $logger;
39
40
41
		public function __construct(){
42
			//add the resources already loaded during application bootstrap
43
			//in the list to prevent duplicate or loading the resources again.
44
			static::$loaded = class_loaded();
45
			
46
			//Load resources from autoload configuration
47
			$this->loadResourcesFromAutoloadConfig();
48
		}
49
50
		/**
51
		 * Get the logger singleton instance
52
		 * @return Log the logger instance
53
		 */
54
		private static function getLogger(){
55
			if(self::$logger == null){
56
				self::$logger[0] =& class_loader('Log', 'classes');
57
				self::$logger[0]->setLogger('Library::Loader');
58
			}
59
			return self::$logger[0];
60
		}
61
62
		/**
63
		 * Load the model class
64
		 *
65
		 * @param  string $class    the class name to be loaded
66
		 * @param  string $instance the name of the instance to use in super object
67
		 *
68
		 * @return void
69
		 */
70
		public static function model($class, $instance = null){
71
			$logger = static::getLogger();
72
			$class = str_ireplace('.php', '', $class);
73
			$class = trim($class, '/\\');
74
			$file = ucfirst($class).'.php';
75
			$logger->debug('Loading model [' . $class . '] ...');
76
			if(! $instance){
77
				//for module
78
				if(strpos($class, '/') !== false){
79
					$path = explode('/', $class);
80
					if(isset($path[1])){
81
						$instance = strtolower($path[1]);
82
					}
83
				}
84
				else{
85
					$instance = strtolower($class);
86
				}
87
			}
88
			if(isset(static::$loaded[$instance])){
89
				$logger->info('Model [' . $class . '] already loaded no need to load it again, cost in performance');
90
				return;
91
			}
92
			$classFilePath = APPS_MODEL_PATH . $file;
93
			//first check if this model is in the module
94
			$logger->debug('Checking model [' . $class . '] from module list ...');
95
			$searchModuleName = null;
96
			$obj = & get_instance();
97
			//check if the request class contains module name
98
			if(strpos($class, '/') !== false){
99
				$path = explode('/', $class);
100
				if(isset($path[0]) && in_array($path[0], Module::getModuleList())){
101
					$searchModuleName = $path[0];
102
					$class = ucfirst($path[1]);
103
				}
104
			}
105
			else{
106
				$class = ucfirst($class);
107
			}
108
109
			if(! $searchModuleName && !empty($obj->moduleName)){
110
				$searchModuleName = $obj->moduleName;
111
			}
112
			$moduleModelFilePath = Module::findModelFullPath($class, $searchModuleName);
113
			if($moduleModelFilePath){
114
				$logger->info('Found model [' . $class . '] from module [' .$searchModuleName. '], the file path is [' .$moduleModelFilePath. '] we will used it');
115
				$classFilePath = $moduleModelFilePath;
116
			}
117
			else{
118
				$logger->info('Cannot find model [' . $class . '] from modules using the default location');
119
			}
120
			$logger->info('The model file path to be loaded is [' . $classFilePath . ']');
121
			if(file_exists($classFilePath)){
122
				require_once $classFilePath;
123
				if(class_exists($class)){
124
					$c = new $class();
125
					$obj = & get_instance();
126
					$obj->{$instance} = $c;
127
					static::$loaded[$instance] = $class;
128
					$logger->info('Model [' . $class . '] --> ' . $classFilePath . ' loaded successfully.');
129
				}
130
				else{
131
					show_error('The file '.$classFilePath.' exists but does not contain the class ['. $class . ']');
132
				}
133
			}
134
			else{
135
				show_error('Unable to find the model [' . $class . ']');
136
			}
137
		}
138
139
140
		/**
141
		 * Load the library class
142
		 *
143
		 * @param  string $class    the library class name to be loaded
144
		 * @param  string $instance the instance name to use in super object
145
		 * @param mixed $params the arguments to pass to the constructor
146
		 *
147
		 * @return void
148
		 */
149
		public static function library($class, $instance = null, array $params = array()){
150
			$logger = static::getLogger();
151
			$class = str_ireplace('.php', '', $class);
152
			$class = trim($class, '/\\');
153
			$file = ucfirst($class) .'.php';
154
			$logger->debug('Loading library [' . $class . '] ...');
155
			if(! $instance){
156
				//for module
157
				if(strpos($class, '/') !== false){
158
					$path = explode('/', $class);
159
					if(isset($path[1])){
160
						$instance = strtolower($path[1]);
161
					}
162
				}
163
				else{
164
					$instance = strtolower($class);
165
				}
166
			}
167
			if(isset(static::$loaded[$instance])){
168
				$logger->info('Library [' . $class . '] already loaded no need to load it again, cost in performance');
169
				return;
170
			}
171
			$obj = & get_instance();
172
			//TODO for Database library
173
			if(strtolower($class) == 'database'){
174
				$logger->info('This is the Database library ...');
175
				$dbInstance = & class_loader('Database', 'classes', $params);
176
				$obj->{$instance} = $dbInstance;
177
				static::$loaded[$instance] = $class;
178
				$logger->info('Library Database loaded successfully.');
179
				return;
180
			}
181
			$libraryFilePath = null;
182
			$logger->debug('Check if this is a system library ...');
183
			if(file_exists(CORE_LIBRARY_PATH . $file)){
184
				$libraryFilePath = CORE_LIBRARY_PATH . $file;
185
				$class = ucfirst($class);
186
				$logger->info('This library is a system library');
187
			}
188
			else{
189
				$logger->info('This library is not a system library');	
190
				//first check if this library is in the module
191
				$logger->debug('Checking library [' . $class . '] from module list ...');
192
				$searchModuleName = null;
193
				//check if the request class contains module name
194
				if(strpos($class, '/') !== false){
195
					$path = explode('/', $class);
196
					if(isset($path[0]) && in_array($path[0], Module::getModuleList())){
197
						$searchModuleName = $path[0];
198
						$class = ucfirst($path[1]);
199
					}
200
				}
201
				else{
202
					$class = ucfirst($class);
203
				}
204
				if(! $searchModuleName && !empty($obj->moduleName)){
205
					$searchModuleName = $obj->moduleName;
206
				}
207
				$moduleLibraryPath = Module::findLibraryFullPath($class, $searchModuleName);
208
				if($moduleLibraryPath){
209
					$logger->info('Found library [' . $class . '] from module [' .$searchModuleName. '], the file path is [' .$moduleLibraryPath. '] we will used it');
210
					$libraryFilePath = $moduleLibraryPath;
211
				}
212
				else{
213
					$logger->info('Cannot find library [' . $class . '] from modules using the default location');
214
				}
215
			}
216
			if(! $libraryFilePath){
217
				$searchDir = array(LIBRARY_PATH);
218
				foreach($searchDir as $dir){
219
					$filePath = $dir . $file;
220
					if(file_exists($filePath)){
221
						$libraryFilePath = $filePath;
222
						//is already found not to continue
223
						break;
224
					}
225
				}
226
			}
227
			$logger->info('The library file path to be loaded is [' . $libraryFilePath . ']');
228
			if($libraryFilePath){
229
				require_once $libraryFilePath;
230
				if(class_exists($class)){
231
					$c = $params ? new $class($params) : new $class();
232
					$obj = & get_instance();
233
					$obj->{$instance} = $c;
234
					static::$loaded[$instance] = $class;
235
					$logger->info('Library [' . $class . '] --> ' . $libraryFilePath . ' loaded successfully.');
236
				}
237
				else{
238
					show_error('The file '.$libraryFilePath.' exists but does not contain the class '.$class);
239
				}
240
			}
241
			else{
242
				show_error('Unable to find library class [' . $class . ']');
243
			}
244
		}
245
246
		/**
247
		 * Load the helper
248
		 *
249
		 * @param  string $function the helper name to be loaded
250
		 *
251
		 * @return void
252
		 */
253
		public static function functions($function){
254
			$logger = static::getLogger();
255
			$function = str_ireplace('.php', '', $function);
256
			$function = trim($function, '/\\');
257
			$function = str_ireplace('function_', '', $function);
258
			$file = 'function_'.$function.'.php';
259
			$logger->debug('Loading helper [' . $function . '] ...');
260
			if(isset(static::$loaded['function_' . $function])){
261
				$logger->info('Helper [' . $function . '] already loaded no need to load it again, cost in performance');
262
				return;
263
			}
264
			$functionFilePath = null;
265
			//first check if this helper is in the module
266
			$logger->debug('Checking helper [' . $function . '] from module list ...');
267
			$searchModuleName = null;
268
			$obj = & get_instance();
269
			//check if the request class contains module name
270
			if(strpos($function, '/') !== false){
271
				$path = explode('/', $function);
272
				if(isset($path[0]) && in_array($path[0], Module::getModuleList())){
273
					$searchModuleName = $path[0];
274
					$function = 'function_' . $path[1] . '.php';
275
					$file = $path[0] . DS . 'function_'.$function.'.php';
276
				}
277
			}
278
			if(! $searchModuleName && !empty($obj->moduleName)){
279
				$searchModuleName = $obj->moduleName;
280
			}
281
			$moduleFunctionPath = Module::findFunctionFullPath($function, $searchModuleName);
282
			if($moduleFunctionPath){
283
				$logger->info('Found helper [' . $function . '] from module [' .$searchModuleName. '], the file path is [' .$moduleFunctionPath. '] we will used it');
284
				$functionFilePath = $moduleFunctionPath;
285
			}
286
			else{
287
				$logger->info('Cannot find helper [' . $function . '] from modules using the default location');
288
			}
289
			if(! $functionFilePath){
290
				$searchDir = array(FUNCTIONS_PATH, CORE_FUNCTIONS_PATH);
291
				foreach($searchDir as $dir){
292
					$filePath = $dir . $file;
293
					if(file_exists($filePath)){
294
						$functionFilePath = $filePath;
295
						//is already found not to continue
296
						break;
297
					}
298
				}
299
			}
300
			$logger->info('The helper file path to be loaded is [' . $functionFilePath . ']');
301
			if($functionFilePath){
302
				require_once $functionFilePath;
303
				static::$loaded['function_' . $function] = $functionFilePath;
304
				$logger->info('Helper [' . $function . '] --> ' . $functionFilePath . ' loaded successfully.');
305
			}
306
			else{
307
				show_error('Unable to find helper file [' . $file . ']');
308
			}
309
		}
310
311
		/**
312
		 * Load the configuration file
313
		 *
314
		 * @param  string $filename the configuration filename located at CONFIG_PATH or MODULE_PATH/config
315
		 *
316
		 * @return void
317
		 */
318
		public static function config($filename){
319
			$logger = static::getLogger();
320
			$filename = str_ireplace('.php', '', $filename);
321
			$filename = trim($filename, '/\\');
322
			$filename = str_ireplace('config_', '', $filename);
323
			$file = 'config_'.$filename.'.php';
324
			$logger->debug('Loading configuration [' . $filename . '] ...');
325
			if(isset(static::$loaded['config_' . $filename])){
326
				$logger->info('Configuration [' . $file . '] already loaded no need to load it again, cost in performance');
327
				return;
328
			}
329
			$configFilePath = CONFIG_PATH . $file;
330
			//first check if this config is in the module
331
			$logger->debug('Checking config [' . $filename . '] from module list ...');
332
			$searchModuleName = null;
333
			$obj = & get_instance();
334
			//check if the request class contains module name
335
			if(strpos($filename, '/') !== false){
336
				$path = explode('/', $filename);
337
				if(isset($path[0]) && in_array($path[0], Module::getModuleList())){
338
					$searchModuleName = $path[0];
339
					$filename = $path[1] . '.php';
340
				}
341
			}
342
			if(! $searchModuleName && !empty($obj->moduleName)){
343
				$searchModuleName = $obj->moduleName;
344
			}
345
			$moduleConfigPath = Module::findConfigFullPath($filename, $searchModuleName);
346
			if($moduleConfigPath){
347
				$logger->info('Found config [' . $filename . '] from module [' .$searchModuleName. '], the file path is [' .$moduleConfigPath. '] we will used it');
348
				$configFilePath = $moduleConfigPath;
349
			}
350
			else{
351
				$logger->info('Cannot find config [' . $filename . '] from modules using the default location');
352
			}
353
			$logger->info('The config file path to be loaded is [' . $configFilePath . ']');
354
			$config = array();
355
			if(file_exists($configFilePath)){
356
				require_once $configFilePath;
357
				if(! empty($config) && is_array($config)){
358
					Config::setAll($config);
359
				}
360
			}
361
			else{
362
				show_error('Unable to find config file ['. $configFilePath . ']');
363
			}
364
			static::$loaded['config_' . $filename] = $configFilePath;
365
			$logger->info('Configuration [' . $configFilePath . '] loaded successfully.');
366
			$logger->info('The custom application configuration loaded are listed below: ' . stringfy_vars($config));
367
			unset($config);
368
		}
369
370
371
		/**
372
		 * Load the language
373
		 *
374
		 * @param  string $language the language name to be loaded
375
		 *
376
		 * @return void
377
		 */
378
		public static function lang($language){
379
			$logger = static::getLogger();
380
			$language = str_ireplace('.php', '', $language);
381
			$language = trim($language, '/\\');
382
			$language = str_ireplace('lang_', '', $language);
383
			$file = 'lang_'.$language.'.php';
384
			$logger->debug('Loading language [' . $language . '] ...');
385
			if(isset(static::$loaded['lang_' . $language])){
386
				$logger->info('Language [' . $language . '] already loaded no need to load it again, cost in performance');
387
				return;
388
			}
389
			//determine the current language
390
			$appLang = get_config('default_language');
391
			//if the language exists in the cookie use it
392
			$cfgKey = get_config('language_cookie_name');
393
			$objCookie = & class_loader('Cookie');
394
			$cookieLang = $objCookie->get($cfgKey);
395
			if($cookieLang){
396
				$appLang = $cookieLang;
397
			}
398
			$languageFilePath = null;
399
			//first check if this language is in the module
400
			$logger->debug('Checking language [' . $language . '] from module list ...');
401
			$searchModuleName = null;
402
			$obj = & get_instance();
403
			//check if the request class contains module name
404
			if(strpos($language, '/') !== false){
405
				$path = explode('/', $language);
406
				if(isset($path[0]) && in_array($path[0], Module::getModuleList())){
407
					$searchModuleName = $path[0];
408
					$language = 'lang_' . $path[1] . '.php';
409
					$file = $path[0] . DS .$language;
410
				}
411
			}
412
			if(! $searchModuleName && !empty($obj->moduleName)){
413
				$searchModuleName = $obj->moduleName;
414
			}
415
			$moduleLanguagePath = Module::findLanguageFullPath($language, $searchModuleName, $appLang);
416
			if($moduleLanguagePath){
417
				$logger->info('Found language [' . $language . '] from module [' .$searchModuleName. '], the file path is [' .$moduleLanguagePath. '] we will used it');
418
				$languageFilePath = $moduleLanguagePath;
419
			}
420
			else{
421
				$logger->info('Cannot find language [' . $language . '] from modules using the default location');
422
			}
423
			if(! $languageFilePath){
424
				$searchDir = array(APP_LANG_PATH, CORE_LANG_PATH);
425
				foreach($searchDir as $dir){
426
					$filePath = $dir . $appLang . DS . $file;
427
					if(file_exists($filePath)){
428
						$languageFilePath = $filePath;
429
						//is already found not to continue
430
						break;
431
					}
432
				}
433
			}
434
			$logger->info('The language file path to be loaded is [' . $languageFilePath . ']');
435
			if($languageFilePath){
436
				$lang = array();
437
				require_once $languageFilePath;
438
				if(! empty($lang) && is_array($lang)){
439
					$logger->info('Language file  [' .$languageFilePath. '] contains the valid languages keys add them to language list');
440
					//Note: may be here the class 'Lang' not yet loaded
441
					$langObj =& class_loader('Lang', 'classes');
442
					$langObj->addLangMessages($lang);
443
					//free the memory
444
					unset($lang);
445
				}
446
				static::$loaded['lang_' . $language] = $languageFilePath;
447
				$logger->info('Language [' . $language . '] --> ' . $languageFilePath . ' loaded successfully.');
448
			}
449
			else{
450
				show_error('Unable to find language file [' . $file . ']');
451
			}
452
		}
453
454
455
		private function getResourcesFromAutoloadConfig(){
456
			$autoloads = array();
457
			$autoloads['config']    = array();
458
			$autoloads['languages'] = array();
459
			$autoloads['libraries'] = array();
460
			$autoloads['models']    = array();
461
			$autoloads['functions'] = array();
462
			//loading of the resources in autoload.php configuration file
463
			if(file_exists(CONFIG_PATH . 'autoload.php')){
464
				$autoload = array();
465
				require_once CONFIG_PATH . 'autoload.php';
466
				if(! empty($autoload) && is_array($autoload)){
467
					$autoloads = array_merge($autoloads, $autoload);
468
					unset($autoload);
469
				}
470
			}
471
			//loading autoload configuration for modules
472
			$modulesAutoloads = Module::getModulesAutoloadConfig();
473
			if(! empty($modulesAutoloads) && is_array($modulesAutoloads)){
474
				$autoloads = array_merge_recursive($autoloads, $modulesAutoloads);
475
			}
476
			return $autoloads;
477
		}
478
479
		/**
480
		 * Load the autoload configuration
481
		 * @return void
482
		 */
483
		private function loadResourcesFromAutoloadConfig(){
484
			$autoloads = array();
485
			$autoloads['config']    = array();
486
			$autoloads['languages'] = array();
487
			$autoloads['libraries'] = array();
488
			$autoloads['models']    = array();
489
			$autoloads['functions'] = array();
490
491
			$list = $this->getResourcesFromAutoloadConfig();
492
			$autoloads = array_merge($autoloads, $list);
493
			
494
			//config autoload
495
			$this->loadAutoloadResourcesArray('config', $autoloads['config']);
496
			
497
			//languages autoload
498
			$this->loadAutoloadResourcesArray('lang', $autoloads['languages']);
499
			
500
			//libraries autoload
501
			$this->loadAutoloadResourcesArray('library', $autoloads['libraries']);
502
503
			//models autoload
504
			$this->loadAutoloadResourcesArray('model', $autoloads['models']);
505
			
506
			//functions autoload
507
			$this->loadAutoloadResourcesArray('functions', $autoloads['functions']);
508
		}
509
510
		/**
511
		 * Load the resources autoload array
512
		 * @param  string $method    this object method name to call
513
		 * @param  array  $resources the resource to load
514
		 * @return void            
515
		 */
516
		private function loadAutoloadResourcesArray($method, array $resources){
517
			foreach ($resources as $name) {
518
				$this->{$method}($name);
519
			}
520
		}
521
	}
522