-
Notifications
You must be signed in to change notification settings - Fork 42
/
i18n.php
167 lines (148 loc) · 5.8 KB
/
i18n.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
<?php
/*
@nom: i18n
@auteur: Idleman (http://blog.idleman.fr)
@description: Fonctions de gestion de la traduction
*/
class Translation {
// Répertoire contenant les traductions
const LOCALE_DIR = 'locale';
/* Langue utilisée si aucune langue n'est demandée ou si les langues
* demandées ne sont pas disponibles. Idem pour les traductions.*/
const DEFAULT_LANGUAGE = 'fr';
// tableau associatif des traductions
private $trans = array();
public $languages = [];
public $language = ''; // langue courante
public $translatedLanguages = array(); // langues traduites
private $location = '';
/** @param location L'endroit où se trouve le dossier 'locale'
* @param languages Les langues demandées */
function __construct($location, $languages=array()) {
$this->location = $location;
if (!is_array($languages)) $languages = array($languages);
$this->translatedLanguages = $this->listLanguages();
$languages[]=self::DEFAULT_LANGUAGE;
$this->languages = $languages;
foreach ($languages as $language) {
if (empty($language)) continue;
if ($this->load($language)) {
$this->language = $language;
break;
}
}
}
/* @return la liste des langues avec une traduction */
protected function listLanguages() {
$translatedLanguages = array();
$files = glob($this->location.'/'.self::LOCALE_DIR.'/*.json');
if (is_array($files)) {
foreach($files as $file){
preg_match('/([a-z]{2})\.json$/', $file, $matches);
$hasLocale = !empty($matches);
assert($hasLocale);
$translatedLanguages [] = $matches[1];
}
}
return $translatedLanguages;
}
/* Charge la traduction
* @param language la langue sélectionnée
* @return TRUE si le chargement s'est bien fait, FALSE sinon */
protected function load($language) {
if (!preg_match('/^[a-z]{2}$/', $language)) {
error_log("Invalid language: '$language'");
return false;
}
$trans = $this->loadFile($language);
if (empty($trans)) return false;
$isLanguageKnown = in_array($language, $this->translatedLanguages);
assert($isLanguageKnown);
if ($language!=self::DEFAULT_LANGUAGE) {
$defaultTrans = $this->loadFile(self::DEFAULT_LANGUAGE);
$hasDefaultTrans = !empty($defaultTrans);
assert($hasDefaultTrans);
$trans = array_merge($defaultTrans, $trans);
}
$this->trans = $trans;
return true;
}
/* Charge un fichier
* @param $language Le fichier de langue concerné
* @return Tableau associatif contenant les traductions */
protected function loadFile($language) {
$fileName = $this->location.'/'.self::LOCALE_DIR.'/'.$language.'.json';
$content = @file_get_contents($fileName);
if (empty($content)) {
$translations = array();
} else {
$translations = json_decode($content, true);
foreach ($translations as $id => $translation) {
if (empty($translation)) {
# Retire les traductions vides afin qu'elles soient
# traduites dans une autre langue si possible.
unset($translations[$id]);
}
}
if (!empty($content) && empty($translations))
error_log("Error while loading '$fileName'");
}
return $translations;
}
/* Retourne la traduction et substitue les variables.
* get('TEST_TRANS', array('4'))
* Retournera 'Nombre : 4' si TEST_TRANS == 'Nombre : $1' */
function get($key, $args=array()) {
if (isset($this->trans[$key])&&!empty($this->trans[$key])) {
$value = $this->trans[$key];
for($i=0;$i<count($args);$i++){
$value = str_replace('$'.($i+1), $args[$i], $value);
}
} else {
$value = $key;
}
return $value;
}
/* Ajoute une traduction à la suite de celle-ci.
* Note : il faudra appeler getJson() si nécessaire */
function append(Translation $other) {
$this->trans = array_merge($this->trans, $other->trans);
}
/* @return la version Json des traductions */
function getJson() {
return json_encode($this->trans);
}
/* @return un tableau des langues préférées */
static function getHttpAcceptLanguages() {
/** Exemple de directive :
* eo,fr;q=0.8,fr-FR;q=0.6,en-US;q=0.4,en;q=0.2
* Les langues sont séparées entre elles par des virgules.
* Chaque langue est séparée du coefficient, si présent, par un point-virgule.
*/
$httpAcceptLanguage = isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ?
$_SERVER['HTTP_ACCEPT_LANGUAGE'] : self::DEFAULT_LANGUAGE;
$languageList = array();
foreach (explode(',', $httpAcceptLanguage) as $language) {
$languageList[] = substr($language, 0, 2); // fr-FR;q=0.6 --> fr
}
return array_unique($languageList); // en-US,en-UK --> en, en --> en
}
}
// Initialise le singleton, avec les langues possibles
function i18n_init($languages, $location){
global $i18n,$i18n_js;
if (!isset($i18n)) {
// Charge d'abord les traductions de base
$i18n = new Translation(dirname(__FILE__), $languages);
// Charge ensuite la traduction demandée (celle du thème courant)
$i18n->append(new Translation($location, $languages));
$i18n_js = $i18n->getJson();
}
return $i18n->language;
}
// Appel rapide de la traduction
function _t($key,$args=array(),$debug=false){
global $i18n;
return $i18n->get($key, $args);
}
?>