vendor/symfony/src/Symfony/Component/Locale/Resources/data/update-data.php
changeset 0 7f95f8617b0b
equal deleted inserted replaced
-1:000000000000 0:7f95f8617b0b
       
     1 <?php
       
     2 
       
     3 /*
       
     4  * This file is part of the Symfony package.
       
     5  *
       
     6  * (c) Fabien Potencier <fabien@symfony.com>
       
     7  *
       
     8  * For the full copyright and license information, please view the LICENSE
       
     9  * file that was distributed with this source code.
       
    10  */
       
    11 
       
    12 function bailout($message)
       
    13 {
       
    14     exit($message."\n");
       
    15 }
       
    16 
       
    17 function check_dir($source)
       
    18 {
       
    19     if (!file_exists($source)) {
       
    20         bailout('The directory '.$source.' does not exist');
       
    21     }
       
    22 
       
    23     if (!is_dir($source)) {
       
    24         bailout('The file '.$source.' is not a directory');
       
    25     }
       
    26 }
       
    27 
       
    28 function check_command($command)
       
    29 {
       
    30     exec('which '.$command, $output, $result);
       
    31 
       
    32     if ($result !== 0) {
       
    33         bailout('The command "'.$command.'" is not installed');
       
    34     }
       
    35 }
       
    36 
       
    37 function clear_directory($directory)
       
    38 {
       
    39     $iterator = new \DirectoryIterator($directory);
       
    40 
       
    41     foreach ($iterator as $file) {
       
    42         if (!$file->isDot()) {
       
    43             if ($file->isDir()) {
       
    44                 clear_directory($file->getPathname());
       
    45             } else {
       
    46                 unlink($file->getPathname());
       
    47             }
       
    48         }
       
    49     }
       
    50 }
       
    51 
       
    52 function make_directory($directory)
       
    53 {
       
    54     if (!file_exists($directory)) {
       
    55         mkdir($directory);
       
    56     }
       
    57 
       
    58     if (!is_dir($directory)) {
       
    59         bailout('The file '.$directory.' already exists but is no directory');
       
    60     }
       
    61 }
       
    62 
       
    63 function list_files($directory, $extension)
       
    64 {
       
    65     $files = array();
       
    66     $iterator = new \DirectoryIterator($directory);
       
    67 
       
    68     foreach ($iterator as $file) {
       
    69         if (!$file->isDot() && substr($file->getFilename(), -strlen($extension)) === $extension) {
       
    70             $files[] = substr($file->getFilename(), 0, -strlen($extension));
       
    71         }
       
    72     }
       
    73 
       
    74     return $files;
       
    75 }
       
    76 
       
    77 function genrb($source, $target)
       
    78 {
       
    79     exec('genrb -d '.$target.' '.$source.DIRECTORY_SEPARATOR.'*.txt', $output, $result);
       
    80 
       
    81     if ($result !== 0) {
       
    82         bailout('genrb failed');
       
    83     }
       
    84 }
       
    85 
       
    86 function genrb_file($target, $source, $locale)
       
    87 {
       
    88     exec('genrb -v -d '.$target.' '.$source.DIRECTORY_SEPARATOR.$locale.'.txt', $output, $result);
       
    89 
       
    90     if ($result !== 0) {
       
    91         bailout('genrb failed');
       
    92     }
       
    93 }
       
    94 
       
    95 function load_resource_bundle($locale, $directory)
       
    96 {
       
    97     $bundle = \ResourceBundle::create($locale, $directory);
       
    98 
       
    99     if (null === $bundle) {
       
   100         bailout('The resource bundle for locale '.$locale.' could not be loaded from directory '.$directory);
       
   101     }
       
   102 
       
   103     return $bundle;
       
   104 }
       
   105 
       
   106 function get_data($index, $dataDir, $locale = 'en', $constraint = null)
       
   107 {
       
   108     $data = array();
       
   109     $bundle = load_resource_bundle($locale, __DIR__.DIRECTORY_SEPARATOR.$dataDir);
       
   110 
       
   111     foreach ($bundle->get($index) as $code => $name) {
       
   112         if (null !== $constraint) {
       
   113             if ($constraint($code)) {
       
   114                 $data[$code] = $name;
       
   115             }
       
   116             continue;
       
   117         }
       
   118 
       
   119         $data[$code] = $name;
       
   120     }
       
   121 
       
   122     $collator = new \Collator($locale);
       
   123     $collator->asort($data);
       
   124 
       
   125     return $data;
       
   126 }
       
   127 
       
   128 function create_stub_datafile($locale, $target, $data) {
       
   129     $template = <<<TEMPLATE
       
   130 <?php
       
   131 
       
   132 /*
       
   133  * This file is part of the Symfony package.
       
   134  *
       
   135  * (c) Fabien Potencier <fabien@symfony.com>
       
   136  *
       
   137  * For the full copyright and license information, please view the LICENSE
       
   138  * file that was distributed with this source code.
       
   139  */
       
   140 
       
   141 return %s;
       
   142 
       
   143 TEMPLATE;
       
   144 
       
   145     $data = var_export($data, true);
       
   146     $data = preg_replace('/array \(/', 'array(', $data);
       
   147     $data = preg_replace('/\n {1,10}array\(/', 'array(', $data);
       
   148     $data = preg_replace('/  /', '    ', $data);
       
   149     $data = sprintf($template, $data);
       
   150 
       
   151     file_put_contents($target.DIRECTORY_SEPARATOR.$locale.'.php', $data);
       
   152 }
       
   153 
       
   154 if ($GLOBALS['argc'] !== 2) {
       
   155     bailout(<<<MESSAGE
       
   156 Usage: php update-data.php [icu-data-directory]
       
   157 
       
   158 Updates the ICU resources in Symfony2 from the given ICU data directory. You
       
   159 can checkout the ICU data directory via SVN:
       
   160 
       
   161     $ svn co http://source.icu-project.org/repos/icu/icu/trunk/source/data icu-data
       
   162 
       
   163 MESSAGE
       
   164     );
       
   165 }
       
   166 
       
   167 // Verify that all required directories exist
       
   168 $source = $GLOBALS['argv'][1];
       
   169 
       
   170 check_dir($source);
       
   171 
       
   172 $source = realpath($source);
       
   173 
       
   174 check_dir($source.DIRECTORY_SEPARATOR.'curr');
       
   175 check_dir($source.DIRECTORY_SEPARATOR.'lang');
       
   176 check_dir($source.DIRECTORY_SEPARATOR.'locales');
       
   177 check_dir($source.DIRECTORY_SEPARATOR.'region');
       
   178 
       
   179 check_command('genrb');
       
   180 
       
   181 // Convert the *.txt resource bundles to *.res files
       
   182 $target = __DIR__;
       
   183 $currDir = $target.DIRECTORY_SEPARATOR.'curr';
       
   184 $langDir = $target.DIRECTORY_SEPARATOR.'lang';
       
   185 $localesDir = $target.DIRECTORY_SEPARATOR.'locales';
       
   186 $namesDir = $target.DIRECTORY_SEPARATOR.'names';
       
   187 $namesGeneratedDir = $namesDir.DIRECTORY_SEPARATOR.'generated';
       
   188 $regionDir = $target.DIRECTORY_SEPARATOR.'region';
       
   189 
       
   190 make_directory($currDir);
       
   191 clear_directory($currDir);
       
   192 
       
   193 genrb_file($currDir, $source.DIRECTORY_SEPARATOR.'curr', 'en');
       
   194 genrb_file($currDir, $source.DIRECTORY_SEPARATOR.'curr', 'supplementalData');
       
   195 
       
   196 // It seems \ResourceBundle does not like locale names with uppercase chars then we rename the binary file
       
   197 // See: http://bugs.php.net/bug.php?id=54025
       
   198 $filename_from = $currDir.DIRECTORY_SEPARATOR.'supplementalData.res';
       
   199 $filename_to   = $currDir.DIRECTORY_SEPARATOR.'supplementaldata.res';
       
   200 
       
   201 if (!rename($filename_from, $filename_to)) {
       
   202     bailout('The file '.$filename_from.' could not be renamed');
       
   203 }
       
   204 
       
   205 make_directory($langDir);
       
   206 clear_directory($langDir);
       
   207 genrb($source.DIRECTORY_SEPARATOR.'lang', $langDir);
       
   208 
       
   209 make_directory($localesDir);
       
   210 clear_directory($localesDir);
       
   211 genrb($source.DIRECTORY_SEPARATOR.'locales', $localesDir);
       
   212 
       
   213 make_directory($regionDir);
       
   214 clear_directory($regionDir);
       
   215 genrb($source.DIRECTORY_SEPARATOR.'region', $regionDir);
       
   216 
       
   217 make_directory($namesDir);
       
   218 clear_directory($namesDir);
       
   219 
       
   220 make_directory($namesGeneratedDir);
       
   221 clear_directory($namesGeneratedDir);
       
   222 
       
   223 // Discover the list of supported locales, which are the names of the resource
       
   224 // bundles in the "locales" directory
       
   225 $supportedLocales = list_files($localesDir, '.res');
       
   226 
       
   227 sort($supportedLocales);
       
   228 
       
   229 // Delete unneeded locales
       
   230 foreach ($supportedLocales as $key => $supportedLocale) {
       
   231     // Delete all aliases from the list
       
   232     // i.e., "az_AZ" is an alias for "az_Latn_AZ"
       
   233     $localeBundleOrig = file_get_contents($source.DIRECTORY_SEPARATOR.'locales'.DIRECTORY_SEPARATOR.$supportedLocale.'.txt');
       
   234 
       
   235     // The key "%%ALIAS" is not accessible through the \ResourceBundle class
       
   236     if (strpos($localeBundleOrig, '%%ALIAS') !== false) {
       
   237         unset($supportedLocales[$key]);
       
   238     }
       
   239 
       
   240     // Delete locales that have no content (i.e. only "Version" key)
       
   241     $localeBundle = load_resource_bundle($supportedLocale, $localesDir);
       
   242 
       
   243     // There seems to be no other way for identifying all keys in this specific
       
   244     // resource bundle
       
   245     $bundleKeys = array();
       
   246 
       
   247     foreach ($localeBundle as $bundleKey => $_) {
       
   248         $bundleKeys[] = $bundleKey;
       
   249     }
       
   250 
       
   251     if ($bundleKeys === array('Version')) {
       
   252         unset($supportedLocales[$key]);
       
   253     }
       
   254 }
       
   255 
       
   256 // Discover the list of locales for which individual language/region names
       
   257 // exist. This list contains for example "de" and "de_CH", but not "de_DE" which
       
   258 // is equal to "de"
       
   259 $translatedLocales = array_unique(array_merge(
       
   260     list_files($langDir, '.res'),
       
   261     list_files($regionDir, '.res')
       
   262 ));
       
   263 
       
   264 sort($translatedLocales);
       
   265 
       
   266 // For each translated locale, generate a list of locale names
       
   267 // Each locale name has the form: "Language (Script, Region, Variant1, ...)
       
   268 // Script, Region and Variants are optional. If none of them is available,
       
   269 // the braces are not printed.
       
   270 foreach ($translatedLocales as $translatedLocale) {
       
   271     // Don't include ICU's root resource bundle
       
   272     if ($translatedLocale === 'root') {
       
   273         continue;
       
   274     }
       
   275 
       
   276     $langBundle = load_resource_bundle($translatedLocale, $langDir);
       
   277     $regionBundle = load_resource_bundle($translatedLocale, $regionDir);
       
   278     $localeNames = array();
       
   279 
       
   280     foreach ($supportedLocales as $supportedLocale) {
       
   281         // Don't include ICU's root resource bundle
       
   282         if ($supportedLocale === 'root') {
       
   283             continue;
       
   284         }
       
   285 
       
   286         $lang = \Locale::getPrimaryLanguage($supportedLocale);
       
   287         $script = \Locale::getScript($supportedLocale);
       
   288         $region = \Locale::getRegion($supportedLocale);
       
   289         $variants = \Locale::getAllVariants($supportedLocale);
       
   290 
       
   291         // Currently the only available variant is POSIX, which we don't want
       
   292         // to include in the list
       
   293         if (count($variants) > 0) {
       
   294             continue;
       
   295         }
       
   296 
       
   297         $langName = $langBundle->get('Languages')->get($lang);
       
   298         $extras = array();
       
   299 
       
   300         // Some languages are simply not translated
       
   301         // Example: "az" (Azerbaijani) has no translation in "af" (Afrikaans)
       
   302         if (!$langName) {
       
   303             continue;
       
   304         }
       
   305 
       
   306         // "af" (Afrikaans) has no "Scripts" block
       
   307         if (!$langBundle->get('Scripts')) {
       
   308             continue;
       
   309         }
       
   310 
       
   311         // "as" (Assamese) has no "Variants" block
       
   312         if (!$langBundle->get('Variants')) {
       
   313             continue;
       
   314         }
       
   315 
       
   316         // Discover the name of the script part of the locale
       
   317         // i.e. in zh_Hans_MO, "Hans" is the script
       
   318         if ($script) {
       
   319             // Some languages are translated together with their script,
       
   320             // i.e. "zh_Hans" is translated as "Simplified Chinese"
       
   321             if ($langBundle->get('Languages')->get($lang.'_'.$script)) {
       
   322                 $langName = $langBundle->get('Languages')->get($lang.'_'.$script);
       
   323 
       
   324                 // If the script is appended in braces, extract it
       
   325                 // i.e. "zh_Hans" is translated as "Chinesisch (vereinfacht)"
       
   326                 // in "de"
       
   327                 if (strpos($langName, '(') !== false) {
       
   328                     list($langName, $scriptName) = preg_split('/[\s()]/', $langName, null, PREG_SPLIT_NO_EMPTY);
       
   329 
       
   330                     $extras[] = $scriptName;
       
   331                 }
       
   332             } else {
       
   333                 $scriptName = $langBundle->get('Scripts')->get($script);
       
   334 
       
   335                 // Some scripts are not translated into every language
       
   336                 if (!$scriptName) {
       
   337                     continue;
       
   338                 }
       
   339 
       
   340                 $extras[] = $scriptName;
       
   341             }
       
   342         }
       
   343 
       
   344         // Discover the name of the region part of the locale
       
   345         // i.e. in de_AT, "AT" is the region
       
   346         if ($region) {
       
   347             // Some languages are translated together with their region,
       
   348             // i.e. "en_GB" is translated as "British English"
       
   349             // we don't include these languages though because they mess up
       
   350             // the locale sorting
       
   351             // if ($langBundle->get('Languages')->get($lang.'_'.$region)) {
       
   352             //     $langName = $langBundle->get('Languages')->get($lang.'_'.$region);
       
   353             // } else {
       
   354             $regionName = $regionBundle->get('Countries')->get($region);
       
   355 
       
   356             // Some regions are not translated into every language
       
   357             if (!$regionName) {
       
   358                 continue;
       
   359             }
       
   360 
       
   361             $extras[] = $regionName;
       
   362             // }
       
   363         }
       
   364 
       
   365         if (count($extras) > 0) {
       
   366             $langName .= ' ('.implode(', ', $extras).')';
       
   367         }
       
   368 
       
   369         $localeNames[$supportedLocale] = $langName;
       
   370     }
       
   371 
       
   372     // If no names could be generated for the current locale, skip it
       
   373     if (count($localeNames) === 0) {
       
   374         continue;
       
   375     }
       
   376 
       
   377     echo "Generating $translatedLocale...\n";
       
   378 
       
   379     $file = fopen($namesGeneratedDir.DIRECTORY_SEPARATOR.$translatedLocale.'.txt', 'w');
       
   380 
       
   381     fwrite($file, "$translatedLocale{\n");
       
   382     fwrite($file, "    Locales{\n");
       
   383 
       
   384     foreach ($localeNames as $supportedLocale => $langName) {
       
   385         fwrite($file, "        $supportedLocale{\"$langName\"}\n");
       
   386     }
       
   387 
       
   388     fwrite($file, "    }\n");
       
   389     fwrite($file, "}\n");
       
   390     fclose($file);
       
   391 }
       
   392 
       
   393 // Convert generated files to binary format
       
   394 genrb($namesGeneratedDir, $namesDir);
       
   395 
       
   396 // Clean up
       
   397 clear_directory($namesGeneratedDir);
       
   398 rmdir($namesGeneratedDir);
       
   399 
       
   400 
       
   401 // Generate the data to the stubbed intl classes We only extract data for the 'en' locale
       
   402 // The extracted data is used only by the stub classes
       
   403 $defaultLocale = 'en';
       
   404 
       
   405 $currencies = array();
       
   406 $currenciesMeta = array();
       
   407 $defaultMeta = array();
       
   408 
       
   409 $bundle = load_resource_bundle('supplementaldata', __DIR__.'/curr');
       
   410 
       
   411 foreach ($bundle->get('CurrencyMeta') as $code => $data) {
       
   412     // The 'DEFAULT' key contains the fraction digits and the rounding increment that are common for a lot of currencies
       
   413     // Only currencies with different values are added to the icu-data (e.g: CHF and JPY)
       
   414     if ('DEFAULT' == $code) {
       
   415         $defaultMeta = array(
       
   416             'fractionDigits'    => $data[0],
       
   417             'roundingIncrement' => $data[1],
       
   418         );
       
   419 
       
   420         continue;
       
   421     }
       
   422 
       
   423     $currenciesMeta[$code]['fractionDigits'] = $data[0];
       
   424     $currenciesMeta[$code]['roundingIncrement'] = $data[1];
       
   425 }
       
   426 
       
   427 $bundle = load_resource_bundle('en', __DIR__.'/curr');
       
   428 
       
   429 foreach ($bundle->get('Currencies') as $code => $data) {
       
   430     $currencies[$code]['symbol'] = $data[0];
       
   431     $currencies[$code]['name']   = $data[1];
       
   432 
       
   433     if (!isset($currenciesMeta[$code])) {
       
   434         $currencies[$code]['fractionDigits'] = $defaultMeta['fractionDigits'];
       
   435         $currencies[$code]['roundingIncrement'] = $defaultMeta['roundingIncrement'];
       
   436         continue;
       
   437     }
       
   438 
       
   439     $currencies[$code]['fractionDigits'] = $currenciesMeta[$code]['fractionDigits'];
       
   440     $currencies[$code]['roundingIncrement'] = $currenciesMeta[$code]['roundingIncrement'];
       
   441 }
       
   442 
       
   443 // Countries.
       
   444 $countriesConstraint = function($code)
       
   445 {
       
   446     // Global countries (f.i. "America") have numeric codes
       
   447     // Countries have alphabetic codes
       
   448     // "ZZ" is the code for unknown country
       
   449     if (ctype_alpha($code) && 'ZZ' !== $code) {
       
   450         return true;
       
   451     }
       
   452 
       
   453     return false;
       
   454 };
       
   455 
       
   456 $countries = get_data('Countries', 'region', $defaultLocale, $countriesConstraint);
       
   457 
       
   458 // Languages
       
   459 $languagesConstraint = function($code)
       
   460 {
       
   461     // "mul" is the code for multiple languages
       
   462     if ('mul' !== $code) {
       
   463         return true;
       
   464     }
       
   465 
       
   466     return false;
       
   467 };
       
   468 
       
   469 $languages = get_data('Languages', 'lang', $defaultLocale, $languagesConstraint);
       
   470 
       
   471 // Display locales
       
   472 $displayLocales = get_data('Locales', 'names', $defaultLocale);
       
   473 
       
   474 // Create the stubs datafiles
       
   475 $stubDir = $target.DIRECTORY_SEPARATOR.'stub';
       
   476 $stubCurrDir = $stubDir.DIRECTORY_SEPARATOR.'curr';
       
   477 $stubLangDir = $stubDir.DIRECTORY_SEPARATOR.'lang';
       
   478 $stubNamesDir = $stubDir.DIRECTORY_SEPARATOR.'names';
       
   479 $stubRegionDir = $stubDir.DIRECTORY_SEPARATOR.'region';
       
   480 
       
   481 // Create the directories
       
   482 make_directory($stubDir);
       
   483 make_directory($stubCurrDir);
       
   484 make_directory($stubLangDir);
       
   485 make_directory($stubNamesDir);
       
   486 make_directory($stubRegionDir);
       
   487 
       
   488 clear_directory($stubCurrDir);
       
   489 clear_directory($stubLangDir);
       
   490 clear_directory($stubNamesDir);
       
   491 clear_directory($stubRegionDir);
       
   492 
       
   493 create_stub_datafile($defaultLocale, $stubCurrDir, $currencies);
       
   494 create_stub_datafile($defaultLocale, $stubLangDir, $languages);
       
   495 create_stub_datafile($defaultLocale, $stubNamesDir, $displayLocales);
       
   496 create_stub_datafile($defaultLocale, $stubRegionDir, $countries);
       
   497 
       
   498 // Clean up
       
   499 clear_directory($currDir);
       
   500 rmdir($currDir);