Completed
Push — master ( 75c398...3c71f0 )
by Thierry
01:47
created

Container   A

Complexity

Total Complexity 42

Size/Duplication

Total Lines 521
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 20

Importance

Changes 0
Metric Value
dl 0
loc 521
rs 9.0399
c 0
b 0
f 0
wmc 42
lcom 2
cbo 20

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