Issues (281)

Branch: master

src/Backend/Core/Language/Language.php (2 issues)

1
<?php
2
3
namespace Backend\Core\Language;
4
5
use Backend\Core\Engine\Model;
6
use Backend\Modules\Locale\Engine\Model as BackendLocaleModel;
7
use RuntimeException;
8
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
9
10
/**
11
 * This class will store the language-dependant content for the Backend, it will also store the
12
 * current language for the user.
13
 */
14
class Language
15
{
16
    /**
17
     * The errors
18
     *
19
     * @var array
20
     */
21
    protected static $err = [];
22
23
    /**
24
     * The labels
25
     *
26
     * @var array
27
     */
28
    protected static $lbl = [];
29
30
    /**
31
     * The messages
32
     *
33
     * @var array
34
     */
35
    protected static $msg = [];
36
37
    /**
38
     * The active languages
39
     *
40
     * @var array
41
     */
42
    protected static $activeLanguages;
43
44
    /**
45
     * The current interface-language
46
     *
47
     * @var string
48
     */
49
    protected static $currentInterfaceLanguage;
50
51
    /**
52
     * The current language that the user is working with
53
     *
54
     * @var string
55
     */
56
    protected static $currentWorkingLanguage;
57
58
    public static function getActiveLanguages(): array
59
    {
60
        // validate the cache
61
        if (empty(self::$activeLanguages)) {
62
            self::$activeLanguages = (array) Model::get('fork.settings')->get('Core', 'active_languages');
63
        }
64
65
        // return from cache
66
        return self::$activeLanguages;
67
    }
68
69
    /**
70
     * Get all active languages in a format usable by SpoonForm's addRadioButton
71
     *
72
     * @return array
73
     */
74
    public static function getCheckboxValues(): array
75
    {
76
        $languages = self::getActiveLanguages();
77
        $results = [];
78
79
        // stop here if no languages are present
80
        if (empty($languages)) {
81
            return [];
82
        }
83
84
        // addRadioButton requires an array with keys 'value' and 'label'
85
        foreach ($languages as $abbreviation) {
86
            $results[] = [
87
                'value' => $abbreviation,
88
                'label' => self::lbl(mb_strtoupper($abbreviation)),
89
            ];
90
        }
91
92
        return $results;
93
    }
94
95 71
    public static function getCurrentModule(): string
96
    {
97
        // Needed to make it possible to use the backend language in the console.
98 71
        if (!defined('APPLICATION') || APPLICATION === 'Console') {
99
            return 'Core';
100
        }
101
102 71
        if (Model::getContainer()->has('url')) {
103 71
            return Model::get('url')->getModule();
104
        }
105
106
        if (Model::requestIsAvailable() && Model::getRequest()->query->has('module')) {
107
            return Model::getRequest()->query->get('module');
108
        }
109
110
        return 'Core';
111
    }
112
113 71
    public static function getError(string $key, string $module = null): string
114
    {
115 71
        $module = $module ?? self::getCurrentModule();
116
117 71
        $key = \SpoonFilter::toCamelCase($key);
118
119
        // check if the error exists
120 71
        if (isset(self::$err[$module][$key])) {
121 5
            return self::$err[$module][$key];
122
        }
123
124
        // check if the error exists in the Core
125 71
        if (isset(self::$err['Core'][$key])) {
126 71
            return self::$err['Core'][$key];
127
        }
128
129
        // otherwise return the key in label-format
130 2
        return '{$err' . \SpoonFilter::toCamelCase($module) . $key . '}';
131
    }
132
133 71
    public static function getErrors(): array
134
    {
135 71
        return self::$err;
136
    }
137
138 131
    public static function getInterfaceLanguage(): string
139
    {
140 131
        if (self::$currentInterfaceLanguage === null) {
0 ignored issues
show
The condition self::currentInterfaceLanguage === null is always false.
Loading history...
141
            self::$currentInterfaceLanguage = Model::getContainer()->getParameter('site.default_language');
142
        }
143
144 131
        return self::$currentInterfaceLanguage;
145
    }
146
147 131
    public static function getInterfaceLanguages(): array
148
    {
149 131
        $languages = [];
150
151
        // grab the languages from the settings & loop language to reset the label
152 131
        foreach ((array) Model::get('fork.settings')->get('Core', 'interface_languages', ['en']) as $key) {
153
            // fetch language's translation
154 131
            $languages[$key] = self::getLabel(mb_strtoupper($key), 'Core');
155
        }
156
157
        // sort alphabetically
158 131
        asort($languages);
159
160
        // return languages
161 131
        return $languages;
162
    }
163
164 131
    public static function getLabel(string $key, string $module = null): string
165
    {
166 131
        $module = $module ?? self::getCurrentModule();
167
168 131
        $key = \SpoonFilter::toCamelCase($key);
169
170
        // check if the label exists
171 131
        if (isset(self::$lbl[$module][$key])) {
172 131
            return self::$lbl[$module][$key];
173
        }
174
175
        // check if the label exists in the Core
176 131
        if (isset(self::$lbl['Core'][$key])) {
177 71
            return self::$lbl['Core'][$key];
178
        }
179
180
        // otherwise return the key in label-format
181 131
        return '{$lbl' . \SpoonFilter::toCamelCase($module) . $key . '}';
182
    }
183
184 71
    public static function getLabels(): array
185
    {
186 71
        return self::$lbl;
187
    }
188
189 71
    public static function getMessage(string $key, string $module = null): string
190
    {
191 71
        $key = \SpoonFilter::toCamelCase((string) $key);
192 71
        $module = $module ?? self::getCurrentModule();
193
194
        // check if the message exists
195 71
        if (isset(self::$msg[$module][$key])) {
196 23
            return self::$msg[$module][$key];
197
        }
198
199
        // check if the message exists in the Core
200 71
        if (isset(self::$msg['Core'][$key])) {
201 67
            return self::$msg['Core'][$key];
202
        }
203
204
        // otherwise return the key in label-format
205 71
        return '{$msg' . \SpoonFilter::toCamelCase($module) . $key . '}';
206
    }
207
208 71
    public static function getMessages(): array
209
    {
210 71
        return self::$msg;
211
    }
212
213 131
    public static function getWorkingLanguage(): string
214
    {
215 131
        if (self::$currentWorkingLanguage === null) {
0 ignored issues
show
The condition self::currentWorkingLanguage === null is always false.
Loading history...
216 34
            self::$currentWorkingLanguage = Model::getContainer()->getParameter('site.default_language');
217
        }
218
219 131
        return self::$currentWorkingLanguage;
220
    }
221
222 131
    public static function getWorkingLanguages(): array
223
    {
224 131
        $languages = [];
225
226
        // grab the languages from the settings & loop language to reset the label
227 131
        foreach ((array) Model::get('fork.settings')->get('Core', 'languages', ['en']) as $key) {
228
            // fetch the language's translation
229 131
            $languages[$key] = self::getLabel(mb_strtoupper($key), 'Core');
230
        }
231
232
        // sort alphabetically
233 131
        asort($languages);
234
235 131
        return $languages;
236
    }
237
238
    /**
239
     * Set locale
240
     * It will require the correct file and init the needed vars
241
     *
242
     * @param string $language The language to load.
243
     */
244 131
    public static function setLocale(string $language): void
245
    {
246 131
        $application = (!defined('APPLICATION') || APPLICATION === 'Console') ? 'Backend' : APPLICATION;
247
248
        // validate file, generate it if needed
249 131
        if (!is_file(BACKEND_CACHE_PATH . '/Locale/en.json')) {
250 2
            BackendLocaleModel::buildCache('en', $application);
251
        }
252 131
        if (!is_file(BACKEND_CACHE_PATH . '/Locale/' . $language . '.json')) {
253
            // if you use the language in the console act like it is in the backend
254
            BackendLocaleModel::buildCache($language, $application);
255
        }
256
257
        // store
258 131
        self::$currentInterfaceLanguage = $language;
259
260
        // attempt to set a cookie
261
        try {
262
            // Needed to make it possible to use the backend language in the console.
263 131
            if (defined('APPLICATION') && APPLICATION !== 'Console') {
264 131
                Model::getContainer()->get('fork.cookie')->set('interface_language', $language);
265
            }
266
        } catch (RuntimeException|ServiceNotFoundException $e) {
267
            // settings cookies isn't allowed, because this isn't a real problem we ignore the exception
268
        }
269
270
        // set English translations, they'll be the fallback
271 131
        $translations = json_decode(
272 131
            file_get_contents(BACKEND_CACHE_PATH . '/Locale/en.json'),
273 131
            true
274
        );
275 131
        self::$err = (array) ($translations['err'] ?? []);
276 131
        self::$lbl = (array) ($translations['lbl'] ?? []);
277 131
        self::$msg = (array) ($translations['msg'] ?? []);
278
279
        // overwrite with the requested language's translations
280 131
        $translations = json_decode(
281 131
            file_get_contents(BACKEND_CACHE_PATH . '/Locale/' . $language . '.json'),
282 131
            true
283
        );
284 131
        $err = (array) ($translations['err'] ?? []);
285 131
        $lbl = (array) ($translations['lbl'] ?? []);
286 131
        $msg = (array) ($translations['msg'] ?? []);
287 131
        foreach ($err as $module => $translations) {
288 131
            if (!isset(self::$err[$module])) {
289
                self::$err[$module] = [];
290
            }
291 131
            self::$err[$module] = array_merge(self::$err[$module], $translations);
292
        }
293 131
        foreach ($lbl as $module => $translations) {
294 131
            if (!isset(self::$lbl[$module])) {
295
                self::$lbl[$module] = [];
296
            }
297 131
            self::$lbl[$module] = array_merge(self::$lbl[$module], $translations);
298
        }
299 131
        foreach ($msg as $module => $translations) {
300 131
            if (!isset(self::$msg[$module])) {
301
                self::$msg[$module] = [];
302
            }
303 131
            self::$msg[$module] = array_merge(self::$msg[$module], $translations);
304
        }
305 131
    }
306
307
    /**
308
     * @param string $language The language to use, if not provided we will use the working language.
309
     */
310 131
    public static function setWorkingLanguage(string $language): void
311
    {
312 131
        self::$currentWorkingLanguage = $language;
313 131
    }
314
315 71
    public static function err(string $key, string $module = null): string
316
    {
317 71
        return self::getError($key, $module);
318
    }
319
320 74
    public static function lbl(string $key, string $module = null): string
321
    {
322 74
        return self::getLabel($key, $module);
323
    }
324
325 71
    public static function msg(string $key, string $module = null): string
326
    {
327 71
        return self::getMessage($key, $module);
328
    }
329
330
    public static function isActiveLanguage(string $language): bool
331
    {
332
        return in_array($language, self::getActiveLanguages(), true);
333
    }
334
}
335