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