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