Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 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 32741 2011-07-09 09:41:59Z 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    symfony
50
 * @subpackage i18n
51
 */
52
class sfCultureInfo
53
{
54
  /**
55
   * ICU data filename extension.
56
   * @var string
57
   */
58
  protected $dataFileExt = '.dat';
59
 
60
  /**
61
   * The ICU data array.
62
   * @var array
63
   */
64
  protected $data = array();
65
 
66
  /**
67
   * The current culture.
68
   * @var string
69
   */
70
  protected $culture;
71
 
72
  /**
73
   * Directory where the ICU data is stored.
74
   * @var string
75
   */
76
  protected $dataDir;
77
 
78
  /**
79
   * A list of ICU date files loaded.
80
   * @var array
81
   */
82
  protected $dataFiles = array();
83
 
84
  /**
85
   * The current date time format info.
86
   * @var sfDateTimeFormatInfo
87
   */
88
  protected $dateTimeFormat;
89
 
90
  /**
91
   * The current number format info.
92
   * @var sfNumberFormatInfo
93
   */
94
  protected $numberFormat;
95
 
96
  /**
97
   * A list of properties that are accessable/writable.
98
   * @var array
99
   */
100
  protected $properties = array();
101
 
102
  /**
103
   * Culture type, all.
104
   * @see getCultures()
105
   * @var int
106
   */
107
  const ALL = 0;
108
 
109
  /**
110
   * Culture type, neutral.
111
   * @see getCultures()
112
   * @var int
113
   */
114
  const NEUTRAL = 1;
115
 
116
  /**
117
   * Culture type, specific.
118
   *
119
   * @see getCultures()
120
   * @var int
121
   */
122
  const SPECIFIC = 2;
123
 
124
  /**
125
   * Gets the sfCultureInfo that for this culture string.
126
   *
127
   * @param string  $culture The culture for this instance
128
   * @return sfCultureInfo Invariant culture info is "en"
129
   */
130
  public static function getInstance($culture = 'en')
131
  {
132
    static $instances = array();
133
 
134
    if (!isset($instances[$culture]))
135
    {
136
      $instances[$culture] = new sfCultureInfo($culture);
137
    }
138
 
139
    return $instances[$culture];
140
  }
141
 
142
  /**
143
   * Displays the culture name.
144
   *
145
   * @return string the culture name.
146
   * @see getName()
147
   */
148
  public function __toString()
149
  {
150
    return $this->getName();
151
  }
152
 
153
  /**
154
   * Allows functions that begins with 'set' to be called directly
155
   * as an attribute/property to retrieve the value.
156
   *
157
   * @param string $name The property to get
158
   * @return mixed
159
   */
160
  public function __get($name)
161
  {
162
    $getProperty = 'get'.$name;
163
    if (in_array($getProperty, $this->properties))
164
    {
165
      return $this->$getProperty();
166
    }
167
    else
168
    {
169
      throw new sfException(sprintf('Property %s does not exists.', $name));
170
    }
171
  }
172
 
173
  /**
174
   * Allows functions that begins with 'set' to be called directly
175
   * as an attribute/property to set the value.
176
   *
177
   * @param string $name  The property to set
178
   * @param string $value The property value
179
   */
180
  public function __set($name, $value)
181
  {
182
    $setProperty = 'set'.$name;
183
    if (in_array($setProperty, $this->properties))
184
    {
185
      $this->$setProperty($value);
186
    }
187
    else
188
    {
189
      throw new sfException(sprintf('Property %s can not be set.', $name));
190
    }
191
  }
192
 
193
  /**
194
   * Initializes a new instance of the sfCultureInfo class based on the
195
   * culture specified by name. E.g. <code>new sfCultureInfo('en_AU');</code>
196
   * The culture indentifier must be of the form
197
   * "<language>_(country/region/variant)".
198
   *
199
   * @param string $culture a culture name, e.g. "en_AU".
200
   * @return return new sfCultureInfo.
201
   */
202
  public function __construct($culture = 'en')
203
  {
204
    $this->properties = get_class_methods($this);
205
 
206
    if (empty($culture))
207
    {
208
      $culture = 'en';
209
    }
210
 
211
    $this->dataDir = self::dataDir();
212
    $this->dataFileExt = self::fileExt();
213
 
214
    $this->setCulture($culture);
215
 
216
    $this->loadCultureData('root');
217
    $this->loadCultureData($culture);
218
  }
219
 
220
  /**
221
   * Gets the default directory for the ICU data.
222
   * The default is the "data" directory for this class.
223
   *
224
   * @return string directory containing the ICU data.
225
   */
226
  protected static function dataDir()
227
  {
228
    return dirname(__FILE__).'/data/';
229
  }
230
 
231
  /**
232
   * Gets the filename extension for ICU data. Default is ".dat".
233
   *
234
   * @return string filename extension for ICU data.
235
   */
236
  protected static function fileExt()
237
  {
238
    return '.dat';
239
  }
240
 
241
  /**
242
   * Determines if a given culture is valid. Simply checks that the
243
   * culture data exists.
244
   *
245
   * @param string $culture a culture
246
   * @return boolean true if valid, false otherwise.
247
   */
248
  static public function validCulture($culture)
249
  {
250
    if (preg_match('/^[a-z]{2}(_[A-Z]{2,5}){0,2}$/', $culture))
251
    {
252
      return is_file(self::dataDir().$culture.self::fileExt());
253
    }
254
 
255
    return false;
256
  }
257
 
258
  /**
259
   * Sets the culture for the current instance. The culture indentifier
260
   * must be of the form "<language>_(country/region)".
261
   *
262
   * @param string $culture culture identifier, e.g. "fr_FR_EURO".
263
   */
264
  protected function setCulture($culture)
265
  {
266
    if (!empty($culture))
267
    {
268
      if (!preg_match('/^[a-z]{2}(_[A-Z]{2,5}){0,2}$/', $culture))
269
      {
270
        throw new sfException(sprintf('Invalid culture supplied: %s', $culture));
271
      }
272
    }
273
 
274
    $this->culture = $culture;
275
  }
276
 
277
  /**
278
   * Loads the ICU culture data for the specific culture identifier.
279
   *
280
   * @param string $culture the culture identifier.
281
   */
282
  protected function loadCultureData($culture)
283
  {
284
    $file_parts = explode('_', $culture);
285
    $current_part = $file_parts[0];
286
 
287
    $files = array($current_part);
288
 
289
    for ($i = 1, $max = count($file_parts); $i < $max; $i++)
290
    {
291
      $current_part .= '_'.$file_parts[$i];
292
      $files[] = $current_part;
293
    }
294
 
295
    foreach ($files as $file)
296
    {
297
      $filename = $this->dataDir.$file.$this->dataFileExt;
298
 
299
      if (is_file($filename) == false)
300
      {
301
        throw new sfException(sprintf('Data file for "%s" was not found.', $file));
302
      }
303
 
304
      if (in_array($filename, $this->dataFiles) == false)
305
      {
306
        array_unshift($this->dataFiles, $file);
307
 
308
        $data = &$this->getData($filename);
309
        $this->data[$file] = &$data;
310
 
311
        if (isset($data['__ALIAS']))
312
        {
313
          $this->loadCultureData($data['__ALIAS']);
314
        }
315
        unset($data);
316
      }
317
    }
318
  }
319
 
320
  /**
321
   * Gets the data by unserializing the ICU data from disk.
322
   * The data files are cached in a static variable inside
323
   * this function.
324
   *
325
   * @param string $filename the ICU data filename
326
   * @return array ICU data
327
   */
328
  protected function &getData($filename)
329
  {
330
    static $data  = array();
331
    static $files = array();
332
 
333
    if (!in_array($filename, $files))
334
    {
335
      $data[$filename] = unserialize(file_get_contents($filename));
336
      $files[] = $filename;
337
    }
338
 
339
    return $data[$filename];
340
  }
341
 
342
  /**
343
   * Finds the specific ICU data information from the data.
344
   * The path to the specific ICU data is separated with a slash "/".
345
   * E.g. To find the default calendar used by the culture, the path
346
   * "calendar/default" will return the corresponding default calendar.
347
   * Use merge=true to return the ICU including the parent culture.
348
   * E.g. The currency data for a variant, say "en_AU" contains one
349
   * entry, the currency for AUD, the other currency data are stored
350
   * in the "en" data file. Thus to retrieve all the data regarding
351
   * currency for "en_AU", you need to use findInfo("Currencies,true);.
352
   *
353
   * @param string  $path   the data you want to find.
354
   * @param boolean $merge  merge the data from its parents.
355
   * @return mixed the specific ICU data.
356
   */
357
  protected function findInfo($path = '/', $merge = false)
358
  {
359
    $result = array();
360
    foreach ($this->dataFiles as $section)
361
    {
362
      $info = $this->searchArray($this->data[$section], $path);
363
 
364
      if ($info)
365
      {
366
        if ($merge)
367
        {
368
          $result = $this->array_add($result, $info);
369
        }
370
        else
371
        {
372
          return $info;
373
        }
374
      }
375
    }
376
 
377
    return $result;
378
  }
379
 
380
  /**
381
   * Adds an array to an already existing array.
382
   * If an element is already existing in array1 it is not overwritten.
383
   * If this element is an array this logic will be applied recursively.
384
   */
385
  private function array_add($array1, $array2)
386
  {
387
    foreach ($array2 as $key => $value)
388
    {
389
      if (isset($array1[$key]))
390
      {
391
        if(is_array($array1[$key]) && is_array($value))
392
        {
393
          $array1[$key] = $this->array_add($array1[$key], $value);
394
        }
395
      }
396
      else
397
      {
398
        $array1[$key] = $value;
399
      }
400
    }
401
    return $array1;
402
  }
403
 
404
  /**
405
   * Searches the array for a specific value using a path separated using
406
   * slash "/" separated path. e.g to find $info['hello']['world'],
407
   * the path "hello/world" will return the corresponding value.
408
   *
409
   * @param array   $info  the array for search
410
   * @param string  $path  slash "/" separated array path.
411
   * @return mixed the value array using the path
412
   */
413
  protected function searchArray($info, $path = '/')
414
  {
415
    $index = explode('/', $path);
416
 
417
    $array = $info;
418
 
419
    for ($i = 0, $max = count($index); $i < $max; $i++)
420
    {
421
      $k = $index[$i];
422
      if ($i < $max - 1 && isset($array[$k]))
423
      {
424
        $array = $array[$k];
425
      }
426
      else if ($i == $max - 1 && isset($array[$k]))
427
      {
428
        return $array[$k];
429
      }
430
    }
431
  }
432
 
433
  /**
434
   * Gets the culture name in the format
435
   * "<languagecode2>_(country/regioncode2)".
436
   *
437
   * @return string culture name.
438
   */
439
  public function getName()
440
  {
441
    return $this->culture;
442
  }
443
 
444
  /**
445
   * Gets the sfDateTimeFormatInfo that defines the culturally appropriate
446
   * format of displaying dates and times.
447
   *
448
   * @return sfDateTimeFormatInfo date time format information for the culture.
449
   */
450
  public function getDateTimeFormat()
451
  {
452
    if (null === $this->dateTimeFormat)
453
    {
454
      $calendar = $this->getCalendar();
455
      $info = $this->findInfo("calendar/{$calendar}", true);
456
      $this->setDateTimeFormat(new sfDateTimeFormatInfo($info));
457
    }
458
 
459
    return $this->dateTimeFormat;
460
  }
461
 
462
  /**
463
   * Sets the date time format information.
464
   *
465
   * @param sfDateTimeFormatInfo $dateTimeFormat the new date time format info.
466
   */
467
  public function setDateTimeFormat($dateTimeFormat)
468
  {
469
    $this->dateTimeFormat = $dateTimeFormat;
470
  }
471
 
472
  /**
473
   * Gets the default calendar used by the culture, e.g. "gregorian".
474
   *
475
   * @return string the default calendar.
476
   */
477
  public function getCalendar()
478
  {
479
    return $this->findInfo('calendar/default');
480
  }
481
 
482
  /**
483
   * Gets the culture name in the language that the culture is set
484
   * to display. Returns <code>array('Language','Country');</code>
485
   * 'Country' is omitted if the culture is neutral.
486
   *
487
   * @return array array with language and country as elements, localized.
488
   */
489
  public function getNativeName()
490
  {
491
    $lang = substr($this->culture, 0, 2);
492
    $reg = substr($this->culture, 3, 2);
493
    $language = $this->findInfo("Languages/{$lang}");
494
    $region = $this->findInfo("Countries/{$reg}");
495
    if ($region)
496
    {
497
      return $language.' ('.$region.')';
498
    }
499
    else
500
    {
501
      return $language;
502
    }
503
  }
504
 
505
  /**
506
   * Gets the culture name in English.
507
   * Returns <code>array('Language','Country');</code>
508
   * 'Country' is omitted if the culture is neutral.
509
   *
510
   * @return array array with language and country as elements.
511
   */
512
  public function getEnglishName()
513
  {
514
    $lang = substr($this->culture, 0, 2);
515
    $reg = substr($this->culture, 3, 2);
516
    $culture = $this->getInvariantCulture();
517
 
518
    $language = $culture->findInfo("Languages/{$lang}");
519
    if (count($language) == 0)
520
    {
521
      return $this->culture;
522
    }
523
 
524
    $region = $culture->findInfo("Countries/{$reg}");
525
 
526
    return $region ? $language.' ('.$region.')' : $language;
527
  }
528
 
529
  /**
530
   * Gets the sfCultureInfo that is culture-independent (invariant).
531
   * Any changes to the invariant culture affects all other
532
   * instances of the invariant culture.
533
   * The invariant culture is assumed to be "en";
534
   *
535
   * @return sfCultureInfo invariant culture info is "en".
536
   */
537
  static function getInvariantCulture()
538
  {
539
    static $invariant;
540
 
541
    if (null === $invariant)
542
    {
543
      $invariant = new sfCultureInfo();
544
    }
545
 
546
    return $invariant;
547
  }
548
 
549
  /**
550
   * Gets a value indicating whether the current sfCultureInfo
551
   * represents a neutral culture. Returns true if the culture
552
   * only contains two characters.
553
   *
554
   * @return boolean true if culture is neutral, false otherwise.
555
   */
556
  public function getIsNeutralCulture()
557
  {
558
    return strlen($this->culture) == 2;
559
  }
560
 
561
  /**
562
   * Gets the sfNumberFormatInfo that defines the culturally appropriate
563
   * format of displaying numbers, currency, and percentage.
564
   *
565
   * @return sfNumberFormatInfo the number format info for current culture.
566
   */
567
  public function getNumberFormat()
568
  {
569
    if (null === $this->numberFormat)
570
    {
571
      $elements = $this->findInfo('NumberElements');
572
      $patterns = $this->findInfo('NumberPatterns');
573
      $currencies = $this->getCurrencies(null, true);
574
      $data = array('NumberElements' => $elements, 'NumberPatterns' => $patterns, 'Currencies' => $currencies);
575
 
576
      $this->setNumberFormat(new sfNumberFormatInfo($data));
577
    }
578
 
579
    return $this->numberFormat;
580
  }
581
 
582
  /**
583
   * Sets the number format information.
584
   *
585
   * @param sfNumberFormatInfo $numberFormat the new number format info.
586
   */
587
  public function setNumberFormat($numberFormat)
588
  {
589
    $this->numberFormat = $numberFormat;
590
  }
591
 
592
  /**
593
   * Gets the sfCultureInfo that represents the parent culture of the
594
   * current sfCultureInfo
595
   *
596
   * @return sfCultureInfo parent culture information.
597
   */
598
  public function getParent()
599
  {
600
    if (strlen($this->culture) == 2)
601
    {
602
      return $this->getInvariantCulture();
603
    }
604
 
605
    return new sfCultureInfo(substr($this->culture, 0, 2));
606
  }
607
 
608
  /**
609
   * Gets the list of supported cultures filtered by the specified
610
   * culture type. This is an EXPENSIVE function, it needs to traverse
611
   * a list of ICU files in the data directory.
612
   * This function can be called statically.
613
   *
614
   * @param int $type culture type, sfCultureInfo::ALL, sfCultureInfo::NEUTRAL
615
   * or sfCultureInfo::SPECIFIC.
616
   * @return array list of culture information available.
617
   */
618
  static function getCultures($type = sfCultureInfo::ALL)
619
  {
620
    $dataDir = sfCultureInfo::dataDir();
621
    $dataExt = sfCultureInfo::fileExt();
622
    $dir = dir($dataDir);
623
 
624
    $neutral = array();
625
    $specific = array();
626
 
627
    while (false !== ($entry = $dir->read()))
628
    {
629
      if (is_file($dataDir.$entry) && substr($entry, -4) == $dataExt && $entry != 'root'.$dataExt)
630
      {
631
        $culture = substr($entry, 0, -4);
632
        if (strlen($culture) == 2)
633
        {
634
          $neutral[] = $culture;
635
        }
636
        else
637
        {
638
          $specific[] = $culture;
639
        }
640
      }
641
    }
642
    $dir->close();
643
 
644
    switch ($type)
645
    {
646
      case sfCultureInfo::ALL:
647
        $all =  array_merge($neutral, $specific);
648
        sort($all);
649
        return $all;
650
        break;
651
      case sfCultureInfo::NEUTRAL:
652
        return $neutral;
653
        break;
654
      case sfCultureInfo::SPECIFIC:
655
        return $specific;
656
        break;
657
    }
658
  }
659
 
660
  /**
661
   * Get the country name in the current culture for the given code.
662
   *
663
   * @param  string $code A valid country code
664
   *
665
   * @return string The country name in the current culture
666
   */
667
  public function getCountry($code)
668
  {
669
    $countries = $this->findInfo('Countries', true);
670
 
671
    if (!isset($countries[$code]))
672
    {
673
      throw new InvalidArgumentException(sprintf('The country %s does not exist.', $code));
674
    }
675
 
676
    return $countries[$code];
677
  }
678
 
679
  /**
680
   * Get the currency name in the current culture for the given code.
681
   *
682
   * @param  string $code A valid currency code
683
   *
684
   * @return string The currency name in the current culture
685
   */
686
  public function getCurrency($code)
687
  {
688
    $currencies = $this->findInfo('Currencies', true);
689
 
690
    if (!isset($currencies[$code]))
691
    {
692
      throw new InvalidArgumentException(sprintf('The currency %s does not exist.', $code));
693
    }
694
 
695
    return $currencies[$code][1];
696
  }
697
 
698
  /**
699
   * Get the language name in the current culture for the given code.
700
   *
701
   * @param  string $code A valid language code
702
   *
703
   * @return string The language name in the current culture
704
   */
705
  public function getLanguage($code)
706
  {
707
    $languages = $this->findInfo('Languages', true);
708
 
709
    if (!isset($languages[$code]))
710
    {
711
      throw new InvalidArgumentException(sprintf('The language %s does not exist.', $code));
712
    }
713
 
714
    return $languages[$code];
715
  }
716
 
717
  /**
718
   * Gets a list of countries in the language of the localized version.
719
   *
720
   * @param  array $countries An array of countries used to restrict the returned array (null by default, which means all countries)
721
   *
722
   * @return array a list of localized country names.
723
   */
724
  public function getCountries($countries = null)
725
  {
726
    // remove integer keys as they do not represent countries
727
    $allCountries = array();
728
    foreach ($this->findInfo('Countries', true) as $key => $value)
729
    {
730
      if (!is_int($key))
731
      {
732
        $allCountries[$key] = $value;
733
      }
734
    }
735
 
736
    // restrict countries to a sub-set
737
    if (null !== $countries)
738
    {
739
      if ($problems = array_diff($countries, array_keys($allCountries)))
740
      {
741
        throw new InvalidArgumentException(sprintf('The following countries do not exist: %s.', implode(', ', $problems)));
742
      }
743
 
744
      $allCountries = array_intersect_key($allCountries, array_flip($countries));
745
    }
746
 
747
    $this->sortArray($allCountries);
748
 
749
    return $allCountries;
750
  }
751
 
752
  /**
753
   * Gets a list of currencies in the language of the localized version.
754
   *
755
   * @param  array   $currencies An array of currencies used to restrict the returned array (null by default, which means all currencies)
756
   * @param  Boolean $full       Whether to return the symbol and the name or not (false by default)
757
   *
758
   * @return array a list of localized currencies.
759
   */
760
  public function getCurrencies($currencies = null, $full = false)
761
  {
762
    $allCurrencies = $this->findInfo('Currencies', true);
763
 
764
    // restrict countries to a sub-set
765
    if (null !== $currencies)
766
    {
767
      if ($problems = array_diff($currencies, array_keys($allCurrencies)))
768
      {
769
        throw new InvalidArgumentException(sprintf('The following currencies do not exist: %s.', implode(', ', $problems)));
770
      }
771
 
772
      $allCurrencies = array_intersect_key($allCurrencies, array_flip($currencies));
773
    }
774
 
775
    if (!$full)
776
    {
777
      foreach ($allCurrencies as $key => $value)
778
      {
779
        $allCurrencies[$key] = $value[1];
780
      }
781
    }
782
 
783
    $this->sortArray($allCurrencies);
784
 
785
    return $allCurrencies;
786
  }
787
 
788
  /**
789
   * Gets a list of languages in the language of the localized version.
790
   *
791
   * @param  array $languages An array of languages used to restrict the returned array (null by default, which means all languages)
792
   *
793
   * @return array list of localized language names.
794
   */
795
  public function getLanguages($languages = null)
796
  {
797
    $allLanguages = $this->findInfo('Languages', true);
798
 
799
    // restrict languages to a sub-set
800
    if (null !== $languages)
801
    {
802
      if ($problems = array_diff($languages, array_keys($allLanguages)))
803
      {
804
        throw new InvalidArgumentException(sprintf('The following languages do not exist: %s.', implode(', ', $problems)));
805
      }
806
 
807
      $allLanguages = array_intersect_key($allLanguages, array_flip($languages));
808
    }
809
 
810
    $this->sortArray($allLanguages);
811
 
812
    return $allLanguages;
813
  }
814
 
815
  /**
816
   * Gets a list of scripts in the language of the localized version.
817
   *
818
   * @return array list of localized script names.
819
   */
820
  public function getScripts()
821
  {
822
    return $this->findInfo('Scripts', true);
823
  }
824
 
825
  /**
826
   * Gets a list of timezones in the language of the localized version.
827
   *
828
   * @return array list of localized timezones.
829
   */
830
  public function getTimeZones()
831
  {
832
    //new format since ICU 3.8
833
    //zoneStrings contains metaTimezones
834
    $metadata = $this->findInfo('zoneStrings', true);
835
    //TimeZones contains the Timezone name => metaTimezone identifier
836
    $timeZones = $this->findInfo('TimeZones', true);
837
    foreach ($timeZones as $key => $value)
838
    {
839
      $timeZones[$key] = $metadata['meta:'.$value];
840
      $timeZones[$key]['identifier'] = $key;
841
      $timeZones[$key]['city'] = str_replace('_', ' ', substr($key, strpos($key, '/') + 1));
842
    }
843
    return $timeZones;
844
  }
845
 
846
  /**
847
   * sorts the passed array according to the locale of this sfCultureInfo class
848
   *
849
   * @param  array the array to pe sorted wiht "asort" and this locale
850
   */
851
  public function sortArray(&$array)
852
  {
853
    $oldLocale = setlocale(LC_COLLATE, 0);
854
    setlocale(LC_COLLATE, $this->getName());
855
    asort($array, SORT_LOCALE_STRING);
856
    setlocale(LC_COLLATE, $oldLocale);
857
  }
858
}