Lokalizace - Jet\Locale
Možnost vytvářet projekty v různých lokalizacích (tedy určené pro více jazyků a také regionů/zemí/států) je jeden z důležitých rysů a základních vlastností platformy Jet. Vychází to z faktu, že takových projektů jsem na své pracovní cestě "potkal" celou řadu. A získal jsem tak poznatky díky úspěchům, ale i neúspěchům a chybám, či slepým uličkám. Proto je tento rys tak důležitý a prolíná se celým systémem. Je to jeden ze základních kamenů MVC, ale lokalizace je dokonce samostatný datový typ v ORM DataModel. Proto toto téma zařazuji jako jednu z prvních kapitol. Ale dost řečí ... Jde se na věc.
Lokalizace? Proč ne jazyk, nebo jazyková mutace?
Proč nepoužívám jednoduše termín jazyková mutace, jazyk, či tak podobně? V úvodu jsem zmínil nezdary a to ne náhodou. Jeden z těch nezdarů byl právě o tom, že jsem si myslel, že rozlišení podle jazyka bude stačit a postavil tak CMS. Má naivita byla potrestána a vyléčena velice záhy. Přišel projekt, který v sobě zahrnoval spoustu zemí a spoustu jazykových mutací. Obsah měl být do značné míry propojen a sdílen. Radoval jsem se jak jsme na takový projekt připraveni. Až jsme narazili na takovou "drobnost". Že ani ta němčina v Rakousku není úplně stejná němčina jako v Německu ... O americké a britské angličtině ani nemluvím. A pak tu máme běžně země, kde nepoužívá jeden jazyk, ale dva a více. Švýcarsko, Belgie, Kanada ... A ostatně i naše bývalé Československo ...
Vázat něco čistě jen na nějaký jazyk prostě nestačí. Jazyk není jeden a nejde jen o jazyk. Jde i o zobrazování čísel, cen, datumů a časů ... Prostě je to téma samo o sobě. Takto už je to zřejmé, že? Mě to ale před lety prostě nedošlo ... Ale teď už to vím. Proto Jet používá striktně pojem lokalizace a pracuje s entitou Locale.
Jak vypadá Locale v Jet?
Nic zvláštního ... Jde o identifikátor používaný ICU. Jedná se o řetězec složený ze dvou kódů oddělených znakem "_".
Například naše: cs_CZ
První kód je ISO 639 kód pro jazyk (cs - čeština)
Druhý kód je ISO 3166 kód pro zemi (CZ - Česká republika / Česko)
Pozor! Ve skutečnosti v rámci tohoto kódu může být ještě víc informací. Týká se např. čínštiny a podobně. Po pravdě jsem tento aspekt v praxi ještě nepoužil, ale je to jeden z důvodů, proč se v systému nepoužívá kód v podobě textového řetězce, ale instance třídy Jet\Locale. To je velice důležité! Jakmile někam předáváte Locale, nepracujete s textem, ale instancí této třídy. Do budoucna předpokládám, že se Jet\Locale ještě rozšíří na základě praktických poznatků - třeba právě poznatků od vás - kolegyň a kolegů. Ale základem je mít v aplikaci pevně daný řád a systém a ten systém říká, že se používá kód lokalizace dle ISO norem, ale vždy ve formě instance Jet\Locale.
Třída Jet\Locale
Jak už víte, tak v systému se nepoužívá kód lokalizace ve formě textového řetězce, ale vše co s lokalizací pracuje očekává instanci této třídy. Je to tedy sice relativně malá, osamocená, ale o to důležitější třída. Pojďme se na ní kouknout. Co je jejím určením?
- Její instance představuje informaci o konkrétní lokalizaci. Tedy instance této třídy se všude používá jako primární identifikátor lokalizace.
- Jedná se také o fasádu nad řadou funkcí již integrovaných v samotném PHP.
- Umožňuje pohodlně formátovat čísla, časové údaje a ceny.
- Umožňuje pracovat s lokalizací jako takovou. Například získat přesný název dané lokalizace a to třeba i v jiné lokalizaci (viz dále)
A nyní se již podívejme na třídu samotnou. Metody si rozdělíme podle toho zda jsou určené pro všeobecné použití (to budou metody statické) a metody vztahující se ke konkrétní lokalizaci - nestatické.
Nestatické metody - práce s konkrétní lokalizací
Metoda | Význam |
---|---|
public __construct( string|null $locale = null ) |
Jako parametr konstruktoru může být (a v praxi většinou je) předán textový kód lokalizace dle ISO norem. Tedy např. "cs_CZ", ale samozřejmě jakýkoliv jiný. Pokud je tomu tak, pak je tento kód automaticky rozparsován a objekt je nastaven. K parsování je využita metoda public static \Locale::parseLocale(string $locale): ?array samotného PHP. Jak již bylo uvedeno, tak třída Jet\Locale představuje fasádu nad věcmi, které PHP již standardně obsahuje. Konkrétně jde o modul Intl. Ten je již od dávných dob PHP5.3 brán jako standardní a tedy se s ním prostě počítá. |
public getRegion( ): string |
Vrátí dvoumístný kód regionu (nebo chcete-li země) dle ISO 3166. |
public getLanguage( ): string |
Vrátí kód jazyka dle ISO 639 |
public getName( Locale|null $in_locale = null ): string |
Vrátí pro koncového uživatele čitelný celý název lokalizace. Tedy například "čeština (Česko)" pro lokalizaci cs_CZ. Parametr $in_locale určuje v jaké lokalizaci má být název vrácen. Tedy je možné získat název lokalizace cs_CZ ovšem čitelný pro USA, tedy pro lokalizaci en_US. Pak metoda vrátí: "Czech (Czechia)" Pokud parametr není zadán, pak je použita aktuální lokalizace. |
public getLanguageName( Locale|null $in_locale = null ): string |
Vrátí pro koncového uživatele čitelný celý název jazyka. Tedy například "čeština" pro cs_CZ. Parametr $in_locale určuje v jaké lokalizaci má být název vrácen. Tedy je možné získat název jazyka cs_CZ ovšem čitelný pro USA, tedy pro lokalizaci en_US. Pak metoda vrátí: "Czech" Pokud parametr není zadán, pak je použita aktuální lokalizace. |
public getRegionName( Locale|null $in_locale = null ): string |
Vrátí pro koncového uživatele čitelný celý název země - regionu. Tedy například "Česko" pro cs_CZ. Parametr $in_locale určuje v jaké lokalizaci má být název vrácen. Tedy je možné získat název jazyka cs_CZ ovšem čitelný pro USA, tedy pro lokalizaci en_US. Pak metoda vrátí: "Czechia" Pokud parametr není zadán, pak je použita aktuální lokalizace. |
public getTimeZone( ): string |
Vrací kód časové zóny. Pozor! Hodnota není nastavena například konstruktorem. Jaká bude použita časová zóna pro danou lokalizaci záleží na vás a na situaci. Nemusí totiž vždy platit, že použitá lokalizace = časová zóna. Navíc velké země jsou v několika časových zónách. Tedy časová zóna není žádná jednoznačná věc. Jako výchozí je vzata ta časová zóna, kterou má jako výchozí nastaveno PHP, potažmo server. Ovšem například v inicializeru při použití MVC můžete aktuální lokalizaci nastavit časovou zónu dle vašich potřeb. |
public setTimeZone( string $time_zone ): void |
Nastavuje lokalizaci časovou zónu. Více viz předchozí metoda getTimeZone. |
public getCalendar( ): int |
Vrací číslo použitého kalendáře. Výchozí je gregoriánský kalendář. Ale situace je analogická s časovou zónou. Tedy jaký bude použit kalendář záleží na mnoha faktorech, konkrétním projektu, konkrétní situaci a konkrétní aplikaci. Tedy stejně jako u časové zóny je možné si kalendář nastavit (viz metoda getTimeZone ) Typy kalendářů jsou Jet\Locale::CALENDAR_GREGORIAN a Jet\Locale::CALENDAR_TRADITIONAL, ale jedná se opět o fasádu nad PHP. |
public setCalendar( int $calendar ): void |
Nastavuje použitý kalendář. Více viz předchozí metoda getCalendar. |
public getLocale(): string | S lokalizací je pochopitelně někde nutné pracovat opět jako s řetězcem. Například při ukládání tohoto údaje - ať už do databáze, nebo do souboru. Za tímto účelem tyto metody vrací textový kód lokalizace. Instanci Jet\Locale tedy lze přetypovat na string. |
public __toString(): string | |
public toString(): string | |
public formatDate( ?Data_DateTime $date_and_time, int $format = self::DATE_TIME_FORMAT_MEDIUM ): string |
Vrátí datum naformátované dle zvyklostí platných pro danou lokalizaci. Možné formáty viz konstanty. |
public formatDateAndTime( ?Data_DateTime $date_and_time, int $date_format = self::DATE_TIME_FORMAT_MEDIUM, int $time_format = self::DATE_TIME_FORMAT_SHORT ): string |
Vrátí datum a čas naformátovaný dle zvyklostí platných pro danou lokalizaci. Možné formáty viz konstanty. |
public formatTime( ?Data_DateTime $date_and_time, int $time_format = self::DATE_TIME_FORMAT_SHORT ): string |
Vrátí čas naformátovaný dle zvyklostí platných pro danou lokalizaci. Možné formáty viz konstanty. |
public formatInt( int $number ): string |
Vrátí celé číslo naformátované dle zvyklostí platných pro danou lokalizaci. |
public formatFloat( float $number, int $min_fraction_digits = 0, int $max_fraction_digits = 2 ): string |
Vrátí desetinné číslo naformátované dle zvyklostí platných pro danou lokalizaci. Je možné určit minimální a maximální počet desetinných míst. |
public formatSize( int $bytes, string $unit = 'iB', int $max_places = 2, string $glue = ' ' ): string |
Vrátí údaj o datovém objemu (např. velikosti souboru) naformátovaný dle zvyklostí platných pro danou lokalizaci. |
public formatCurrency( float|int $value, string $currency ) : string |
Vrátí částku naformátovanou dle zvyklostí platných pro danou lokalizaci a v dané měně. Měna je určena kóden dle ISO 4217. (Měna také není pevně navázána na lokalizaci) |
public getCurrencyFormatter( string $currency ): \NumberFormatter |
Vrátí instanci PHP třídy \NumberFormatter inicializovanou tak, aby byla připravena naformátovat čísla v dané lokalizaci a měně. Měna je určena kóden dle ISO 4217. |
Statické metody - obecné
Metoda | Význam |
---|---|
public static getCurrentLocale( ): Locale |
Vrátí instanci aktuálně platné (momentálně nastavené) lokalizace. |
public static setCurrentLocale( Locale $current_locale ): void |
Nastaví aktuálně platnou lokalizaci. Pokud budete používat Jet MVC, tak toto router udělá za vás. V opačném případě (pokud nepoužijete Jet MVC) je pochopitelně potřeba si aktuální Locale nastavit. |
public static date( ?Data_DateTime $date_and_time, int $format = self::DATE_TIME_FORMAT_MEDIUM ): string |
Jedná se o zkratku pro:
Locale::getCurrentLocale()->formatDate( $date_and_time, $format );
Stačí tedy:
Locale::date( $date_and_time, $format );
|
public static dateAndTime( ?Data_DateTime $date_and_time, int $date_format = self::DATE_TIME_FORMAT_MEDIUM, int $time_format = self::DATE_TIME_FORMAT_SHORT ): string |
Jedná se o zkratku pro:
Locale::getCurrentLocale()->formatDateAndTime( $date_and_time, $date_format, $time_format );
Stačí tedy:
Locale::dateAndTime( $date_and_time, $date_format, $time_format );
|
public static time( ?Data_DateTime $date_and_time, int $time_format = self::DATE_TIME_FORMAT_SHORT ): string |
Jedná se o zkratku pro:
Locale::getCurrentLocale()->formatTime( $date_and_time, $time_format );
Stačí tedy:
Locale::dateAndTime( $date_and_time, $time_format );
|
public static int( int $number ): string |
Jedná se o zkratku pro:
Locale::getCurrentLocale()->formatInt( $number );
Stačí tedy:
Locale::int( $number );
|
public static float( float $number, int $min_fraction_digits = 0, int $max_fraction_digits = 2 ): string |
Jedná se o zkratku pro:
Locale::getCurrentLocale()->formatFloat( $number, $min_fraction_digits, $max_fraction_digits );
Stačí tedy:
Locale::float( $number, $min_fraction_digits, $max_fraction_digits );
|
public static size( int $bytes, string $unit = 'iB', int $max_places = 2, string $glue = ' ' ): string |
Jedná se o zkratku pro:
Locale::getCurrentLocale()->formatSize( $bytes, $unit, $max_places, $glue );
Stačí tedy:
Locale::size( $bytes, $unit, $max_places, $glue );
|
public static currency( float|int $value, string $currency ): string |
Jedná se o zkratku pro:
Locale::getCurrentLocale()->formatCurrency( $value, $currency );
Stačí tedy:
Locale::currency( $value, $currency );
|
public static getAllLocalesList( null|Locale $in_locale = null ) : array |
Vrátí všechny známé lokalizace, respektive jejich názvy. Výstupem je pole, kde klíč je kód lokalizace a hodnota je název lokalizace. Parametrem $in_locale lze určit v jaké lokalizaci budou názvy lokalizací. Výchozí je aktuální lokalizace. |
Konstanty
Konstanta | Význam |
---|---|
Jet\Locale::CALENDAR_GREGORIAN | Odpovídá PHP konstaně \IntlDateFormatter::GREGORIAN |
Jet\Locale::CALENDAR_TRADITIONAL | Odpovídá PHP konstaně \IntlDateFormatter::TRADITIONAL |
Jet\Locale::DATE_TIME_FORMAT_SHORT | Odpovídá PHP konstaně \IntlDateFormatter::SHORT |
Jet\Locale::DATE_TIME_FORMAT_MEDIUM | Odpovídá PHP konstaně \IntlDateFormatter::MEDIUM |
Jet\Locale::DATE_TIME_FORMAT_LONG | Odpovídá PHP konstaně \IntlDateFormatter::LONG |
Jet\Locale::DATE_TIME_FORMAT_FULL | Odpovídá PHP konstaně \IntlDateFormatter::FULL |