Completed
Push — master ( 45ace6...1d4cea )
by Derek Stephen
01:36
created

ApplicationPackage::setupPackages()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3

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