diff options
Diffstat (limited to 'engine/lib/languages.php')
| -rw-r--r-- | engine/lib/languages.php | 465 |
1 files changed, 352 insertions, 113 deletions
diff --git a/engine/lib/languages.php b/engine/lib/languages.php index 5292b5403..61ba91ddb 100644 --- a/engine/lib/languages.php +++ b/engine/lib/languages.php @@ -1,115 +1,354 @@ -<?php
-
- /**
- * Elgg language module
- * Functions to manage language and translations.
- *
- * @package Elgg
- * @subpackage Core
- * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU Public License version 2
- * @author Curverider Ltd
- * @copyright Curverider Ltd 2008
- * @link http://elgg.org/
- */
-
- /**
- * 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] = array_merge($CONFIG->translations[$country_code],$language_array);
- }
- return true;
-
- }
- return false;
-
- }
-
- /**
- * Given a message shortcode, returns an appropriately translated full-text string
- *
- * @param string $message_key The short message code
- * @param string $language Optionally, the standard language code (defaults to the site default, then English)
- * @return string Either the translated string, or the original English string, or an empty string
- */
- function elgg_echo($message_key, $language = "") {
-
- global $CONFIG;
- - if ((empty($language)) && (isset($_SESSION['user'])) && ($_SESSION['user']->language)) - $language = $_SESSION['user']->language; -
- if ((empty($language)) && (isset($CONFIG->language)))
- $language = $CONFIG->language; -
- if (isset($CONFIG->translations[$language][$message_key])) {
- return $CONFIG->translations[$language][$message_key];
- } else if (isset($CONFIG->translations["en"][$message_key])) {
- return $CONFIG->translations["en"][$message_key];
- }
-
- return $message_key;
-
- }
-
- /**
- * When given a full path, finds translation files and loads them
- *
- * @param string $path Full path
- */
- function register_translations($path) { - global $CONFIG; - - if (isset($CONFIG->debug) && $CONFIG->debug == true) error_log("Translations loaded from : $path");
- - if ($handle = opendir($path)) {
- while ($language = readdir($handle)) {
- if (!in_array($language,array('.','..','.svn','CVS')) && !is_dir($path . $language)) {
- @include($path . $language);
- }
- }
+<?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 bool 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() { + $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; +} + +/** + * @access private + */ +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.lang"); + if ($data) { + add_translation($language, unserialize($data)); + } else { + $loaded = false; } - else - error_log("Missing translation path $path");
- }
- - /** - * Return an array of installed translations as an associative array "two letter code" => "native language name". - */ - function get_installed_translations() - { - global $CONFIG; - - $installed = array(); - - foreach ($CONFIG->translations as $k => $v) - $installed[$k] = elgg_echo($k, $k); - - return $installed; } -
- register_translations(dirname(dirname(dirname(__FILE__))) . "/languages/");
-
-?>
\ No newline at end of file + + 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 bool success + */ +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. + * + * @todo Better on demand loading based on language_paths array + * + * @return void + */ +function reload_all_translations() { + global $CONFIG; + + static $LANG_RELOAD_ALL_RUN; + if ($LANG_RELOAD_ALL_RUN) { + return; + } + + if ($CONFIG->i18n_loaded_from_cache) { + $cache = elgg_get_system_cache(); + $cache_dir = $cache->getVariable("cache_path"); + $filenames = elgg_get_file_list($cache_dir, array(), array(), array(".lang")); + foreach ($filenames as $filename) { + if (preg_match('/([a-z]+)\.[^.]+$/', $filename, $matches)) { + $language = $matches[1]; + $data = elgg_load_system_cache("$language.lang"); + if ($data) { + add_translation($language, unserialize($data)); + } + } + } + } else { + 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; +} |
