summaryrefslogtreecommitdiff
path: root/includes
diff options
context:
space:
mode:
Diffstat (limited to 'includes')
-rw-r--r--includes/common.inc80
-rw-r--r--includes/locale.inc108
2 files changed, 119 insertions, 69 deletions
diff --git a/includes/common.inc b/includes/common.inc
index 5f5f9b66e..e4400995e 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -1126,37 +1126,44 @@ function fix_gpc_magic() {
* - @variable: escape plain text to HTML (check_plain)
* - %variable: escape text and theme as a placeholder for user-submitted
* content (check_plain + theme_placeholder)
- * @param $langcode
- * Optional language code to translate to a language other than what is used
- * to display the page.
+ * @param $options
+ * An associative array of additional options, with the following keys:
+ * - 'langcode' (default to the current language) The language code to
+ * translate to a language other than what is used to display the page.
+ * - 'context' (default to the empty context) The context the source string
+ * belongs to.
* @return
* The translated string.
*/
-function t($string, $args = array(), $langcode = NULL) {
+function t($string, array $args = array(), array $options = array()) {
global $language;
$custom_strings = &drupal_static(__FUNCTION__);
- if (!isset($langcode)) {
- $langcode = isset($language->language) ? $language->language : 'en';
+ // Merge in default.
+ if (empty($options['langcode'])) {
+ $options['langcode'] = isset($language->language) ? $language->language : 'en';
+ }
+ if (empty($options['context'])) {
+ $options['context'] = '';
}
// First, check for an array of customized strings. If present, use the array
// *instead of* database lookups. This is a high performance way to provide a
// handful of string replacements. See settings.php for examples.
// Cache the $custom_strings variable to improve performance.
- if (!isset($custom_strings[$langcode])) {
- $custom_strings[$langcode] = variable_get('locale_custom_strings_' . $langcode, array());
+ if (!isset($custom_strings[$options['langcode']])) {
+ $custom_strings[$options['langcode']] = variable_get('locale_custom_strings_' . $options['langcode'], array());
}
// Custom strings work for English too, even if locale module is disabled.
- if (isset($custom_strings[$langcode][$string])) {
- $string = $custom_strings[$langcode][$string];
+ if (isset($custom_strings[$options['langcode']][$options['context']][$string])) {
+ $string = $custom_strings[$options['langcode']][$options['context']][$string];
}
// Translate with locale module if enabled.
// We don't use drupal_function_exists() here, because it breaks the testing
// framework if the locale module is enabled in the parent site (we cannot
// unload functions in PHP).
- elseif (module_exists('locale') && $langcode != 'en') {
- $string = locale($string, $langcode);
+ elseif (module_exists('locale') && $options['langcode'] != 'en') {
+ $string = locale($string, $options['context'], $options['langcode']);
}
if (empty($args)) {
return $string;
@@ -1711,34 +1718,37 @@ function format_xml_elements($array) {
* content (check_plain + theme_placeholder)
* Note that you do not need to include @count in this array.
* This replacement is done automatically for the plural case.
- * @param $langcode
- * Optional language code to translate to a language other than
- * what is used to display the page.
+ * @param $options
+ * An associative array of additional options, with the following keys:
+ * - 'langcode' (default to the current language) The language code to
+ * translate to a language other than what is used to display the page.
+ * - 'context' (default to the empty context) The context the source string
+ * belongs to.
* @return
* A translated string.
*/
-function format_plural($count, $singular, $plural, $args = array(), $langcode = NULL) {
+function format_plural($count, $singular, $plural, array $args = array(), array $options = array()) {
$args['@count'] = $count;
if ($count == 1) {
- return t($singular, $args, $langcode);
+ return t($singular, $args, $options);
}
// Get the plural index through the gettext formula.
- $index = (function_exists('locale_get_plural')) ? locale_get_plural($count, $langcode) : -1;
+ $index = (function_exists('locale_get_plural')) ? locale_get_plural($count, isset($options['langcode']) ? $options['langcode'] : NULL) : -1;
// Backwards compatibility.
if ($index < 0) {
- return t($plural, $args, $langcode);
+ return t($plural, $args, $options);
}
else {
switch ($index) {
case "0":
- return t($singular, $args, $langcode);
+ return t($singular, $args, $options);
case "1":
- return t($plural, $args, $langcode);
+ return t($plural, $args, $options);
default:
unset($args['@count']);
$args['@count[' . $index . ']'] = $count;
- return t(strtr($plural, array('@count' => '@count[' . $index . ']')), $args, $langcode);
+ return t(strtr($plural, array('@count' => '@count[' . $index . ']')), $args, $options);
}
}
}
@@ -1777,19 +1787,19 @@ function parse_size($size) {
*/
function format_size($size, $langcode = NULL) {
if ($size < DRUPAL_KILOBYTE) {
- return format_plural($size, '1 byte', '@count bytes', array(), $langcode);
+ return format_plural($size, '1 byte', '@count bytes', array(), array('langcode' => $langcode));
}
else {
$size = $size / DRUPAL_KILOBYTE; // Convert bytes to kilobytes.
$units = array(
- t('@size KB', array(), $langcode),
- t('@size MB', array(), $langcode),
- t('@size GB', array(), $langcode),
- t('@size TB', array(), $langcode),
- t('@size PB', array(), $langcode),
- t('@size EB', array(), $langcode),
- t('@size ZB', array(), $langcode),
- t('@size YB', array(), $langcode),
+ t('@size KB', array(), array('langcode' => $langcode)),
+ t('@size MB', array(), array('langcode' => $langcode)),
+ t('@size GB', array(), array('langcode' => $langcode)),
+ t('@size TB', array(), array('langcode' => $langcode)),
+ t('@size PB', array(), array('langcode' => $langcode)),
+ t('@size EB', array(), array('langcode' => $langcode)),
+ t('@size ZB', array(), array('langcode' => $langcode)),
+ t('@size YB', array(), array('langcode' => $langcode)),
);
foreach ($units as $unit) {
if (round($size, 2) >= DRUPAL_KILOBYTE) {
@@ -1830,7 +1840,7 @@ function format_interval($timestamp, $granularity = 2, $langcode = NULL) {
foreach ($units as $key => $value) {
$key = explode('|', $key);
if ($timestamp >= $value) {
- $output .= ($output ? ' ' : '') . format_plural(floor($timestamp / $value), $key[0], $key[1], array(), $langcode);
+ $output .= ($output ? ' ' : '') . format_plural(floor($timestamp / $value), $key[0], $key[1], array(), array('langcode' => $langcode));
$timestamp %= $value;
$granularity--;
}
@@ -1839,7 +1849,7 @@ function format_interval($timestamp, $granularity = 2, $langcode = NULL) {
break;
}
}
- return $output ? $output : t('0 sec', array(), $langcode);
+ return $output ? $output : t('0 sec', array(), array('langcode' => $langcode));
}
/**
@@ -1908,13 +1918,13 @@ function format_date($timestamp, $type = 'medium', $format = '', $timezone = NUL
for ($i = 0; $i < $max; $i++) {
$c = $format[$i];
if (strpos('AaeDlMT', $c) !== FALSE) {
- $date .= t(date_format($date_time, $c), array(), $langcode);
+ $date .= t(date_format($date_time, $c), array(), array('langcode' => $langcode));
}
elseif ($c == 'F') {
// Special treatment for long month names: May is both an abbreviation
// and a full month name in English, but other languages have
// different abbreviations.
- $date .= trim(t('!long-month-name ' . date_format($date_time, $c), array('!long-month-name' => ''), $langcode));
+ $date .= t(date_format($date_time, $c), array(), array('context' => 'Long month name', 'langcode' => $langcode));
}
elseif (strpos('BcdGgHhIijLmNnOoPSstUuWwYyZz', $c) !== FALSE) {
$date .= date_format($date_time, $c);
diff --git a/includes/locale.inc b/includes/locale.inc
index 79613f933..0142bdbe8 100644
--- a/includes/locale.inc
+++ b/includes/locale.inc
@@ -883,31 +883,36 @@ function locale_translate_export_po_form_submit($form, &$form_state) {
*/
function locale_translate_edit_form(&$form_state, $lid) {
// Fetch source string, if possible.
- $source = db_query('SELECT source, textgroup, location FROM {locales_source} WHERE lid = :lid', array(':lid' => $lid))->fetchObject();
+ $source = db_query('SELECT source, context, textgroup, location FROM {locales_source} WHERE lid = :lid', array(':lid' => $lid))->fetchObject();
if (!$source) {
drupal_set_message(t('String not found.'), 'error');
drupal_goto('admin/international/translate/translate');
}
// Add original text to the top and some values for form altering.
- $form = array(
- 'original' => array(
- '#type' => 'item',
- '#title' => t('Original text'),
- '#markup' => check_plain(wordwrap($source->source, 0)),
- ),
- 'lid' => array(
- '#type' => 'value',
- '#value' => $lid
- ),
- 'textgroup' => array(
- '#type' => 'value',
- '#value' => $source->textgroup,
- ),
- 'location' => array(
- '#type' => 'value',
- '#value' => $source->location
- ),
+ $form['original'] = array(
+ '#type' => 'item',
+ '#title' => t('Original text'),
+ '#markup' => check_plain(wordwrap($source->source, 0)),
+ );
+ if (!empty($source->context)) {
+ $form['context'] = array(
+ '#type' => 'item',
+ '#title' => t('Context'),
+ '#markup' => check_plain($source->context),
+ );
+ }
+ $form['lid'] = array(
+ '#type' => 'value',
+ '#value' => $lid
+ );
+ $form['textgroup'] = array(
+ '#type' => 'value',
+ '#value' => $source->textgroup,
+ );
+ $form['location'] = array(
+ '#type' => 'value',
+ '#value' => $source->location
);
// Include default form controls with empty values for all languages.
@@ -1035,7 +1040,7 @@ function locale_translate_edit_form_submit($form, &$form_state) {
* String deletion confirmation page.
*/
function locale_translate_delete_page($lid) {
- if ($source = db_query('SELECT * FROM {locales_source} WHERE lid = :lid', array(':lid' => $lid))->fetchObject()) {
+ if ($source = db_query('SELECT lid, source FROM {locales_source} WHERE lid = :lid', array(':lid' => $lid))->fetchObject()) {
return drupal_get_form('locale_translate_delete_form', $source);
}
else {
@@ -1287,8 +1292,26 @@ function _locale_import_read_po($op, $file, $mode = NULL, $lang = NULL, $group =
$current["msgid"] = $quoted;
$context = "MSGID";
}
+ elseif (!strncmp("msgctxt", $line, 7)) {
+ if ($context == "MSGSTR") { // End current entry, start a new one
+ _locale_import_one_string($op, $current, $mode, $lang, $file, $group);
+ $current = array();
+ }
+ elseif (!empty($current["msgctxt"])) { // Already in this context? Parse error
+ _locale_import_message('The translation file %filename contains an error: "msgctxt" is unexpected on line %line.', $file, lineno);
+ return FALSE;
+ }
+ $line = trim(substr($line, 7));
+ $quoted = _locale_import_parse_quoted($line);
+ if ($quoted === FALSE) {
+ _locale_import_message('The translation file %filename contains a syntax error on line %line.', $file, $lineno);
+ return FALSE;
+ }
+ $current["msgctxt"] = $quoted;
+ $context = "MSGCTXT";
+ }
elseif (!strncmp("msgstr[", $line, 7)) {
- if (($context != "MSGID") && ($context != "MSGID_PLURAL") && ($context != "MSGSTR_ARR")) { // Must come after msgid, msgid_plural, or msgstr[]
+ if (($context != "MSGID") && ($context != "MSGCTXT") && ($context != "MSGID_PLURAL") && ($context != "MSGSTR_ARR")) { // Must come after msgid, msgxtxt, msgid_plural, or msgstr[]
_locale_import_message('The translation file %filename contains an error: "msgstr[]" is unexpected on line %line.', $file, $lineno);
return FALSE;
}
@@ -1308,7 +1331,7 @@ function _locale_import_read_po($op, $file, $mode = NULL, $lang = NULL, $group =
$context = "MSGSTR_ARR";
}
elseif (!strncmp("msgstr", $line, 6)) {
- if ($context != "MSGID") { // Should come just after a msgid block
+ if (($context != "MSGID") && ($context != "MSGCTXT")) { // Should come just after a msgid or msgctxt block
_locale_import_message('The translation file %filename contains an error: "msgstr" is unexpected on line %line.', $file, $lineno);
return FALSE;
}
@@ -1330,6 +1353,9 @@ function _locale_import_read_po($op, $file, $mode = NULL, $lang = NULL, $group =
if (($context == "MSGID") || ($context == "MSGID_PLURAL")) {
$current["msgid"] .= $quoted;
}
+ elseif ($context == "MSGCTXT") {
+ $current["msgctxt"] .= $quoted;
+ }
elseif ($context == "MSGSTR") {
$current["msgstr"] .= $quoted;
}
@@ -1344,7 +1370,7 @@ function _locale_import_read_po($op, $file, $mode = NULL, $lang = NULL, $group =
}
// End of PO file, flush last entry
- if (($context == "MSGSTR") || ($context == "MSGSTR_ARR")) {
+ if (!empty($current) && !empty($current['msgstr'])) {
_locale_import_one_string($op, $current, $mode, $lang, $file, $group);
}
elseif ($context != "COMMENT") {
@@ -1401,7 +1427,7 @@ function _locale_import_one_string($op, $value = NULL, $mode = NULL, $lang = NUL
// Store string in memory (only supports single strings)
case 'mem-store':
- $strings[$value['msgid']] = $value['msgstr'];
+ $strings[isset($value['msgctxt']) ? $value['msgctxt'] : ''][$value['msgid']] = $value['msgstr'];
return;
// Called at end of import to inform the user
@@ -1454,7 +1480,7 @@ function _locale_import_one_string($op, $value = NULL, $mode = NULL, $lang = NUL
if ($key == 0) {
$plid = 0;
}
- $plid = _locale_import_one_string_db($report, $lang, $english[$key], $trans, $group, $comments, $mode, $plid, $key);
+ $plid = _locale_import_one_string_db($report, $lang, isset($value['msgctxt']) ? $value['msgctxt'] : '', $english[$key], $trans, $group, $comments, $mode, $plid, $key);
}
}
@@ -1462,7 +1488,7 @@ function _locale_import_one_string($op, $value = NULL, $mode = NULL, $lang = NUL
// A simple string to import.
$english = $value['msgid'];
$translation = $value['msgstr'];
- _locale_import_one_string_db($report, $lang, $english, $translation, $group, $comments, $mode);
+ _locale_import_one_string_db($report, $lang, isset($value['msgctxt']) ? $value['msgctxt'] : '', $english, $translation, $group, $comments, $mode);
}
}
} // end of db-store operation
@@ -1476,6 +1502,8 @@ function _locale_import_one_string($op, $value = NULL, $mode = NULL, $lang = NUL
* array(inserts, updates, deletes).
* @param $langcode
* Language code to import string into.
+ * @param $context
+ * The context of this string.
* @param $source
* Source string.
* @param $translation
@@ -1493,8 +1521,8 @@ function _locale_import_one_string($op, $value = NULL, $mode = NULL, $lang = NUL
* @return
* The string ID of the existing string modified or the new string added.
*/
-function _locale_import_one_string_db(&$report, $langcode, $source, $translation, $textgroup, $location, $mode, $plid = 0, $plural = 0) {
- $lid = db_query("SELECT lid FROM {locales_source} WHERE source = :source AND textgroup = :textgroup", array(':source' => $source, ':textgroup' => $textgroup))->fetchField();
+function _locale_import_one_string_db(&$report, $langcode, $context, $source, $translation, $textgroup, $location, $mode, $plid = 0, $plural = 0) {
+ $lid = db_query("SELECT lid FROM {locales_source} WHERE source = :source AND context = :context AND textgroup = :textgroup", array(':source' => $source, ':context' => $context, ':textgroup' => $textgroup))->fetchField();
if (!empty($translation)) {
// Skip this string unless it passes a check for dangerous code.
@@ -1547,7 +1575,12 @@ function _locale_import_one_string_db(&$report, $langcode, $source, $translation
else {
// No such source string in the database yet.
$lid = db_insert('locales_source')
- ->fields(array('location' => $location, 'source' => $source, 'textgroup' => $textgroup))
+ ->fields(array(
+ 'location' => $location,
+ 'source' => $source,
+ 'context' => (string) $context,
+ 'textgroup' => $textgroup,
+ ))
->execute();
db_insert('locales_target')
@@ -1932,6 +1965,7 @@ function _locale_parse_js_file($filepath) {
->fields(array(
'location' => $filepath,
'source' => $string,
+ 'context' => '',
'textgroup' => 'default',
))
->execute();
@@ -1958,17 +1992,18 @@ function _locale_parse_js_file($filepath) {
*/
function _locale_export_get_strings($language = NULL, $group = 'default') {
if (isset($language)) {
- $result = db_query("SELECT s.lid, s.source, s.location, t.translation, t.plid, t.plural FROM {locales_source} s LEFT JOIN {locales_target} t ON s.lid = t.lid AND t.language = :language WHERE s.textgroup = :textgroup ORDER BY t.plid, t.plural", array(':language' => $language->language, ':textgroup' => $group));
+ $result = db_query("SELECT s.lid, s.source, s.context, s.location, t.translation, t.plid, t.plural FROM {locales_source} s LEFT JOIN {locales_target} t ON s.lid = t.lid AND t.language = :language WHERE s.textgroup = :textgroup ORDER BY t.plid, t.plural", array(':language' => $language->language, ':textgroup' => $group));
}
else {
- $result = db_query("SELECT s.lid, s.source, s.location, t.plid, t.plural FROM {locales_source} s LEFT JOIN {locales_target} t ON s.lid = t.lid WHERE s.textgroup = :textgroup ORDER BY t.plid, t.plural", array(':textgroup' => $group));
+ $result = db_query("SELECT s.lid, s.source, s.context, s.location, t.plid, t.plural FROM {locales_source} s LEFT JOIN {locales_target} t ON s.lid = t.lid WHERE s.textgroup = :textgroup ORDER BY t.plid, t.plural", array(':textgroup' => $group));
}
$strings = array();
foreach ($result as $child) {
$string = array(
'comment' => $child->location,
'source' => $child->source,
- 'translation' => isset($child->translation) ? $child->translation : ''
+ 'context' => $child->context,
+ 'translation' => isset($child->translation) ? $child->translation : '',
);
if ($child->plid) {
// Has a parent lid. Since we process in the order of plids,
@@ -2045,6 +2080,9 @@ function _locale_export_po_generate($language = NULL, $strings = array(), $heade
$output .= '#: ' . $string['comment'] . "\n";
}
$output .= 'msgid ' . _locale_export_string($string['source']);
+ if (!empty($string['context'])) {
+ $output .= 'msgctxt ' . _locale_export_string($string['context']);
+ }
if (!empty($string['plural'])) {
$plural = $string['plural'];
$output .= 'msgid_plural ' . _locale_export_string($strings[$plural]['source']);
@@ -2199,7 +2237,7 @@ function _locale_translate_seek() {
$sql_query = db_select('locales_source', 's');
$sql_query->leftJoin('locales_target', 't', 't.lid = s.lid');
- $sql_query->fields('s', array('source', 'location', 'lid', 'textgroup'));
+ $sql_query->fields('s', array('source', 'location', 'context', 'lid', 'textgroup'));
$sql_query->fields('t', array('translation', 'language'));
// Compute LIKE section.
@@ -2242,7 +2280,7 @@ function _locale_translate_seek() {
$locales = $sql_query->execute();
$groups = module_invoke_all('locale', 'groups');
- $header = array(t('Text group'), t('String'), ($limit_language) ? t('Language') : t('Languages'), array('data' => t('Operations'), 'colspan' => '2'));
+ $header = array(t('Text group'), t('String'), t('Context'), ($limit_language) ? t('Language') : t('Languages'), array('data' => t('Operations'), 'colspan' => '2'));
$strings = array();
foreach ($locales as $locale) {
@@ -2252,6 +2290,7 @@ function _locale_translate_seek() {
'languages' => array(),
'location' => $locale->location,
'source' => $locale->source,
+ 'context' => $locale->context,
);
}
if (isset($locale->language)) {
@@ -2264,6 +2303,7 @@ function _locale_translate_seek() {
$rows[] = array(
$groups[$string['group']],
array('data' => check_plain(truncate_utf8($string['source'], 150, FALSE, TRUE)) . '<br /><small>' . $string['location'] . '</small>'),
+ $string['context'],
array('data' => _locale_translate_language_list($string['languages'], $limit_language), 'align' => 'center'),
array('data' => l(t('edit'), "admin/international/translate/edit/$lid", array('query' => drupal_get_destination())), 'class' => 'nowrap'),
array('data' => l(t('delete'), "admin/international/translate/delete/$lid", array('query' => drupal_get_destination())), 'class' => 'nowrap'),