]> git.agnieray.net Git - galette.git/blob - galette/lib/Galette/Core/I18n.php
Locale was not updated on translator
[galette.git] / galette / lib / Galette / Core / I18n.php
1 <?php
2
3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4
5 /**
6 * i18n handling
7 *
8 * PHP version 5
9 *
10 * Copyright © 2007-2018 The Galette Team
11 *
12 * This file is part of Galette (http://galette.tuxfamily.org).
13 *
14 * Galette is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation, either version 3 of the License, or
17 * (at your option) any later version.
18 *
19 * Galette is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with Galette. If not, see <http://www.gnu.org/licenses/>.
26 *
27 * @category Core
28 * @package Galette
29 *
30 * @author Johan Cwiklinski <johan@x-tnd.be>
31 * @copyright 2007-2020 The Galette Team
32 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
33 * @link http://galette.tuxfamily.org
34 * @since Available since 0.7dev - 2007-07-06
35 */
36
37 namespace Galette\Core;
38
39 use Analog\Analog;
40
41 /**
42 * i18n handling
43 *
44 * @category Core
45 * @name i18n
46 * @package Galette
47 * @author Johan Cwiklinski <johan@x-tnd.be>
48 * @copyright 2007-2020 The Galette Team
49 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
50 * @link http://galette.tuxfamily.org
51 * @since Available since 0.7dev - 2007-07-06
52 */
53
54 class I18n
55 {
56 private $id;
57 private $longid;
58 private $name;
59 private $abbrev;
60
61 const DEFAULT_LANG = 'fr_FR';
62
63 private $dir = 'lang/';
64 private $path;
65
66 private $rtl_langs = [
67 'ar',
68 'az',
69 'fa',
70 'he',
71 'ur'
72 ];
73
74 /**
75 * Default constructor.
76 * Initialize default language and set environment variables
77 *
78 * @param bool $lang true if there were a language change
79 *
80 * @return void
81 */
82 public function __construct($lang = false)
83 {
84 $this->path = GALETTE_ROOT . $this->dir;
85 $this->guessLangs();
86
87 if (!$lang) {
88 //try to determine user language
89 $dlang = self::DEFAULT_LANG;
90 if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
91 $blang = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
92 if (substr($blang, 0, 2) == 'fr') {
93 $dlang = 'fr_FR';
94 } elseif (substr($blang, 0, 2) == 'en') {
95 $dlang = 'en_US';
96 } else {
97 $dlang = self::DEFAULT_LANG;
98 }
99 }
100 $this->changeLanguage($dlang);
101 } else {
102 $this->load($lang);
103 }
104 }
105
106 /**
107 * Load language parameters
108 *
109 * @param string $id Identifier for requested language
110 *
111 * @return void
112 */
113 public function changeLanguage($id)
114 {
115 Analog::log('Trying to set locale to ' . $id, Analog::DEBUG);
116 $this->load($id);
117 $this->updateEnv();
118 }
119
120 /**
121 * Update environment according to locale.
122 * Mainly used at app initialization or at login
123 *
124 * @return void
125 */
126 public function updateEnv()
127 {
128 global $translator;
129
130 setlocale(LC_ALL, $this->getLongID());
131
132 if (
133 putenv("LANG=" . $this->getLongID())
134 or putenv("LANGUAGE=" . $this->getLongID())
135 or putenv("LC_ALL=" . $this->getLongID())
136 ) {
137 $textdomain = realpath(GALETTE_ROOT . 'lang');
138 //main translation domain
139 $domain = 'galette';
140 bindtextdomain($domain, $textdomain);
141 //set default translation domain and encoding
142 textdomain($domain);
143 bind_textdomain_codeset($domain, 'UTF-8');
144 }
145 if ($translator) {
146 $translator->setLocale($this->getLongID());
147 }
148 }
149
150 /**
151 * Load a language
152 *
153 * @param string $id identifier for the language to load
154 *
155 * @return void
156 */
157 private function load($id)
158 {
159 if (!isset($this->langs[$id])) {
160 $msg = 'Lang ' . $id . ' does not exist, switching to default.';
161 Analog::log($msg, Analog::WARNING);
162 $id = self::DEFAULT_LANG;
163 }
164 $lang = $this->langs[$id];
165 $this->id = $id;
166 $this->longid = $lang['long'];
167 $this->name = $lang['longname'];
168 $this->abbrev = $lang['shortname'];
169 }
170
171 /**
172 * List languages
173 *
174 * @return array list of all active languages
175 */
176 public function getList()
177 {
178 $result = array();
179 foreach (array_keys($this->langs) as $id) {
180 $result[] = new I18n((string)$id);
181 }
182
183 return $result;
184 }
185
186 /**
187 * List languages as simple array
188 *
189 * @return array
190 */
191 public function getArrayList()
192 {
193 $list = $this->getList();
194 $al = array();
195 foreach ($list as $l) {
196 //FIXME: shoudl use mb with sthing like:
197 //$strlen = mb_strlen($string, $encoding);
198 //$firstChar = mb_substr($string, 0, 1, $encoding);
199 //$then = mb_substr($string, 1, $strlen - 1, $encoding);
200 //return mb_strtoupper($firstChar, $encoding) . $then;
201 $al[$l->getID()] = $l->getName();
202 }
203 return $al;
204 }
205
206 /**
207 * Gets language full name from its ID
208 *
209 * @param string $id the language identifier
210 *
211 * @return string name for specified identifier
212 */
213 public function getNameFromId($id)
214 {
215 if (isset($this->langs[$id])) {
216 return $this->langs[$id]['longname'];
217 } else {
218 return str_replace(
219 '%lang',
220 $id,
221 _T('Unknown lang (%lang)')
222 );
223 }
224 }
225
226 /**
227 * Get current id
228 *
229 * @return string current language identifier
230 */
231 public function getID()
232 {
233 return $this->id;
234 }
235
236 /**
237 * Get long identifier
238 *
239 * @return string current language long identifier
240 */
241 public function getLongID()
242 {
243 return $this->longid;
244 }
245
246 /**
247 * Get current name
248 *
249 * @return string current language name
250 */
251 public function getName()
252 {
253 return $this->name;
254 }
255
256 /**
257 * Get current abreviation
258 *
259 * @return string current language abreviation
260 */
261 public function getAbbrev()
262 {
263 return $this->abbrev;
264 }
265
266 /**
267 * Is a string seem to be UTF-8 one ?
268 *
269 * @param string $str string to analyze
270 *
271 * @return boolean
272 */
273 public static function seemUtf8($str)
274 {
275 return mb_check_encoding($str, 'UTF-8');
276 }
277
278 /**
279 * Guess available languages from directories
280 * that are present in the lang directory.
281 *
282 * Will store foud langs in class langs variable and return it.
283 *
284 * @return array
285 */
286 public function guessLangs()
287 {
288 $dir = new \DirectoryIterator($this->path);
289 $langs = [];
290 foreach ($dir as $fileinfo) {
291 if ($fileinfo->isDir() && !$fileinfo->isDot()) {
292 $lang = $fileinfo->getFilename();
293 $real_lang = str_replace('.utf8', '', $lang);
294 $parsed_lang = \Locale::parseLocale($lang);
295
296 $langs[$real_lang] = [
297 'long' => $lang,
298 'shortname' => $parsed_lang['language'],
299 'longname' => ucfirst(
300 \Locale::getDisplayLanguage(
301 $lang,
302 $real_lang
303 )
304 )
305 ];
306 }
307 }
308 ksort($langs);
309 $this->langs = $langs;
310 return $this->langs;
311 }
312
313 /**
314 * Is current language RTL?
315 *
316 * @return boolean
317 */
318 public function isRTL()
319 {
320 return in_array(
321 $this->getAbbrev(),
322 $this->rtl_langs
323 );
324 }
325 }