Completed
Push — master ( 37f718...2ac5d7 )
by Derek Stephen
01:39
created

ApplicationPackage   A

Complexity

Total Complexity 36

Size/Duplication

Total Lines 312
Duplicated Lines 8.65 %

Coupling/Cohesion

Components 1
Dependencies 19

Test Coverage

Coverage 91.5%

Importance

Changes 0
Metric Value
wmc 36
lcom 1
cbo 19
dl 27
loc 312
ccs 140
cts 153
cp 0.915
rs 9.52
c 0
b 0
f 0

16 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A addToContainer() 0 14 1
A setConfigArray() 0 6 2
B setupViewEngine() 27 55 1
A setupTranslator() 0 6 1
A setupPdoConnection() 0 18 1
A setupDownloadController() 0 8 1
A setupRouteFirewall() 0 5 1
A setupLogs() 0 19 5
A setupModuleViewOverrides() 0 11 2
A overrideViewFolder() 0 8 2
A getEntityPath() 0 4 1
A hasEntityPath() 0 4 1
A initMiddlewareStack() 0 5 1
A setupMiddlewareStack() 0 15 5
B setupModules() 0 45 10

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
namespace Bone\Mvc;
4
5
use Barnacle\Container;
6
use Barnacle\Exception\NotFoundException;
7
use Barnacle\RegistrationInterface;
8
use Bone\Firewall\FirewallPackage;
9
use Bone\Http\Middleware\Stack;
10
use Bone\Http\MiddlewareAwareInterface;
11
use Bone\I18n\I18nPackage;
12
use Bone\I18n\I18nRegistrationInterface;
13
use Bone\I18n\View\Extension\LocaleLink;
14
use Bone\I18n\View\Extension\Translate;
15
use Bone\Mvc\Controller\DownloadController;
16
use Bone\Mvc\Router;
17
use Bone\Mvc\Router\Decorator\ExceptionDecorator;
18
use Bone\Mvc\Router\Decorator\NotAllowedDecorator;
19
use Bone\Mvc\Router\Decorator\NotFoundDecorator;
20
use Bone\Mvc\Router\PlatesStrategy;
21
use Bone\Mvc\Router\RouterConfigInterface;
22
use Bone\Mvc\View\Extension\Plates\AlertBox;
23
use Bone\Mvc\View\ViewEngine;
24
use Bone\View\Helper\Paginator;
25
use Bone\Mvc\View\PlatesEngine;
26
use Bone\I18n\Service\TranslatorFactory;
27
use League\Plates\Template\Folders;
28
use League\Route\Strategy\ApplicationStrategy;
29
use League\Route\Strategy\JsonStrategy;
30
use Locale;
31
use PDO;
32
use Laminas\Diactoros\ResponseFactory;
33
use Laminas\I18n\Translator\Loader\Gettext;
34
use Laminas\I18n\Translator\Translator;
35
use Psr\Http\Server\MiddlewareInterface;
36
37
class ApplicationPackage implements RegistrationInterface
38
{
39
    /** @var array $config */
40
    private $config;
41
42
    /** @var Router $router */
43
    private $router;
44
45
    /** @var bool $i18nEnabledSite */
46
    private $i18nEnabledSite = false;
47
48
    /** @var array $supportedLocales */
49
    private $supportedLocales = [];
50
51
    /**
52
     * ApplicationPackage constructor.
53
     * @param array $config
54
     * @param Router $router
55
     */
56 9
    public function __construct(array $config, Router $router)
57
    {
58 9
        $this->config = $config;
59 9
        $this->router = $router;
60 9
    }
61
62
    /**
63
     * @param Container $c
64
     */
65 9
    public function addToContainer(Container $c)
66
    {
67 9
        $this->setConfigArray($c);
68 9
        $this->setupLogs($c);
69 9
        $this->setupPdoConnection($c);
70 9
        $this->setupViewEngine($c);
71 9
        $this->initMiddlewareStack($c);
72 9
        $this->setupTranslator($c);
73 9
        $this->setupModules($c);
74 9
        $this->setupModuleViewOverrides($c);
75 9
        $this->setupDownloadController($c);
76 9
        $this->setupRouteFirewall($c);
77 9
        $this->setupMiddlewareStack($c);
78 9
    }
79
80
    /**
81
     * @param Container $c
82
     */
83 9
    private function setConfigArray(Container $c)
84
    {
85 9
        foreach ($this->config as $key => $value) {
86 9
            $c[$key] = $value;
87
        }
88 9
    }
89
90
    /**
91
     * @param Container $c
92
     */
93 9
    private function setupViewEngine(Container $c)
94
    {
95
        // set up the view engine dependencies
96 9
        $viewEngine = new PlatesEngine($c->get('viewFolder'));
97 9
        $viewEngine->loadExtension(new AlertBox());
98
99 9
        $c[PlatesEngine::class] = $viewEngine;
100
101 View Code Duplication
        $c[NotFoundDecorator::class] = $c->factory(function (Container $c) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
102 9
            $layout = $c->get('default_layout');
103 9
            $templates = $c->get('error_pages');
104 9
            $viewEngine = $c->get(PlatesEngine::class);
105 9
            $notFoundDecorator = new NotFoundDecorator($viewEngine, $templates);
106 9
            $notFoundDecorator->setLayout($layout);
107
108 9
            return $notFoundDecorator;
109 9
        });
110
111 View Code Duplication
        $c[NotAllowedDecorator::class] = $c->factory(function (Container $c) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
112 9
            $layout = $c->get('default_layout');
113 9
            $templates = $c->get('error_pages');
114 9
            $viewEngine = $c->get(PlatesEngine::class);
115 9
            $notAllowedDecorator = new NotAllowedDecorator($viewEngine, $templates);
116 9
            $notAllowedDecorator->setLayout($layout);
117
118 9
            return $notAllowedDecorator;
119 9
        });
