| [ Index ] |
|
Code source de PRADO 3.0.6 |
1 <?php 2 3 /** 4 * CultureInfo class file. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the BSD License. 8 * 9 * Copyright(c) 2004 by Qiang Xue. All rights reserved. 10 * 11 * To contact the author write to {@link mailto:qiang.xue@gmail.com Qiang Xue} 12 * The latest version of PRADO can be obtained from: 13 * {@link http://prado.sourceforge.net/} 14 * 15 * @author Wei Zhuo <weizhuo[at]gmail[dot]com> 16 * @version $Id: CultureInfo.php 1397 2006-09-07 07:55:53Z wei $ 17 * @package System.I18N.core 18 */ 19 20 /** 21 * CultureInfo class. 22 * 23 * Represents information about a specific culture including the 24 * names of the culture, the calendar used, as well as access to 25 * culture-specific objects that provide methods for common operations, 26 * such as formatting dates, numbers, and currency. 27 * 28 * The CultureInfo class holds culture-specific information, such as the 29 * associated language, sublanguage, country/region, calendar, and cultural 30 * conventions. This class also provides access to culture-specific 31 * instances of DateTimeFormatInfo and NumberFormatInfo. These objects 32 * contain the information required for culture-specific operations, 33 * such as formatting dates, numbers and currency. 34 * 35 * The culture names follow the format "<languagecode>_<country/regioncode>", 36 * where <languagecode> is a lowercase two-letter code derived from ISO 639 37 * codes. You can find a full list of the ISO-639 codes at 38 * http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt 39 * 40 * The <country/regioncode2> is an uppercase two-letter code derived from 41 * ISO 3166. A copy of ISO-3166 can be found at 42 * http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html 43 * 44 * For example, Australian English is "en_AU". 45 * 46 * @author Xiang Wei Zhuo <weizhuo[at]gmail[dot]com> 47 * @version $Id: CultureInfo.php 1397 2006-09-07 07:55:53Z wei $ 48 * @package System.I18N.core 49 */ 50 class CultureInfo 51 { 52 /** 53 * ICU data filename extension. 54 * @var string 55 */ 56 private $dataFileExt = '.dat'; 57 58 /** 59 * The ICU data array. 60 * @var array 61 */ 62 private $data = array(); 63 64 /** 65 * The current culture. 66 * @var string 67 */ 68 private $culture; 69 70 /** 71 * Directory where the ICU data is stored. 72 * @var string 73 */ 74 private $dataDir; 75 76 /** 77 * A list of ICU date files loaded. 78 * @var array 79 */ 80 private $dataFiles = array(); 81 82 /** 83 * The current date time format info. 84 * @var DateTimeFormatInfo 85 */ 86 private $dateTimeFormat; 87 88 /** 89 * The current number format info. 90 * @var NumberFormatInfo 91 */ 92 private $numberFormat; 93 94 /** 95 * A list of properties that are accessable/writable. 96 * @var array 97 */ 98 protected $properties = array(); 99 100 /** 101 * Culture type, all. 102 * @see getCultures() 103 * @var int 104 */ 105 const ALL = 0; 106 107 /** 108 * Culture type, neutral. 109 * @see getCultures() 110 * @var int 111 */ 112 const NEUTRAL = 1; 113 114 /** 115 * Culture type, specific. 116 * @see getCultures() 117 * @var int 118 */ 119 const SPECIFIC = 2; 120 121 /** 122 * Display the culture name. 123 * @return string the culture name. 124 * @see getName() 125 */ 126 function __toString() 127 { 128 return $this->getName(); 129 } 130 131 132 /** 133 * Allow functions that begins with 'set' to be called directly 134 * as an attribute/property to retrieve the value. 135 * @return mixed 136 */ 137 function __get($name) 138 { 139 $getProperty = 'get'.$name; 140 if(in_array($getProperty, $this->properties)) 141 return $this->$getProperty(); 142 else 143 throw new Exception('Property '.$name.' does not exists.'); 144 } 145 146 /** 147 * Allow functions that begins with 'set' to be called directly 148 * as an attribute/property to set the value. 149 */ 150 function __set($name, $value) 151 { 152 $setProperty = 'set'.$name; 153 if(in_array($setProperty, $this->properties)) 154 $this->$setProperty($value); 155 else 156 throw new Exception('Property '.$name.' can not be set.'); 157 } 158 159 160 /** 161 * Initializes a new instance of the CultureInfo class based on the 162 * culture specified by name. E.g. <code>new CultureInfo('en_AU');</cdoe> 163 * The culture indentifier must be of the form 164 * "language_(country/region/variant)". 165 * @param string a culture name, e.g. "en_AU". 166 * @return return new CultureInfo. 167 */ 168 function __construct($culture='en') 169 { 170 $this->properties = get_class_methods($this); 171 172 if(empty($culture)) 173 $culture = 'en'; 174 175 $this->dataDir = $this->dataDir(); 176 $this->dataFileExt = $this->fileExt(); 177 178 $this->setCulture($culture); 179 180 $this->loadCultureData('root'); 181 $this->loadCultureData($culture); 182 } 183 184 /** 185 * Get the default directory for the ICU data. 186 * The default is the "data" directory for this class. 187 * @return string directory containing the ICU data. 188 */ 189 protected static function dataDir() 190 { 191 return dirname(__FILE__).'/data/'; 192 } 193 194 /** 195 * Get the filename extension for ICU data. Default is ".dat". 196 * @return string filename extension for ICU data. 197 */ 198 protected static function fileExt() 199 { 200 return '.dat'; 201 } 202 203 /** 204 * Determine if a given culture is valid. Simply checks that the 205 * culture data exists. 206 * @param string a culture 207 * @return boolean true if valid, false otherwise. 208 */ 209 public function validCulture($culture) 210 { 211 if(preg_match('/^[a-z]{2}(_[A-Z]{2,5}){0,2}$/', $culture)) 212 return is_file(self::dataDir().$culture.self::fileExt()); 213 214 return false; 215 } 216 217 /** 218 * Set the culture for the current instance. The culture indentifier 219 * must be of the form "<language>_(country/region)". 220 * @param string culture identifier, e.g. "fr_FR_EURO". 221 */ 222 protected function setCulture($culture) 223 { 224 if(!empty($culture)) 225 { 226 if (!preg_match('/^[a-z]{2}(_[A-Z]{2,5}){0,2}$/', $culture)) 227 throw new Exception('Invalid culture supplied: ' . $culture); 228 } 229 230 $this->culture = $culture; 231 } 232 233 /** 234 * Load the ICU culture data for the specific culture identifier. 235 * @param string the culture identifier. 236 */ 237 protected function loadCultureData($culture) 238 { 239 $file_parts = explode('_',$culture); 240 $current_part = $file_parts[0]; 241 242 $files = array($current_part); 243 244 for($i = 1, $k = count($file_parts); $i < $k; ++$i) 245 { 246 $current_part .= '_'.$file_parts[$i]; 247 $files[] = $current_part; 248 } 249 250 foreach($files as $file) 251 { 252 $filename = $this->dataDir.$file.$this->dataFileExt; 253 254 if(is_file($filename) == false) 255 throw new Exception('Data file for "'.$file.'" was not found.'); 256 257 if(in_array($filename, $this->dataFiles) === false) 258 { 259 array_unshift($this->dataFiles, $file); 260 261 $data = &$this->getData($filename); 262 $this->data[$file] = &$data; 263 264 if(isset($data['__ALIAS'])) 265 $this->loadCultureData($data['__ALIAS'][0]); 266 unset($data); 267 } 268 } 269 } 270 271 /** 272 * Get the data by unserializing the ICU data from disk. 273 * The data files are cached in a static variable inside 274 * this function. 275 * @param string the ICU data filename 276 * @return array ICU data 277 */ 278 protected function &getData($filename) 279 { 280 static $data = array(); 281 static $files = array(); 282 283 if(!in_array($filename, $files)) 284 { 285 $data[$filename] = unserialize(file_get_contents($filename)); 286 $files[] = $filename; 287 } 288 289 return $data[$filename]; 290 } 291 292 /** 293 * Find the specific ICU data information from the data. 294 * The path to the specific ICU data is separated with a slash "/". 295 * E.g. To find the default calendar used by the culture, the path 296 * "calendar/default" will return the corresponding default calendar. 297 * Use merge=true to return the ICU including the parent culture. 298 * E.g. The currency data for a variant, say "en_AU" contains one 299 * entry, the currency for AUD, the other currency data are stored 300 * in the "en" data file. Thus to retrieve all the data regarding 301 * currency for "en_AU", you need to use findInfo("Currencies,true);. 302 * @param string the data you want to find. 303 * @param boolean merge the data from its parents. 304 * @return mixed the specific ICU data. 305 */ 306 protected function findInfo($path='/', $merge=false) 307 { 308 $result = array(); 309 foreach($this->dataFiles as $section) 310 { 311 $info = $this->searchArray($this->data[$section], $path); 312 313 if($info) 314 { 315 if($merge) 316 $result = array_merge($info,$result); 317 else 318 return $info; 319 } 320 } 321 322 return $result; 323 } 324 325 /** 326 * Search the array for a specific value using a path separated using 327 * slash "/" separated path. e.g to find $info['hello']['world'], 328 * the path "hello/world" will return the corresponding value. 329 * @param array the array for search 330 * @param string slash "/" separated array path. 331 * @return mixed the value array using the path 332 */ 333 private function searchArray($info, $path='/') 334 { 335 $index = explode('/',$path); 336 337 $array = $info; 338 339 for($i = 0, $k = count($index); $i < $k; ++$i) 340 { 341 $value = $index[$i]; 342 if($i < $k-1 && isset($array[$value])) 343 $array = $array[$value]; 344 else if ($i == $k-1 && isset($array[$value])) 345 return $array[$value]; 346 } 347 } 348 349 /** 350 * Gets the culture name in the format 351 * "<languagecode2>_(country/regioncode2)". 352 * @return string culture name. 353 */ 354 function getName() 355 { 356 return $this->culture; 357 } 358 359 /** 360 * Gets the DateTimeFormatInfo that defines the culturally appropriate 361 * format of displaying dates and times. 362 * @return DateTimeFormatInfo date time format information for the culture. 363 */ 364 function getDateTimeFormat() 365 { 366 if(is_null($this->dateTimeFormat)) 367 { 368 $calendar = $this->getCalendar(); 369 $info = $this->findInfo("calendar/{$calendar}", true); 370 $this->setDateTimeFormat(new DateTimeFormatInfo($info)); 371 } 372 373 return $this->dateTimeFormat; 374 } 375 376 /** 377 * Set the date time format information. 378 * @param DateTimeFormatInfo the new date time format info. 379 */ 380 function setDateTimeFormat($dateTimeFormat) 381 { 382 $this->dateTimeFormat = $dateTimeFormat; 383 } 384 385 /** 386 * Gets the default calendar used by the culture, e.g. "gregorian". 387 * @return string the default calendar. 388 */ 389 function getCalendar() 390 { 391 $info = $this->findInfo('calendar/default'); 392 return $info[0]; 393 } 394 395 /** 396 * Gets the culture name in the language that the culture is set 397 * to display. Returns <code>array('Language','Country');</code> 398 * 'Country' is omitted if the culture is neutral. 399 * @return array array with language and country as elements, localized. 400 */ 401 function getNativeName() 402 { 403 $lang = substr($this->culture,0,2); 404 $reg = substr($this->culture,3,2); 405 $language = $this->findInfo("Languages/{$lang}"); 406 $region = $this->findInfo("Countries/{$reg}"); 407 if($region) 408 return $language[0].' ('.$region[0].')'; 409 else 410 return $language[0]; 411 } 412 413 /** 414 * Gets the culture name in English. 415 * Returns <code>array('Language','Country');</code> 416 * 'Country' is omitted if the culture is neutral. 417 * @return array array with language and country as elements. 418 */ 419 function getEnglishName() 420 { 421 $lang = substr($this->culture,0,2); 422 $reg = substr($this->culture,3,2); 423 $culture = $this->getInvariantCulture(); 424 425 $language = $culture->findInfo("Languages/{$lang}"); 426 $region = $culture->findInfo("Countries/{$reg}"); 427 if($region) 428 return $language[0].' ('.$region[0].')'; 429 else 430 return $language[0]; 431 } 432 433 /** 434 * Gets the CultureInfo that is culture-independent (invariant). 435 * Any changes to the invariant culture affects all other 436 * instances of the invariant culture. 437 * The invariant culture is assumed to be "en"; 438 * @return CultureInfo invariant culture info is "en". 439 */ 440 static function getInvariantCulture() 441 { 442 static $invariant; 443 if(is_null($invariant)) 444 $invariant = new CultureInfo(); 445 return $invariant; 446 } 447 448 /** 449 * Gets a value indicating whether the current CultureInfo 450 * represents a neutral culture. Returns true if the culture 451 * only contains two characters. 452 * @return boolean true if culture is neutral, false otherwise. 453 */ 454 function getIsNeutralCulture() 455 { 456 return strlen($this->culture) == 2; 457 } 458 459 /** 460 * Gets the NumberFormatInfo that defines the culturally appropriate 461 * format of displaying numbers, currency, and percentage. 462 * @return NumberFormatInfo the number format info for current culture. 463 */ 464 function getNumberFormat() 465 { 466 if(is_null($this->numberFormat)) 467 { 468 $elements = $this->findInfo('NumberElements'); 469 $patterns = $this->findInfo('NumberPatterns'); 470 $currencies = $this->getCurrencies(); 471 $data = array( 'NumberElements'=>$elements, 472 'NumberPatterns'=>$patterns, 473 'Currencies' => $currencies); 474 475 $this->setNumberFormat(new NumberFormatInfo($data)); 476 } 477 return $this->numberFormat; 478 } 479 480 /** 481 * Set the number format information. 482 * @param NumberFormatInfo the new number format info. 483 */ 484 function setNumberFormat($numberFormat) 485 { 486 $this->numberFormat = $numberFormat; 487 } 488 489 /** 490 * Gets the CultureInfo that represents the parent culture of the 491 * current CultureInfo 492 * @return CultureInfo parent culture information. 493 */ 494 function getParent() 495 { 496 if(strlen($this->culture) == 2) 497 return $this->getInvariantCulture(); 498 499 $lang = substr($this->culture,0,2); 500 return new CultureInfo($lang); 501 } 502 503 /** 504 * Gets the list of supported cultures filtered by the specified 505 * culture type. This is an EXPENSIVE function, it needs to traverse 506 * a list of ICU files in the data directory. 507 * This function can be called statically. 508 * @param int culture type, CultureInfo::ALL, CultureInfo::NEUTRAL 509 * or CultureInfo::SPECIFIC. 510 * @return array list of culture information available. 511 */ 512 static function getCultures($type=CultureInfo::ALL) 513 { 514 $dataDir = CultureInfo::dataDir(); 515 $dataExt = CultureInfo::fileExt(); 516 $dir = dir($dataDir); 517 518 $neutral = array(); 519 $specific = array(); 520 521 while (false !== ($entry = $dir->read())) 522 { 523 if(is_file($dataDir.$entry) 524 && substr($entry,-4) == $dataExt 525 && $entry != 'root'.$dataExt) 526 { 527 $culture = substr($entry,0,-4); 528 if(strlen($culture) == 2) 529 $neutral[] = $culture; 530 else 531 $specific[] = $culture; 532 } 533 } 534 $dir->close(); 535 536 switch($type) 537 { 538 case CultureInfo::ALL : 539 $all = array_merge($neutral, $specific); 540 sort($all); 541 return $all; 542 break; 543 case CultureInfo::NEUTRAL : 544 return $neutral; 545 break; 546 case CultureInfo::SPECIFIC : 547 return $specific; 548 break; 549 } 550 } 551 552 /** 553 * Simplify a single element array into its own value. 554 * E.g. <code>array(0 => array('hello'), 1 => 'world');</code> 555 * becomes <code>array(0 => 'hello', 1 => 'world');</code> 556 * @param array with single elements arrays 557 * @return array simplified array. 558 */ 559 private function simplify($array) 560 { 561 for($i = 0, $k = count($array); $i<$k; ++$i) 562 { 563 $key = key($array); 564 if(is_array($array[$key]) 565 && count($array[$key]) == 1) 566 $array[$key] = $array[$key][0]; 567 next($array); 568 } 569 return $array; 570 } 571 572 /** 573 * Get a list of countries in the language of the localized version. 574 * @return array a list of localized country names. 575 */ 576 function getCountries() 577 { 578 return $this->simplify($this->findInfo('Countries',true)); 579 } 580 581 /** 582 * Get a list of currencies in the language of the localized version. 583 * @return array a list of localized currencies. 584 */ 585 function getCurrencies() 586 { 587 return $this->findInfo('Currencies',true); 588 } 589 590 /** 591 * Get a list of languages in the language of the localized version. 592 * @return array list of localized language names. 593 */ 594 function getLanguages() 595 { 596 return $this->simplify($this->findInfo('Languages',true)); 597 } 598 599 /** 600 * Get a list of scripts in the language of the localized version. 601 * @return array list of localized script names. 602 */ 603 function getScripts() 604 { 605 return $this->simplify($this->findInfo('Scripts',true)); 606 } 607 608 /** 609 * Get a list of timezones in the language of the localized version. 610 * @return array list of localized timezones. 611 */ 612 function getTimeZones() 613 { 614 return $this->simplify($this->findInfo('zoneStrings',true)); 615 } 616 } 617 618 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Sun Feb 25 21:07:04 2007 | par Balluche grâce à PHPXref 0.7 |