Class Language

Description

Translations of messages in different languages

Located in /program/lib/language.class.php (line 33)


	
			
Variable Summary
 array $languages
 array $phrases
Method Summary
 void Language ([string $default_domain = ''])
 array get_filenames_to_try (string $full_domain, string $location_hint, string $language_key)
 array get_languages_to_try (string $language_key)
 string get_phrase (string $phrase_key, [string $full_domain = ''], [array $replace = ''], [string $location_hint = ''], [string $language_key = ''])
 array get_phrases_from_database (string $full_domain, string $language_key)
 array get_phrases_from_file (string $filename)
 void reset_cache ([string $language_key = ''], [string $full_domain = ''])
 array retrieve_languages ([bool $force_reread = FALSE])
Variables
string $default_domain (line 41)
  • var: $default_domain the text domain to use if none is specified
array $languages = array() (line 38)
  • var: $languages a cached list of all language records
array $phrases = array() (line 35)
  • var: $phrases a cache of translated phrases
Methods
Constructor Language (line 51)

constructor

Set up the instance of this class. If no default domain is specified, 'was' is used. We always read the current list of all languages into core, for future reference.

void Language ([string $default_domain = ''])
  • string $default_domain: used when no domain is specified when requesting a translation
get_active_language_names (line 109)

return an array with active languages and language names

this returns an array with language_key => language_name pairs, one entry per active language, ordered by language name. This array can be used in language picklists or to translate a language key to readable form. Note that we use the name of a language expressed in the language itself.

  • return: language_keys and names
array get_active_language_names ()
get_current_language (line 144)

determine the default language to use for translation of phrases

This routine determines which language to use for prompts and messages if not specified explicitly in calls to $this->get_phrase(). There are various ways in which a language can be determined. Here's the list, in order of significance:

  • $_GET['language']
  • $_SESSION['language_key']
  • $USER->language_key
  • $CFG->language_key
  • constant value 'en' (the native language)
Note that all languages are validated agains the list of valid and active languages as collected in $this->languages. If a language is NOT valid, the next test is tried. If all else fails we return 'en' for English, which is the native language and which should always be valid.

  • return: a valid language code for an active language
  • uses: $USER;
  • uses: $CFG
string get_current_language ()
get_filenames_to_try (line 453)

calculate an ordered list of filenames to try for translation of phrases

WAS uses a separate language file for every text domain; basically the name of the text domain is the name of the file without the .php-extension. However, in order to prevent name clashes, modules and themes and addons have their own prefix: 'm_' for modules and 't_' for themes and 'a_' for addons.

The language translations for the installer are based on more or less the same trick: the prefix 'i_' identifies files in the directory /program/install/languages.

This trick with prefixing leads to the following search orders for generic phrases and module-, theme- and addon-specific phrases.

Example 1: phrases with $domain='login': {$CFG->progdir}/languages/{$language_key}/login.php {$CFG->datadir}/languages/{$language_key}/login.php

Example 2: phrases with $domain='m_guestbook': {$CFG->progdir}/modules/guestbook/languages/{$language_key}/guestbook.php {$CFG->progdir}/languages/{$language_key}/m_guestbook.php {$CFG->datadir}/languages/{$language_key}/m_guestbook.php

Example 3: phrases with $domain='login' and a hint in $location_hint: {$location_hint}/{$language_key}/login.php {$CFG->datadir}/languages/{$language_key}/login.php

Example 4: phrases with $domain='m_guestbook' and a hint in $location_hint: {$location_hint}/{$language_key}/guestbook.php {$location_hint}/{$language_key}/m_guestbook.php {$CFG->datadir}/languages/{$language_key}/m_guestbook.php

Example 5: phrases with $domain='i_demodata': {$CFG->progdir}/install/languages/{$language_key}/demodata.php {$CFG->datadir}/languages/{$language_key}/i_demodata.php

  • return: an ordered list of filenames
  • uses: $CFG
array get_filenames_to_try (string $full_domain, string $location_hint, string $language_key)
  • string $full_domain: indicates the text domain including optional module/theme/addon prefix
  • string $location_hint: hints at a location of language file(s)
  • string $language_key: target language
get_languages_to_try (line 395)

calculate a list of possible languages and parent-languages to try for translations

This constructs an array with all ancestors (=parent languages) of $language_key and English if that language was not yet added.

  • return: ordered list of language, all parent languages and English
array get_languages_to_try (string $language_key)
  • string $language_key: language of which to find all parents
get_phrase (line 317)

translation of phrases via a phrase key

This routine looks up the text associated with the phrase key. If no domain is specified, the domain 'was' is tried. If no valid language is specified, the current language is used. If a location hint is specified, we trust the caller knows best where to look and we try locating a translations file in that directory location first.

