API / Minn\I18n

Minn\I18n

13 classes, 61 public methods and 18 internals. This page is the public surface; each class name opens the whole class.

Catalog final readonly class

public/minn/src/Minn/I18n/Catalog.php · 56 lines · Open the class →

One translation file's contents: its headers as written, its messages keyed the gettext way (the context, a 0x04 byte, then the original; the original alone without a context), each with its translated forms and, where the file says, the original plural, and the file's plural rule. An empty translation is still a translation: it is what the file says.

new__construct(array $headers, array $entries, Minn\I18n\PluralRule $plural)
@param array<string, string> $headers
@param array<string, array{translations: list<string>, plural: ?string}> $entries
propreadonly array $headers
propreadonly array $entries
propreadonly Minn\I18n\PluralRule $plural
staticfrom(array $headers, array $entries): self

A catalog from headers and entries, its plural rule taken from the headers.

statickey(string $original, ?string $context): string

The lookup key for an original in a context; an empty or missing context is no context.

methodheaderValue(string $name): ?string

A header's value, its name matched without case.

methodtranslate(string $key): ?string

The translation of a message, empty when the file says so, or null when the file has no entry.

methodtranslatePlural(string $key, int $count): ?string

The form of a message a count takes under this file's rule (the first form when the file has fewer), or null when the file has no entry.

methodhas(string $key): bool

Whether the file has an entry for the message.

Gettext final class

public/minn/src/Minn/I18n/Gettext.php · 84 lines · Open the class →

Translation as plugins see it (__, _x, _n and the rest map here): the message looked up in its domain's loaded files (loading the domain just in time on first use, through the loader the runtime hands over), else the English, then the gettext filters a plugin may change it through. Engine code translates here rather than through the WordPress names; with no runtime (an engine CLI verb) there is nothing loaded, and the English stands.

staticloadWith(Closure $loader): void

The runtime's just-in-time loader for a domain's files. @param Closure(string): mixed $loader

@param Closure(string): mixed $loader
statictext(string $text, string $domain = 'default'): string

A message (__).

staticinContext(string $text, string $context, string $domain = 'default'): string

A message in a context (_x).

staticplural(string $single, string $plural, int $number, string $domain = 'default'): string

The form a count takes (_n): the domain's own plural, else English's.

staticpluralInContext(string $single, string $plural, int $number, string $context, string $domain = 'default'): string

The form a count takes in a context (_nx).

staticlookup(string $domain, string $key): ?string

A domain's translation of a message key, or null (no runtime to have loaded one, no file, no entry).

staticpluralForm(string $single, string $plural, int $number, string $domain, ?string $context): string

The plural form a count takes in a domain, or English's when no file has the message.

insidehooked()

LegacyPluralForms final class

public/minn/src/Minn/I18n/LegacyPluralForms.php · 190 lines · Open the class →

The plural expression reader the old POMO library carries (Plural_Forms), kept apart from PluralExpression because plugins see its quirks: it reads only n, whole numbers, parentheses, % and the comparisons, && and ||, and the ternary, skipping spaces and tabs alone. It turns the expression into postfix tokens once (operators of equal strength group to the left, the ternary to the right) and runs them on a stack per number: an operand the stack lacks is null, == and != compare strictly, values stay as PHP left them until the answer is cast to an integer, and % is PHP's own, so a zero divisor throws. Every refusal is an Exception with the reference's words (probe translation-files).

staticparse(string $expression): array

The expression as postfix tokens: ['var'], ['value', int] or ['op', string].

@return list<array{0: string, 1?: int|string}>
staticexecute(array $tokens, int $n): int

The value of postfix tokens for one number.

@param list<array{0: string, 1?: int|string}> $tokens
insidetoken(), operator(), closeParenthesis(), closeTernary(), apply(), strengths()

LocalDates final class

public/minn/src/Minn/I18n/LocalDates.php · 35 lines · Open the class →

A date in the site's language, as the reference's wp_date writes one: PHP's format, with the weekday and month names (D, l, F, M) and the meridiems (a, A) in the language's own words, and a month written after its day in the genitive where the language declines month names. Backslashed characters stay as written.

staticformat(DateTimeInterface $time, string $format): string

The date in the format given, its names translated.

LocaleStack final class

public/minn/src/Minn/I18n/LocaleStack.php · 42 lines · Open the class →

