[ Index ]
 

Code source de Symfony 1.0.0

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/lib/i18n/ -> sfCultureInfo.class.php (source)

   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  }


Généré le : Fri Mar 16 22:42:14 2007 par Balluche grâce à PHPXref 0.7