Completed
Push — master ( af0d2f...ba91a3 )
by Derek Stephen
48:41 queued 47:10
created

ApplicationPackage::addEntityPathsFromPackages()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 4

Importance

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