1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
class Ajde_Lang extends Ajde_Object_Singleton |
4
|
|
|
{ |
5
|
|
|
protected $_adapter = null; |
6
|
|
|
protected $_lang; |
7
|
|
|
|
8
|
|
|
protected $_autoTranslationOfModels = true; |
9
|
|
|
|
10
|
|
|
protected static $_niceNames = [ |
11
|
|
|
'aa' => 'Afar', |
12
|
|
|
'ab' => 'Abkhaz', |
13
|
|
|
'ae' => 'Avestan', |
14
|
|
|
'af' => 'Afrikaans', |
15
|
|
|
'ak' => 'Akan', |
16
|
|
|
'am' => 'Amharic', |
17
|
|
|
'an' => 'Aragonese', |
18
|
|
|
'ar' => 'Arabic', |
19
|
|
|
'as' => 'Assamese', |
20
|
|
|
'av' => 'Avaric', |
21
|
|
|
'ay' => 'Aymara', |
22
|
|
|
'az' => 'Azerbaijani', |
23
|
|
|
'ba' => 'Bashkir', |
24
|
|
|
'be' => 'Belarusian', |
25
|
|
|
'bg' => 'Bulgarian', |
26
|
|
|
'bh' => 'Bihari', |
27
|
|
|
'bi' => 'Bislama', |
28
|
|
|
'bm' => 'Bambara', |
29
|
|
|
'bn' => 'Bengali', |
30
|
|
|
'bo' => 'Tibetan Standard, Tibetan, Central', |
31
|
|
|
'br' => 'Breton', |
32
|
|
|
'bs' => 'Bosnian', |
33
|
|
|
'ca' => 'Catalan; Valencian', |
34
|
|
|
'ce' => 'Chechen', |
35
|
|
|
'ch' => 'Chamorro', |
36
|
|
|
'co' => 'Corsican', |
37
|
|
|
'cr' => 'Cree', |
38
|
|
|
'cs' => 'Czech', |
39
|
|
|
'cu' => 'Old Church Slavonic, Church Slavic, Church Slavonic, Old Bulgarian, Old Slavonic', |
40
|
|
|
'cv' => 'Chuvash', |
41
|
|
|
'cy' => 'Welsh', |
42
|
|
|
'da' => 'Danish', |
43
|
|
|
'de' => 'German', |
44
|
|
|
'dv' => 'Divehi; Dhivehi; Maldivian;', |
45
|
|
|
'dz' => 'Dzongkha', |
46
|
|
|
'ee' => 'Ewe', |
47
|
|
|
'el' => 'Greek, Modern', |
48
|
|
|
'en' => 'English', |
49
|
|
|
'eo' => 'Esperanto', |
50
|
|
|
'es' => 'Spanish; Castilian', |
51
|
|
|
'et' => 'Estonian', |
52
|
|
|
'eu' => 'Basque', |
53
|
|
|
'fa' => 'Persian', |
54
|
|
|
'ff' => 'Fula; Fulah; Pulaar; Pular', |
55
|
|
|
'fi' => 'Finnish', |
56
|
|
|
'fj' => 'Fijian', |
57
|
|
|
'fo' => 'Faroese', |
58
|
|
|
'fr' => 'French', |
59
|
|
|
'fy' => 'Western Frisian', |
60
|
|
|
'ga' => 'Irish', |
61
|
|
|
'gd' => 'Scottish Gaelic; Gaelic', |
62
|
|
|
'gl' => 'Galician', |
63
|
|
|
'gn' => 'GuaranÃ', |
64
|
|
|
'gu' => 'Gujarati', |
65
|
|
|
'gv' => 'Manx', |
66
|
|
|
'ha' => 'Hausa', |
67
|
|
|
'he' => 'Hebrew (modern)', |
68
|
|
|
'hi' => 'Hindi', |
69
|
|
|
'ho' => 'Hiri Motu', |
70
|
|
|
'hr' => 'Croatian', |
71
|
|
|
'ht' => 'Haitian; Haitian Creole', |
72
|
|
|
'hu' => 'Hungarian', |
73
|
|
|
'hy' => 'Armenian', |
74
|
|
|
'hz' => 'Herero', |
75
|
|
|
'ia' => 'Interlingua', |
76
|
|
|
'id' => 'Indonesian', |
77
|
|
|
'ie' => 'Interlingue', |
78
|
|
|
'ig' => 'Igbo', |
79
|
|
|
'ii' => 'Nuosu', |
80
|
|
|
'ik' => 'Inupiaq', |
81
|
|
|
'io' => 'Ido', |
82
|
|
|
'is' => 'Icelandic', |
83
|
|
|
'it' => 'Italian', |
84
|
|
|
'iu' => 'Inuktitut', |
85
|
|
|
'ja' => 'Japanese (ja)', |
86
|
|
|
'jv' => 'Javanese (jv)', |
87
|
|
|
'ka' => 'Georgian', |
88
|
|
|
'kg' => 'Kongo', |
89
|
|
|
'ki' => 'Kikuyu, Gikuyu', |
90
|
|
|
'kj' => 'Kwanyama, Kuanyama', |
91
|
|
|
'kk' => 'Kazakh', |
92
|
|
|
'kl' => 'Kalaallisut, Greenlandic', |
93
|
|
|
'km' => 'Khmer', |
94
|
|
|
'kn' => 'Kannada', |
95
|
|
|
'ko' => 'Korean', |
96
|
|
|
'kr' => 'Kanuri', |
97
|
|
|
'ks' => 'Kashmiri', |
98
|
|
|
'ku' => 'Kurdish', |
99
|
|
|
'kv' => 'Komi', |
100
|
|
|
'kw' => 'Cornish', |
101
|
|
|
'ky' => 'Kirghiz, Kyrgyz', |
102
|
|
|
'la' => 'Latin', |
103
|
|
|
'lb' => 'Luxembourgish, Letzeburgesch', |
104
|
|
|
'lg' => 'Luganda', |
105
|
|
|
'li' => 'Limburgish, Limburgan, Limburger', |
106
|
|
|
'ln' => 'Lingala', |
107
|
|
|
'lo' => 'Lao', |
108
|
|
|
'lt' => 'Lithuanian', |
109
|
|
|
'lu' => 'Luba-Katanga', |
110
|
|
|
'lv' => 'Latvian', |
111
|
|
|
'mg' => 'Malagasy', |
112
|
|
|
'mh' => 'Marshallese', |
113
|
|
|
'mi' => 'Maori', |
114
|
|
|
'mk' => 'Macedonian', |
115
|
|
|
'ml' => 'Malayalam', |
116
|
|
|
'mn' => 'Mongolian', |
117
|
|
|
'mr' => 'Marathi (Mara?hi)', |
118
|
|
|
'ms' => 'Malay', |
119
|
|
|
'mt' => 'Maltese', |
120
|
|
|
'my' => 'Burmese', |
121
|
|
|
'na' => 'Nauru', |
122
|
|
|
'nb' => 'Norwegian Bokmål', |
123
|
|
|
'nd' => 'North Ndebele', |
124
|
|
|
'ne' => 'Nepali', |
125
|
|
|
'ng' => 'Ndonga', |
126
|
|
|
'nl' => 'Dutch', |
127
|
|
|
'nn' => 'Norwegian Nynorsk', |
128
|
|
|
'no' => 'Norwegian', |
129
|
|
|
'nr' => 'South Ndebele', |
130
|
|
|
'nv' => 'Navajo, Navaho', |
131
|
|
|
'ny' => 'Chichewa; Chewa; Nyanja', |
132
|
|
|
'oc' => 'Occitan', |
133
|
|
|
'oj' => 'Ojibwe, Ojibwa', |
134
|
|
|
'om' => 'Oromo', |
135
|
|
|
'or' => 'Oriya', |
136
|
|
|
'os' => 'Ossetian, Ossetic', |
137
|
|
|
'pa' => 'Panjabi, Punjabi', |
138
|
|
|
'pi' => 'Pali', |
139
|
|
|
'pl' => 'Polish', |
140
|
|
|
'ps' => 'Pashto, Pushto', |
141
|
|
|
'pt' => 'Portuguese', |
142
|
|
|
'qu' => 'Quechua', |
143
|
|
|
'rm' => 'Romansh', |
144
|
|
|
'rn' => 'Kirundi', |
145
|
|
|
'ro' => 'Romanian, Moldavian, Moldovan', |
146
|
|
|
'ru' => 'Russian', |
147
|
|
|
'rw' => 'Kinyarwanda', |
148
|
|
|
'sa' => 'Sanskrit (Sa?sk?ta)', |
149
|
|
|
'sc' => 'Sardinian', |
150
|
|
|
'sd' => 'Sindhi', |
151
|
|
|
'se' => 'Northern Sami', |
152
|
|
|
'sg' => 'Sango', |
153
|
|
|
'si' => 'Sinhala, Sinhalese', |
154
|
|
|
'sk' => 'Slovak', |
155
|
|
|
'sl' => 'Slovene', |
156
|
|
|
'sm' => 'Samoan', |
157
|
|
|
'sn' => 'Shona', |
158
|
|
|
'so' => 'Somali', |
159
|
|
|
'sq' => 'Albanian', |
160
|
|
|
'sr' => 'Serbian', |
161
|
|
|
'ss' => 'Swati', |
162
|
|
|
'st' => 'Southern Sotho', |
163
|
|
|
'su' => 'Sundanese', |
164
|
|
|
'sv' => 'Swedish', |
165
|
|
|
'sw' => 'Swahili', |
166
|
|
|
'ta' => 'Tamil', |
167
|
|
|
'te' => 'Telugu', |
168
|
|
|
'tg' => 'Tajik', |
169
|
|
|
'th' => 'Thai', |
170
|
|
|
'ti' => 'Tigrinya', |
171
|
|
|
'tk' => 'Turkmen', |
172
|
|
|
'tl' => 'Tagalog', |
173
|
|
|
'tn' => 'Tswana', |
174
|
|
|
'to' => 'Tonga (Tonga Islands)', |
175
|
|
|
'tr' => 'Turkish', |
176
|
|
|
'ts' => 'Tsonga', |
177
|
|
|
'tt' => 'Tatar', |
178
|
|
|
'tw' => 'Twi', |
179
|
|
|
'ty' => 'Tahitian', |
180
|
|
|
'ug' => 'Uighur, Uyghur', |
181
|
|
|
'uk' => 'Ukrainian', |
182
|
|
|
'ur' => 'Urdu', |
183
|
|
|
'uz' => 'Uzbek', |
184
|
|
|
've' => 'Venda', |
185
|
|
|
'vi' => 'Vietnamese', |
186
|
|
|
'vo' => 'Volapük', |
187
|
|
|
'wa' => 'Walloon', |
188
|
|
|
'wo' => 'Wolof', |
189
|
|
|
'xh' => 'Xhosa', |
190
|
|
|
'yi' => 'Yiddish', |
191
|
|
|
'yo' => 'Yoruba', |
192
|
|
|
'za' => 'Zhuang, Chuang', |
193
|
|
|
'zh' => 'Chinese', |
194
|
|
|
'zu' => 'Zulu', |
195
|
|
|
]; |
196
|
|
|
|
197
|
|
|
/** |
198
|
|
|
* @return Ajde_Lang |
199
|
|
|
*/ |
200
|
|
|
public static function getInstance() |
201
|
|
|
{ |
202
|
|
|
static $instance; |
203
|
|
|
|
204
|
|
|
return $instance === null ? $instance = new self : $instance; |
205
|
|
|
} |
206
|
|
|
|
207
|
|
|
protected function __construct() |
208
|
|
|
{ |
209
|
|
|
$this->setLang($this->detect()); |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
public static function trans($ident, $module = null) |
213
|
|
|
{ |
214
|
|
|
return self::getInstance()->translate($ident, $module); |
215
|
|
|
} |
216
|
|
|
|
217
|
|
|
public function getLang() |
218
|
|
|
{ |
219
|
|
|
return $this->_lang; |
220
|
|
|
} |
221
|
|
|
|
222
|
|
|
public function getShortLang($lang = null) |
223
|
|
|
{ |
224
|
|
|
return $lang ? substr($lang, 0, 2) : substr($this->_lang, 0, 2); |
225
|
|
|
} |
226
|
|
|
|
227
|
|
|
public function getAlternateUrl($lang = null) |
228
|
|
|
{ |
229
|
|
|
$routeLang = $this->getShortLang(); |
230
|
|
|
$currentUrl = preg_replace('/^' . $routeLang . '\/?/', '', Ajde::app()->getRoute()->getOriginalRoute()); |
231
|
|
|
|
232
|
|
|
return config("app.rootUrl") . $this->getShortLang($lang) . '/' . $currentUrl; |
233
|
|
|
} |
234
|
|
|
|
235
|
|
|
public function setLang($lang) |
236
|
|
|
{ |
237
|
|
|
setlocale(LC_ALL, $lang, $lang . '.utf8', $lang . '.UTF8', $lang . 'utf-8', $lang . '.UTF-8'); |
238
|
|
|
$this->_lang = $lang; |
239
|
|
|
} |
240
|
|
|
|
241
|
|
|
public function getAvailableLang($langCode) |
242
|
|
|
{ |
243
|
|
|
$availableLangs = $this->getAvailable(); |
244
|
|
|
$availableShortLangs = []; |
245
|
|
|
foreach ($availableLangs as $availableLang) { |
246
|
|
|
$availableShortLangs[substr($availableLang, 0, 2)] = $availableLang; |
247
|
|
|
} |
248
|
|
|
if (in_array($langCode, $availableLangs)) { |
249
|
|
|
return $langCode; |
250
|
|
|
} |
251
|
|
|
if (array_key_exists($langCode, $availableShortLangs)) { |
252
|
|
|
return $availableShortLangs[$langCode]; |
253
|
|
|
} |
254
|
|
|
|
255
|
|
|
return false; |
256
|
|
|
} |
257
|
|
|
|
258
|
|
|
public function setGlobalLang($lang) |
259
|
|
|
{ |
260
|
|
|
$this->setLang($lang); |
261
|
|
|
Config::set("i18n.rootUrl", config("app.rootUrl") . $this->getShortLang() . '/'); |
262
|
|
|
} |
263
|
|
|
|
264
|
|
|
protected function detect() |
265
|
|
|
{ |
266
|
|
|
if (config("i18n.autodetect")) { |
267
|
|
|
$acceptedLangs = $this->getLanguagesFromHeader(); |
268
|
|
|
foreach ($acceptedLangs as $acceptedLang => $priority) { |
269
|
|
|
if ($langMatch = $this->getAvailableLang($acceptedLang)) { |
270
|
|
|
return $langMatch; |
271
|
|
|
} |
272
|
|
|
} |
273
|
|
|
} |
274
|
|
|
|
275
|
|
|
return $defaultLang = config("lang"); |
|
|
|
|
276
|
|
|
} |
277
|
|
|
|
278
|
|
|
public function disableAutoTranslationOfModels() |
279
|
|
|
{ |
280
|
|
|
$this->_autoTranslationOfModels = false; |
281
|
|
|
} |
282
|
|
|
|
283
|
|
|
public function enableAutoTranslationOfModels() |
284
|
|
|
{ |
285
|
|
|
$this->_autoTranslationOfModels = true; |
286
|
|
|
} |
287
|
|
|
|
288
|
|
|
public function autoTranslateModels($enabled = null) |
289
|
|
|
{ |
290
|
|
|
if (isset($enabled)) { |
291
|
|
|
$this->_autoTranslationOfModels = $enabled; |
292
|
|
|
} |
293
|
|
|
|
294
|
|
|
return $this->_autoTranslationOfModels; |
295
|
|
|
} |
296
|
|
|
|
297
|
|
|
protected function getLanguagesFromHeader() |
298
|
|
|
{ |
299
|
|
|
// @source http://www.thefutureoftheweb.com/blog/use-accept-language-header |
300
|
|
|
$langs = []; |
301
|
|
|
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { |
302
|
|
|
// break up string into pieces (languages and q factors) |
303
|
|
|
preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', |
304
|
|
|
$_SERVER['HTTP_ACCEPT_LANGUAGE'], $lang_parse); |
305
|
|
|
if (count($lang_parse[1])) { |
306
|
|
|
// create a list like "en" => 0.8 |
307
|
|
|
$langs = array_combine($lang_parse[1], $lang_parse[4]); |
308
|
|
|
|
309
|
|
|
// set default to 1 for any without q factor |
310
|
|
|
foreach ($langs as $lang => $val) { |
311
|
|
|
if ($val === '') { |
312
|
|
|
$langs[$lang] = 1; |
313
|
|
|
} |
314
|
|
|
} |
315
|
|
|
|
316
|
|
|
// sort list based on value |
317
|
|
|
arsort($langs, SORT_NUMERIC); |
318
|
|
|
} |
319
|
|
|
} |
320
|
|
|
|
321
|
|
|
return $langs; |
322
|
|
|
} |
323
|
|
|
|
324
|
|
|
public function getAvailable() |
325
|
|
|
{ |
326
|
|
|
$langs = Ajde_Fs_Find::findFiles(LANG_DIR, '*'); |
327
|
|
|
$return = []; |
328
|
|
|
foreach ($langs as $lang) { |
329
|
|
|
$return[] = basename($lang); |
330
|
|
|
} |
331
|
|
|
|
332
|
|
|
return $return; |
333
|
|
|
} |
334
|
|
|
|
335
|
|
|
public function getAvailableNiceNames() |
336
|
|
|
{ |
337
|
|
|
$langs = Ajde_Fs_Find::findFiles(LANG_DIR, '*'); |
338
|
|
|
$return = []; |
339
|
|
|
foreach ($langs as $lang) { |
340
|
|
|
$lang = basename($lang); |
341
|
|
|
$return[$lang] = $this->getNiceName($lang); |
342
|
|
|
} |
343
|
|
|
|
344
|
|
|
return $return; |
345
|
|
|
} |
346
|
|
|
|
347
|
|
|
/** |
348
|
|
|
* @return Ajde_Lang_Adapter_Abstract |
349
|
|
|
*/ |
350
|
|
|
public function getAdapter() |
351
|
|
|
{ |
352
|
|
|
if ($this->_adapter === null) { |
353
|
|
|
$adapterName = 'Ajde_Lang_Adapter_' . ucfirst(config("i18n.adapter")); |
354
|
|
|
$this->_adapter = new $adapterName(); |
355
|
|
|
} |
356
|
|
|
|
357
|
|
|
return $this->_adapter; |
358
|
|
|
} |
359
|
|
|
|
360
|
|
|
public function translate($ident, $module = null) |
361
|
|
|
{ |
362
|
|
|
return $this->getAdapter()->get($ident, $module); |
363
|
|
|
} |
364
|
|
|
|
365
|
|
|
public function get($ident, $module = null) |
|
|
|
|
366
|
|
|
{ |
367
|
|
|
// TODO: |
368
|
|
|
throw new Ajde_Core_Exception_Deprecated('Use Ajde_Lang::translate() instead'); |
369
|
|
|
} |
370
|
|
|
|
371
|
|
|
public function getNiceName($lang = null) |
372
|
|
|
{ |
373
|
|
|
if (!$lang) { |
374
|
|
|
$lang = $this->getLang(); |
375
|
|
|
} |
376
|
|
|
|
377
|
|
|
return $this->niceName($lang); |
378
|
|
|
} |
379
|
|
|
|
380
|
|
|
public static function niceName($lang) |
381
|
|
|
{ |
382
|
|
|
return self::$_niceNames[substr(strtolower($lang), 0, 2)]; |
383
|
|
|
} |
384
|
|
|
|
385
|
|
|
} |
386
|
|
|
|
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.
Both the
$myVar
assignment in line 1 and the$higher
assignment in line 2 are dead. The first because$myVar
is never used and the second because$higher
is always overwritten for every possible time line.