Completed
Push — dev-master ( f1d44b...511541 )
by Derek Stephen
01:34
created

ApplicationPackage   A

Complexity

Total Complexity 32

Size/Duplication

Total Lines 293
Duplicated Lines 9.22 %

Coupling/Cohesion

Components 1
Dependencies 19

Test Coverage

Coverage 95.24%

Importance

Changes 0
Metric Value
wmc 32
lcom 1
cbo 19
dl 27
loc 293
ccs 140
cts 147
cp 0.9524
rs 9.84
c 0
b 0
f 0

14 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A addToContainer() 0 12 1
A setConfigArray() 0 6 2
A setLocale() 0 8 1
B setupViewEngine() 27 60 2
A setupTranslator() 0 14 3
A setupPdoConnection() 0 18 1
A setupDownloadController() 0 8 1
A setupLogs() 0 19 5
A setupModuleViewOverrides() 0 11 2
A getEntityPath() 0 4 1
A hasEntityPath() 0 4 1
A overrideViewFolder() 0 8 2
B setupModules() 0 40 9

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