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