diff options
Diffstat (limited to 'engine/lib/languages.php')
| -rw-r--r-- | engine/lib/languages.php | 350 | 
1 files changed, 350 insertions, 0 deletions
| diff --git a/engine/lib/languages.php b/engine/lib/languages.php new file mode 100644 index 000000000..98006f7cd --- /dev/null +++ b/engine/lib/languages.php @@ -0,0 +1,350 @@ +<?php +/** + * Elgg language module + * Functions to manage language and translations. + * + * @package Elgg.Core + * @subpackage Languages + */ + +/** + * Given a message key, returns an appropriately translated full-text string + * + * @param string $message_key The short message code + * @param array  $args        An array of arguments to pass through vsprintf(). + * @param string $language    Optionally, the standard language code + *                            (defaults to site/user default, then English) + * + * @return string Either the translated string, the English string, + * or the original language string. + */ +function elgg_echo($message_key, $args = array(), $language = "") { +	global $CONFIG; + +	static $CURRENT_LANGUAGE; + +	// old param order is deprecated +	if (!is_array($args)) { +		elgg_deprecated_notice( +			'As of Elgg 1.8, the 2nd arg to elgg_echo() is an array of string replacements and the 3rd arg is the language.', +			1.8 +		); + +		$language = $args; +		$args = array(); +	} + +	if (!isset($CONFIG->translations)) { +		// this means we probably had an exception before translations were initialized +		register_translations(dirname(dirname(dirname(__FILE__))) . "/languages/"); +	} + +	if (!$CURRENT_LANGUAGE) { +		$CURRENT_LANGUAGE = get_language(); +	} +	if (!$language) { +		$language = $CURRENT_LANGUAGE; +	} + +	if (isset($CONFIG->translations[$language][$message_key])) { +		$string = $CONFIG->translations[$language][$message_key]; +	} else if (isset($CONFIG->translations["en"][$message_key])) { +		$string = $CONFIG->translations["en"][$message_key]; +		$lang = $CONFIG->translations["en"][$language]; +		elgg_log(sprintf('Missing %s translation for "%s" language key', $lang, $message_key), 'NOTICE'); +	} else { +		$string = $message_key; +		elgg_log(sprintf('Missing English translation for "%s" language key', $message_key), 'NOTICE'); +	} + +	// only pass through if we have arguments to allow backward compatibility +	// with manual sprintf() calls. +	if ($args) { +		$string = vsprintf($string, $args); +	} + +	return $string; +} + +/** + * Add a translation. + * + * Translations are arrays in the Zend Translation array format, eg: + * + *	$english = array('message1' => 'message1', 'message2' => 'message2'); + *  $german = array('message1' => 'Nachricht1','message2' => 'Nachricht2'); + * + * @param string $country_code   Standard country code (eg 'en', 'nl', 'es') + * @param array  $language_array Formatted array of strings + * + * @return true|false Depending on success + */ +function add_translation($country_code, $language_array) { +	global $CONFIG; +	if (!isset($CONFIG->translations)) { +		$CONFIG->translations = array(); +	} + +	$country_code = strtolower($country_code); +	$country_code = trim($country_code); +	if (is_array($language_array) && sizeof($language_array) > 0 && $country_code != "") { +		if (!isset($CONFIG->translations[$country_code])) { +			$CONFIG->translations[$country_code] = $language_array; +		} else { +			$CONFIG->translations[$country_code] = $language_array + $CONFIG->translations[$country_code]; +		} +		return true; +	} +	return false; +} + +/** + * Detect the current language being used by the current site or logged in user. + * + * @return string The language code for the site/user or "en" if not set + */ +function get_current_language() { +	global $CONFIG; + +	$language = get_language(); + +	if (!$language) { +		$language = 'en'; +	} + +	return $language; +} + +/** + * Gets the current language in use by the system or user. + * + * @return string The language code (eg "en") or false if not set + */ +function get_language() { +	global $CONFIG; + +	$user = elgg_get_logged_in_user_entity(); +	$language = false; + +	if (($user) && ($user->language)) { +		$language = $user->language; +	} + +	if ((!$language) && (isset($CONFIG->language)) && ($CONFIG->language)) { +		$language = $CONFIG->language; +	} + +	if ($language) { +		return $language; +	} + +	return false; +} + +function _elgg_load_translations() { +	global $CONFIG; + +	if ($CONFIG->system_cache_enabled) { +		$loaded = true; +		$languages = array_unique(array('en', get_current_language())); +		foreach ($languages as $language) { +			$data = elgg_load_system_cache("$language.php"); +			if ($data) { +				add_translation($language, unserialize($data)); +			} else { +				$loaded = false; +			} +		} + +		if ($loaded) { +			$CONFIG->i18n_loaded_from_cache = true; +			// this is here to force  +			$CONFIG->language_paths[dirname(dirname(dirname(__FILE__))) . "/languages/"] = true; +			return; +		} +	} + +	// load core translations from languages directory +	register_translations(dirname(dirname(dirname(__FILE__))) . "/languages/"); +} + + + +/** + * When given a full path, finds translation files and loads them + * + * @param string $path     Full path + * @param bool   $load_all If true all languages are loaded, if + *                         false only the current language + en are loaded + * + * @return void + */ +function register_translations($path, $load_all = false) { +	global $CONFIG; + +	$path = sanitise_filepath($path); + +	// Make a note of this path just incase we need to register this language later +	if (!isset($CONFIG->language_paths)) { +		$CONFIG->language_paths = array(); +	} +	$CONFIG->language_paths[$path] = true; + +	// Get the current language based on site defaults and user preference +	$current_language = get_current_language(); +	elgg_log("Translations loaded from: $path"); + +	// only load these files unless $load_all is true. +	$load_language_files = array( +		'en.php', +		"$current_language.php" +	); + +	$load_language_files = array_unique($load_language_files); + +	$handle = opendir($path); +	if (!$handle) { +		elgg_log("Could not open language path: $path", 'ERROR'); +		return false; +	} + +	$return = true; +	while (false !== ($language = readdir($handle))) { +		// ignore bad files +		if (substr($language, 0, 1) == '.' || substr($language, -4) !== '.php') { +			continue; +		} + +		if (in_array($language, $load_language_files) || $load_all) { +			if (!include_once($path . $language)) { +				$return = false; +				continue; +			} +		} +	} + +	return $return; +} + +/** + * Reload all translations from all registered paths. + * + * This is only called by functions which need to know all possible translations, namely the + * statistic gathering ones. + * + * @todo Better on demand loading based on language_paths array + * + * @return bool + */ +function reload_all_translations() { +	global $CONFIG; + +	static $LANG_RELOAD_ALL_RUN; +	if ($LANG_RELOAD_ALL_RUN) { +		return null; +	} + +	foreach ($CONFIG->language_paths as $path => $dummy) { +		register_translations($path, true); +	} + +	$LANG_RELOAD_ALL_RUN = true; +} + +/** + * Return an array of installed translations as an associative + * array "two letter code" => "native language name". + * + * @return array + */ +function get_installed_translations() { +	global $CONFIG; + +	// Ensure that all possible translations are loaded +	reload_all_translations(); + +	$installed = array(); + +	foreach ($CONFIG->translations as $k => $v) { +		$installed[$k] = elgg_echo($k, array(), $k); +		if (elgg_is_admin_logged_in()) { +			$completeness = get_language_completeness($k); +			if (($completeness < 100) && ($k != 'en')) { +				$installed[$k] .= " (" . $completeness . "% " . elgg_echo('complete') . ")"; +			} +		} +	} + +	return $installed; +} + +/** + * Return the level of completeness for a given language code (compared to english) + * + * @param string $language Language + * + * @return int + */ +function get_language_completeness($language) { +	global $CONFIG; + +	// Ensure that all possible translations are loaded +	reload_all_translations(); + +	$language = sanitise_string($language); + +	$en = count($CONFIG->translations['en']); + +	$missing = get_missing_language_keys($language); +	if ($missing) { +		$missing = count($missing); +	} else { +		$missing = 0; +	} + +	//$lang = count($CONFIG->translations[$language]); +	$lang = $en - $missing; + +	return round(($lang / $en) * 100, 2); +} + +/** + * Return the translation keys missing from a given language, + * or those that are identical to the english version. + * + * @param string $language The language + * + * @return mixed + */ +function get_missing_language_keys($language) { +	global $CONFIG; + +	// Ensure that all possible translations are loaded +	reload_all_translations(); + +	$missing = array(); + +	foreach ($CONFIG->translations['en'] as $k => $v) { +		if ((!isset($CONFIG->translations[$language][$k])) +		|| ($CONFIG->translations[$language][$k] == $CONFIG->translations['en'][$k])) { +			$missing[] = $k; +		} +	} + +	if (count($missing)) { +		return $missing; +	} + +	return false; +} + +/** + * Initialize the language library + * @access private + */ +function elgg_languages_init() { +	$lang = get_current_language(); +	elgg_register_simplecache_view("js/languages/$lang"); +} + +elgg_register_event_handler('init', 'system', 'elgg_languages_init'); | 
