Completed
Push — master ( 71f3ca...10d1fd )
by Thierry
01:44
created

Container   B

Complexity

Total Complexity 43

Size/Duplication

Total Lines 535
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 21

Importance

Changes 0
Metric Value
dl 0
loc 535
rs 8.96
c 0
b 0
f 0
wmc 43
lcom 2
cbo 21

37 Methods

Rating   Name   Duplication   Size   Complexity  
A getInstance() 0 8 2
A __construct() 0 8 1
A getSentryContainer() 0 4 1
A setSentryContainer() 0 4 1
B init() 0 107 1
A get() 0 8 3
A set() 0 4 1
A getPluginManager() 0 4 1
A getRequestHandler() 0 4 1
A getRequestFactory() 0 4 1
A getParameterFactory() 0 4 1
A getResponseManager() 0 4 1
A getCodeGenerator() 0 4 1
A getConfig() 0 4 1
A newConfig() 0 4 1
A getDialog() 0 4 1
A getMinifier() 0 4 1
A getTranslator() 0 4 1
A getTemplate() 0 4 1
A getValidator() 0 4 1
A getPaginator() 0 4 1
A setPaginationRenderer() 0 4 1
A getEventDispatcher() 0 4 1
A getResponse() 0 4 1
A newResponse() 0 4 1
A getJaxon() 0 4 1
A getVersion() 0 4 1
A getSentry() 0 4 1
A setSentry() 0 4 1
A getArmada() 0 4 1
A setArmada() 0 4 1
A initViewRenderers() 0 4 1
A initViewNamespaces() 0 5 1
A addViewRenderer() 0 21 3
A getViewRenderer() 0 10 2
A getSessionManager() 0 4 1
A setSessionManager() 0 4 1

How to fix   Complexity   

Complex Class

Complex classes like Container often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Container, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * Container.php - Jaxon data container
5
 *
6
 * Provide container service for Jaxon utils class instances.
7
 *
8
 * @package jaxon-core
9
 * @author Thierry Feuzeu <[email protected]>
10
 * @copyright 2016 Thierry Feuzeu <[email protected]>
11
 * @license https://opensource.org/licenses/BSD-3-Clause BSD 3-Clause License
12
 * @link https://github.com/jaxon-php/jaxon-core
13
 */
