Completed
Push — master ( 80e7cf...0854c8 )
by Derek Stephen
56s
created

ApplicationPackage::setupModuleViewOverrides()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

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