|
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
$myVarassignment in line 1 and the$higherassignment in line 2 are dead. The first because$myVaris never used and the second because$higheris always overwritten for every possible time line.