14
15
namespace Jaxon\DI;
16
17
use Lemon\Event\EventDispatcher;
18
use Jaxon\Sentry\View\Renderer;
19
20
use Jaxon\Jaxon;
21
use Jaxon\Response\Response;
22
use Jaxon\Config\Config;
23
use Jaxon\Config\Reader as ConfigReader;
24
use Jaxon\Request\Support\CallableRepository;
25
use Jaxon\Request\Handler as RequestHandler;
26
use Jaxon\Response\Manager as ResponseManager;
27
use Jaxon\Plugin\Manager as PluginManager;
28
use Jaxon\Factory\Request as RequestFactory;
29
use Jaxon\Factory\Parameter as ParameterFactory;
30
use Jaxon\Code\Generator as CodeGenerator;
31
use Jaxon\Dialog\Dialog;
32
use Jaxon\Utils\Template\Minifier;
33
use Jaxon\Utils\Translation\Translator;
34
use Jaxon\Utils\Template\Template;
35
use Jaxon\Utils\Validation\Validator;
36
use Jaxon\Utils\Pagination\Paginator;
37
use Jaxon\Utils\Pagination\Renderer as PaginationRenderer;
38
39
class Container
40
{
41
    // The Dependency Injection Container
42
    private $coreContainer = null;
43
44
    // The Dependency Injection Container
45
    private $sentryContainer = null;
46
47
    // The only instance of the Container (Singleton)
48
    private static $xInstance = null;
49
50
    public static function getInstance()
51
    {
52
        if(!self::$xInstance)
53
        {
54
            self::$xInstance = new Container();
55
        }
56
        return self::$xInstance;
57
    }
58
59
    private function __construct()
60
    {
61
        $this->coreContainer = new \Pimple\Container();
62
63
        $sTranslationDir = realpath(__DIR__ . '/../../translations');
64
        $sTemplateDir = realpath(__DIR__ . '/../../templates');
65
        $this->init($sTranslationDir, $sTemplateDir);
66
    }
67
68
    /**
69
     * Get the container provided by the integrated framework
70
     *
71
     * @return ContainerInterface
72
     */
73
    public function getSentryContainer()
74
    {
75
        return $this->sentryContainer;
76
    }
77
78
    /**
79
     * Set the container provided by the integrated framework
80
     *
81
     * @param ContainerInterface  $container     The container implementation
82
     *
83
     * @return void
84
     */
85
    public function setSentryContainer(ContainerInterface $container)
86
    {
87
        $this->sentryContainer = $container;
88
    }
89
90
    /**
91
     * Set the parameters and create the objects in the dependency injection container
92
     *
93
     * @param string        $sTranslationDir     The translation directory
94
     * @param string        $sTemplateDir        The template directory
95
     *
96
     * @return void
97
     */
98
    private function init($sTranslationDir, $sTemplateDir)
99
    {
100
        /*
101
         * Parameters
102
         */
103
        // Translation directory
104
        $this->coreContainer['jaxon.core.translation_dir'] = $sTranslationDir;
105
        // Template directory
106
        $this->coreContainer['jaxon.core.template_dir'] = $sTemplateDir;
107
108
        /*
109
         * Core library objects
110
         */
111
        // Jaxon Core
112
        $this->coreContainer[Jaxon::class] = function ($c) {
0 ignored issues
show
Unused Code introduced by
The parameter $c 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...
113
            return new Jaxon();
114
        };
115
        // Global Response
116
        $this->coreContainer[Response::class] = function ($c) {
0 ignored issues
show
Unused Code introduced by
The parameter $c 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...
117
            return new Response();
118
        };
119
        // Dialog
120
        $this->coreContainer[Dialog::class] = function ($c) {
0 ignored issues
show
Unused Code introduced by
The parameter $c 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...
121
            return new Dialog();
122
        };
123
124
        /*
125
         * Managers
126
         */
127
        // Callable objects repository
128
        $this->coreContainer[CallableRepository::class] = function ($c) {
0 ignored issues
show
Unused Code introduced by
The parameter $c 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...
129
            return new CallableRepository();
130
        };
131
        // Plugin Manager
132
        $this->coreContainer[PluginManager::class] = function ($c) {
0 ignored issues
show
Unused Code introduced by
The parameter $c 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...
133
            return new PluginManager();
134
        };
135
        // Request Manager
136
        $this->coreContainer[RequestHandler::class] = function ($c) {
137
            return new RequestHandler($c[PluginManager::class]);
138
        };
139
        // Request Factory
140
        $this->coreContainer[RequestFactory::class] = function ($c) {
141
            return new RequestFactory($c[CallableRepository::class]);
142
        };
143
        // Parameter Factory
144
        $this->coreContainer[ParameterFactory::class] = function ($c) {
0 ignored issues
show
Unused Code introduced by
The parameter $c 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...
145
            return new ParameterFactory();
146
        };
147
        // Response Manager
148
        $this->coreContainer[ResponseManager::class] = function ($c) {
0 ignored issues
show
Unused Code introduced by
The parameter $c 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...
149
            return new ResponseManager();
150
        };
151
        // Code Generator
152
        $this->coreContainer[CodeGenerator::class] = function ($c) {
153
            return new CodeGenerator($c[PluginManager::class]);
154
        };
155
156
        /*
157
         * Config
158
         */
159
        $this->coreContainer[Config::class] = function ($c) {
0 ignored issues
show
Unused Code introduced by
The parameter $c 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...
160
            return new Config();
161
        };
162
        $this->coreContainer[ConfigReader::class] = function ($c) {
0 ignored issues
show
Unused Code introduced by
The parameter $c 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...
163
            return new ConfigReader();
164
        };
165
166
        /*
167
         * Services
168
         */
169
        // Minifier
170
        $this->coreContainer[Minifier::class] = function ($c) {
0 ignored issues
show
Unused Code introduced by
The parameter $c 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...
171
            return new Minifier();
172
        };
173
        // Translator
174
        $this->coreContainer[Translator::class] = function ($c) {
175
            return new Translator($c['jaxon.core.translation_dir'], $c[Config::class]);
176
        };
177
        // Template engine
178
        $this->coreContainer[Template::class] = function ($c) {
179
            return new Template($c['jaxon.core.template_dir']);
180
        };
181
        // Validator
182
        $this->coreContainer[Validator::class] = function ($c) {
183
            return new Validator($c[Translator::class], $c[Config::class]);
184
        };
185
        // Pagination Renderer
186
        $this->coreContainer[PaginationRenderer::class] = function ($c) {
187
            return new PaginationRenderer($c[Template::class]);
188
        };
189
        // Pagination Paginator
190
        $this->coreContainer[Paginator::class] = function ($c) {
191
            return new Paginator($c[PaginationRenderer::class]);
192
        };
193
        // Event Dispatcher
194
        $this->coreContainer[EventDispatcher::class] = function ($c) {
0 ignored issues
show
Unused Code introduced by
The parameter $c 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...
195
            return new EventDispatcher();
196
        };
197
198
        // View Renderer Facade
199
        // $this->coreContainer[\Jaxon\Sentry\View\Facade::class] = function ($c) {
200
        //     $aRenderers = $c['jaxon.view.data.renderers'];
201
        //     $sDefaultNamespace = $c['jaxon.view.data.namespace.default'];
202
        //     return new \Jaxon\Sentry\View\Facade($aRenderers, $sDefaultNamespace);
203
        // };
204
    }
205
206
    /**
207
     * Get a class instance
208
     *
209
     * @return object        The class instance
210
     */
211
    public function get($sClass)
212
    {
213
        if($this->sentryContainer != null && $this->sentryContainer->has($sClass))
214
        {
215
            return $this->sentryContainer->get($sClass);
216
        }
217
        return $this->coreContainer[$sClass];
218
    }
219
220
    /**
221
     * Set a DI closure
222
     *
223
     * @param string                $sClass             The full class name
224
     * @param Closure               $xClosure           The closure
225
     *
226
     * @return void
227
     */
228
    public function set($sClass, $xClosure)
229
    {
230
        $this->coreContainer[$sClass] = $xClosure;
231
    }
232
233
    /**
234
     * Get the plugin manager
235
     *
236
     * @return Jaxon\Plugin\Manager
237
     */
238
    public function getPluginManager()
239
    {
240
        return $this->coreContainer[PluginManager::class];
241
    }
242
243
    /**
244
     * Get the request handler
245
     *
246
     * @return Jaxon\Request\Handler
247
     */
248
    public function getRequestHandler()
249
    {
250
        return $this->coreContainer[RequestHandler::class];
251
    }
252
253
    /**
254
     * Get the request factory
255
     *
256
     * @return Jaxon\Factory\Request
257
     */
258
    public function getRequestFactory()
259
    {
260
        return $this->coreContainer[RequestFactory::class];
261
    }
262
263
    /**
264
     * Get the parameter factory
265
     *
266
     * @return Jaxon\Factory\Parameter
267
     */
268
    public function getParameterFactory()
269
    {
270
        return $this->coreContainer[ParameterFactory::class];
271
    }
272
273
    /**
274
     * Get the response manager
275
     *
276
     * @return Jaxon\Response\Manager
277
     */
278
    public function getResponseManager()
279
    {
280
        return $this->coreContainer[ResponseManager::class];
281
    }
282
283
    /**
284
     * Get the code generator
285
     *
286
     * @return Jaxon\Code\Generator
287
     */
288
    public function getCodeGenerator()
289
    {
290
        return $this->coreContainer[CodeGenerator::class];
291
    }
292
293
    /**
294
     * Get the config manager
295
     *
296
     * @return Jaxon\Config\Config
297
     */
298
    public function getConfig()
299
    {
300
        return $this->coreContainer[Config::class];
301
    }
302
303
    /**
304
     * Create a new the config manager
305
     *
306
     * @return Jaxon\Config\Config            The config manager
307
     */
308
    public function newConfig()
309
    {
310
        return new \Jaxon\Config\Config();
311
    }
312
313
    /**
314
     * Get the dialog wrapper
315
     *
316
     * @return Jaxon\Dialog\Config
317
     */
318
    public function getDialog()
319
    {
320
        return $this->coreContainer[Dialog::class];
321
    }
322
323
    /**
324
     * Get the minifier
325
     *
326
     * @return Jaxon\Utils\Template\Minifier
327
     */
328
    public function getMinifier()
329
    {
330
        return $this->coreContainer[Minifier::class];
331
    }
332
333
    /**
334
     * Get the translator
335
     *
336
     * @return Jaxon\Utils\Translation\Translator
337
     */
338
    public function getTranslator()
339
    {
340
        return $this->coreContainer[Translator::class];
341
    }
342
343
    /**
344
     * Get the template engine
345
     *
346
     * @return Jaxon\Utils\Template\Template
347
     */
348
    public function getTemplate()
349
    {
350
        return $this->coreContainer[Template::class];
351
    }
352
353
    /**
354
     * Get the validator
355
     *
356
     * @return Jaxon\Utils\Validation\Validator
357
     */
358
    public function getValidator()
359
    {
360
        return $this->coreContainer[Validator::class];
361
    }
362
363
    /**
364
     * Get the paginator
365
     *
366
     * @return Jaxon\Utils\Pagination\Paginator
367
     */
368
    public function getPaginator()
369
    {
370
        return $this->coreContainer[Paginator::class];
371
    }
372
373
    /**
374
     * Set the pagination renderer
375
     *
376
     * @param Jaxon\Utils\Pagination\Renderer  $xRenderer    The pagination renderer
377
     *
378
     * @return void
379
     */
380
    public function setPaginationRenderer(PaginationRenderer $xRenderer)
381
    {
382
        $this->coreContainer[PaginationRenderer::class] = $xRenderer;
383
    }
384
385
    /**
386
     * Get the event dispatcher
387
     *
388
     * @return Lemon\Event\EventDispatcher
389
     */
390
    public function getEventDispatcher()
391
    {
392
        return $this->coreContainer[EventDispatcher::class];
393
    }
394
395
    /**
396
     * Get the global Response object
397
     *
398
     * @return Jaxon\Response\Response
399
     */
400
    public function getResponse()
401
    {
402
        return $this->coreContainer[Response::class];
403
    }
404
405
    /**
406
     * Create a new Jaxon response object
407
     *
408
     * @return Jaxon\Response\Response
409
     */
410
    public function newResponse()
411
    {
412
        return new Response();
413
    }
414
415
    /**
416
     * Get the main Jaxon object
417
     *
418
     * @return Jaxon\Jaxon
419
     */
420
    public function getJaxon()
421
    {
422
        return $this->coreContainer[Jaxon::class];
423
    }
424
425
    /**
426
     * Get the Jaxon library version number
427
     *
428
     * @return string
429
     */
430
    public function getVersion()
431
    {
432
        return $this->getJaxon()->getVersion();
433
    }
434
435
    /**
436
     * Get the Sentry instance
437
     *
438
     * @return Jaxon\Sentry\Sentry
439
     */
440
    public function getSentry()
441
    {
442
        return $this->coreContainer['jaxon.sentry'];
443
    }
444
445
    /**
446
     * Set the Sentry instance
447
     *
448
     * @param Jaxon\Sentry\Sentry     $xSentry            The Sentry instance
449
     *
450
     * @return void
451
     */
452
    public function setSentry($xSentry)
453
    {
454
        $this->coreContainer['jaxon.sentry'] = $xSentry;
455
    }
456
457
    /**
458
     * Get the Armada instance
459
     *
460
     * @return Jaxon\Armada\Armada
461
     */
462
    public function getArmada()
463
    {
464
        return $this->coreContainer['jaxon.armada'];
465
    }
466
467
    /**
468
     * Set the Armada instance
469
     *
470
     * @param Jaxon\Armada\Armada     $xArmada            The Armada instance
471
     *
472
     * @return void
473
     */
474
    public function setArmada($xArmada)
475
    {
476
        $this->coreContainer['jaxon.armada'] = $xArmada;
477
    }
478
479
    /**
480
     * Set the view renderers data
481
     *
482
     * @param array                $aRenderers          Array of renderer names with namespace as key
483
     *
484
     * @return void
485
     */
486
    public function initViewRenderers($aRenderers)
487
    {
488
        $this->coreContainer['jaxon.view.data.renderers'] = $aRenderers;
489
    }
490
491
    /**
492
     * Set the view namespaces data
493
     *
494
     * @param array                $aNamespaces         Array of namespaces with renderer name as key
495
     *
496
     * @return void
497
     */
498
    public function initViewNamespaces($aNamespaces, $sDefaultNamespace)
499
    {
500
        $this->coreContainer['jaxon.view.data.namespaces'] = $aNamespaces;
501
        $this->coreContainer['jaxon.view.data.namespace.default'] = $sDefaultNamespace;
502
    }
503
504
    /**
505
     * Add a view renderer
506
     *
507
     * @param string                $sId                The unique identifier of the view renderer
508
     * @param Closure               $xClosure           A closure to create the view instance
509
     *
510
     * @return void
511
     */
512
    public function addViewRenderer($sId, $xClosure)
513
    {
514
        // Return the non-initialiazed view renderer
515
        $this->coreContainer['jaxon.sentry.view.base.' . $sId] = $xClosure;
516
517
        // Return the initialized view renderer
518
        $this->coreContainer['jaxon.sentry.view.' . $sId] = function ($c) use ($sId) {
519
            // Get the defined renderer
520
            $renderer = $c['jaxon.sentry.view.base.' . $sId];
521
            // Init the renderer with the template namespaces
522
            $aNamespaces = $this->coreContainer['jaxon.view.data.namespaces'];
523
            if(key_exists($sId, $aNamespaces))
524
            {
525
                foreach($aNamespaces[$sId] as $ns)
526
                {
527
                    $renderer->addNamespace($ns['namespace'], $ns['directory'], $ns['extension']);
528
                }
529
            }
530
            return $renderer;
531
        };
532
    }
533
534
    /**
535
     * Get the view renderer
536
     *
537
     * @param string                $sId                The unique identifier of the view renderer
538
     *
539
     * @return Jaxon\Sentry\Interfaces\View
540
     */
541
    public function getViewRenderer($sId = '')
542
    {
543
        if(!$sId)
544
        {
545
            // Return the view renderer facade
546
            return $this->coreContainer[\Jaxon\Sentry\View\Facade::class];
547
        }
548
        // Return the view renderer with the given id
549
        return $this->coreContainer['jaxon.sentry.view.' . $sId];
550
    }
551
552
    /**
553
     * Get the session object
554
     *
555
     * @return Jaxon\Sentry\Interfaces\Session
556
     */
557
    public function getSessionManager()
558
    {
559
        return $this->coreContainer['jaxon.armada.session'];
560
    }
561
562
    /**
563
     * Set the session
564
     *
565
     * @param Closure      $xClosure      A closure to create the session instance
566
     *
567
     * @return void
568
     */
569
    public function setSessionManager($xClosure)
570
    {
571
        $this->coreContainer['jaxon.armada.session'] = $xClosure;
572
    }
573
}
574