The locales a request switched into, innermost last, each with the user whose locale it is (false when a locale was named outright). Empty means the request speaks its own locale.

methodpush(string $locale, int|false $userId = false): void

Enters a locale, a user's or one named outright.

methodpop(): ?string

Leaves the innermost locale; the one now in force, or null when none is switched.

methodclear(): void

Leaves every switched locale.

methodcurrent(): ?string

The innermost switched locale, or null.

methodcurrentUser(): int|false

The user whose locale is innermost, or false (none switched, or a locale named outright).

methodswitched(): bool

Whether any locale is switched in.

MoFile final class

public/minn/src/Minn/I18n/MoFile.php · 106 lines · Open the class →

The GNU gettext binary catalog (.mo), read and written. The file opens with a magic number that also says its byte order, then a revision, the message count, and the offsets of two tables of (length, offset) pairs: the originals, then the translations. The entry with an empty original carries the headers; a plural original is "singular NUL plural" and its translations are NUL-separated; a context precedes the original with a 0x04 byte.

staticread(string $bytes): ?Minn\I18n\Catalog

The catalog in a .mo file's bytes, or null when they are not one.

staticwrite(array $headers, array $entries): string

A .mo file's bytes for headers and entries, little-endian, entries in the sorted order gettext expects.

@param array<string, string> $headers
@param array<string, array{translations: list<string>, plural: ?string}> $entries
insidebyteOrder(), string(), headers(), headerBlock()

PhpFile final class

public/minn/src/Minn/I18n/PhpFile.php · 22 lines · Open the class →

The PHP translation file (.l10n.php): a file that returns an array of its lower-cased headers and a "messages" map from the gettext key to the translation, plural forms joined by NUL bytes. It is the site's own data, read the way the reference reads it, by including it.

staticread(string $file): ?Minn\I18n\Catalog

The catalog a .l10n.php file returns, or null when it returns no messages.

PluralExpression final class

public/minn/src/Minn/I18n/PluralExpression.php · 147 lines · Open the class →

The C subset a Plural-Forms header writes its rule in: the number n, integer literals, parentheses, ! and unary minus, * / %, + -, the four comparisons, == and !=, && and ||, and the ternary, with C's precedence and the ternary binding to the right. Parsed into a small tree once and evaluated per number; nothing is ever handed to PHP to run.

staticparse(string $expression): ?array

The expression as a tree, or null when it is not a whole expression.

@return array<int, mixed>|null
staticevaluate(array $node, int $n): int

The value of a parsed expression for one number; true is 1 and false 0.

@param array<int, mixed> $node
insidebinary(), tokens(), ternary(), binaryLevel(), unary()

PluralRule final readonly class

public/minn/src/Minn/I18n/PluralRule.php · 36 lines · Open the class →

A language's plural rule from its Plural-Forms header: how many forms it has and which form a number takes. A file without the header follows English (two forms, n != 1); an expression that does not parse sends every number to the first form, as the reference does.

propreadonly int $count
propreadonly string $expression
staticenglish(): self

English: one form for 1, the other for everything else.

staticfromHeader(?string $header): self

The rule a Plural-Forms header states.

staticfromExpression(int $count, string $expression): self

A rule from a form count and an expression in n.

methodindex(int $n): int

The form a number takes.

ScriptTranslations final class

public/minn/src/Minn/I18n/ScriptTranslations.php · 60 lines · Open the class →

Where a script's JSON translations are found, and how they reach the page. A script is placed by its URL: inside a plugin or a theme, its path there; elsewhere on the site, its path from the site root; off the site, nowhere. The JSON files are named by the md5 of that path (with ".min.js" read as ".js"), or by the script's handle in a folder a plugin names.

staticplace(string $src, string $siteUrl, string $pluginsUrl, string $themesUrl): array

A script's path inside its plugin, theme or site, and the languages subfolder for it ("plugins", "themes", or "" for the site); the path is false for a script off the site.

@return array{0: string|false, 1: string}
staticabsolute(string $src, string $siteUrl): string

The script made absolute the way place() reads it, for the filter that may move it.

staticfileHash(string $relative): string

The md5 a translation file is named by: a minified script shares its source's file.

staticprefix(string $domain, string $locale): string

The start of a translation file's name: the core domain goes by locale alone.

