| [ Index ] |
|
Code source de Horde 3.1.3 |
1 <?php 2 /** 3 * The NLS:: class provides Native Language Support. This includes common 4 * methods for handling language detection and selection, timezones, and 5 * hostname->country lookups. 6 * 7 * $Horde: framework/NLS/NLS.php,v 1.82.4.13 2006/01/24 07:50:26 selsky Exp $ 8 * 9 * Copyright 1999-2006 Jon Parise <jon@horde.org> 10 * Copyright 1999-2006 Chuck Hagenbuch <chuck@horde.org> 11 * Copyright 2002-2006 Jan Schneider <jan@horde.org> 12 * Copyright 2003-2006 Michael Slusarz <slusarz@bigworm.colorado.edu> 13 * 14 * See the enclosed file COPYING for license information (LGPL). If you 15 * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html. 16 * 17 * @author Jon Parise <jon@horde.org> 18 * @author Chuck Hagenbuch <chuck@horde.org> 19 * @author Jan Schneider <jan@horde.org> 20 * @author Michael Slusarz <slusarz@bigworm.colorado.edu> 21 * @since Horde 3.0 22 * @package Horde_NLS 23 */ 24 class NLS { 25 26 /** 27 * Selects the most preferred language for the current client session. 28 * 29 * @return string The selected language abbreviation. 30 */ 31 function select() 32 { 33 global $nls, $prefs; 34 35 $lang = Util::getFormData('new_lang'); 36 37 /* First, check if language pref is locked and, if so, set it to its 38 value */ 39 if (isset($prefs) && $prefs->isLocked('language')) { 40 $language = $prefs->getValue('language'); 41 /* Check if the user selected a language from the login screen */ 42 } elseif (!empty($lang)) { 43 $language = $lang; 44 /* Check if we have a language set in a cookie */ 45 } elseif (isset($_SESSION['horde_language'])) { 46 $language = $_SESSION['horde_language']; 47 /* Use site-wide default, if one is defined */ 48 } elseif (!empty($nls['defaults']['language'])) { 49 $language = $nls['defaults']['language']; 50 /* Try browser-accepted languages. */ 51 } elseif (!empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { 52 /* The browser supplies a list, so return the first valid one. */ 53 $browser_langs = explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']); 54 foreach ($browser_langs as $lang) { 55 /* Strip quality value for language */ 56 if (($pos = strpos($lang, ';')) !== false) { 57 $lang = substr($lang, 0, $pos); 58 } 59 $lang = NLS::_map(trim($lang)); 60 if (NLS::isValid($lang)) { 61 $language = $lang; 62 break; 63 } 64 /* In case no full match, save best guess based on prefix */ 65 if (!isset($partial_lang) && 66 NLS::isValid(NLS::_map(substr($lang, 0, 2)))) { 67 $partial_lang = NLS::_map(substr($lang, 0, 2)); 68 } 69 } 70 } 71 72 if (!isset($language)) { 73 if (isset($partial_lang)) { 74 $language = $partial_lang; 75 } else { 76 /* No dice auto-detecting, default to US English. */ 77 $language = 'en_US'; 78 } 79 } 80 81 return basename($language); 82 } 83 84 /** 85 * Sets the language. 86 * 87 * @param string $lang The language abbreviation. 88 */ 89 function setLang($lang = null) 90 { 91 include_once HORDE_BASE . '/config/nls.php'; 92 93 if (empty($lang) || !NLS::isValid($lang)) { 94 $lang = NLS::select(); 95 } 96 97 if (isset($GLOBALS['language'])) { 98 if ($GLOBALS['language'] == $lang) { 99 return; 100 } else { 101 $GLOBALS['registry']->clearCache(); 102 } 103 } 104 105 $GLOBALS['language'] = $lang; 106 $_SESSION['horde_language'] = $lang; 107 108 /* First try language with the current charset. */ 109 $lang_charset = $lang . '.' . NLS::getCharset(); 110 if ($lang_charset != setlocale(LC_ALL, $lang_charset)) { 111 /* Next try language with its default charset. */ 112 global $nls; 113 $charset = !empty($nls['charsets'][$lang]) ? $nls['charsets'][$lang] : 'ISO-8859-1'; 114 $lang_charset = $lang . '.' . $charset; 115 NLS::_cachedCharset(0, $charset); 116 if ($lang_charset != setlocale(LC_ALL, $lang_charset)) { 117 /* At last try language solely. */ 118 $lang_charset = $lang; 119 setlocale(LC_ALL, $lang_charset); 120 } 121 } 122 @putenv('LANG=' . $lang_charset); 123 @putenv('LANGUAGE=' . $lang_charset); 124 } 125 126 /** 127 * Sets the gettext domain. 128 * 129 * @param string $app The application name. 130 * @param string $directory The directory where the application's 131 * LC_MESSAGES directory resides. 132 * @param string $charset The charset. 133 */ 134 function setTextdomain($app, $directory, $charset) 135 { 136 bindtextdomain($app, $directory); 137 textdomain($app); 138 139 /* The existence of this function depends on the platform. */ 140 if (function_exists('bind_textdomain_codeset')) { 141 NLS::_cachedCharset(0, bind_textdomain_codeset($app, $charset)); 142 } 143 144 if (!headers_sent()) { 145 header('Content-Type: text/html; charset=' . $charset); 146 } 147 } 148 149 /** 150 * Determines whether the supplied language is valid. 151 * 152 * @param string $language The abbreviated name of the language. 153 * 154 * @return boolean True if the language is valid, false if it's not 155 * valid or unknown. 156 */ 157 function isValid($language) 158 { 159 return !empty($GLOBALS['nls']['languages'][$language]); 160 } 161 162 /** 163 * Maps languages with common two-letter codes (such as nl) to the 164 * full gettext code (in this case, nl_NL). Returns the language 165 * unmodified if it isn't an alias. 166 * 167 * @access private 168 * 169 * @param string $language The language code to map. 170 * 171 * @return string The mapped language code. 172 */ 173 174 function _map($language) 175 { 176 require_once 'Horde/String.php'; 177 178 $aliases = &$GLOBALS['nls']['aliases']; 179 180 // Translate the $language to get broader matches. 181 // (eg. de-DE should match de_DE) 182 $trans_lang = str_replace('-', '_', $language); 183 $lang_parts = explode('_', $trans_lang); 184 $trans_lang = String::lower($lang_parts[0]); 185 if (isset($lang_parts[1])) { 186 $trans_lang .= '_' . String::upper($lang_parts[1]); 187 } 188 189 // See if we get a match for this 190 if (!empty($aliases[$trans_lang])) { 191 return $aliases[$trans_lang]; 192 } 193 194 // If we get that far down, the language cannot be found. 195 // Return $trans_lang. 196 return $trans_lang; 197 } 198 199 /** 200 * Returns the charset for the current language. 201 * 202 * @param boolean $original If true returns the original charset of the 203 * translation, the actually used one otherwise. 204 * 205 * @return string The character set that should be used with the current 206 * locale settings. 207 */ 208 function getCharset($original = false) 209 { 210 global $language, $nls; 211 212 /* Get cached results. */ 213 $cacheKey = intval($original); 214 $charset = NLS::_cachedCharset($cacheKey); 215 if (!is_null($charset)) { 216 return $charset; 217 } 218 219 if ($original) { 220 $charset = empty($nls['charsets'][$language]) ? 'ISO-8859-1' : $nls['charsets'][$language]; 221 } else { 222 require_once 'Horde/Browser.php'; 223 $browser = &Browser::singleton(); 224 225 if ($browser->hasFeature('utf') && 226 (Util::extensionExists('iconv') || 227 Util::extensionExists('mbstring'))) { 228 $charset = 'UTF-8'; 229 } 230 } 231 232 if (is_null($charset)) { 233 $charset = NLS::getExternalCharset(); 234 } 235 236 NLS::_cachedCharset($cacheKey, $charset); 237 return $charset; 238 } 239 240 241 /** 242 * Returns the current charset of the environment 243 * 244 * @return string The character set that should be used with the current 245 * locale settings. 246 */ 247 function getExternalCharset() 248 { 249 global $language, $nls; 250 251 /* Get cached results. */ 252 $charset = NLS::_cachedCharset(2); 253 if (!is_null($charset)) { 254 return $charset; 255 } 256 257 $lang_charset = setlocale(LC_ALL, 0); 258 if (strpos($lang_charset, ';') === false && 259 strpos($lang_charset, '/') === false) { 260 $lang_charset = explode('.', $lang_charset); 261 if ((count($lang_charset) == 2) && !empty($lang_charset[1])) { 262 NLS::_cachedCharset(2, $lang_charset[1]); 263 return $lang_charset[1]; 264 } 265 } 266 267 return (!empty($nls['charsets'][$language])) ? $nls['charsets'][$language] : 'ISO-8859-1'; 268 } 269 270 /** 271 * Sets or returns the charset used under certain conditions. 272 * 273 * @access private 274 * 275 * @param integer $index The ID of a cache slot. 0 for the UI charset, 1 276 * for the translation charset and 2 for the 277 * external charset. 278 * @param string $charset If specified, this charset will be stored in the 279 * given cache slot. Otherwise the content of the 280 * specified cache slot will be returned. 281 */ 282 function _cachedCharset($index, $charset = null) 283 { 284 static $cache; 285 286 if (!isset($cache)) { 287 $cache = array(); 288 } 289 290 if ($charset == null) { 291 return isset($cache[$index]) ? $cache[$index] : null; 292 } else { 293 $cache[$index] = $charset; 294 } 295 } 296 297 /** 298 * Returns the charset to use for outgoing emails. 299 * 300 * @return string The preferred charset for outgoing mails based on 301 * the user's preferences and the current language. 302 */ 303 function getEmailCharset() 304 { 305 global $prefs, $language, $nls; 306 307 $charset = $prefs->getValue('sending_charset'); 308 if (!empty($charset)) { 309 return $charset; 310 } 311 return isset($nls['emails'][$language]) ? $nls['emails'][$language] : 312 (isset($nls['charsets'][$language]) ? $nls['charsets'][$language] : 'ISO-8859-1'); 313 } 314 315 /** 316 * Check to see if character set is valid for htmlspecialchars() calls. 317 * 318 * @param string $charset The character set to check. 319 * 320 * @return boolean Is charset valid for the current system? 321 */ 322 function checkCharset($charset) 323 { 324 static $check; 325 326 if (is_null($charset) || empty($charset)) { 327 return false; 328 } 329 330 if (isset($check[$charset])) { 331 return $check[$charset]; 332 } elseif (!isset($check)) { 333 $check = array(); 334 } 335 336 $valid = true; 337 338 ini_set('track_errors', 1); 339 @htmlspecialchars('', ENT_COMPAT, $charset); 340 if (isset($php_errormsg)) { 341 $valid = false; 342 } 343 ini_restore('track_errors'); 344 345 $check[$charset] = $valid; 346 347 return $valid; 348 } 349 350 /** 351 * Sets the charset. 352 * In general, the applied charset is automatically determined by browser 353 * language and browser capabilities and there's no need to manually call 354 * setCharset. However for headless (RPC) operations the charset may be 355 * set manually to ensure correct character conversion in the backend. 356 * 357 * @param string $charset If specified, this charset will be stored in the 358 * given cache slot. 359 * 360 * @param integer $index The ID of a cache slot. 0 for the UI charset, 1 361 * for the translation charset and 2 for the 362 * external charset. Defaults to 0: this is the 363 * charset returned by getCharset and used for 364 * conversion. 365 */ 366 367 function setCharset($charset,$index = 0) 368 { 369 NLS::_cachedCharset($index, $charset); 370 } 371 372 /** 373 * Sets the current timezone, if available. 374 */ 375 function setTimeZone() 376 { 377 global $prefs; 378 379 $tz = $prefs->getValue('timezone'); 380 if (!empty($tz)) { 381 @putenv('TZ=' . $tz); 382 } 383 } 384 385 /** 386 * Get the locale info returned by localeconv(), but cache it, to 387 * avoid repeated calls. 388 * 389 * @return array The results of localeconv(). 390 */ 391 function getLocaleInfo() 392 { 393 static $lc_info; 394 395 if (!isset($lc_info)) { 396 $lc_info = localeconv(); 397 } 398 399 return $lc_info; 400 } 401 402 /** 403 * Get the language info returned by nl_langinfo(), but cache it, to 404 * avoid repeated calls. 405 * 406 * @since Horde 3.1 407 * 408 * @param const $item The langinfo item to return. 409 * 410 * @return array The results of nl_langinfo(). 411 */ 412 function getLangInfo($item) 413 { 414 static $nl_info = array(); 415 416 if (!isset($nl_info[$item])) { 417 $nl_info[$item] = nl_langinfo($item); 418 } 419 420 return $nl_info[$item]; 421 } 422 423 /** 424 * Get country information from a hostname or IP address. 425 * 426 * @param string $host The hostname or IP address. 427 * 428 * @return mixed On success, return an array with the following entries: 429 * 'code' => Country Code 430 * 'name' => Country Name 431 * On failure, return false. 432 */ 433 function getCountryByHost($host) 434 { 435 global $conf; 436 437 /* List of generic domains that we know is not in the country TLD 438 list. See: http://www.iana.org/gtld/gtld.htm */ 439 $generic = array( 440 'aero', 'biz', 'com', 'coop', 'edu', 'gov', 'info', 'int', 'mil', 441 'museum', 'name', 'net', 'org', 'pro' 442 ); 443 444 $checkHost = $host; 445 if (preg_match('/^\d+\.\d+\.\d+\.\d+$/', $host)) { 446 $checkHost = @gethostbyaddr($host); 447 } 448 449 /* Get the TLD of the hostname. */ 450 $pos = strrpos($checkHost, '.'); 451 if ($pos === false) { 452 return false; 453 } 454 $domain = String::lower(substr($checkHost, $pos + 1)); 455 456 /* Try lookup via TLD first. */ 457 if (!in_array($domain, $generic)) { 458 require 'Horde/NLS/tld.php'; 459 if (isset($tld[$domain])) { 460 return array('code' => $domain, 'name' => $tld[$domain]); 461 } 462 } 463 464 /* Try GeoIP lookup next. */ 465 if (!empty($conf['geoip']['datafile'])) { 466 require_once 'Horde/NLS/GeoIP.php'; 467 $geoip = &NLS_GeoIP::singleton($conf['geoip']['datafile']); 468 $id = $geoip->countryIdByName($checkHost); 469 if (!empty($id)) { 470 return array('code' => String::lower($GLOBALS['GEOIP_COUNTRY_CODES'][$id]), 'name' => $GLOBALS['GEOIP_COUNTRY_NAMES'][$id]); 471 } 472 } 473 474 return false; 475 } 476 477 /** 478 * Returns a Horde image link to the country flag. 479 * 480 * @param string $host The hostname or IP address. 481 * 482 * @return string The image URL, or the empty string on error. 483 */ 484 function generateFlagImageByHost($host) 485 { 486 global $registry; 487 488 $data = NLS::getCountryByHost($host); 489 if ($data !== false) { 490 $img = $data['code'] . '.png'; 491 if (file_exists($registry->get('themesfs', 'horde') . '/graphics/flags/' . $img)) { 492 return Horde::img($img, $data['name'], array('title' => $data['name']), $registry->getImageDir('horde') . '/flags'); 493 } else { 494 return '[' . $data['name'] . ']'; 495 } 496 } 497 498 return ''; 499 } 500 501 /** 502 * Returns either a specific or all ISO-3166 country names. 503 * 504 * @param string $code The ISO 3166 country code. 505 * 506 * @return mixed If a country code has been requested will return the 507 * corresponding country name. If empty will return an 508 * array of all the country codes and their names. 509 */ 510 function &getCountryISO($code = '') 511 { 512 static $countries = array(); 513 if (empty($countries)) { 514 require_once 'Horde/NLS/countries.php'; 515 } 516 if (empty($code)) { 517 return $countries; 518 } elseif (isset($countries[$code])) { 519 return $countries[$code]; 520 } 521 return false; 522 } 523 524 }
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Sun Feb 25 18:01:28 2007 | par Balluche grâce à PHPXref 0.7 |