]> git.mxchange.org Git - friendica.git/blob - include/pgettext.php
Merge remote-tracking branch 'upstream/develop' into item-permissions
[friendica.git] / include / pgettext.php
1 <?php
2
3 /**
4  * @brief translation support
5  *
6  * Get the language setting directly from system variables, bypassing Config::get()
7  * as database may not yet be configured.
8  *
9  * If possible, we use the value from the browser.
10  *
11  */
12
13 use Friendica\Core\Config;
14
15 require_once "include/dba.php";
16
17 /**
18  * @brief get the prefered language from the HTTP_ACCEPT_LANGUAGE header
19  */
20 function get_browser_language() {
21
22         $lang_list = [];
23         if (x($_SERVER, 'HTTP_ACCEPT_LANGUAGE')) {
24                 // break up string into pieces (languages and q factors)
25                 preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i',
26                         $_SERVER['HTTP_ACCEPT_LANGUAGE'], $lang_parse);
27
28                 if (count($lang_parse[1])) {
29                         // go through the list of prefered languages and add a generic language
30                         // for sub-linguas (e.g. de-ch will add de) if not already in array
31                         for ($i = 0; $i < count($lang_parse[1]); $i++) {
32                                 $lang_list[] = strtolower($lang_parse[1][$i]);
33                                 if (strlen($lang_parse[1][$i])>3 ) {
34                                         $dashpos = strpos($lang_parse[1][$i], '-');
35                                         if (!in_array(substr($lang_parse[1][$i], 0, $dashpos), $lang_list ) ) {
36                                                 $lang_list[] = strtolower(substr($lang_parse[1][$i], 0, $dashpos));
37                                         }
38                                 }
39                         }
40                 }
41         }
42
43         // check if we have translations for the preferred languages and pick the 1st that has
44         foreach ($lang_list as $lang) {
45                 if ($lang === 'en' || (file_exists("view/lang/$lang") && is_dir("view/lang/$lang"))) {
46                         $preferred = $lang;
47                         break;
48                 }
49         }
50         if (isset($preferred)) {
51                 return $preferred;
52         }
53
54         // in case none matches, get the system wide configured language, or fall back to English
55         return Config::get('system', 'language', 'en');
56 }
57
58
59 function push_lang($language) {
60         global $lang, $a;
61
62         $a->langsave = $lang;
63
64         if ($language === $lang) {
65                 return;
66         }
67
68         if (isset($a->strings) && count($a->strings)) {
69                 $a->stringsave = $a->strings;
70         }
71         $a->strings = [];
72         load_translation_table($language);
73         $lang = $language;
74 }
75
76 function pop_lang() {
77         global $lang, $a;
78
79         if ($lang === $a->langsave) {
80                 return;
81         }
82
83         if (isset($a->stringsave)) {
84                 $a->strings = $a->stringsave;
85         } else {
86                 $a->strings = [];
87         }
88
89         $lang = $a->langsave;
90 }
91
92 // l
93
94 /**
95  * load string translation table for alternate language
96  *
97  * first addon strings are loaded, then globals
98  *
99  * @param string $lang language code to load
100  */
101 function load_translation_table($lang) {
102         $a = get_app();
103
104         $a->strings = [];
105         // load enabled addons strings
106         $addons = dba::select('addon', ['name'], ['installed' => true]);
107         while ($p = dba::fetch($addons)) {
108                 $name = $p['name'];
109                 if (file_exists("addon/$name/lang/$lang/strings.php")) {
110                         include("addon/$name/lang/$lang/strings.php");
111                 }
112         }
113
114         if (file_exists("view/lang/$lang/strings.php")) {
115                 include("view/lang/$lang/strings.php");
116         }
117
118 }
119
120 /**
121  * @brief Return the localized version of the provided string with optional string interpolation
122  *
123  * This function takes a english string as parameter, and if a localized version
124  * exists for the current language, substitutes it before performing an eventual
125  * string interpolation (sprintf) with additional optional arguments.
126  *
127  * Usages:
128  * - t('This is an example')
129  * - t('URL %s returned no result', $url)
130  * - t('Current version: %s, new version: %s', $current_version, $new_version)
131  *
132  * @param string $s
133  * @return string
134  */
135 function t($s)
136 {
137         $a = get_app();
138
139         if (x($a->strings, $s)) {
140                 $t = $a->strings[$s];
141                 $s = is_array($t) ? $t[0] : $t;
142         }
143         if (func_num_args() > 1) {
144                 $args = array_slice(func_get_args(), 1);
145                 $s = @vsprintf($s, $args);
146         }
147
148         return $s;
149 }
150
151 /**
152  * @brief Return the localized version of a singular/plural string with optional string interpolation
153  *
154  * This function takes two english strings as parameters, singular and plural, as
155  * well as a count. If a localized version exists for the current language, they
156  * are used instead. Discrimination between singular and plural is done using the
157  * localized function if any or the default one. Finally, a string interpolation
158  * is performed using the count as parameter.
159  *
160  * Usages:
161  * - tt('Like', 'Likes', $count)
162  * - tt("%s user deleted", "%s users deleted", count($users))
163  *
164  * @global type $lang
165  * @param string $singular
166  * @param string $plural
167  * @param int $count
168  * @return string
169  */
170 function tt($singular, $plural, $count)
171 {
172         global $lang;
173         $a = get_app();
174
175         if (x($a->strings, $singular)) {
176                 $t = $a->strings[$singular];
177                 if (is_array($t)) {
178                         $plural_function = 'string_plural_select_' . str_replace('-', '_', $lang);
179                         if (function_exists($plural_function)) {
180                                 $plural_function = 'string_plural_select_default';
181                         }
182                         $i = $plural_function($count);
183                         $s = $t[$i];
184                 } else {
185                         $s = $t;
186                 }
187         } elseif (string_plural_select_default($count)) {
188                 $s = $plural;
189         } else {
190                 $s = $singular;
191         }
192
193         $s = @sprintf($s, $count);
194
195         return $s;
196 }
197
198 // provide a fallback which will not collide with
199 // a function defined in any language file
200 function string_plural_select_default($n)
201 {
202         return $n != 1;
203 }
204
205
206
207 /**
208  * @brief Return installed languages codes as associative array
209  *
210  * Scans the view/lang directory for the existence of "strings.php" files, and
211  * returns an alphabetical list of their folder names (@-char language codes).
212  * Adds the english language if it's missing from the list.
213  *
214  * Ex: array('de' => 'de', 'en' => 'en', 'fr' => 'fr', ...)
215  *
216  * @return array
217  */
218 function get_available_languages() {
219         $langs = [];
220         $strings_file_paths = glob('view/lang/*/strings.php');
221
222         if (is_array($strings_file_paths) && count($strings_file_paths)) {
223                 if (!in_array('view/lang/en/strings.php', $strings_file_paths)) {
224                         $strings_file_paths[] = 'view/lang/en/strings.php';
225                 }
226                 asort($strings_file_paths);
227                 foreach ($strings_file_paths as $strings_file_path) {
228                         $path_array = explode('/', $strings_file_path);
229                         $langs[$path_array[2]] = $path_array[2];
230                 }
231         }
232         return $langs;
233 }