120
121 View Code Duplication
        $c[ExceptionDecorator::class] = $c->factory(function (Container $c) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
122 9
            $viewEngine = $c->get(PlatesEngine::class);
123 9
            $layout = $c->get('default_layout');
124 9
            $templates = $c->get('error_pages');
125 9
            $decorator = new ExceptionDecorator($viewEngine, $templates);
126 9
            $decorator->setLayout($layout);
127
128 9
            return $decorator;
129 9
        });
130
131
        $c[PlatesStrategy::class] = $c->factory(function (Container $c) {
132 9
            $viewEngine = $c->get(PlatesEngine::class);
133 9
            $notFoundDecorator = $c->get(NotFoundDecorator::class);
134 9
            $notAllowedDecorator = $c->get(NotAllowedDecorator::class);
135 9
            $exceptionDecorator = $c->get(ExceptionDecorator::class);
136 9
            $layout = $c->get('default_layout');
137 9
            $strategy = new PlatesStrategy($viewEngine, $notFoundDecorator, $notAllowedDecorator, $layout, $exceptionDecorator);
138
139 9
            return $strategy;
140 9
        });
141
142
        /** @var PlatesStrategy $strategy */
143 9
        $strategy = $c->get(PlatesStrategy::class);
144 9
        $strategy->setContainer($c);
145
146 9
        $this->router->setStrategy($strategy);
147 9
    }
148
149
    /**
150
     * @param Container $c
151
     */
152 9
    private function setupModules(Container $c)
153
    {
154
        // set up the modules and vendor package modules
155 9
        $packages = $c->get('packages');
156 9
        $i18n = $c->get('i18n');
157
        /** @var Translator $translator */
158 9
        $translator = $c->get(Translator::class);
159
160 9
        foreach ($packages as $packageName) {
161 9
            if (class_exists($packageName)) {
162
                /** @var RegistrationInterface $package */
163 9
                $package = new $packageName();
164
165 9
                if ($package->hasEntityPath()) {
166 9
                    $paths = $c['entity_paths'];
167 9
                    $paths[] = $package->getEntityPath();
168 9
                    $c['entity_paths'] = $paths;
169
                }
170
            }
171
        }
172 9
        reset($packages);
173 9
        foreach ($packages as $packageName) {
174 9
            if (class_exists($packageName)) {
175
                /** @var RegistrationInterface $package */
176 9
                $package = new $packageName();
177 9
                $package->addToContainer($c);
178
179 9
                if ($package instanceof RouterConfigInterface) {
180 9
                    $package->addRoutes($c, $this->router);
181
                }
182
183 9
                if ($package instanceof I18nRegistrationInterface) {
184 9
                    foreach ($i18n['supported_locales'] as $locale) {
185 9
                        $factory = new TranslatorFactory();
186 9
                        $factory->addPackageTranslations($translator, $package, $locale);
187
                    }
188
                }
189
190 9
                if ($package instanceof MiddlewareAwareInterface) {
191
                    $stack = $c->get(Stack::class);
192 9
                    $package->addMiddleware($stack);
193
                }
194
            }
195
        }
196 9
    }
197
198
    /**
199
     * @param Container $c
200
     */
201 9
    private function setupTranslator(Container $c)
202
    {
203 9
        $package = new I18nPackage();
204 9
        $package->addToContainer($c);
205 9
        $package->addMiddleware($c->get(Stack::class), $c);
206 9
    }
