Completed
Push — master ( 1f9c82...39029c )
by Anton
36:30 queued 34:41
created

Bootstrap::initTranslator()   A

Complexity

Conditions 5
Paths 8

Size

Total Lines 36

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
cc 5
nc 8
nop 0
dl 0
loc 36
ccs 0
cts 25
cp 0
crap 30
rs 9.0328
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright Bluz PHP Team
4
 * @link      https://github.com/bluzphp/skeleton
5
 */
6
7
declare(strict_types=1);
8
9
namespace Application;
10
11
use Application\Auth;
12
use Bluz\Application\Application;
13
use Bluz\Auth\AuthException;
14
use Bluz\Controller\Controller;
15
use Bluz\Http\Exception\ForbiddenException;
16
use Bluz\Http\Exception\RedirectException;
17
use Bluz\Proxy\Auth as AuthProxy;
18
use Bluz\Proxy\Config;
19
use Bluz\Proxy\Layout;
20
use Bluz\Proxy\Logger;
21
use Bluz\Proxy\Messages;
22
use Bluz\Proxy\Request;
23
use Bluz\Proxy\Response;
24
use Bluz\Proxy\Router;
25
use Bluz\Proxy\Session;
26
use Bluz\Proxy\Translator;
27
28
/**
29
 * Bootstrap
30
 *
31
 * @category Application
32
 * @package  Bootstrap
33
 */
34
class Bootstrap extends 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...
35
{
36
    /**
37
     * {@inheritdoc}
38
     */
39
    protected function initTranslator(): void
40
    {
41
        $translator = new \Bluz\Translator\Translator();
42
        $translator->setOptions(Config::get('translator'));
43
44
        // supported locales
45
        // en_US, ru_RU, uk_UA
46
        $locales = [
47
            'en' => 'en_US',
48
            'ru' => 'ru_RU',
49
            'uk' => 'uk_UA',
50
        ];
51
52
        // try to check locale from cookies
53
        $locale = Request::getCookie('locale');
54
55
        // try to get locale from browser
56
        if (!$locale) {
57
            $languages = Request::getAcceptLanguage();
58
            foreach ($languages as $language => $priority) {
59
                if (array_key_exists($language, $locales)) {
60
                    $locale = $language;
61
                    break;
62
                }
63
            }
64
        }
65
66
        // normalize locale
67
        if (array_key_exists($locale, $locales)) {
68
            $translator->setLocale($locales[$locale]);
69
        }
70
71
        $translator->init();
72
73
        Translator::setInstance($translator);
74
    }
75
76
    /**
77
     * {@inheritdoc}
78
     *
79
     * @param Controller $controller
80
     *
81
     * @return void
82
     * @throws AuthException
83
     * @throws Exception
84
     * @throws \Bluz\Db\Exception\DbException
85
     * @throws \Bluz\Db\Exception\InvalidPrimaryKeyException
86
     */
87
    protected function preDispatch($controller): void
88
    {
89
        // example of setup default title
90
        Layout::title('Bluz Skeleton');
91
92
        if (!AuthProxy::getIdentity() && $controller->getModule() !== Router::getErrorModule()) {
93
            if ($token = Request::getCookie('Auth-Token')) {
94
                // try to login by token from cookies
95
                try {
96
                    Auth\Provider\Cookie::authenticate($token);
97
                } catch (AuthException $e) {
98
                    $this->getResponse()->setCookie('Auth-Token', '', 1, '/');
99
                }
100
            } elseif ($token = Request::getHeader('Auth-Token')) {
101
                // try to login by token from headers
102
                Auth\Provider\Token::authenticate($token);
103
            }
104
        }
105
        parent::preDispatch($controller);
106
    }
107
108
    /**
109
     * Denied access
110
     *
111
     * @param ForbiddenException $exception
112
     *
113
     * @return \Bluz\Controller\Controller|null
114
     */
115
    public function forbidden(ForbiddenException $exception): ?Controller
116
    {
117
        // for AJAX and API calls (over JSON)
118
        $jsonOrApi = Request::isXmlHttpRequest()
119
            || (Request::checkAccept([Request::TYPE_HTML, Request::TYPE_JSON]) === Request::TYPE_JSON);
120
121
        // for guest, for requests
122
        if (!$jsonOrApi && !AuthProxy::getIdentity()) {
123
            // save URL to session and redirect make sense if presentation is null
124
            Session::set('rollback', Request::getUri()->__toString());
125
            // add error notice
126
            Messages::addError('You don\'t have permissions, please sign in');
127
            // redirect to Sign In page
128
            $redirect = new RedirectException();
129
            $redirect->setUrl(Router::getUrl('users', 'signin'));
130
            return $this->redirect($redirect);
131
        }
132
        return $this->error($exception);
133
    }
134
135
    /**
136
     * Render with debug headers
137
     *
138
     * @return void
139
     */
140
    public function render(): void
141
    {
142
        Logger::info('app:render');
143
        Logger::info('app:files:' . count(get_included_files()));
144
145
        if ($this->isDebug()) {
146
            if (!headers_sent()) {
147
                $this->sendInfoHeaders();
148
            }
149
            if (ob_get_level() > 0 && ob_get_length() > 0) {
150
                Logger::error('Output has been sent previously');
151
                return;
152
            }
153
        }
154
        parent::render();
155
    }
156
157
    /**
158
     * Finish it
159
     *
160
     * @return void
161
     */
162
    public function end(): void
163
    {
164
        if ($errors = Logger::get('error')) {
165
            $this->sendErrors($errors);
166
        }
167
    }
168
169
    /**
170
     * Send information headers
171
     *
172
     * @return void
173
     */
174
    protected function sendInfoHeaders(): void
175
    {
176
        $debugString = sprintf(
177
            '%fsec; %skb',
178
            microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'],
179
            ceil(memory_get_usage() / 1024)
180
        );
181
        $debugString .= '; ' . Request::getModule() . '/' . Request::getController();
182
183
        Response::setHeader('Bluz-Debug', $debugString);
184
185
        if ($info = Logger::get('info')) {
186
            Response::setHeader('Bluz-Bar', json_encode($info));
187
        } else {
188
            Response::setHeader('Bluz-Bar', '{"!":"Logger is disabled"}');
189
        }
190
    }
191
192
    /**
193
     * sendErrorBody
194
     *
195
     * @param  array $errors
196
     *
197
     * @return void
198
     */
199
    protected function sendErrors($errors): void
200
    {
201
        foreach ($errors as $message) {
202
            errorLog(new \ErrorException($message, 0, E_USER_ERROR));
203
        }
204
    }
205
}
206