Class TranslateTool

Description

Methods to access properties of a language and modify translations

This class is used to manage languages and translations. The following functions are supplied

  • add a new language
  • edit the properties of an existing language (including active flag)
  • add/edit translations of texts
The default action is to show a list of existing languages. From there the user can navigate to adding/editing language properties or manipulating translations in a particular language.

Located in /program/lib/translatetool.class.php (line 56)


	
			
Variable Summary
 array $domains
 array $languages
 object|null $output
Method Summary
 TranslateTool TranslateTool (object &$output)
 array a_param (string $chore, [string|null $language_key = NULL], [string|null $domain = NULL])
 string code_highlight (string &$source, [string $highlight_on = '<span class="translatetool_code">'], [string $highlight_off = '</span>'])
 bool diff_to_text (string $language_key, string $full_domain, array &$diff, string &$text)
 array get_dialogdef_language ([string $language_key = ''])
 array get_dialogdef_language_domain ([string $language_key = ''], [string $full_domain = ''])
 array get_domains ()
 string get_icon_edit (string $language_key)
 array get_options_languages ([string $skip_language_key = ''])
 void get_strings_system ( $language_key,  $full_domain, array &$string, array &$comment, string $languagekey, string $full_domein)
 int guess_row_count (string &$text, [int $maximum = 15])
 void language_add ()
 void language_edit ()
 void language_save ()
 bool put_strings_userfile (string $language_key, string $full_domain, array &$diff)
 array render_translation_dialog (string $href, array &$dialogdef, [string $method = 'post'], [string|array $attributes = ''])
 void show_domain_menu (string $language_key, [string $current_domain = ''])
 bool submit_diff_to_project (string $language_key, string $full_domain, array &$diff)
Variables
array $domains = array() (line 67)
  • var: list of all language domains grouped by program, modules, themes and install
array $languages = array() (line 64)
  • var: list of all language records (including inactive ones), keyed with language_key
object|null $output = NULL (line 58)
  • var: collects the html output
bool $show_parent_menu = FALSE (line 61)
  • var: if TRUE the calling routing is allowed to use the menu area (e.g. show config mgr menu)
Methods
Constructor TranslateTool (line 77)

construct a TranslateTool object

This initialises the TranslateTool and also dispatches the chore to do.

  • uses: $LANGUAGE
  • uses: $CFG
TranslateTool TranslateTool (object &$output)
  • object &$output: collects the html output
a_param (line 992)

shorthand for the anchor parameters that lead to the translate tool

  • return: ready-to-use array with parameters for constructing a-tag
array a_param (string $chore, [string|null $language_key = NULL], [string|null $domain = NULL])
  • string $chore: the next chore that could be done
  • string|null $language_key: the language of interest or NULL if none
  • string|null $domain: the full domain of interest or NULL if none
code_highlight (line 1127)

hightlight code constructs in texts that are to be translated

this routine highlights the following code constructs:

  • HTML-tages such as '<strong>' and '<em>'
  • Variables such as '{USERNAME}' and '{FILE}'
  • Tildes in hotkeys such as '~Yes' and '~No'
All of these code elements are sandwiched between $highlight_on and $highlight_off. The HTML-tags are escaped using htmlspecialchars making it possible to actually display them as text (otherwise they might be rendered as actual code in the browser). The HTML-codes '
' and '<p>' receive special treatment: they are rendered as visible text and also as a newline.

Note: This assumes that all '{' are eventually followed by a '}'. As long as this is true, we can easily use a str_replace() to sandwich {VARIABLE} between highlights. If there is only a single '{' or '}' the highlights won't match. It _could_ be a problem and if it is, the relevant code should iterate / chomp through the string with something like preg_match('/({[a-zA-Z0-9_]+})/',$string,$matches)

As an added bonus, sequences of two consecutive spaces are replaced with non-breakable spaces. This is handy for phrases that use spaces to indent text, e.g. in simple text-only email messages.

By using a reference we prevent the endless coping of (long) strings to the stack; this should save time & space.

  • return: the string with highlighted code elements and escaped HTML-tags
