GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — 3.0 ( 57de80...0d3e66 )
by Vermeulen
02:19
created

Application::loadMemcached()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 25
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 25
rs 8.5806
cc 4
eloc 14
nc 4
nop 0
1
<?php
2
3
namespace BFW;
4
5
use \Exception;
6
use \BFW\Helpers\Constants;
7
8
/**
9
 * Application class
10
 * Manage all BFW application
11
 * Load and init components, modules, ...
12
 */
13
class Application extends Subjects
14
{
15
    /**
16
     * @const ERR_MEMCACHED_NOT_CLASS_DEFINED Exception code if memcache(d) is
17
     * enabled but the class to use is not defined.
18
     */
19
    const ERR_MEMCACHED_NOT_CLASS_DEFINED = 1301001;
20
    
21
    /**
22
     * @const ERR_MEMCACHED_CLASS_NOT_FOUND Exception code if the memcache(d)
23
     * class is not found.
24
     */
25
    const ERR_MEMCACHED_CLASS_NOT_FOUND = 1301002;
26
    
27
    /**
28
     * @const ERR_CLI_NO_FILE_SPECIFIED Exception code if the cli file to run
29
     * is not specified
30
     */
31
    const ERR_CLI_NO_FILE_SPECIFIED = 1301003;
32
    
33
    /**
34
     * @const ERR_CLI_FILE_NOT_FOUND Exception code if the cli file to run is
35
     * not found.
36
     */
37
    const ERR_CLI_FILE_NOT_FOUND = 1301004;
38
    
39
    /**
40
     * @var \BFW\Application|null $instance Application instance (Singleton)
41
     */
42
    protected static $instance = null;
43
44
    /**
45
     * @var string $rootDir Path to the application project directory
46
     */
47
    protected $rootDir = '';
48
49
    /**
50
     * @var \BFW\Config $config Config's instance for BFW
51
     */
52
    protected $config;
53
54
    /**
55
     * @var \BFW\Core\Options $options Option's instance for the core
56
     */
57
    protected $options;
58
59
    /**
60
     * @var \Composer\Autoload\ClassLoader $composerLoader Loader used by
61
     *  composer.
62
     */
63
    protected $composerLoader;
64
65
    /**
66
     * @var array[] $runSteps All steps used for run the application
67
     */
68
    protected $runSteps = [];
69
70
    /**
71
     * @var Object $memcached The class used to connect to memcache(d) server.
72
     * The class name should be declared into config file.
73
     */
74
    protected $memcached;
75
76
    /**
77
     * @var \BFW\Request $request Informations about the http request
78
     */
79
    protected $request;
80
81
    /**
82
     * @var \BFW\Modules $modules System who manage all modules
83
     */
84
    protected $modules;
85
    
86
    /**
87
     * @var \BFW\Core\Errors $errors System who manage personal errors page
88
     */
89
    protected $errors;
90
91
    /**
92
     * Constructor
93
     * Init output buffering
94
     * Declare run steps
95
     * Set UTF-8 header
96
     * 
97
     * protected for Singleton pattern
98
     */
99
    protected function __construct()
100
    {
101
        //Start the output buffering
102
        ob_start();
103
104
        $this->declareRunSteps();
105
106
        //Defaut http header. Define here add possiblity to override him
107
        header('Content-Type: text/html; charset=utf-8');
108
    }
109
110
    /**
111
     * Get the Application instance (Singleton pattern)
112
     * 
113
     * @param array $options Options passed to application
114
     * 
115
     * @return \BFW\Application The current instance of this class
116
     */
117
    public static function getInstance($options = [])
118
    {
119
        if (self::$instance === null) {
120
            $calledClass = get_called_class(); //Autorize extends this class
121
            self::$instance = new $calledClass;
122
            self::$instance->initSystem($options);
123
        }
124
125
        return self::$instance;
126
    }
127
128
    /**
129
     * Like getInstance. This is to have a keyword easier for users who want
130
     * initialize the application
131
     * 
132
     * @param array $options Options passed to application
133
     * 
134
     * @return \BFW\Application The current instance of this class
135
     */
136
    public static function init($options = [])
137
    {
138
        $calledClass = get_called_class(); //Autorize extends this class
139
        return $calledClass::getInstance($options);
140
    }
141
142
    /**
143
     * Getter to access to composerLoader property
144
     * 
145
     * @return \Composer\Autoload\ClassLoader The composer class loader
146
     */
147
    public function getComposerLoader()
148
    {
149
        return $this->composerLoader;
150
    }
151
152
    /**
153
     * Getter to access to the config instance
154
     * 
155
     * @return \BFW\Config
156
     */
157
    public function getConfig()
158
    {
159
        return $this->config;
160
    }
161
    
162
    /**
163
     * Getter to access to memcache instance
164
     * 
165
     * @return Object|null
166
     */
167
    public function getMemcached()
168
    {
169
        return $this->memcached;
170
    }
171
    
172
    /**
173
     * Getter to access to a module
174
     * 
175
     * @param string $moduleName The module name to access
176
     * 
177
     * @return \BFW\Module
178
     */
179
    public function getModule($moduleName)
180
    {
181
        return $this->modules->getModule($moduleName);
182
    }
183
184
    /**
185
     * Getter to access to an option's value
186
     * 
187
     * @param string $optionKey The key for the option
188
     * 
189
     * @return mixed
190
     */
191
    public function getOption($optionKey)
192
    {
193
        return $this->options->getValue($optionKey);
194
    }
195
    
196
    /**
197
     * Getter to access to the Request instance
198
     * 
199
     * @return \BFW\Request
200
     */
201
    public function getRequest()
202
    {
203
        return $this->request;
204
    }
205
    
206
    /**
207
     * Initialize all components
208
     * 
209
     * @param array $options Options passed to application
210
     * 
211
     * @return void
212
     */
213
    protected function initSystem($options)
214
    {
215
        $this->initOptions($options);
216
        $this->initConstants();
217
        $this->initComposerLoader();
218
        $this->initConfig();
219
        $this->initRequest();
220
        $this->initSession();
221
        $this->initErrors();
222
        $this->initModules();
223
    }
224
225
    /**
226
     * Initialize options with the class \BFW\Core\Options
227
     * 
228
     * @param array $options The option passed when initialize this class
229
     */
230
    protected function initOptions($options)
231
    {
232
        $defaultOptions = [
233
            'rootDir'    => null,
234
            'vendorDir'  => null,
235
            'runSession' => true
236
        ];
237
238
        $this->options = new \BFW\Core\Options($defaultOptions, $options);
239
    }
240
241
    /**
242
     * Initialize all constants used by framework
243
     * Use helper Constants::create to allow override of constants
244
     * 
245
     * @return void
246
     */
247
    protected function initConstants()
248
    {
249
        Constants::create('ROOT_DIR', $this->options->getValue('rootDir'));
250
251
        Constants::create('APP_DIR', ROOT_DIR.'app/');
252
        Constants::create('SRC_DIR', ROOT_DIR.'src/');
253
        Constants::create('WEB_DIR', ROOT_DIR.'web/');
254
255
        Constants::create('CONFIG_DIR', APP_DIR.'config/');
256
        Constants::create('MODULES_DIR', APP_DIR.'modules/');
257
258
        Constants::create('CLI_DIR', SRC_DIR.'cli/');
259
        Constants::create('CTRL_DIR', SRC_DIR.'controllers/');
260
        Constants::create('MODELES_DIR', SRC_DIR.'modeles/');
261
        Constants::create('VIEW_DIR', SRC_DIR.'view/');
262
    }
263
264
    /**
265
     * Initialize composer loader
266
     * Obtain the composerLoader instance
267
     * Call addComposerNamespaces method to add Application namespaces
268
     * 
269
     * @return void
270
     */
271
    protected function initComposerLoader()
272
    {
273
        $this->composerLoader = require(
274
            $this->options->getValue('vendorDir').'autoload.php'
275
        );
276
        $this->addComposerNamespaces();
277
    }
278
279
    /**
280
     * Initialize the property config with \BFW\Config instance
281
     * The config class will search all file in "bfw" directory and load files
282
     * 
283
     * @return void
284
     */
285
    protected function initConfig()
286
    {
287
        $this->config = new \BFW\Config('bfw');
288
        $this->config->loadFiles();
289
    }
290
291
    /**
292
     * Initialize request property with the \BFW\Request class
293
     * 
294
     * @return void
295
     */
296
    protected function initRequest()
297
    {
298
        $this->request = \BFW\Request::getInstance();
299
    }
300
301
    /**
302
     * Initiliaze php session if option "runSession" is not (bool) false
303
     * 
304
     * @return void
305
     */
306
    protected function initSession()
307
    {
308
        if ($this->options->getValue('runSession') === false) {
309
            return;
310
        }
311
312
        //Destroy session cookie if browser quit
313
        session_set_cookie_params(0);
314
315
        //Run session
316
        session_start();
317
    }
318
319
    /**
320
     * Initialize errors property with the \BFW\Core\Errors class
321
     * 
322
     * @return void
323
     */
324
    protected function initErrors()
325
    {
326
        $this->errors = new \BFW\Core\Errors();
327
    }
328
329
    /**
330
     * Initialize modules property with the \BFW\Modules class
331
     * 
332
     * @return void
333
     */
334
    protected function initModules()
335
    {
336
        $this->modules = new \BFW\Modules;
337
    }
338
339
    /**
340
     * Add namespaces used by a BFW Application to composer
341
     * 
342
     * @return void
343
     */
344
    protected function addComposerNamespaces()
345
    {
346
        $this->composerLoader->addPsr4('Controller\\', CTRL_DIR);
347
        $this->composerLoader->addPsr4('Modules\\', MODULES_DIR);
348
        $this->composerLoader->addPsr4('Modeles\\', MODELES_DIR);
349
    }
350
351
    /**
352
     * Declare all steps to run the application
353
     * 
354
     * @return void
355
     */
356
    protected function declareRunSteps()
357
    {
358
        $this->runSteps = [
359
            [$this, 'loadMemcached'],
360
            [$this, 'readAllModules'],
361
            [$this, 'loadAllCoreModules'],
362
            [$this, 'loadAllAppModules'],
363
            [$this, 'runCliFile']
364
        ];
365
    }
366
367
    /**
368
     * Run the application
369
     * 
370
     * @return void
371
     */
372 View Code Duplication
    public function run()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
373
    {
374
        foreach ($this->runSteps as $action) {
375
            $action();
376
377
            $notifyAction = $action;
378
            if (is_array($action)) {
379
                $notifyAction = $action[1];
380
            }
381
382
            $this->notifyAction('apprun_'.$notifyAction);
383
        }
384
385
        $this->notifyAction('bfw_run_finish');
386
    }
387
388
    /**
389
     * Connect to memcache(d) server with the class declared in config file
390
     * 
391
     * @return Object
392
     * 
393
     * @throws Exception If memcached is enabled but no class is define. Or if
394
     *  The class declared into the config is not found.
395
     */
396
    protected function loadMemcached()
397
    {
398
        $memcachedConfig = $this->config->getValue('memcached');
399
400
        if ($memcachedConfig['enabled'] === false) {
401
            return;
402
        }
403
404
        $class = $memcachedConfig['class'];
405
        if (empty($class)) {
406
            throw new Exception(
407
                'Memcached is active but no class is define',
408
                $this::ERR_MEMCACHED_NOT_CLASS_DEFINED
409
            );
410
        }
411
412
        if (class_exists($class) === false) {
413
            throw new Exception(
414
                'Memcache class '.$class.' not found.',
415
                $this::ERR_MEMCACHED_CLASS_NOT_FOUND
416
            );
417
        }
418
419
        $this->memcached = new $class;
420
    }
421
422
    /**
423
     * Read all directories in modules directory and add each module to Modules
424
     * class.
425
     * Generate the load tree.
426
     * Not initialize modules !
427
     * 
428
     * @return void
429
     */
430
    protected function readAllModules()
431
    {
432
        $listModules = array_diff(scandir(MODULES_DIR), ['.', '..']);
433
434
        foreach ($listModules as $moduleName) {
435
            $modulePath = realpath(MODULES_DIR.$moduleName); //Symlink
436
437
            if (!is_dir($modulePath)) {
438
                continue;
439
            }
440
441
            $this->modules->addModule($moduleName);
442
        }
443
444
        $this->modules->readNeedMeDependencies();
445
        $this->modules->generateTree();
446
    }
447
448
    /**
449
     * Load core modules defined into config bfw file.
450
     * Only module for controller, router, database and template only.
451
     * 
452
     * @return void
453
     */
454
    protected function loadAllCoreModules()
455
    {
456
        foreach ($this->config->getValue('modules') as $moduleInfos) {
457
            $moduleName    = $moduleInfos['name'];
458
            $moduleEnabled = $moduleInfos['enabled'];
459
460
            if (empty($moduleName) || $moduleEnabled === false) {
461
                continue;
462
            }
463
464
            $this->loadModule($moduleName);
465
        }
466
    }
467
468
    /**
469
     * Load all modules (except core).
470
     * Get the load tree, read him and load all modules with the order
471
     * declared into the tree.
472
     * 
473
     * @return void
474
     */
475
    protected function loadAllAppModules()
476
    {
477
        $tree = $this->modules->getLoadTree();
478
479
        foreach ($tree as $firstLine) {
480
            foreach ($firstLine as $secondLine) {
481
                foreach ($secondLine as $moduleName) {
482
                    $this->loadModule($moduleName);
483
                }
484
            }
485
        }
486
    }
487
488
    /**
489
     * Load a module
490
     * 
491
     * @param string $moduleName The module's name to load
492
     * 
493
     * @return void
494
     */
495
    protected function loadModule($moduleName)
496
    {
497
        $this->notifyAction('load_module_'.$moduleName);
498
        $this->modules->getModule($moduleName)->runModule();
499
    }
500
501
    /**
502
     * Run the cli file if we're in cli mode
503
     * 
504
     * @return void
505
     * 
506
     * @throws Exception If no file is specified or if the file not exist.
507
     */
508
    protected function runCliFile()
509
    {
510
        if (PHP_SAPI !== 'cli') {
511
            return;
512
        }
513
514
        $cliArgs = getopt('f:');
515
        if (!isset($cliArgs['f'])) {
516
            throw new Exception(
517
                'Error: No file specified.',
518
                $this::ERR_CLI_NO_FILE_SPECIFIED
519
            );
520
        }
521
522
        $file = $cliArgs['f'];
523
        if (!file_exists(CLI_DIR.$file.'.php')) {
524
            throw new Exception(
525
                'File to execute not found.',
526
                $this::ERR_CLI_FILE_NOT_FOUND
527
            );
528
        }
529
530
        $fctRunCliFile = function() use ($file) {
531
            require_once(CLI_DIR.$file.'.php');
532
        };
533
534
        $this->notifyAction('run_cli_file');
535
        $fctRunCliFile();
536
    }
537
}
538