staticblock(string $domain, string $json): string

The inline script that hands a script's translations to wp.i18n before the script runs.

insideorigin()

SiteLanguage final class

public/minn/src/Minn/I18n/SiteLanguage.php · 43 lines · Open the class →

The site's language as pages declare it: the locale in force (a switched one first, then what pre_determine_locale or the WPLANG option give, through the locale filter) and the html element's dir and lang attributes, which a plugin may change through language_attributes.

staticlocale(): string

The locale in force (get_locale).

statictag(): string

The language tag pages carry: the locale with a hyphen, plain "en" read as en_US.

staticattributes(string $doctype = 'html'): string

The html element's dir and lang attributes (lang for html, xml:lang for xhtml or a non-HTML html_type).

TextDomains final class

public/minn/src/Minn/I18n/TextDomains.php · 191 lines · Open the class →

The text domains this request knows: each domain's files in the order they were loaded, and the domains looked for and not found (known, with no files), all in the order they first appeared, which is the order a locale switch reloads them in. A lookup asks a domain's files in load order and the first one with a translation answers, each under its own plural rule. The registry also remembers the folder a plugin or theme named for its domain (and how files there are named), and the domains unloaded for good.

methodadd(string $domain, string $file, Minn\I18n\Catalog $catalog): void

Adds a loaded file to a domain; a file already loaded there is not added twice.

methodhas(string $domain): bool

Whether any file is loaded for the domain.

methodunload(string $domain): bool

Forgets a domain and its files; true when it had any.

methodaccept(string $domain): void

Records that load_textdomain() loaded a file for the domain. A file that does not parse adds nothing to look up, yet the reference's global functions count its domain as loaded, while its translation controller does not (probe translations-early-wplang).

methodopened(string $domain): bool

Whether the global functions count the domain as loaded: a file loaded, or one load_textdomain() accepted.

methodmarkKnown(string $domain): void

Records that a domain was asked for, so it is looked for once and reloaded on a switch.

methodwaiting(string $domain): bool

Whether a translation lookup should look for the domain's files: it was never looked for, or nothing was found and a folder has been named for it since (the reference looks again after each load_plugin_textdomain; probe plugin-data).

methodknown(string $domain): bool

Whether the domain was loaded or looked for.

methodknownDomains(): array

Every known domain, in the order it first appeared.

@return list<string>
methodunloadFile(string $domain, string $file): bool

Drops one file from a domain; true when it was loaded.

methodcatalogs(string $domain): array

The domain's files and catalogs, first loaded first.

@return array<string, Catalog>
methodtranslate(string $domain, string $key): ?string

The first loaded translation of a key in the domain, or null.

methodtranslatePlural(string $domain, array $keys, int $count): ?string

The first loaded plural form for a count, or null: each key is looked for in every file before the next key (the full "singular NUL plural" key, then the singular alone).

@param list<string> $keys
methodrememberFolder(string $domain, string $folder): void

Records the folder a plugin or theme named for its domain; files there are "{domain}-{locale}".

methodrememberThemeFolder(string $domain, string $folder): void

Records the active theme's own language folder; files there are named by locale alone.

methodfolderFile(string $domain, string $locale): ?string

The .mo path a domain's named folder would hold for a locale, if a folder was named.

methodclose(string $domain): void

Keeps an unloaded domain from loading again on its own.

methodclosed(string $domain): bool

Whether the domain was unloaded for good.

methoddomains(): array

The domains with files loaded.

@return list<string>
insidelookAgainUnlessLoaded()

TranslationFiles final class

public/minn/src/Minn/I18n/TranslationFiles.php · 48 lines · Open the class →

Which file a request for a .mo path reads, and reading it. Asked for "x.mo", the reference reads "x.l10n.php" when the format is php and that file is there, and the .mo only otherwise; asked for the mo format, only the .mo.

staticcandidates(string $mofile, string $format): array

The files to try for a requested .mo path, in order.

@return list<string>
staticlanguages(string $dir, ?string $asked = NULL): array

The languages a folder holds core translations for (each .mo but the time zone names, the network admin's and the admin's), as get_available_languages lists them, through its filter ($asked: the folder as the caller named it, null for the site's own).

@return list<string>
staticread(string $file): ?Minn\I18n\Catalog

A translation file's catalog by its extension, or null when it cannot be read as one.