207
208
209
    /**
210
     * @param Container $c
211
     */
212 9
    private function setupPdoConnection(Container $c)
213
    {
214
        // set up a db connection
215
        $c[PDO::class] = $c->factory(function (Container $c): PDO {
216 1
            $credentials = $c->get('db');
217 1
            $host = $credentials['host'];
218 1
            $db = $credentials['database'];
219 1
            $user = $credentials['user'];
220 1
            $pass = $credentials['pass'];
221
222 1
            $dbConnection = new PDO('mysql:host=' . $host . ';dbname=' . $db, $user, $pass, [
223 1
                PDO::ATTR_EMULATE_PREPARES => false,
224
                PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
225
            ]);
226
227 1
            return $dbConnection;
228 9
        });
229 9
    }
230
231
    /**
232
     * @param Container $c
233
     */
234 9
    private function setupDownloadController(Container $c): void
235
    {
236 9
        $uploadDirectory = $c->get('uploads_dir');
237 9
        $c[DownloadController::class] = new DownloadController($uploadDirectory);
238 9
        $strategy = new JsonStrategy(new ResponseFactory());
239 9
        $strategy->setContainer($c);
240 9
        $this->router->map('GET', '/download', [DownloadController::class, 'downloadAction'])->setStrategy($strategy);
241 9
    }
242
243
    /**
244
     * @param Container $c
245
     */
246 9
    private function setupRouteFirewall(Container $c): void
247
    {
248 9
        $firewallPackage = new FirewallPackage();
249 9
        $firewallPackage->addToContainer($c);
250 9
    }
251
252
    /**
253
     * @param Container $c
254
     */
255 9
    private function setupLogs(Container $c)
256
    {
257 9
        if ($c->has('display_errors')) {
258
            ini_set('display_errors', $c->get('display_errors'));
259
        }
260
261 9
        if ($c->has('error_reporting')) {
262
            error_reporting($c->get('error_reporting'));
263
        }
264
265 9
        if ($c->has('error_log')) {
266
            $errorLog = $c->get('error_log');
267
            if (!file_exists($errorLog)) {
268
                file_put_contents($errorLog, '');
269
                chmod($errorLog, 0775);
270
            }
271
            ini_set($c->get('error_log'), $errorLog);
272
        }
273 9
    }
274
275
    /**
276
     * @param Container $c
277
     */
278 9
    private function setupModuleViewOverrides(Container $c): void
279
    {
280
        /** @var PlatesEngine $viewEngine */
281 9
        $viewEngine = $c->get(PlatesEngine::class);
282 9
        $views = $c->get('views');
283 9
        $registeredViews = $viewEngine->getFolders();
284
285 9
        foreach ($views as $view => $folder) {
286 9
            $this->overrideViewFolder($view, $folder, $registeredViews);
287
        }
288 9
    }
289
290
    /**
291
     * @param string $view
292
     * @param string $folder
293
     * @param array $registeredViews
294
     * @param PlatesEngine $viewEngine
0 ignored issues
show
Bug introduced by
There is no parameter named $viewEngine. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
295
     */
296 9
    private function overrideViewFolder(string $view, string $folder, Folders $registeredViews): void
297
    {
298 9
        if ($registeredViews->exists($view)) {
299
            /** @var \League\Plates\Template\Folder $currentFolder */
300 1
            $currentFolder = $registeredViews->get($view);
301 1
            $currentFolder->setPath($folder);
302
        }
303 9
    }
304
305
    /**
306
     * @return string
307
     */
308 1
    public function getEntityPath(): string
309
    {
310 1
        return '';
311
    }
312
313
    /**
314
     * @return bool
315
     */
316 1
    public function hasEntityPath(): bool
317
    {
318 1
        return false;
319
    }
320
321
    /**
322
     * @param Container $c
323
     */
324 9
    private function initMiddlewareStack(Container $c): void
325
    {
326 9
        $router = $c->get(Router::class);
327 9
        $c[Stack::class] = new Stack($router);
328 9
    }
329
330
    /**
331
     * @param Container $c
332
     */
333 9
    private function setupMiddlewareStack(Container $c): void
334
    {
335 9
        $stack = $c->get(Stack::class);
336 9
        $middlewareStack = $c->has('stack') ? $c->get('stack') : [];
337
338 9
        foreach ($middlewareStack as $middleware) {
339
            if ($middleware instanceof MiddlewareInterface) {
340
                $stack->addMiddleWare($middleware);
341
            } elseif ($c->has($middleware)) {
342
                $stack->addMiddleWare($c->get($middleware));
343
            } else {
344
                $stack->addMiddleWare(new $middleware());
345
            }
346
        }
347
    }
348
}