Completed
Push — master ( 3999cc...7004fd )
by Anton
04:02 queued 01:32
created

Application::initTranslator()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 8
ccs 6
cts 6
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Bluz Framework Component
4
 *
5
 * @copyright Bluz PHP Team
6
 * @link      https://github.com/bluzphp/framework
7
 */
8
9
declare(strict_types=1);
10
11
namespace Bluz\Application;
12
13
use Bluz\Application\Exception\ApplicationException;
14
use Bluz\Config\ConfigLoader;
15
use Bluz\Http\Exception\ForbiddenException;
16
use Bluz\Http\Exception\NotAcceptableException;
17
use Bluz\Http\Exception\NotAllowedException;
18
use Bluz\Http\Exception\RedirectException;
19
use Bluz\Common;
20
use Bluz\Common\Exception\CommonException;
21
use Bluz\Common\Exception\ComponentException;
22
use Bluz\Controller\Controller;
23
use Bluz\Controller\ControllerException;
24
use Bluz\Proxy\Config;
25
use Bluz\Proxy\Layout;
26
use Bluz\Proxy\Logger;
27
use Bluz\Proxy\Messages;
28
use Bluz\Proxy\Request;
29
use Bluz\Proxy\Response;
30
use Bluz\Proxy\Router;
31
use Bluz\Proxy\Session;
32
use Bluz\Proxy\Translator;
33
use Bluz\Request\RequestFactory;
34
use Bluz\Response\Response as ResponseInstance;
35
use Zend\Diactoros\ServerRequest;
36
37
/**
38
 * Application
39
 *
40
 * @package  Bluz\Application
41
 * @link     https://github.com/bluzphp/framework/wiki/Application
42
 * @author   Anton Shevchuk
43
 * @created  06.07.11 16:25
44
 *
45
 * @method Controller error(\Exception $exception)
46
 * @method mixed forbidden(ForbiddenException $exception)
47
 * @method null redirect(RedirectException $url)
48
 */
