Completed
Push — master ( c0ebc5...b1031b )
by Derek Stephen
09:29
created

ApplicationPackage::initMiddlewareStack()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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