string code_highlight (string &$source, [string $highlight_on = '<span class="translatetool_code">'], [string $highlight_off = '</span>'])
  • string &$source: the string that needs code highlighting
  • string $highlight_on: is inserted before the code element that is highlighted
  • string $highlight_off: is inserted after the code element that is highlighted
diff_to_text (line 1349)

convert an array with key-value-pairs to a php source file that can be included as a user translation

All key-value-pairs are converted to something like this:

    ... $string['key'] = 'value'; ...

We specifially use single quotes in order to prevent any variable expansion within the strings. We do escape embedded single quotes, naturally. Furtermore, some metadata is added to the top of the resulting file, including information about the creation time, the program version that was used, the version of the (English) source file on which this translation is based and finally information about the file version of the system strings which was used to diff against.

Note: If the file with these system strings do not exist (because the language is all new, indicated by a version 'v0', _all_ strings are stored in the diff and thus in the user file. That file could be used as a new starting point for the new language in a next version of the program.

Note: we try very hard to defeat tricks with the contents of the metadata (i.e. we don't trust _full_name and _email to not contain tricks like '*' followed by '/' (which would prematurely end the comment in the header) etc.

  • return: TRUE on success, FALSE on failure
bool diff_to_text (string $language_key, string $full_domain, array &$diff, string &$text)
  • string $language_key: identifies the language
  • string $full_domain: indicates the language domain
  • array &$diff: contains all key-value-pairs for the modified translation
  • string &$text: receives the complete sourcefile created from $diff
get_dialogdef_language (line 729)

construct the language dialog (used for both add and edit)

this constructs a language dialog definition, maybe filled with data The main difference between dialogs for add and edit is that an existing language code ($language_key) cannot be changed; the corresponding field is shown in 'viewonly' mode. Another small difference is that an existing language cannot have itself as a parent language.

Note that we populate the 'edit' dialog with existing data from $this->languages.

  • return: contains the dialog definition
array get_dialogdef_language ([string $language_key = ''])
  • string $language_key: identifies the language to edit (empty string for add new language)
get_dialogdef_language_domain (line 810)

construct the translation dialog for selected language and domain

this constructs a translation dialog definition, filled with translations for language $language_key and domain $full_domain. The labels for the fields are derived from the English texts in $full_domain, in the order specified by the English file. If the English file contains comments, these are added to the item too (to be displayed as additional information for the translator). The current translation of the $full_domain is retrieved the usual way, via function t() (shorthand for $LANGUAGE->get_phrase()) but without translating any variables (e.g. {VALUE}). Note that if a translation of a phrase does not exist in the target language, the get_phrase() routine will eventually yield the English translation (after trying the language parents first). Also note that the translated phrases could be retrieved from a user file (ie. a file from $CFG->datadir/languages/$language_key/$full_domain).

  • return: contains the dialog definition
  • todo: try to figure this out: when the delimiter in $name was a dot '.' $_POST contained a '_' instead. WTF? (it seems that a colon works... for now)
  • uses: $USER
  • uses: $CFG
array get_dialogdef_language_domain ([string $language_key = ''], [string $full_domain = ''])
  • string $language_key: identifies the language to edit
  • string $full_domain: identifies the language domain
get_domains (line 1020)

return an ordered list of translation domains

this constructs a list of language domains, grouped by 'program','modules','themes' or 'install'. This array is the basis for validating full domains (in $_POST'ed data) and also to construct a menu.

Note that we use the translations from the files themselves in the current language to construct this list. Every translatefile should have at least the string 'translatetool_title' and 'translatetool_description'. Currently the sort order is based on the (internal) name of the modules. This should do the trick for translators: the order of files to translate in the menu does not depend on the translation of the module- or theme-title. (In the page manager and elsewhere it may be different).

  • return: contains list of displayable titles and descriptions, keyed by full_domain
array get_domains ()
get_icon_edit (line 969)

construct a clickable icon to edit the properties of this language

  • return: ready-to-use A-tag
  • uses: $WAS_SCRIPT_NAME
  • uses: $USER
  • uses: $CFG
string get_icon_edit (string $language_key)
  • string $language_key
get_options_languages (line 907)

fetch a list of languages available as parent language

this constructs a list of languages that can be used as a list of parent language options in a listbox or radiobuttons.

  • return: ready for use as an options array in a listbox or radiobuttons
array get_options_languages ([string $skip_language_key = ''])
  • string $skip_language_key: suppress this language in list (language cannot be its own parent)
get_strings_system (line 1175)

retrieve strings (translations) and comments from an official (system) translation file

This routine reads the system translations for $language_key and $full_domain from a file. For the translations of the main program we look for a single file in $CFG->progdir/languages/$language_key/. For modules, themes and addons we try two different locations: one within the moduel/theme/addon directory tree and subsequently in the generic directory $CFG->progdir/languages/$language_key/.

The names of modules/themes/addons are derived by stripping the 2-character prefix (m_, t_ or a_) from the full domain.

Translations for the installer are searched for in the /program/install/languages tree.

  • return: results are stored in arrays &$string and &$comment
void get_strings_system ( $language_key,  $full_domain, array &$string, array &$comment, string $languagekey, string $full_domein)
  • string $languagekey: the two or three letter ISO 639 language code
  • string $full_domein: the language domain of interest
  • array &$string: receives the translations (this parameter must be called 'string')
  • array &$comment: receives the comments (this parameter must be called 'comment')
  • $language_key
  • $full_domain
guess_row_count (line 1081)

try to calculate a reasonable number of textarea rows based on the contents of $text

By using a reference we prevent the endless coping of (long) strings to the stack; this should save time & space.

  • return: a positive number indicating the # or rows or $maximum (default maximum = 15)
int guess_row_count (string &$text, [int $maximum = 15])
  • string &$text: the string to analyse
  • int $maximum: the maximum value this routine returns
languages_overview (line 175)

display list of languages with edit icons and an option to add a language

this constructs the languages overview: a link to add a language, followed by a list of languages based on the languages in the database. Every language has an icon through which the properties of the language can be modified, including setting/resetting the active flag. (Only active languages can be used on the website and in the CMS). Note that we use _all_ languages here, including inactive ones.

Note that the calling routine (the tools manager) is allowed to display a menu because we set the parameter show_parent_menu to TRUE here.

The constructed list looks something like this:

        Add a language [E] Deutsch (de) (inactive) [E] English (en) [E] Nederlands (nl) ...

The clickable icons [E] lead to the Edit language properties. The clickable titles lead to the actual translations The clickable link 'Add an area' leads to the add new language dialog.

  • return: results are returned as output in $this->output
  • todo: should we add a paging function to the (perhaps looooong) list of languages?
  • uses: $WAS_SCRIPT_NAME
  • uses: $CFG
  • uses: $USER
void languages_overview ()
language_add (line 231)

present the language dialog where the user can enter properties for a new language

this displays a dialog where the user can enter the properties of a new language. These properties are:

  • name (expressed in the language itself)
  • key (2- or 3-letter code, presumably based on ISO 639-1 or ISO 639-2
  • parent_key (this language is based on which existing language)
  • active flag
The new languageis saved via performing the 'chore' TRANSLATETOOL_CHORE_LANGUAGE_SAVE_NEW.

  • return: results are returned as output in $this->output
  • uses: $WAS_SCRIPT_NAME
  • uses: $USER
void language_add ()
language_edit (line 252)

show the language edit dialog

display a dialog where the user can modify language properties. we re-use the routine that created the add language dialog.

  • return: results are returned as output in $this->output
  • uses: $WAS_SCRIPT_NAME
  • uses: $USER
void language_edit ()
language_save (line 427)

validate and save modified data to database

this saves data from the edit language dialog if data validates. If the data does NOT validate, the edit screen is displayed again otherwise the languages overview is displayed again.

  • return: results are returned as output in $this->output
  • uses: $WAS_SCRIPT_NAME
  • uses: $USER
  • uses: $LANGUAGE
  • uses: $CFG
void language_save ()
language_savenew (line 300)

save the newly added language to the database

This saves the essential information of a new language to the database, using sensible defaults for the other fields. Also, a data directory is created in $CFG->datadir

If something goes wrong, the user can redo the dialog, otherwise we return to the languages overview, with the newly added language in the list, too.

Apart from the standard checks the following checks are done:

  • the language key should be an acceptable directory name
  • the language key should be lowercase
  • the language key should not exist already (in $this->languages)
  • the directory should not yet exist
  • the directory must be created here and now

  • return: results are returned as output in $this->output
  • uses: $WAS_SCRIPT_NAME
  • uses: $USER
  • uses: $LANGUAGE
  • uses: $CFG
void language_savenew ()
put_strings_userfile (line 1283)

save new or changed translations to a file under CFG->datadir/languages

  • return: TRUE on success, FALSE on failure
bool put_strings_userfile (string $language_key, string $full_domain, array &$diff)
  • string $language_key: identifies the language to save
  • string $full_domain: indicates which language domain needs to be saved
  • array &$diff: contains all key-value-pairs for the modified translation
render_translation_dialog (line 1228)

render a translation dialog based on a dialog definition

This routine looks a bit like the generic dialog_quickform(). The differences are:

  • we show a comment (if any) in a box before label and input
  • the labels don't have hotkeys based on tildes at all (except the submit buttons)
  • comments and labels are wrapped in separate div's especially for the occasion
We do take any errors into account: fields with errors are displayed using the additional error class (which shows a label completely in red to indicate the error).

  • return: constructed HTML-form with dialog, one line per array element
  • uses: html_form()
array render_translation_dialog (string $href, array &$dialogdef, [string $method = 'post'], [string|array $attributes = ''])
  • string $href: the target of the HTML form
  • array &$dialogdef: the array which describes the complete dialog
  • string $method: method to submit data to the server, either 'post' or 'get'
  • string|array $attributes: holds the attributes to add to the form tag
show_domain_menu (line 934)

display the domain menu via $this->output

This displays a clickable menu on in the menu area on the left of the screen.

  • return: results are returned as output in $this->output
void show_domain_menu (string $language_key, [string $current_domain = ''])
  • string $language_key: the language currently being edited
  • string $current_domain: the currently selected language domain (used to emphasize the option in the menu)
show_parent_menu (line 132)

allow the caller to use the menu area (or not)

this routine tells the caller if it is OK to use the menu area (TRUE returned) or not (FALSE returned).

  • return: TRUE if menu area is available, FALSE otherwise
bool show_parent_menu ()
submit_diff_to_project (line 1408)

send new or changed translations back to the project

This sends an e-mail back to the project with the translation. We do so in the form of an attachment, but with a 'safe' extension (.bin rather than .php). This means that we will be able to traverse any firewalls and spamfilters and malware detectors.

The _notes are used as the body of the message, the file is attached.

Note that we send a copy of the message to the site itself (either the from-addres or the reply-to-address).

  • return: TRUE on success, FALSE on failure
bool submit_diff_to_project (string $language_key, string $full_domain, array &$diff)
  • string $language_key: identifies the language to submit
  • string $full_domain: indicates which language domain needs to be submitted
  • array &$diff: contains all key-value-pairs for the modified translation
translation_edit (line 507)

show an edit dialog with phrases from $full_domain in $language_key

After some sanity checking this routine shows al dialog where the user can edit translations for the selected language and domain. Note that this could be a huge dialog, depending on the size of the language domein ('admin' is notoriously large). Sending this routine to the browser can take some time.

void translation_edit ()
translation_save (line 568)

save the modified translations in a file in the tree CFG->datadir/languages/

this routine validates the dialog data and attempts to save the changes in the file $full_domain in the directory CFG->datadir/languages/$language_key/. Also, we may need to send a message to the Website@School project with our changes (depending on the flag _submit).

  • return: data saved and output written to browser via $this->output
void translation_save ()

Documentation generated on Tue, 28 Jun 2016 19:12:21 +0200 by phpDocumentor 1.4.0