49
class Application
0 ignored issues
show
Coding Style introduced by
Since you have declared the constructor as private, maybe you should also declare the class as final.
Loading history...
50
{
51
    use Common\Helper;
52
    use Common\Singleton;
53
54
    /**
55
     * @var string Environment name
56
     */
57
    protected $environment = 'production';
58
59
    /**
60
     * @var string Application path
61
     */
62
    protected $path;
63
64
    /**
65
     * @var bool Debug application flag
66
     */
67
    protected $debugFlag = false;
68
69
    /**
70
     * @var bool Layout usage flag
71
     */
72
    protected $layoutFlag = true;
73
74
    /**
75
     * Get application environment
76
     *
77
     * @return string
78
     */
79 602
    public function getEnvironment(): string
80
    {
81 602
        return $this->environment;
82
    }
83
84
    /**
85
     * Get path to Application
86
     *
87
     * @return string
88
     * @throws \ReflectionException
89
     */
90 602
    public function getPath(): string
91
    {
92 602
        if (!$this->path) {
93 602
            if (\defined('PATH_APPLICATION')) {
94 602
                $this->path = PATH_APPLICATION;
95
            } else {
96
                $reflection = new \ReflectionClass($this);
97
                // 3 level up
98
                $this->path = \dirname($reflection->getFileName(), 3);
99
            }
100
        }
101 602
        return $this->path;
102
    }
103
104
    /**
105
     * Return Debug flag
106
     *
107
     * @return bool
108
     */
109 2
    public function isDebug(): bool
110
    {
111 2
        return $this->debugFlag;
112
    }
113
114
    /**
115
     * Return/setup Layout Flag
116
     *
117
     * @param  bool|null $flag
118
     *
119
     * @return bool
120
     */
121 35
    public function useLayout($flag = null): bool
122
    {
123 35
        if (\is_bool($flag)) {
124 28
            $this->layoutFlag = $flag;
125
        }
126
127 35
        return $this->layoutFlag;
128
    }
129
130
    /**
131
     * Initialize system packages
132
     *
133
     * @param  string $environment
134
     *
135
     * @throws ApplicationException
136
     * @return void
137
     */
138 602
    public function init($environment = 'production'): void
139
    {
140 602
        $this->environment = $environment;
141
142
        try {
143
            // initial default helper path
144 602
            $this->addHelperPath(__DIR__ . '/Helper/');
145
146
            // init Config
147 602
            $this->initConfig();
148
149
            // first log message
150 602
            Logger::info('app:init');
151
152
            // init Session, start inside class (if needed)
153 602
            Session::getInstance();
154
155
            // init Messages
156 602
            Messages::getInstance();
157
158
            // init Request
159 602
            $this->initRequest();
160
161
            // init Response
162 602
            $this->initResponse();
163
164
            // init Translator
165 602
            $this->initTranslator();
166
167
            // init Router
168 602
            $this->initRouter();
169
        } catch (\Exception $e) {
170
            throw new ApplicationException("Application can't be loaded: " . $e->getMessage());
171
        }
172 602
    }
173
174
    /**
175
     * Initial Request instance
176
     *
177
     * @return void
178
     * @throws \Bluz\Config\ConfigException
179
     * @throws \ReflectionException
180
     */
181 602
    protected function initConfig(): void
182
    {
183 602
        $loader = new ConfigLoader();
184 602
        $loader->setPath($this->getPath());
185 602
        $loader->setEnvironment($this->getEnvironment());
186 602
        $loader->load();
187
188 602
        $config = new \Bluz\Config\Config();
189 602
        $config->setFromArray($loader->getConfig());
190
191 602
        Config::setInstance($config);
192
193
        // setup configuration for current environment
194 602
        if ($debug = Config::get('debug')) {
195
            $this->debugFlag = (bool)$debug;
196
        }
197
198
        // initial php settings
199 602
        if ($ini = Config::get('php')) {
200
            foreach ($ini as $key => $value) {
201
                $result = ini_set($key, $value);
202
                Logger::info('app:init:php:' . $key . ':' . ($result ?: '---'));
203
            }
204
        }
205 602
    }
206
207
    /**
208
     * Initial Request instance
209
     *
210
     * @return void
211
     * @throws \InvalidArgumentException
212
     */
213 602
    protected function initRequest(): void
214
    {
215 602
        $request = RequestFactory::fromGlobals();
216
217 602
        Request::setInstance($request);
218 602
    }
219
220
    /**
221
     * Initial Response instance
222
     *
223
     * @return void
224
     */
225 602
    protected function initResponse(): void
226
    {
227 602
        $response = new ResponseInstance();
228
229 602
        Response::setInstance($response);
230 602
    }
231
232
    /**
233
     * Get Response instance
234
     *
235
     * @return \Bluz\Response\Response
236
     */
237 3
    public function getResponse(): ResponseInstance
238
    {
239 3
        return Response::getInstance();
240
    }
241
242
    /**
243
     * Get Request instance
244
     *
245
     * @return \Zend\Diactoros\ServerRequest
246
     */
247 1
    public function getRequest(): ServerRequest
248
    {
249 1
        return Request::getInstance();
250
    }
251
252
    /**
253
     * Initial Router instance
254
     *
255
     * @return void
256
     */
257 602
    protected function initRouter(): void
258
    {
259 602
        $router = new \Bluz\Router\Router();
260 602
        $router->setOptions(Config::get('router'));
261
262 602
        Router::setInstance($router);
263 602
    }
264
265
    /**
266
     * Initial Translator instance
267
     *
268
     * @return void
269
     * @throws Common\Exception\ConfigurationException
270
     */
271 602
    protected function initTranslator(): void
272
    {
273 602
        $translator = new \Bluz\Translator\Translator();
274 602
        $translator->setOptions(Config::get('translator'));
275 602
        $translator->init();
276
277 602
        Translator::setInstance($translator);
278 602
    }
279
280
    /**
281
     * Run application
282
     *
283
     * @return void
284
     */
285 1
    public function run(): void
286
    {
287 1
        $this->process();
288 1
        $this->render();
289 1
        $this->end();
290 1
    }
291
292
    /**
293
     * Process application
294
     *
295
     * Note:
296
     * - Why you don't use "X-" prefix for custom headers?
297
     * - Because it deprecated ({@link http://tools.ietf.org/html/rfc6648})
298
     *
299
     * @return void
300
     */
301 9
    public function process(): void
302
    {
303 9
        $this->preProcess();
304 9
        $this->doProcess();
305 9
        $this->postProcess();
306 9
    }
307
308
    /**
309
     * Extension point: pre process
310
     *
311
     * - Router processing
312
     * - Analyse request headers
313
     *
314
     * @return void
315
     */
316 9
    protected function preProcess(): void
317
    {
318 9
        Router::process();
319
320
        // disable Layout for XmlHttpRequests
321 9
        if (Request::isXmlHttpRequest()) {
322 2
            $this->layoutFlag = false;
323
        }
324
325
        // switch to JSON response based on Accept header
326 9
        if (Request::checkAccept([Request::TYPE_HTML, Request::TYPE_JSON]) === Request::TYPE_JSON) {
327 1
            $this->layoutFlag = false;
328 1
            Response::setType('JSON');
329
        }
330 9
    }
331
332
    /**
333
     * Do process
334
     *
335
     * - Dispatch controller
336
     * - Exceptions handling
337
     * - Setup layout
338
     * - Setup response body
339
     *
340
     * @return void
341
     */
342
    protected function doProcess(): void
343
    {
344
        $module = Request::getModule();
345
        $controller = Request::getController();
346
        $params = Request::getParams();
347
348
        try {
349
            // try to dispatch controller
350
            $result = $this->dispatch($module, $controller, $params);
351
        } catch (ForbiddenException $e) {
352
            // dispatch default error controller
353
            $result = $this->forbidden($e);
354
        } catch (RedirectException $e) {
355
            // should return `null` for disable output and setup redirect headers
356
            $result = $this->redirect($e);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $result is correct as $this->redirect($e) (which targets Bluz\Application\Application::redirect()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
357
        } catch (\Exception $e) {
358
            // dispatch default error controller
359
            $result = $this->error($e);
360
        }
361
362
        // setup layout, if needed
363
        if ($this->useLayout()) {
364
            // render view to layout
365
            // needed for headScript and headStyle helpers
366
            Layout::setContent($result->render());
367
            Response::setBody(Layout::getInstance());
368
        } else {
369
            Response::setBody($result);
370
        }
371
    }
372
373
    /**
374
     * Extension point: post process
375
     *
376
     * @return void
377
     */
378 9
    protected function postProcess(): void
379
    {
380
        // nothing
381 9
    }
382
383
    /**
384
     * Dispatch controller with params
385
     *
386
     * Call dispatch from any \Bluz\Package
387
     *     Application::getInstance()->dispatch($module, $controller, array $params);
388
     *
389
     * @param  string $module
390
     * @param  string $controller
391
     * @param  array  $params
392
     *
393
     * @return Controller
394
     * @throws ComponentException
395
     * @throws CommonException
396
     * @throws ControllerException
397
     * @throws ForbiddenException
398
     * @throws NotAcceptableException
399
     * @throws NotAllowedException
400
     */
401 41
    public function dispatch($module, $controller, array $params = []): Controller
402
    {
403 41
        $instance = new Controller($module, $controller, $params);
404
405 41
        Logger::info("app:dispatch:>>>: $module/$controller");
406 41
        $this->preDispatch($instance);
407
408 40
        Logger::info("app:dispatch:===: $module/$controller");
409 40
        $this->doDispatch($instance);
410
411 38
        Logger::info("app:dispatch:<<<: $module/$controller");
412 38
        $this->postDispatch($instance);
413
414 38
        return $instance;
415
    }
416
417
    /**
418
     * Extension point: pre dispatch
419
     *
420
     * @param  Controller $controller
421
     *
422
     * @return void
423
     */
424 41
    protected function preDispatch($controller): void
425
    {
426
        // check HTTP method
427 41
        $controller->checkHttpMethod();
428
429
        // check ACL privileges
430 40
        $controller->checkPrivilege();
431
432
        // check HTTP Accept header
433 40
        $controller->checkHttpAccept();
434 40
    }
435
436
    /**
437
     * Do dispatch
438
     *
439
     * @param  Controller $controller
440
     *
441
     * @return void
442
     * @throws ComponentException
443
     * @throws ControllerException
444
     */
445 40
    protected function doDispatch($controller): void
446
    {
447
        // run controller
448 40
        $controller->run();
449 38
    }
450
451
    /**
452
     * Extension point: post dispatch
453
     *
454
     * @param  Controller $controller
455
     *
456
     * @return void
457
     */
458 38
    protected function postDispatch($controller): void
0 ignored issues
show
Unused Code introduced by
The parameter $controller is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
459
    {
460
        // nothing by default
461 38
    }
462
463
    /**
464
     * Render, is send Response
465
     *
466
     * @return void
467
     */
468 1
    public function render(): void
469
    {
470 1
        Response::send();
471 1
    }
472
473
    /**
474
     * Extension point: finally method
475
     *
476
     * @return void
477
     */
478 1
    public function end(): void
479
    {
480
        // nothing
481 1
    }
482
}
483