1<?php
2if(!defined('SITE_LOCALE')) {
3	if(function_exists('getOptionFromDB')) {
4		define('SITE_LOCALE', getOptionFromDB('locale'));
5	} else {
6		define('SITE_LOCALE', 'en_US');
7	}
8}
9
10/**
11 * functions-i18n.php -- support functions for internationalization
12 * @package core
13 * @subpackage functions\functions-i18n
14 */
15// force UTF-8 Ø
16function getLanguageArray() {
17	return array(
18					'af'		 => gettext('Afrikaans'),
19					'sq_AL'	 => gettext('Albanian'),
20					'ar_AE'	 => gettext('Arabic (United Arab Emirates)'),
21					'ar_BH'	 => gettext('Arabic (Bahrain)'),
22					'ar_DZ'	 => gettext('Arabic (Algeria)'),
23					'ar_EG'	 => gettext('Arabic (Egypt)'),
24					'ar_IN'	 => gettext('Arabic (Iran)'),
25					'ar_IQ'	 => gettext('Arabic (Iraq)'),
26					'ar_JO'	 => gettext('Arabic (Jordan)'),
27					'ar_KW'	 => gettext('Arabic (Kuwait)'),
28					'ar_LB'	 => gettext('Arabic (Lebanon)'),
29					'ar_LY'	 => gettext('Arabic (Libya)'),
30					'ar_MA'	 => gettext('Arabic (Morocco)'),
31					'ar_OM'	 => gettext('Arabic (Oman)'),
32					'ar_QA'	 => gettext('Arabic (Qatar)'),
33					'ar_SA'	 => gettext('Arabic (Saudi Arabia)'),
34					'ar_SD'	 => gettext('Arabic (Sudan)'),
35					'ar_SY'	 => gettext('Arabic (Syria)'),
36					'ar_TN'	 => gettext('Arabic (Tunisia)'),
37					'ar_YE'	 => gettext('Arabic (Yemen)'),
38					'eu_ES'	 => gettext('Basque (Basque)'),
39					'be_BY'	 => gettext('Belarusian'),
40					'bn_BD'	 => gettext('Bengali'),
41					'bg_BG'	 => gettext('Bulgarian'),
42					'ca_ES'	 => gettext('Catalan'),
43					'zh_Hans_CN'	 => gettext('Chinese (People’s Republic of China)'),
44					'zh_Hans_HK'	 => gettext('Chinese (Hong Kong)'),
45					'zh_Hant_TW'	 => gettext('Chinese (Taiwan)'),
46					'hr_HR'	 => gettext('Croatian'),
47					'cs_CZ'	 => gettext('Czech'),
48					'km_KH'	 => gettext('Cambodian'),
49					'da_DK'	 => gettext('Danish'),
50					'nl_BE'	 => gettext('Dutch (Belgium)'),
51					'nl_NL'	 => gettext('Dutch (The Netherlands)'),
52					'en_AU'	 => gettext('English (Australia)'),
53					'en_CA'	 => gettext('English (Canada)'),
54					'en_GB'	 => gettext('English (United Kingdom)'),
55					'en_IN'	 => gettext('English (India)'),
56					'en_NZ'	 => gettext('English (New Zealand)'),
57					'en_PH'	 => gettext('English (Philippines)'),
58					'en_US'	 => gettext('English (United States)'),
59					'en_ZA'	 => gettext('English (South Africa)'),
60					'en_ZW'	 => gettext('English (Zimbabwe)'),
61					'eo'		 => gettext('Esperanto'),
62					'et_EE'	 => gettext('Estonian'),
63					'fi_FI'	 => gettext('Finnish'),
64					'fo_FO'	 => gettext('Faroese'),
65					'fr_BE'	 => gettext('French (Belgium)'),
66					'fr_CA'	 => gettext('French (Canada)'),
67					'fr_CH'	 => gettext('French (Switzerland)'),
68					'fr_FR'	 => gettext('French (France)'),
69					'fr_LU'	 => gettext('French (Luxembourg)'),
70					'gl_ES'	 => gettext('Galician'),
71					'gu_IN'	 => gettext('Gujarati'),
72					'el'		 => gettext('Greek'),
73					'de_AT'	 => gettext('German (Austria)'),
74					'de_BE'	 => gettext('German (Belgium)'),
75					'de_CH'	 => gettext('German (Switzerland)'),
76					'de_DE'	 => gettext('German (Germany)'),
77					'de_LU'	 => gettext('German (Luxembourg)'),
78					'he_IL'	 => gettext('Hebrew'),
79					'hi_IN'	 => gettext('Hindi'),
80					'hu_HU'	 => gettext('Hungarian'),
81					'id_ID'	 => gettext('Indonesian'),
82					'is_IS'	 => gettext('Icelandic'),
83					'it_CH'	 => gettext('Italian (Switzerland)'),
84					'it_IT'	 => gettext('Italian (Italy)'),
85					'ja_JP'	 => gettext('Japanese'),
86					'ko_KR'	 => gettext('Korean'),
87					'lt_LT'	 => gettext('Lithuanian'),
88					'lv_LV'	 => gettext('Latvian'),
89					'mk_MK'	 => gettext('Macedonian'),
90					'mn_MN'	 => gettext('Mongolian'),
91					'ms_MY'	 => gettext('Malay'),
92					'mg_MG'	 => gettext('Malagasy'),
93					'nb_NO'	 => gettext('Norwegian (Bokmål)'),
94					'no_NO'	 => gettext('Norwegian'),
95					'ni_ID'	 => gettext('Nias'),
96					'fa_IR'	 => gettext('Persian'),
97					'pl_PL'	 => gettext('Polish'),
98					'pt_BR'	 => gettext('Portuguese (Brazil)'),
99					'pt_PT'	 => gettext('Portuguese (Portugal)'),
100					'ro_RO'	 => gettext('Romanian'),
101					'ru_RU'	 => gettext('Russian (Russia)'),
102					'ru_UA'	 => gettext('Russian (Ukraine)'),
103					'si_LK'	 => gettext('Sinhala'),
104					'sk_SK'	 => gettext('Slovak'),
105					'sl_SI'	 => gettext('Slovenian'),
106					'es_AR'	 => gettext('Spanish (Argentina)'),
107					'es_BO'	 => gettext('Spanish (Bolivia)'),
108					'es_CL'	 => gettext('Spanish (Chile)'),
109					'es_CO'	 => gettext('Spanish (Columbia)'),
110					'es_CR'	 => gettext('Spanish (Costa Rica)'),
111					'es_DO'	 => gettext('Spanish (Dominican Republic)'),
112					'es_EC'	 => gettext('Spanish (Ecuador)'),
113					'es_ES'	 => gettext('Spanish (Spain)'),
114					'es_GT'	 => gettext('Spanish (Guatemala)'),
115					'es_HN'	 => gettext('Spanish (Honduras)'),
116					'es_MX'	 => gettext('Spanish (Mexico)'),
117					'es_NI'	 => gettext('Spanish (Nicaragua)'),
118					'es_PA'	 => gettext('Spanish (Panama)'),
119					'es_PE'	 => gettext('Spanish (Peru)'),
120					'es_PR'	 => gettext('Spanish (Puerto Rico)'),
121					'es_PY'	 => gettext('Spanish (Paraguay)'),
122					'es_SV'	 => gettext('Spanish (El Salvador)'),
123					'es_US'	 => gettext('Spanish (United States)'),
124					'es_UY'	 => gettext('Spanish (Uruguay)'),
125					'es_VE'	 => gettext('Spanish (Venezuela)'),
126					'es_LA'	 => gettext('Spanish (Latin America)'),
127					'sr_YU'	 => gettext('Serbian'),
128					'sr_RS'	 => gettext('Serbian'),
129					'sv_FI'	 => gettext('Swedish (Finland)'),
130					'sv_SE'	 => gettext('Swedish (Sweden)'),
131					'ta_IN'	 => gettext('Tamil'),
132					'te_IN'	 => gettext('Telugu'),
133					'th_TH'	 => gettext('Thai'),
134					'tr_TR'	 => gettext('Turkish'),
135					'uk_UA'	 => gettext('Ukrainian'),
136					'uz_UZ'	 => gettext('Uzbek'),
137					'ur_PK'	 => gettext('Urdu (Pakistan)'),
138					'vi_VN'	 => gettext('Vietnamese'),
139					'cy'		 => gettext('Welsh')
140	);
141}
142
143/**
144 * Returns an array of available language locales.
145 *
146 * @return array
147 *
148 */
149function generateLanguageList($all = false) {
150	global $_zp_active_languages, $_zp_all_languages;
151	if (is_null($_zp_all_languages)) {
152		$zp_languages = getLanguageArray();
153		$dir = @opendir(SERVERPATH . "/" . ZENFOLDER . "/locale/");
154		$_zp_active_languages = $_zp_all_languages = array();
155		if ($dir !== false) {
156			while ($dirname = readdir($dir)) {
157				if (is_dir(SERVERPATH . "/" . ZENFOLDER . "/locale/" . $dirname) && (substr($dirname, 0, 1) != '.')) {
158					if (isset($zp_languages[$dirname])) {
159						$language = $zp_languages[$dirname];
160						if (empty($language)) {
161							$language = $dirname;
162						}
163					} else {
164						$language = $dirname;
165					}
166					$_zp_all_languages[$language] = $dirname;
167					if (!getOption('disallow_' . $dirname)) {
168						$_zp_active_languages[$language] = $dirname;
169					}
170				}
171			}
172			closedir($dir);
173		}
174		ksort($_zp_all_languages);
175		ksort($_zp_active_languages);
176	}
177	if ($all) {
178		return $_zp_all_languages;
179	} else {
180		return $_zp_active_languages;
181	}
182}
183
184/**
185 * Sets the locale, etc. to the zenphoto domain details.
186 * Returns the result of setupCurrentLocale()
187 *
188 */
189function setMainDomain() {
190	$locale = getUserLocale();
191	return setupCurrentLocale($locale);
192}
193
194/**
195 * Gettext replacement function for separate translations of third party themes.
196 * @param string $string The string to be translated
197 * @param string $theme The name of the plugin. Only required for strings on the 'theme_description.php' file like the general theme description. If the theme is the current theme the function sets it automatically.
198 * @return string
199 */
200function gettext_th($string, $theme = Null) {
201	global $_zp_gallery;
202	if (empty($theme)) {
203		$theme = $_zp_gallery->getCurrentTheme();
204	}
205	setupDomain($theme, 'theme');
206	$translation = gettext($string);
207	setupDomain();
208	return $translation;
209}
210
211/**
212 * ngettext replacement function for separate translations of third party themes.
213 * @param string $msgid1
214 * @param string $msgid2
215 * @param int $n
216 * @param string $plugin
217 * @return string
218 */
219function ngettext_th($msgid1, $msgid2, $n, $theme = NULL) {
220	global $_zp_gallery;
221	if (empty($theme)) {
222		$theme = $_zp_gallery->getCurrentTheme();
223	}
224	setupDomain($theme, 'theme');
225	$translation = ngettext($msgid1, $msgid2, $n);
226	setupDomain();
227	return $translation;
228}
229
230/**
231 * Gettext replacement function for separate translations of third party plugins within the root plugins folder.
232 * @param string $string The string to be translated
233 * @param string $plugin The name of the plugin. Required.
234 * @return string
235 */
236function gettext_pl($string, $plugin) {
237	setupDomain($plugin, 'plugin');
238	$translation = gettext($string);
239	setupDomain();
240	return $translation;
241}
242
243/**
244 * ngettext replacement function for separate translations of third party plugins within the root plugins folder.
245 * @param string $msgid1
246 * @param string $msgid2
247 * @param int $n
248 * @param string $plugin
249 * @return string
250 */
251function ngettext_pl($msgid1, $msgid2, $n, $plugin) {
252	setupDomain($plugin, 'plugin');
253	$translation = ngettext($msgid1, $msgid2, $n);
254	setupDomain();
255	return $translation;
256}
257
258/**
259 * Wrapper function for setLocale() so that all the proper permutations are used
260 * Returns the result from the setLocale call
261 * @param $locale the local desired
262 * @return string
263 */
264function i18nSetLocale($locale) {
265	global $_zp_RTL_css;
266	$en1 = LOCAL_CHARSET;
267	$en2 = str_replace('ISO-', 'ISO', $en1);
268	$locale_hyphen = str_replace('_', '-', $locale);
269	$simple = explode('-', $locale_hyphen);
270	$try[$locale . '.UTF8'] = $locale . '.UTF8';
271	$try[$locale . '.UTF-8'] = $locale . '.UTF-8';
272	$try[$locale . '.@euro'] = $locale . '.@euro';
273	$try[$locale . '.' . $en2] = $locale . '.' . $en2;
274	$try[$locale . '.' . $en1] = $locale . '.' . $en1;
275	$try[$locale] = $locale;
276	$try[$simple[0]] = $simple[0];
277	$try['NULL'] = NULL;
278	$rslt = setlocale(LC_ALL, $try);
279	$_zp_RTL_css = in_array(substr($rslt, 0, 2), array('fa', 'ar', 'he', 'hi', 'ur'));
280	if (DEBUG_LOCALE) {
281		debugLog("setlocale(" . implode(',', $try) . ") returned: $rslt");
282	}
283	return $rslt;
284}
285
286/**
287 * Sets the translation domain and type for optional theme or plugin based translations
288 * @param $domaine If $type "plugin" or "theme" the file/folder name of the theme or plugin
289 * @param $type NULL (Zenphoto main translation), "theme" or "plugin"
290 */
291function setupDomain($domain = NULL, $type = NULL) {
292	global $_zp_active_languages, $_zp_all_languages;
293	switch ($type) {
294		case "plugin":
295			$domainpath = getPlugin($domain . "/locale/");
296			break;
297		case "theme":
298			$domainpath = SERVERPATH . "/" . THEMEFOLDER . "/" . $domain . "/locale/";
299			break;
300		default:
301			$domain = 'zenphoto';
302			$domainpath = SERVERPATH . "/" . ZENFOLDER . "/locale/";
303			break;
304	}
305	bindtextdomain($domain, $domainpath);
306	// function only since php 4.2.0
307	if (function_exists('bind_textdomain_codeset')) {
308		bind_textdomain_codeset($domain, 'UTF-8');
309	}
310	textdomain($domain);
311	//invalidate because the locale was not setup until now
312	$_zp_active_languages = $_zp_all_languages = NULL;
313}
314
315/**
316 * Setup code for gettext translation
317 * Returns the result of the setlocale call
318 *
319 * @param string $override force locale to this
320 * @return mixed
321 */
322function setupCurrentLocale($override = NULL) {
323	if (is_null($override)) {
324		$locale = getOption('locale');
325	} else {
326		$locale = $override;
327	}
328	if (getOption('disallow_' . $locale)) {
329		if (DEBUG_LOCALE)
330			debugLogBacktrace("setupCurrentLocale($override): $locale denied by option.");
331		$locale = getOption('locale');
332		if (empty($locale) || getOption('disallow_' . $locale)) {
333			$languages = generateLanguageList();
334			$locale = array_shift($languages);
335		}
336	}
337	// gettext setup
338	@putenv("LANG=$locale"); // Windows ???
339	@putenv("LANGUAGE=$locale"); // Windows ???
340	$result = i18nSetLocale($locale);
341	if (!$result) {
342		if (isset($_REQUEST['locale']) || is_null($override)) { // and it was chosen via locale
343			if (isset($_REQUEST['oldlocale'])) {
344				$locale = sanitize($_REQUEST['oldlocale'], 3);
345				setOption('locale', $locale, false);
346				zp_clearCookie('zpcms_locale');
347			}
348		}
349	}
350	if (DEBUG_LOCALE)
351		debugLogBacktrace("setupCurrentLocale($override): locale=$locale, \$result=$result");
352	setupDomain();
353	return $result;
354}
355
356/**
357 * Converts underscore locales like "en_US" to valid IANA/BCP 47 hyphen locales like "en-US"
358 * Needed for example in JS or HTML "lang" attributes.
359 *
360 * @since ZenphotoCMS 1.5.7
361 *
362 * @param string $locale a locale like "en_US", if empty the current locale is used
363 * @return string
364 */
365function getLangAttributeLocale($locale = NULL) {
366	if(empty($locale)) {
367		$locale = getUserLocale();
368	}
369	return str_replace('_', '-', $locale);
370}
371
372/**
373 * This function will parse a given HTTP Accepted language instruction
374 * (or retrieve it from $_SERVER if not provided) and will return a sorted
375 * array. For example, it will parse fr;en-us;q=0.8
376 *
377 * Thanks to Fredbird.org for this code.
378 *
379 * @param string $str optional language string
380 * @return array
381 */
382function parseHttpAcceptLanguage($str = NULL) {
383	// getting http instruction if not provided
384	if (!$str) {
385		$str = @$_SERVER['HTTP_ACCEPT_LANGUAGE'];
386	}
387	if (!is_string($str)) {
388		return array();
389	}
390	$langs = explode(',', $str);
391	// creating output list
392	$accepted = array();
393	foreach ($langs as $lang) {
394		// parsing language preference instructions
395		// 2_digit_code[-longer_code][;q=coefficient]
396		if (preg_match('/([A-Za-z]{1,2})(-([A-Za-z0-9]+))?(;q=([0-9\.]+))?/', $lang, $found)) {
397			// 2 digit lang code
398			$code = $found[1];
399			// lang code complement
400			$morecode = array_key_exists(3, $found) ? $found[3] : false;
401			// full lang code
402			$fullcode = $morecode ? $code . '_' . $morecode : $code;
403			// coefficient (preference value, will be used in sorting the list)
404			$coef = sprintf('%3.1f', array_key_exists(5, $found) ? $found[5] : '1');
405			// for sorting by coefficient
406			if ($coef) { //	q=0 means do not supply this language
407				// adding
408				$accepted[$coef . '-' . $code] = array('code' => $code, 'coef' => $coef, 'morecode' => $morecode, 'fullcode' => $fullcode);
409			}
410		}
411	}
412
413	// sorting the list by coefficient desc
414	krsort($accepted);
415	if (DEBUG_LOCALE) {
416		debugLog("parseHttpAcceptLanguage($str)");
417		debugLogVar('parseHttpAcceptLanguage::$accepted', $accepted);
418	}
419	return $accepted;
420}
421
422/**
423 * checks a "supplied" locale against the valid locales.
424 * Returns a valid locale if one exists else returns NULL
425 * @param string $userlocale
426 */
427function validateLocale($userlocale, $source) {
428	if (DEBUG_LOCALE)
429		debugLog("validateLocale($userlocale,$source)");
430	$userlocale = strtoupper(str_replace('-', '_', $userlocale));
431	$languageSupport = generateLanguageList();
432	$locale = NULL;
433	if (!empty($userlocale)) {
434		foreach ($languageSupport as $key => $value) {
435			if (strtoupper($value) == $userlocale) { // we got a match
436				$locale = $value;
437				if (DEBUG_LOCALE)
438					debugLog("locale set from $source: " . $locale);
439				break;
440			} else if (@preg_match('/^' . $userlocale . '/', strtoupper($value))) { // we got a partial match
441				$locale = $value;
442				if (DEBUG_LOCALE)
443					debugLog("locale set from $source (partial match): " . $locale);
444				break;
445			}
446		}
447	}
448	return $locale;
449}
450
451/**
452 * Returns a saved (or posted) locale. Posted locales are stored as a cookie.
453 *
454 * Sets the 'locale' option to the result (non-persistent)
455 */
456function getUserLocale() {
457	global $_zp_current_admin_obj, $_zp_current_locale;
458	if (!$_zp_current_locale) {
459		if (DEBUG_LOCALE)
460			debugLogBackTrace("getUserLocale()");
461		if (isset($_REQUEST['locale'])) {
462			if (isset($_POST['locale'])) {
463				$_zp_current_locale = validateLocale(sanitize($_POST['locale']), 'POST');
464			} else {
465				$_zp_current_locale = validateLocale(sanitize($_GET['locale']), 'URI string');
466			}
467			if ($_zp_current_locale) {
468				zp_setCookie('zpcms_locale', $_zp_current_locale);
469			}
470			if (DEBUG_LOCALE)
471				debugLog("dynamic_locale from URL: " . sanitize($_REQUEST['locale']) . "=>$_zp_current_locale");
472		} else {
473			$matches = explode('.', @$_SERVER['HTTP_HOST']);
474			if ($_zp_current_locale = validateLocale($matches[0], 'HTTP_HOST')) {
475				zp_clearCookie('zpcms_locale');
476			}
477		}
478
479		if (!$_zp_current_locale && is_object($_zp_current_admin_obj)) {
480			$_zp_current_locale = $_zp_current_admin_obj->getLanguage();
481			if (DEBUG_LOCALE)
482				debugLog("locale from user: " . $_zp_current_locale);
483		}
484
485		if (!$_zp_current_locale) {
486			$localeOption = getOption('locale');
487			$_zp_current_locale = zp_getCookie('zpcms_locale');
488
489			if (DEBUG_LOCALE)
490				debugLog("locale from option: " . $localeOption . '; dynamic locale=' . $_zp_current_locale);
491			if (empty($localeOption) && empty($_zp_current_locale)) { // if one is not set, see if there is a match from 'HTTP_ACCEPT_LANGUAGE'
492				$languageSupport = generateLanguageList();
493				$userLang = parseHttpAcceptLanguage();
494				foreach ($userLang as $lang) {
495					$l = strtoupper($lang['fullcode']);
496					$_zp_current_locale = validateLocale($l, 'HTTP Accept Language');
497					if ($_zp_current_locale)
498						break;
499				}
500			} else {
501				if (empty($_zp_current_locale)) {
502					$_zp_current_locale = $localeOption;
503				}
504			}
505		}
506
507		if (empty($_zp_current_locale)) {
508			// return "default" language, English if allowed, otherwise whatever is the "first" allowed language
509			$languageSupport = generateLanguageList();
510			if (in_array('en_US', $languageSupport)) {
511				$_zp_current_locale = 'en_US';
512			} else {
513				$_zp_current_locale = array_shift($languageSupport);
514			}
515		} else {
516			setOption('locale', $_zp_current_locale, false);
517		}
518		if (DEBUG_LOCALE)
519			debugLog("getUserLocale Returning locale: " . $_zp_current_locale);
520	}
521	return $_zp_current_locale;
522}
523
524/**
525 * Returns the sring for the current language from a serialized set of language strings
526 * Defaults to the string for the current locale, the en_US string, or the first string which ever is present
527 *
528 * @param string $dbstring either a serialized languag string array or a single string
529 * @param string $locale optional locale of the translation desired
530 * @return string
531 */
532function get_language_string($dbstring, $locale = NULL) {
533	$strings = getSerializedArray($dbstring);
534	$actual_local = getOption('locale');
535	if (is_null($locale))
536		$locale = $actual_local;
537	if (isset($strings[$locale])) {
538		return $strings[$locale];
539	}
540	if (isset($strings[$actual_local])) {
541		return $strings[$actual_local];
542	}
543	if (isset($strings['en_US'])) {
544		return $strings['en_US'];
545	}
546	return array_shift($strings);
547}
548
549/**
550 * Returns a list of timezones
551 *
552 * @return unknown
553 */
554function getTimezones() {
555	$cities = array();
556	if (function_exists('timezone_abbreviations_list')) {
557		$timezones = timezone_abbreviations_list();
558		foreach ($timezones as $key => $zones) {
559			foreach ($zones as $id => $zone) {
560				/**
561				 * Only get timezones explicitely not part of "Others" except UTC
562				 * @see http://www.php.net/manual/en/timezones.others.php
563				 */
564				if ($zone['timezone_id'] == 'UTC' || preg_match('/^(Africa|America|Antarctica|Arctic|Asia|Atlantic|Australia|Europe|Indian|Pacific)\//', $zone['timezone_id'])) {
565					$cities[] = $zone['timezone_id'];
566				}
567			}
568		}
569		// Only keep one city (the first and also most important) for each set of possibilities.
570		$cities = array_unique($cities);
571
572		// Sort by area/city name.
573		ksort($cities, SORT_LOCALE_STRING);
574	}
575	return $cities;
576}
577
578/**
579 * Returns the difference between the server timez one and the local (users) time zone
580 *
581 * @param string $server
582 * @param string $local
583 * @return int
584 */
585function timezoneDiff($server, $local) {
586	if (function_exists('timezone_abbreviations_list')) {
587		$timezones = timezone_abbreviations_list();
588		foreach ($timezones as $key => $zones) {
589			foreach ($zones as $id => $zone) {
590				if (!isset($offset_server) && $zone['timezone_id'] === $server) {
591					$offset_server = (int) $zone['offset'];
592				}
593				if (!isset($offset_local) && $zone['timezone_id'] === $local) {
594					$offset_local = (int) $zone['offset'];
595				}
596				if (isset($offset_server) && isset($offset_local)) {
597					return ($offset_server - $offset_local) / 3600;
598				}
599			}
600		}
601	}
602	return 0;
603}
604
605/**
606 * returns a serialized "multilingual array" of translations
607 * Used for setting default options with multi-lingual strings.
608 * @param string $text to be translated
609 */
610function getAllTranslations($text) {
611	$entry_locale = getUserLocale();
612	$result = array('en_US' => $text);
613	$languages = generateLanguageList();
614	foreach ($languages as $language) {
615		setupCurrentLocale($language);
616		$xlated = gettext($text);
617		if ($xlated != $text) { // the string has a translation in this language
618			$result[$language] = $xlated;
619		}
620	}
621	setupCurrentLocale($entry_locale);
622	if (count($result) == 1) {
623		return $text;
624	}
625	return serialize($result);
626}
627
628/**
629 * creates an SEO language prefix list
630 */
631function getLanguageSubdomains() {
632	$domains = array();
633	$langs = generateLanguageList();
634	$domains = array();
635	foreach ($langs as $value) {
636		$domains[substr($value, 0, 2)][] = $value;
637	}
638	$langs = array();
639	foreach ($domains as $simple => $full) {
640		if (count($full) > 1) {
641			foreach ($full as $loc) {
642				$langs[$loc] = $loc;
643			}
644		} else {
645			$langs[$full[0]] = $simple;
646		}
647	}
648	if (isset($langs[SITE_LOCALE])) {
649		$langs[SITE_LOCALE] = '';
650	}
651	return $langs;
652}
653
654/**
655 * Returns a canonical language name string for the location
656 *
657 * @param string $loc the location. If NULL use the current cookie
658 * @param string separator will be used between the major and qualifier parts, e.g. en_US
659 *
660 * @return string
661 */
662function getLanguageText($loc = NULL, $separator = NULL) {
663	global $_locale_Subdomains;
664	if (is_null($loc)) {
665		$text = @$_locale_Subdomains[zp_getCookie('zpcms_locale')];
666	} else {
667		$text = @$_locale_Subdomains[$loc];
668		//en_US always is always empty here so so urls in dynamic locale or html_meta_tags are wrong (Quickfix)
669		if (empty($text)) {
670			$text = $loc;
671		}
672	}
673	if (!is_null($separator)) {
674		$text = str_replace('_', $separator, $text);
675	}
676	return $text;
677}
678
679if (function_exists('date_default_timezone_set')) { // insure a correct time zone
680	$tz = getOption('time_zone');
681	if (!empty($tz)) {
682		$err = error_reporting(0);
683		date_default_timezone_set($tz);
684		@ini_set('date.timezone', $tz);
685		error_reporting($err);
686	}
687	unset($tz);
688}
689
690/**
691 * Gets all locales suppported on the current server as a multidimensional array
692 *
693 * @param bool $plainarray Default false for a multidimensial array grouped by locale base. Set to true to generate a single dimensional array with all locales.
694 *
695 * @author Stephen Billard (sbillard), Malte Müller (acrylian) - adapted from the old former unsupported tool `list_locales.php`
696 * @since ZenphotoCMS 1.5.2
697 * @return array
698 */
699function getSystemLocales($plainarray = false) {
700	if (class_exists('ResourceBundle')) {
701		$locales = ResourceBundle::getLocales('');
702		$array = array();
703		if ($plainarray) {
704			return $locales;
705		} else {
706			foreach ($locales as $locale) {
707				$expl = explode('_', $locale);
708				$array[$expl[0]][] = $locale;
709			}
710			return $array;
711		}
712	}
713	return false;
714}
715
716/**
717 * Returns the real language name to the locale passed.
718 *
719 * If available it will use the native PHP Locale class. It returns the name in the language/locale currently set.
720 * Otherwise the far more limited internal Zenphoto catalogue stored in getLanguageArray() will be used.
721 *
722 * @since ZenphotoCMS 1.5.2
723 *
724 * @param string $locale A vaild locale.
725 * @return string
726 */
727function getLanguageDisplayName($locale) {
728	if (class_exists('Locale')) {
729		return Locale::getDisplayName($locale);
730	} else {
731		$languages = getLanguageArray();
732		if (array_key_exists($locale, $languages)) {
733			return $languages[$locale];
734		}
735	}
736}
737
738$_locale_Subdomains = getLanguageSubdomains();