Completed
Push — master ( b5ae43...2249ad )
by Derek Stephen
04:33
created

ApplicationPackage::initConsoleApp()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

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