Completed
Push — master ( 37ce3f...c57e71 )
by Derek Stephen
04:13
created

ApplicationPackage::setConfigArray()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

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