Locale   A
last analyzed

Complexity

Total Complexity 38

Size/Duplication

Total Lines 273
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 38
eloc 74
dl 0
loc 273
rs 9.36
c 1
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
A setTranslation() 0 3 1
A hasTranslation() 0 11 4
A translate() 0 25 4
A detectLocale() 0 23 6
A getTranslation() 0 11 4
A init() 0 21 5
A get() 0 3 1
A getDefault() 0 3 1
A initLocale() 0 9 3
A set() 0 3 1
A setDefault() 0 3 1
A getTranslationKey() 0 17 4
A loadTranslation() 0 8 3
1
<?php
2
3
namespace Source\Language;
4
5
abstract class Locale
6
{
7
    /**
8
     * Store the transaltion for specific languages
9
     *
10
     * @var array $translation
11
     */
12
    private static $translation = [];
13
14
    /**
15
     * Current locale
16
     *
17
     * @var string $locale
18
     */
19
    private static $locale;
20
21
    /**
22
     * Default locale
23
     *
24
     * @var string $defaultLocale
25
     */
26
    private static $defaultLocale = DEFAULT_COUNTRY;
27
28
    /**
29
     * Lang default dir
30
     *
31
     * @var string $localeDir
32
     */
33
    private static $localeDir = __DIR__ . '/Translation';
34
35
    /**
36
     * Get the Default locale
37
     *
38
     * @return string
39
     */
40
    final public static function getDefault(): string
41
    {
42
        return self::$defaultLocale;
43
    }
44
45
    /**
46
     * Set the default locale
47
     *
48
     * @return void
49
     */
50
    final private static function setDefault(): void
51
    {
52
        self::$locale = self::$defaultLocale;
53
    }
54
55
    /**
56
     * Get the user define locale
57
     *
58
     * @return string
59
     */
60
    final public static function get(): ?string
61
    {
62
        return self::$locale;
63
    }
64
65
    /**
66
     * Set the user define localte
67
     *
68
     * @param string $locale
69
     * @return void
70
     */
71
    final public static function set($locale = null): void
72
    {
73
        self::$locale = $locale;
74
    }
75
76
    /**
77
     * Determine if transltion exist or translation key exist
78
     *
79
     * @param string $locale
80
     * @param string $key
81
     * @return bool
82
     */
83
    final public static function hasTranslation($locale, $key = null): bool
84
    {
85
        if (null == $key && isset(self::$translation[$locale])) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $key of type null|string against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
86
            return true;
87
        }
88
89
        if (isset(self::$translation[$locale][$key])) {
90
            return true;
91
        }
92
93
        return false;
94
    }
95
96
    /**
97
     * Get the transltion for required locale or transtion for key
98
     *
99
     * @param string $locale
100
     * @param string $key
101
     * @return string|array
102
     */
103
    final public static function getTranslation($locale, $key = null)
104
    {
105
        if (null == $key && self::hasTranslation($locale)) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $key of type null|string against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
106
            return self::$translation[$locale];
107
        }
108
109
        if (self::hasTranslation($locale, $key)) {
110
            return self::$translation[$locale][$key];
111
        }
112
113
        return [];
114
    }
115
116
    /**
117
     * Get the transltion for required locale or transtion for key
118
     *
119
     * @param string $key
120
     * @return null|string
121
     */
122
    final public static function getTranslationKey(string $key): ?string
123
    {
124
        if (self::hasTranslation(self::$locale, $key)) {
125
            return self::getTranslation(self::$locale, $key);
126
        }
127
128
        if (self::$locale === self::$defaultLocale) {
129
            return null;
130
        }
131
132
        self::loadTranslation(self::$defaultLocale);
133
134
        if (!self::hasTranslation(self::$defaultLocale, $key)) {
135
            return null;
136
        }
137
138
        $translation = self::getTranslation(self::$defaultLocale, $key);
0 ignored issues
show
Unused Code introduced by
The assignment to $translation is dead and can be removed.
Loading history...
139
    }
140
141
    /**
142
     * Set the transtion for required locale
143
     *
144
     * @param string $locale Language code
145
     * @param string $trans translations array
146
     * @return void
147
     */
