Test Failed
Push — 1.0.0-dev ( 73dca1...204371 )
by nguereza
02:34
created

Loader::lang()   A

Complexity

Conditions 5
Paths 9

Size

Total Lines 34
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 27
c 0
b 0
f 0
nc 9
nop 1
dl 0
loc 34
rs 9.1768
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 extends BaseStaticClass {
27
		
28
        /**
29
         * List of loaded resources
30
         * @var array
31
         */
32
        public static $loaded = array();
33
		
34
35
        public function __construct() {
36
            //add the resources already loaded during application bootstrap
37
            //in the list to prevent duplicate or loading the resources again.
38
            static::$loaded = class_loaded();
39
			
40
            //Load resources from autoload configuration
41
            $this->loadResourcesFromAutoloadConfig();
42
        }
43
44
		
45
        /**
46
         * Load the model class
47
         *
48
         * @param  string $class    the class name to be loaded
49
         * @param  string $instance the name of the instance to use in super object
50
         *
51
         * @return void
52
         */
53
        public static function model($class, $instance = null) {
54
            $logger = static::getLogger();
55
            $class = str_ireplace('.php', '', $class);
56
            $class = trim($class, '/\\');
57
            $file = ucfirst($class) . '.php';
58
            $logger->debug('Loading model [' . $class . '] ...');
59
            //************
60
            if (!$instance) {
61
                $instance = self::getModelLibraryInstanceName($class);
62
            }
63
            //****************
64
            if (isset(static::$loaded[$instance])) {
65
                $logger->info('Model [' . $class . '] already loaded no need to load it again, cost in performance');
66
                return;
67
            }
68
            $classFilePath = APPS_MODEL_PATH . $file;
69
            //first check if this model is in the module
70
            $logger->debug('Checking model [' . $class . '] from module list ...');
71
            //check if the request class contains module name
72
            $moduleInfo = self::getModuleInfoForModelLibrary($class);
73
            $module = $moduleInfo['module'];
74
            $class  = $moduleInfo['class'];
75
			
76
            $moduleModelFilePath = Module::findModelFullPath($class, $module);
77
            if ($moduleModelFilePath) {
78
                $logger->info('Found model [' . $class . '] from module [' . $module . '], the file path is [' . $moduleModelFilePath . '] we will used it');
79
                $classFilePath = $moduleModelFilePath;
80
            } else {
81
                $logger->info('Cannot find model [' . $class . '] from modules using the default location');
82
            }
83
            $logger->info('The model file path to be loaded is [' . $classFilePath . ']');
84
            if (file_exists($classFilePath)) {
85
                require_once $classFilePath;
86
                if (class_exists($class)) {
87
                    $c = new $class();
88
                    $obj = & get_instance();
89
                    $obj->{$instance} = $c;
90
                    static::$loaded[$instance] = $class;
91
                    $logger->info('Model [' . $class . '] --> ' . $classFilePath . ' loaded successfully.');
92
                } else {
93
                    show_error('The file ' . $classFilePath . ' exists but does not contain the class [' . $class . ']');
94
                }
95
            } else {
96
                show_error('Unable to find the model [' . $class . ']');
97
            }
98
        }
99
100
		
101
        /**
102
         * Load the library class
103
         *
104
         * @param  string $class    the library class name to be loaded
105
         * @param  string $instance the instance name to use in super object
106
         * @param mixed $params the arguments to pass to the constructor
107
         *
108
         * @return void
109
         */
110
        public static function library($class, $instance = null, array $params = array()) {
111
            $logger = static::getLogger();
112
            $class = str_ireplace('.php', '', $class);
113
            $class = trim($class, '/\\');
114
            $file = ucfirst($class) . '.php';
115
            $logger->debug('Loading library [' . $class . '] ...');
116
            if (!$instance) {
117
                $instance = self::getModelLibraryInstanceName($class);
118
            }
119
            if (isset(static::$loaded[$instance])) {
120
                $logger->info('Library [' . $class . '] already loaded no need to load it again, cost in performance');
121
                return;
122
            }
123
            $obj = & get_instance();
124
            //Check and load Database library
125
            if (strtolower($class) == 'database') {
126
                $logger->info('This is the Database library ...');
127
                $obj->{$instance} = & class_loader('Database', 'classes/database', $params);
128
                static::$loaded[$instance] = $class;
129
                $logger->info('Library Database loaded successfully.');
130
                return;
131
            }
132
            $libraryFilePath = null;
133
            $logger->debug('Check if this is a system library ...');
134
            if (file_exists(CORE_LIBRARY_PATH . $file)) {
135
                $libraryFilePath = CORE_LIBRARY_PATH . $file;
136
                $class = ucfirst($class);
137
                $logger->info('This library is a system library');
138
            } else {
139
                $logger->info('This library is not a system library');	
140
                //first check if this library is in the module
141
                $info = self::getLibraryPathUsingModuleInfo($class);
142
                $class = $info['class'];
143
                $libraryFilePath = $info['path'];
144
            }
145
            if (!$libraryFilePath && file_exists(LIBRARY_PATH . $file)) {
146
                $libraryFilePath = LIBRARY_PATH . $file;
147
            }
148
            $logger->info('The library file path to be loaded is [' . $libraryFilePath . ']');
149
            self::loadLibrary($libraryFilePath, $class, $instance, $params);
150
        }
151
152
        /**
153
         * Load the helper
154
         *
155
         * @param  string $function the helper name to be loaded
156
         *
157
         * @return void
158
         */
159
        public static function functions($function) {
160
            $logger = static::getLogger();
161
            $function = str_ireplace('.php', '', $function);
162
            $function = trim($function, '/\\');
163
            $function = str_ireplace('function_', '', $function);
164
            $file = 'function_' . $function . '.php';
165
            $logger->debug('Loading helper [' . $function . '] ...');
166
            if (isset(static::$loaded['function_' . $function])) {
167
                $logger->info('Helper [' . $function . '] already loaded no need to load it again, cost in performance');
168
                return;
169
            }
170
            $functionFilePath = null;
171
            //first check if this helper is in the module
172
            $logger->debug('Checking helper [' . $function . '] from module list ...');
173
            $moduleInfo = self::getModuleInfoForFunction($function);
174
            $module    = $moduleInfo['module'];
175
            $function  = $moduleInfo['function'];
176
            if (!empty($moduleInfo['file'])) {
177
                $file = $moduleInfo['file'];
178
            }
179
            $moduleFunctionPath = Module::findFunctionFullPath($function, $module);
180
            if ($moduleFunctionPath) {
181
                $logger->info('Found helper [' . $function . '] from module [' . $module . '], the file path is [' . $moduleFunctionPath . '] we will used it');
182
                $functionFilePath = $moduleFunctionPath;
183
            } else {
184
                $logger->info('Cannot find helper [' . $function . '] from modules using the default location');
185
            }
186
            if (!$functionFilePath) {
187
                $functionFilePath = self::getDefaultFilePathForFunctionLanguage($file, 'function');
188
            }
189
            $logger->info('The helper file path to be loaded is [' . $functionFilePath . ']');
190
            if ($functionFilePath) {
191
                require_once $functionFilePath;
192
                static::$loaded['function_' . $function] = $functionFilePath;
193
                $logger->info('Helper [' . $function . '] --> ' . $functionFilePath . ' loaded successfully.');
194
            } else {
195
                show_error('Unable to find helper file [' . $file . ']');
196
            }
197
        }
198
199
        /**
200
         * Load the configuration file
201
         *
202
         * @param  string $filename the configuration filename located at CONFIG_PATH or MODULE_PATH/config
203
         *
204
         * @return void
205
         */
206
        public static function config($filename) {
207
            $logger = static::getLogger();
208
            $filename = str_ireplace('.php', '', $filename);
209
            $filename = trim($filename, '/\\');
210
            $filename = str_ireplace('config_', '', $filename);
211
            $file = 'config_' . $filename . '.php';
212
            $logger->debug('Loading configuration [' . $filename . '] ...');
213
            if (isset(static::$loaded['config_' . $filename])) {
214
                $logger->info('Configuration [' . $file . '] already loaded no need to load it again, cost in performance');
215
                return;
216
            }
217
            $configFilePath = CONFIG_PATH . $file;
218
            //first check if this config is in the module
219
            $logger->debug('Checking config [' . $filename . '] from module list ...');
220
            $moduleInfo = self::getModuleInfoForConfig($filename);
221
            $module    = $moduleInfo['module'];
222
            $filename  = $moduleInfo['filename'];
223
            $moduleConfigPath = Module::findConfigFullPath($filename, $module);
224
            if ($moduleConfigPath) {
225
                $logger->info('Found config [' . $filename . '] from module [' . $module . '], the file path is [' . $moduleConfigPath . '] we will used it');
226
                $configFilePath = $moduleConfigPath;
227
            } else {
228
                $logger->info('Cannot find config [' . $filename . '] from modules using the default location');
229
            }
230
            $logger->info('The config file path to be loaded is [' . $configFilePath . ']');
231
            $config = array();
232
            if (file_exists($configFilePath)) {
233
                require_once $configFilePath;
234
                if (!empty($config) && is_array($config)) {
235
                    Config::setAll($config);
236
                    static::$loaded['config_' . $filename] = $configFilePath;
237
                    $logger->info('Configuration [' . $configFilePath . '] loaded successfully.');
238
                    $logger->info('The custom application configuration loaded are listed below: ' . stringfy_vars($config));
239
                    unset($config);
240
                }
241
            } else {
242
                show_error('Unable to find config file [' . $configFilePath . ']');
243
            }
244
        }
245
246
247
        /**
248
         * Load the language
249
         *
250
         * @param  string $language the language name to be loaded
251
         *
252
         * @return void
253
         */
254
        public static function lang($language) {
255
            $logger = static::getLogger();
256
            $language = str_ireplace('.php', '', $language);
257
            $language = trim($language, '/\\');
258
            $language = str_ireplace('lang_', '', $language);
259
            $file = 'lang_' . $language . '.php';
260
            $logger->debug('Loading language [' . $language . '] ...');
261
            if (isset(static::$loaded['lang_' . $language])) {
262
                $logger->info('Language [' . $language . '] already loaded no need to load it again, cost in performance');
263
                return;
264
            }
265
            //get the current language
266
            $appLang = self::getAppLang();
267
            $languageFilePath = null;
268
            //first check if this language is in the module
269
            $logger->debug('Checking language [' . $language . '] from module list ...');
270
            $moduleInfo = self::getModuleInfoForLanguage($language);
271
            $module    = $moduleInfo['module'];
272
            $language  = $moduleInfo['language'];
273
            if (!empty($moduleInfo['file'])) {
274
                $file = $moduleInfo['file'];
275
            }
276
            $moduleLanguagePath = Module::findLanguageFullPath($language, $appLang, $module);
277
            if ($moduleLanguagePath) {
278
                $logger->info('Found language [' . $language . '] from module [' . $module . '], the file path is [' . $moduleLanguagePath . '] we will used it');
279
                $languageFilePath = $moduleLanguagePath;
280
            } else {
281
                $logger->info('Cannot find language [' . $language . '] from modules using the default location');
282
            }
283
            if (!$languageFilePath) {
284
                $languageFilePath = self::getDefaultFilePathForFunctionLanguage($file, 'language', $appLang);
285
            }
286
            $logger->info('The language file path to be loaded is [' . $languageFilePath . ']');
287
            self::loadLanguage($languageFilePath, $language);
288
        }
289
290
        /**
291
         * Return the current app language by default will use the value from cookie 
292
         * if can not found will use the default value from configuration
293
         * @return string the app language like "en", "fr"
294
         */
295
        protected static function getAppLang() {
296
            //determine the current language
297
            $appLang = get_config('default_language');
298
            //if the language exists in the cookie use it
299
            $cfgKey = get_config('language_cookie_name');
300
            $objCookie = & class_loader('Cookie');
301
            $cookieLang = $objCookie->get($cfgKey);
302
            if ($cookieLang) {
303
                $appLang = $cookieLang;
304
            }
305
            return $appLang;
306
        }
307
308
        /**
309
         * Return the default full file path for function, language
310
         * @param  string $file    the filename
311
         * @param  string $type    the type can be "function", "language"
312
         * @param  string $appLang the application language, only if type = "language"
313
         * @return string|null          the full file path
314
         */
315
        protected static function getDefaultFilePathForFunctionLanguage($file, $type, $appLang = null){
316
            $searchDir = null;
317
            if ($type == 'function') {
318
               $searchDir = array(FUNCTIONS_PATH, CORE_FUNCTIONS_PATH);
319
            }
320
            else if ($type = 'language') {
0 ignored issues
show
Unused Code introduced by
The assignment to $type is dead and can be removed.
Loading history...
321
                $searchDir = array(APP_LANG_PATH, CORE_LANG_PATH);
322
                $file = $appLang . DS . $file;
323
            }
324
            $fullFilePath = null;
325
            foreach ($searchDir as $dir) {
326
                $filePath = $dir . $file;
327
                if (file_exists($filePath)) {
328
                    $fullFilePath = $filePath;
329
                    //is already found not to continue
330
                    break;
331
                }
332
            }
333
            return $fullFilePath;
334
        }
335
336
        /**
337
         * Get the module using the attribute of super controller "moduleName"
338
         * @param  string|null $module the module if is not null will return it
339
         * @return string|null
340
         */
341
        protected static function getModuleFromSuperController($module){
342
            $obj = & get_instance();
343
            if (!$module && !empty($obj->moduleName)) {
344
                $module = $obj->moduleName;
345
            }
346
            return $module;
347
        }
348
349
        /**
350
         * Get the module information for the model and library to load
351
         * @param  string $class the full class name like moduleName/className, className,
352
         * @return array        the module information
353
         * array(
354
         * 	'module'=> 'module_name'
355
         * 	'class' => 'class_name'
356
         * )
357
         */
358
        protected static function getModuleInfoForModelLibrary($class) {
359
            $module = null;
360
            $path = explode('/', $class);
361
            if (count($path) >= 2 && isset($path[0]) && in_array($path[0], Module::getModuleList())) {
362
                $module = $path[0];
363
                $class = ucfirst($path[1]);
364
            } else {
365
                $class = ucfirst($class);
366
            }
367
            $module = self::getModuleFromSuperController($module);
368
            return array(
369
                        'class' => $class,
370
                        'module' => $module
371
                    );
372
        }
373
374
        /**
375
         * Get the module information for the function to load
376
         * @param  string $function the function name like moduleName/functionName, functionName,
377
         * @return array        the module information
378
         * array(
379
         * 	'module'=> 'module_name'
380
         * 	'function' => 'function'
381
         * 	'file' => 'file'
382
         * )
383
         */
384
        protected static function getModuleInfoForFunction($function) {
385
            $module = null;
386
            $file = null;
387
            //check if the request class contains module name
388
            $path = explode('/', $function);
389
            if (count($path) >= 2 && isset($path[0]) && in_array($path[0], Module::getModuleList())) {
390
                $module = $path[0];
391
                $function = 'function_' . $path[1];
392
                $file = $path[0] . DS . $function . '.php';
393
            }
394
            $module = self::getModuleFromSuperController($module);
395
            return array(
396
                        'function' => $function,
397
                        'module' => $module,
398
                        'file' => $file
399
                    );
400
        }
401
402
        /**
403
         * Get the module information for the language to load
404
         * @param  string $language the language name like moduleName/languageName, languageName,
405
         * @return array        the module information
406
         * array(
407
         * 	'module'=> 'module_name'
408
         * 	'language' => 'language'
409
         * 	'file' => 'file'
410
         * )
411
         */
412
        protected static function getModuleInfoForLanguage($language) {
413
            $module = null;
414
            $file = null;
415
            //check if the request class contains module name
416
            $path = explode('/', $language);
417
            if (count($path) >= 2 && isset($path[0]) && in_array($path[0], Module::getModuleList())) {
418
                $module = $path[0];
419
                $language = 'lang_' . $path[1] . '.php';
420
                $file = $path[0] . DS . $language;
421
            }
422
            $module = self::getModuleFromSuperController($module);
423
            return array(
424
                        'language' => $language,
425
                        'module' => $module,
426
                        'file' => $file
427
                    );
428
        }
429
430
431
        /**
432
         * Get the module information for the config to load
433
         * @param  string $filename the filename of the configuration file,
434
         * @return array        the module information
435
         * array(
436
         * 	'module'=> 'module_name'
437
         * 	'filename' => 'filename'
438
         * )
439
         */
440
        protected static function getModuleInfoForConfig($filename) {
441
            $module = null;
442
            //check if the request class contains module name
443
            $path = explode('/', $filename);
444
            if (count($path) >= 2 && isset($path[0]) && in_array($path[0], Module::getModuleList())) {
445
                $module = $path[0];
446
                $filename = $path[1] . '.php';
447
            }
448
            $module = self::getModuleFromSuperController($module);
449
            return array(
450
                        'filename' => $filename,
451
                        'module' => $module
452
                    );
453
        }
454
455
        /**
456
         * Get the name of model or library instance if is null
457
         * @param  string $class the class name to determine the instance
458
         * @return string        the instance name
459
         */
460
        protected static function getModelLibraryInstanceName($class) {
461
            //for module
462
            $instance = null;
463
            $path = explode('/', $class);
464
            if (count($path) >= 2 && isset($path[1])) {
465
                $instance = strtolower($path[1]);
466
            } else {
467
                $instance = strtolower($class);
468
            }
469
            return $instance;
470
        }
471
472
        /**
473
         * Get the library file path and class name using the module information
474
         * @param  string $class the class name
475
         * @return array        the library file path and class name
476
         */
477
        protected static function getLibraryPathUsingModuleInfo($class) {
478
            $logger = static::getLogger();
479
            $libraryFilePath = null;
480
            $logger->debug('Checking library [' . $class . '] from module list ...');
481
            $moduleInfo = self::getModuleInfoForModelLibrary($class);
482
            $module = $moduleInfo['module'];
483
            $class  = $moduleInfo['class'];
484
            $moduleLibraryPath = Module::findLibraryFullPath($class, $module);
485
            if ($moduleLibraryPath) {
486
                $logger->info('Found library [' . $class . '] from module [' . $module . '], the file path is [' . $moduleLibraryPath . '] we will used it');
487
                $libraryFilePath = $moduleLibraryPath;
488
            } else {
489
                $logger->info('Cannot find library [' . $class . '] from modules using the default location');
490
            }
491
            return array(
492
                        'path' => $libraryFilePath,
493
                        'class' => $class
494
                    );
495
        }
496
497
        /**
498
         * Load the library 
499
         * @param  string $libraryFilePath the file path of the library to load
500
         * @param  string $class           the class name
501
         * @param  string $instance        the instance
502
         * @param  array  $params          the parameter to use
503
         * @return void
504
         */
505
        protected static function loadLibrary($libraryFilePath, $class, $instance, $params = array()) {
506
            if ($libraryFilePath) {
507
                $logger = static::getLogger();
508
                require_once $libraryFilePath;
509
                if (class_exists($class)) {
510
                    $c = $params ? new $class($params) : new $class();
511
                    $obj = & get_instance();
512
                    $obj->{$instance} = $c;
513
                    static::$loaded[$instance] = $class;
514
                    $logger->info('Library [' . $class . '] --> ' . $libraryFilePath . ' loaded successfully.');
515
                } else {
516
                    show_error('The file ' . $libraryFilePath . ' exists but does not contain the class ' . $class);
517
                }
518
            } else {
519
                show_error('Unable to find library class [' . $class . ']');
520
            }
521
        }
522
523
        /**
524
         * Load the language 
525
         * @param  string $languageFilePath the file path of the language to load
526
         * @param  string $language           the language name
527
         * @return void
528
         */
529
        protected static function loadLanguage($languageFilePath, $language) {
530
            if ($languageFilePath) {
531
                $logger = static::getLogger();
532
                $lang = array();
533
                require_once $languageFilePath;
534
                if (!empty($lang) && is_array($lang)) {
535
                    $logger->info('Language file  [' . $languageFilePath . '] contains the valid languages keys add them to language list');
536
                    //Note: may be here the class 'Lang' not yet loaded
537
                    $langObj = & class_loader('Lang', 'classes');
538
                    $langObj->addLangMessages($lang);
539
                    //free the memory
540
                    unset($lang);
541
                }
542
                static::$loaded['lang_' . $language] = $languageFilePath;
543
                $logger->info('Language [' . $language . '] --> ' . $languageFilePath . ' loaded successfully.');
544
            } else {
545
                show_error('Unable to find language [' . $language . ']');
546
            }
547
        }
548
549
        /**
550
         * Load the resources autoload array
551
         * @param  string $method    this object method name to call
552
         * @param  array  $resources the resource to load
553
         * @return void            
554
         */
555
        protected function loadAutoloadResourcesArray($method, array $resources) {
556
            foreach ($resources as $name) {
557
                $this->{$method}($name);
558
            }
559
        }
560
561
        /**
562
         * Get all the autoload using the configuration file
563
         * @return array
564
         */
565
        protected function getResourcesFromAutoloadConfig() {
566
            $autoloads = array();
567
            $autoloads['config']    = array();
568
            $autoloads['languages'] = array();
569
            $autoloads['libraries'] = array();
570
            $autoloads['models']    = array();
571
            $autoloads['functions'] = array();
572
            //loading of the resources from autoload configuration file
573
            if (file_exists(CONFIG_PATH . 'autoload.php')) {
574
                $autoload = array();
575
                require_once CONFIG_PATH . 'autoload.php';
576
                if (!empty($autoload) && is_array($autoload)) {
577
                    $autoloads = array_merge($autoloads, $autoload);
578
                    unset($autoload);
579
                }
580
            }
581
            //loading autoload configuration for modules
582
            $modulesAutoloads = Module::getModulesAutoloadConfig();
583
            if (!empty($modulesAutoloads) && is_array($modulesAutoloads)) {
584
                $autoloads = array_merge_recursive($autoloads, $modulesAutoloads);
585
            }
586
            return $autoloads;
587
        }
588
589
        /**
590
         * Load the autoload configuration
591
         * @return void
592
         */
593
        protected function loadResourcesFromAutoloadConfig() {
594
            $autoloads = array();
595
            $autoloads['config']    = array();
596
            $autoloads['languages'] = array();
597
            $autoloads['libraries'] = array();
598
            $autoloads['models']    = array();
599
            $autoloads['functions'] = array();
600
601
            $list = $this->getResourcesFromAutoloadConfig();
602
            $autoloads = array_merge($autoloads, $list);
603
			
604
            //config autoload
605
            $this->loadAutoloadResourcesArray('config', $autoloads['config']);
606
			
607
            //languages autoload
608
            $this->loadAutoloadResourcesArray('lang', $autoloads['languages']);
609
			
610
            //libraries autoload
611
            $this->loadAutoloadResourcesArray('library', $autoloads['libraries']);
612
613
            //models autoload
614
            $this->loadAutoloadResourcesArray('model', $autoloads['models']);
615
			
616
            //functions autoload
617
            $this->loadAutoloadResourcesArray('functions', $autoloads['functions']);
618
        }
619
    }
620