Note that phrases in a particular language which are found later in the search overwrite the phrases found earlier. These additional phrases (dubbed 'dialect' or 'userdefined translations') can be used to overwrite or correct existing standard ('official') translations. These dialect phrases can be stored in a file in the languages subdirectory of the data directory (writable for the web server but hopefully outside the document root) and/or in the table 'phrases' in the database.

Whether these dialect phrases are actually fetched from disk or database depends on the configuration of the language, via the boolean fields 'dialect_in_database' and 'dialect_in_file'; if the corresponding switch is not TRUE, we don't even bother to go and look, which saves time.

Finally, if a particular phrase is not found in the requested language, we recursively try the parent language(s) of the requested language until there are no more parents. After that, we go for the 'en' translation. If that fails too, we return the phrase_key itself, sandwiched between the strings '(lang) ' and ' (/lang)', where 'lang' is the requested language code. Of course this should not happen if all translations are correct. (Famous last words...)

If a translation is found, we replace all occurences of the keys in the array 'replace' in the translation with the corresponding values. This is done via a simple search and replace rather than a printf()-like way or (shudder) with complicated regex'es.

Note that we store search results in the array $this->phrases so we can re-use those phrases in a next call. We cache the results on a per-domain basis, based on the assumption that after the first phrase in a particular domain is requested, it is likely that more phrases in the same domain will be requested.

Note that the resulting phrases are cached using the original language as the key (in $this->phrases). This means that if a phrase in say 'de' or 'fr' was not found and 'en' was used instead, the English phrases are cached in the 'de' or 'fr' branch of the static array. This saves us time on the next call because we then use the phrases in the substitute language right away instead of going to look everywhere everytime.

Translations are fetched in such a way that the user-defined translations ('dialect') prevail over the system-defined ('official') translations. However, attempts to look for a phrase in a parent language (or 'en') only add the missing translations, preserving the translations in this full_domain that were already found. Quick illustration with Dutch (nl) and English (en): search order is: $nl_database, $nl_userfile, $nl_system, $en_database, $en_userfile, $en_system. The 'en' translations are only used if no corresponding Dutch translation is found. However, the English 'dialect' prevails over the English 'system' translation.

Examples of typical use of this routine:

    echo $LANGUAGE->get_phrase('username');
display the phrase from 'was.php' in the current language

    echo $LANGUAGE->get_phrase('username','login');
display the phrase from 'login.php' in the current language

    echo $LANGUAGE->get_phrase('welcome','',array('{USERNAME}' => $USER->username));
display the phrase from was.php in the default language, substituting the variable '{USERNAME}'.

  • return: translated string with optional values from array 'replace' inserted
  • todo: should we return an error for an invalid specific language?
  • uses: $LANGUAGES
string get_phrase (string $phrase_key, [string $full_domain = ''], [array $replace = ''], [string $location_hint = ''], [string $language_key = ''])
  • string $phrase_key: indicates the phrase that needs to be translated
  • string $full_domain: (optional) indicates the text domain (perhaps with a prefix)
  • array $replace: (optional) an assoc array with key-value-pairs to insert into the translation
  • string $location_hint: (optional) hints at a directory location of language files
  • string $language_key: (optional) target language
get_phrases_from_database (line 216)

retrieve phrases from the database for specified domain and language

  • return: associative array with phrase_keys and translations
array get_phrases_from_database (string $full_domain, string $language_key)
  • string $full_domain: text domain to look for
  • string $language_key: the language to look for
get_phrases_from_file (line 201)

return the $string array after including a file

This includes the specified language file $filename (if it exists) and returns the array $string. This assumes that filename actually consists of lines like this:

    ... $string['key_of_a_phrase'] = 'content of this phrase'; $string['key_with_variable'] = 'Hello, {USERNAME}.'; ...

Because the file is included within the context of this function, the contents are added to the local array $string rather than some global array. This is a feature.

Note that the included file MUST name the array '$string' because otherwise this function will return an empty array. This means that any 'old' Site@School language files must be manipulated before they can be re-used. I'd consider this a feature too.

  • return: all phrases from the specified file or an empty array
array get_phrases_from_file (string $filename)
  • string $filename: which language file to include
reset_cache (line 500)

remove selected entries (per language+domain, per language, or all) from cache

  • return: selected parts of cache reset
void reset_cache ([string $language_key = ''], [string $full_domain = ''])
  • string $language_key: the language
  • string $full_domain: the language domain
retrieve_languages (line 69)

retrieve an array with all active languages from the database

This reads all languages from the database. If there's nothing there, we still return an array with a single element for the English language 'en', because 'en' is the native language of this program. If the language 'en' was not found, we still add it to the array. The resulting array is usually sorted by language name.

  • return: all languages from database, including at least 'en'
array retrieve_languages ([bool $force_reread = FALSE])
  • bool $force_reread: if TRUE we always go to the database, else we try the cached version first

Documentation generated on Tue, 28 Jun 2016 19:10:04 +0200 by phpDocumentor 1.4.0