8000 Simplify access to CLDR/ICU data · Issue #18368 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content
Simplify access to CLDR/ICU data #18368
Closed
@webmozart

Description

@webmozart

At the moment, we have issues with regard to CLDR/ICU data (i.e. information about languages, currencies etc. that is collected by the CLDR project and exposed in a C API by the ICU project):

To fix these problems, I suggest:

  • Moving to static method calls for data access (e.g. Currencies::getLocalizedName('EUR', 'en')). This has been discussed before in Use classes and interfaces to represent the shipped ICU data #11887.
    • The data is always available on the file system since we bundle it with the Intl component, hence I don't see a need to mock this information in tests and static access should be fine.
    • Also, I don't see a need to provide value objects (Currency), since we expose data only. Projects that need value objects need specialized value objects most of the time and are better off if they implement their own. We didn't find a good solution in Use classes and interfaces to represent the shipped ICU data #11887, so I suggest to KISS and move forward.
    • To avoid confusion with value object classes and to underline that the class contains static methods only, I suggest to use plural names.
  • Adding new methods for accessing CLDR data that is currently not being exposed.

This work was started once in #9206, but abandoned. I suggest to look at the PR for inspiration.

To Do

  • Migrate CurrencyBundle to Currencies
  • Migrate LanguageBundle to Languages
  • Migrate LocaleBundle to Locales
  • Migrate RegionBundle to Countries
  • Add Scripts
  • Add Timezones (started in [Intl] Provide translated timezone names #17636)
  • Analyze CLDR data and add accessors for available data

Who wants to work on these PRs?

Canonicalization

We should add canonicalize() methods to all static classes in order to canonicalize (normalize) language/currency/etc. codes. For example, fr-FR and fr_FR are both valid language codes. Within our code, we want to use one specific format, however (namely fr_FR). Language codes received from other sources (browsers, request headers, ...) can be passed to Languages::canonicalize() in order to convert them to Symfony's preferred format.

Currencies API

Here is a proposed API for the Currencies class. I added the doc comments from #9206 where needed for clarity. See #9206 for implementation inspiration.

class Currencies
{
    /**
     * Returns all available currencies.
     *
     * @return string[] An array of ISO 4217 three-letter currency codes
     */
    public static function getCurrencyCodes();

    public static function exists($currencyCode);

    public static function canonicalize($currencyCode);

    public static function getSymbol($currencyCode);

    public static function getLocalizedName($currencyCode, $displayLocale = null);

    public static function getLocalizedNames($displayLocale = null);

    public static function getFractionDigits($currencyCode);

    public static function getRoundingIncrement($currencyCode);

    /**
     * Returns the ISO 4217 numeric code of a currency.
     *
     * For example, the numeric code of the Canadian Dollar ("CAD") is 124. If
     * no numeric code is available for a currency, 0 is returned.
     *
     * @param string $currency A canonical ISO 4217 three-letter currency code
     *                         (e.g. "EUR")
     *
     * @return integer The numeric code
     *
     * @throws InvalidArgumentException If the currency code does not exist
     */
    public static function getNumericCode($currencyCode);

    /**
     * Returns the matching ISO 4217 three-letter codes for a numeric code.
     *
     * For example, the numeric code 124 belongs to the Canadian Dollar ("CAD").
     * Some numeric codes belong to multiple currencies. For example, the
     * number 428 is assigned to both the Latvian Ruble ("LVR") and the Latvian
     * Lats ("LVL"). For this reason, this method always returns an array.
     *
     * @param integer $numericCode An ISO 4217 numeric currency code (e.g. 124)
     *
     * @return string[] The matching ISO 4217 three-letter currency codes
     *
     * @throws InvalidArgumentException If the numeric code does not exist
     */
    public static function forNumericCode($numericCode);
}

Languages API

class Languages
{
    /**
     * Returns all available languages.
     *
     * Languages are returned as lowercase ISO 639-1 two-letter language codes.
     * For languages that don't have a two-letter code, the ISO 639-2
     * three-letter code is used instead.
     *
     * A full table of ISO 639 language codes can be found here:
     * http://www-01.sil.org/iso639-3/codes.asp
     *
     * @return string[] An array of canonical ISO 639 language codes
     */
    public static function getLanguageCodes();

    public static function exists($languageCode);

    public static function canonicalize($languageCode);

    public static function getLocalizedName($languageCode, $displayLocale = null);

    public static function getLocalizedNames($displayLocale = null);

    /**
     * Returns the ISO 639-2 three-letter code of a language.
     *
     * @param string $language A canonical ISO 639 language code (e.g. "en")
     *
     * @return string The ISO 639-2 three-letter code of the language
     *
     * @throws InvalidArgumentException If the language is invalid
     * @throws MissingResourceException If the language has no
     *                                  corresponding three-letter code
     */
    public static function getAlpha3Code($languageCode)
}

Locales API

class Locales
{
    /**
     * Returns all available locales.
     *
     * @return string[] A list of ICU locale codes
     */
    public static function getLocales();

    public static function exists($locale);

    public static function canonicalize($locale);

    public static function getLocalizedName($locale, $displayLocale = null);

    public static function getLocalizedNames($displayLocale = null);
    /**
     * Returns a list of locale aliases.
     *
     * @return string[] An array with locale aliases as keys and ICU locale
     *                  codes as values
     */
    public static function getAliases();

    /**
     * Returns the fallback locale for a given locale, if any
     *
     * @param string $locale The ICU locale code to find the fallback for.
     *
     * @return string|null The ICU locale code of the fallback locale, or null
     *                     if no fallback exists
     */
    public static function getFallbackLocale($locale);
}

Countries API

class Countries
{
    public static function getCountryCodes();

    public static function exists($countryCode);

    public static function canonicalize($countryCode);

    public static function getLocalizedName($countryCode, $displayLocale = null);

    public static function getLocalizedNames($displayLocale = null);

    public static function getAlpha3Code($countryCode);

    public static function forAlpha3Code($alpha3Code);
}

Scripts API

class Scripts
{
    public static function getScriptCodes();

    public static function exists($scriptCode);

    public static function canonicalize($scriptCode);

    public static function getLocalizedName($scriptCode, $displayLocale = null);

    public static function getLocalizedNames($displayLocale = null);
}

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0