148
    final private static function setTranslation($locale, $trans = []): void
149
    {
150
        self::$translation[$locale] = $trans;
151
    }
152
153
    /**
154
     * Load a Transtion into array
155
     *
156
     * @return void
157
     */
158
    final private static function loadTranslation($locale = null, $force = false): void
159
    {
160
        if ($locale == null) {
161
            $locale = self::$locale;
162
        }
163
164
        if (!self::hasTranslation($locale)) {
165
            self::setTranslation($locale, include(sprintf('%s/%s.php', self::$localeDir, COUNTRY_TO_LANG[self::$locale])));
166
        }
167
    }
168
169
    /**
170
     * Initialize locale
171
     *
172
     * @param string $locale
173
     * @return void
174
     */
175
    final public static function init($locale = null, $defaultLocale = null): void
0 ignored issues
show
Unused Code introduced by
The parameter $defaultLocale is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

175
    final public static function init($locale = null, /** @scrutinizer ignore-unused */ $defaultLocale = null): void

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

Loading history...
176
    {
177
        self::initLocale();
178
179
        if (self::$locale != null) {
180
            return;
181
        }
182
183
        if (
184
            $locale == null
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $locale of type null|string against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
185
            || (!preg_match('#^[a-z]+_[a-zA-Z_]+$#', $locale)
186
                && !preg_match('#^[a-z]+_[a-zA-Z]+_[a-zA-Z_]+$#', $locale)
187
            )
188
        ) {
189
            self::detectLocale();
190
            self::initLocale();
191
            return;
192
        }
193
194
        self::$locale = $locale;
195
        self::initLocale();
196
    }
197
198
    /**
199
     * Attempt to autodetect locale
200
     *
201
     * @return void
202
     */
203
    final private static function detectLocale(): void
204
    {
205
        if (!function_exists('geoip_country_code_by_name')) {
206
            error_log('a funcao de GeoIP nao foi encontrada!');
207
            self::setDefault();
208
            return;
209
        }
210
211
        if (!isset($_SERVER['REMOTE_ADDR'])) {
212
            error_log('src_ip não foi encontrado!');
213
            self::setDefault();
214
            return;
215
        }
216
217
        // GeoIP
218
        $country = geoip_country_code_by_name($_SERVER['REMOTE_ADDR']);
219
220
        if ($country) {
221
            self::$locale = isset(COUNTRY_TO_LANG[$country]) ? $country : null;
222
        }
223
224
        if (empty(self::$locale)) {
225
            self::setDefault();
226
        }
227
    }
228
229
    /**
230
     * Check if config for selected locale exists
231
     *
232
     * @return void
233
     */
234
    final private static function initLocale(): void
235
    {
236
        if (null === self::$locale) {
0 ignored issues
show
introduced by
The condition null === self::locale is always false.
Loading history...
237
            self::detectLocale();
238
        }
239
240
        if (!file_exists(sprintf('%s/%s.php', self::$localeDir, @COUNTRY_TO_LANG[self::$locale]))) {
241
            error_log(sprintf('lang: %s of country %s, does not exists!', @COUNTRY_TO_LANG[self::$locale] ?? 'undefined', self::$locale));
242
            self::setDefault();
243
        }
244
    }
245
246
    /**
247
     * Translate a key
248
     *
249
     * @param string Key to be translated
250
     * @param string optional arguments
0 ignored issues
show
Bug introduced by
The type Source\Language\optional was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
251
     * @return string
252
     */
253
    final public static function translate($key): string
254
    {
255
        self::init();
256
        self::loadTranslation(self::$locale);
257
258
        $translation = self::getTranslationKey($key);
259
260
        if (empty($translation)) {
261
            return $key;
262
        }
263
264
        if (false === strpos($translation, '{arg:')) {
265
            return $translation;
266
        }
267
268
        // Replace arguments
269
        $replace = [];
270
        $args = func_get_args();
271
272
        for ($i = 1, $max = count($args); $i < $max; $i++) {
273
            $replace['{arg:' . $i . '}'] = $args[$i];
274
        }
275
276
        // Interpolate replacement values into the messsage then return
277
        return strtr($translation, $replace);
278
    }
279
}
280