Commit 2e535504 authored by Dries's avatar Dries

- Patch #1445004 by Sutharsan, Gábor Hojtsy, roderik, andypost, brantwynn:...

- Patch #1445004 by Sutharsan, Gábor Hojtsy, roderik, andypost, brantwynn: Implement customized translation bit on translations.
parent 3610fd93
This diff is collapsed.
......@@ -73,26 +73,28 @@
');
/**
* Translation import mode overwriting all existing translations
* if new translated version available.
* Flag for locally not customized interface translation.
*
* Such translations are imported from .po files downloaded from
* localize.drupal.org for example.
*/
const LOCALE_IMPORT_OVERWRITE = 0;
const LOCALE_NOT_CUSTOMIZED = 0;
/**
* Translation import mode keeping existing translations and only
* inserting new strings.
* Flag for locally customized interface translation.
*
* Such translations are edited from their imported originals on the user
* interface or are imported as customized.
*/
const LOCALE_IMPORT_KEEP = 1;
const LOCALE_CUSTOMIZED = 1;
/**
* URL language negotiation: use the path prefix as URL language
* indicator.
* URL language negotiation: use the path prefix as URL language indicator.
*/
const LANGUAGE_NEGOTIATION_URL_PREFIX = 0;
/**
* URL language negotiation: use the domain as URL language
* indicator.
* URL language negotiation: use the domain as URL language indicator.
*/
const LANGUAGE_NEGOTIATION_URL_DOMAIN = 1;
......
......@@ -34,62 +34,80 @@ function locale_translate_import_form($form, &$form_state) {
else {
$default = key($existing_languages);
$language_options = array(
t('Already added languages') => $existing_languages,
t('Existing languages') => $existing_languages,
t('Languages not yet added') => language_admin_predefined_list()
);
}
$form['import'] = array('#type' => 'fieldset',
'#title' => t('Import translation'),
);
$form['import']['file'] = array('#type' => 'file',
'#title' => t('Language file'),
$form['file'] = array(
'#type' => 'file',
'#title' => t('Translation file'),
'#size' => 50,
'#description' => t('A Gettext Portable Object (<em>.po</em>) file.'),
);
$form['import']['langcode'] = array('#type' => 'select',
'#title' => t('Import into'),
$form['langcode'] = array(
'#type' => 'select',
'#title' => t('Language'),
'#options' => $language_options,
'#default_value' => $default,
'#description' => t('Choose the language you want to add strings into. If you choose a language which is not yet set up, it will be added.'),
);
$form['import']['mode'] = array('#type' => 'radios',
'#title' => t('Mode'),
'#default_value' => LOCALE_IMPORT_KEEP,
'#options' => array(
LOCALE_IMPORT_OVERWRITE => t('Strings in the uploaded file replace existing ones, new ones are added. The plural format is updated.'),
LOCALE_IMPORT_KEEP => t('Existing strings and the plural format are kept, only new strings are added.')
$form['customized'] = array(
'#title' => t('Treat imported strings as custom translations'),
'#type' => 'checkbox',
);
$form['overwrite_options'] = array(
'#type' => 'container',
'#tree' => TRUE,
);
$form['overwrite_options']['not_customized'] = array(
'#title' => t('Overwrite non-customized translations'),
'#type' => 'checkbox',
'#states' => array(
'checked' => array(
':input[name="customized"]' => array('checked' => TRUE),
),
),
);
$form['import']['submit'] = array('#type' => 'submit', '#value' => t('Import'));
$form['overwrite_options']['customized'] = array(
'#title' => t('Overwrite existing customized translations'),
'#type' => 'checkbox',
);
$form['actions'] = array(
'#type' => 'actions'
);
$form['actions']['submit'] = array(
'#type' => 'submit',
'#value' => t('Import')
);
return $form;
}
/**
* Process the locale import form submission.
* Processes the locale import form submission.
*/
function locale_translate_import_form_submit($form, &$form_state) {
$validators = array('file_validate_extensions' => array('po'));
// Ensure we have the file uploaded
// Ensure we have the file uploaded.
if ($file = file_save_upload('file', $validators)) {
// Add language, if not yet supported
drupal_static_reset('language_list');
$languages = language_list();
$langcode = $form_state['values']['langcode'];
if (!isset($languages[$langcode])) {
// Add language, if not yet supported.
$language = language_load($form_state['values']['langcode']);
if (empty($language)) {
include_once DRUPAL_ROOT . '/core/includes/standard.inc';
$predefined = standard_language_list();
$language = (object) array(
'langcode' => $langcode,
'langcode' => $form_state['values']['langcode'],
);
language_save($language);
drupal_set_message(t('The language %language has been created.', array('%language' => t($predefined[$langcode][0]))));
$language = language_save($language);
drupal_set_message(t('The language %language has been created.', array('%language' => t($language->name))));
}
$customized = $form_state['values']['customized'] ? LOCALE_CUSTOMIZED : LOCALE_NOT_CUSTOMIZED;
// Now import strings into the language
if ($return = _locale_import_po($file, $langcode, $form_state['values']['mode']) == FALSE) {
if ($return = _locale_import_po($file, $language->langcode, $form_state['values']['overwrite_options'], $customized) == FALSE) {
$variables = array('%filename' => $file->filename);
drupal_set_message(t('The translation import of %filename failed.', $variables), 'error');
watchdog('locale', 'The translation import of %filename failed.', $variables, WATCHDOG_ERROR);
......@@ -106,11 +124,9 @@ function locale_translate_import_form_submit($form, &$form_state) {
}
/**
* User interface for the translation export screen.
* Builds form to export Gettext translation files.
*/
function locale_translate_export_screen() {
// Get all enabled languages, except English, if we should not translate that.
drupal_static_reset('language_list');
function locale_translate_export_form($form, &$form_state) {
$languages = language_list(TRUE);
$language_options = array();
foreach ($languages as $langcode => $language) {
......@@ -118,65 +134,80 @@ function locale_translate_export_screen() {
$language_options[$langcode] = $language->name;
}
}
$language_default = language_default();
$output = '';
// Offer translation export if any language is set up.
if (!empty($language_options)) {
$elements = drupal_get_form('locale_translate_export_po_form', $language_options);
$output = drupal_render($elements);
if (empty($language_options)) {
$form['langcode'] = array(
'#type' => 'value',
'#value' => LANGUAGE_SYSTEM,
);
$form['langcode_text'] = array(
'#type' => 'item',
'#title' => t('Language'),
'#markup' => t('No language available. The export will only contain source strings.'),
);
}
else {
$form['langcode'] = array(
'#type' => 'select',
'#title' => t('Language'),
'#options' => $language_options,
'#default_value' => $language_default->langcode,
'#empty_option' => t('Source text only, no translations'),
'#empty_value' => LANGUAGE_SYSTEM,
);
$form['content_options'] = array(
'#type' => 'fieldset',
'#title' => t('Export options'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#tree' => TRUE,
'#states' => array(
'invisible' => array(
':input[name="langcode"]' => array('value' => LANGUAGE_SYSTEM),
),
),
);
$form['content_options']['not_customized'] = array(
'#type' => 'checkbox',
'#title' => t('Include non-customized translations'),
'#default_value' => TRUE,
);
$form['content_options']['customized'] = array(
'#type' => 'checkbox',
'#title' => t('Include customized translations'),
'#default_value' => TRUE,
);
$form['content_options']['not_translated'] = array(
'#type' => 'checkbox',
'#title' => t('Include untranslated text'),
'#default_value' => TRUE,
);
}
$elements = drupal_get_form('locale_translate_export_pot_form');
$output .= drupal_render($elements);
return $output;
}
/**
* Form to export PO files for the languages provided.
*
* @param $names
* An associate array with localized language names
*/
function locale_translate_export_po_form($form, &$form_state, $names) {
$form['export_title'] = array('#type' => 'item',
'#title' => t('Export translation'),
$form['actions'] = array(
'#type' => 'actions'
);
$form['langcode'] = array('#type' => 'select',
'#title' => t('Language name'),
'#options' => $names,
'#description' => t('Select the language to export in Gettext Portable Object (<em>.po</em>) format.'),
$form['actions']['submit'] = array(
'#type' => 'submit',
'#value' => t('Export')
);
$form['actions'] = array('#type' => 'actions');
$form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Export'));
return $form;
}
/**
* Translation template export form.
* Processes a translation (or template) export form submission.
*/
function locale_translate_export_pot_form() {
// Complete template export of the strings
$form['export_title'] = array('#type' => 'item',
'#title' => t('Export template'),
'#description' => t('Generate a Gettext Portable Object Template (<em>.pot</em>) file with all strings from the Drupal locale database.'),
);
$form['actions'] = array('#type' => 'actions');
$form['actions']['submit'] = array('#type' => 'submit', '#value' => t('Export'));
// Reuse PO export submission callback.
$form['#submit'][] = 'locale_translate_export_po_form_submit';
return $form;
}
/**
* Process a translation (or template) export form submission.
*/
function locale_translate_export_po_form_submit($form, &$form_state) {
function locale_translate_export_form_submit($form, &$form_state) {
// If template is required, language code is not given.
$language = NULL;
if (isset($form_state['values']['langcode'])) {
$languages = language_list();
$language = $languages[$form_state['values']['langcode']];
if ($form_state['values']['langcode'] != LANGUAGE_SYSTEM) {
$language = language_load($form_state['values']['langcode']);
}
else {
$language = NULL;
}
_locale_export_po($language, _locale_export_po_generate($language, _locale_export_get_strings($language)));
$content_options = isset($form_state['values']['content_options']) ? $form_state['values']['content_options'] : array();
_locale_export_po($language, _locale_export_po_generate($language, _locale_export_get_strings($language, $content_options)));
}
/**
......@@ -267,7 +298,7 @@ function locale_translate_batch_import($filepath, &$context) {
// we can extract the language code to use for the import from the end.
if (preg_match('!(/|\.)([^\./]+)\.po$!', $filepath, $langcode)) {
$file = (object) array('filename' => drupal_basename($filepath), 'uri' => $filepath);
_locale_import_read_po('db-store', $file, LOCALE_IMPORT_KEEP, $langcode[2]);
_locale_import_read_po('db-store', $file, array(), $langcode[2]);
$context['results'][] = $filepath;
}
}
......
......@@ -6,7 +6,7 @@
#locale-translation-filter-form .form-item-language,
#locale-translation-filter-form .form-item-translation,
#locale-translation-filter-form .form-item-group {
#locale-translation-filter-form .form-item-customized {
float: left; /* LTR */
padding-right: .8em; /* LTR */
margin: 0.1em;
......
......@@ -176,6 +176,12 @@ function locale_schema() {
'default' => '',
'description' => 'Language code. References {language}.langcode.',
),
'customized' => array(
'type' => 'int',
'not null' => TRUE,
'default' => 0, // LOCALE_NOT_CUSTOMIZED
'description' => 'Boolean indicating whether the translation is custom to this site.',
),
),
'primary key' => array('language', 'lid'),
'foreign keys' => array(
......@@ -484,6 +490,19 @@ function locale_update_8005() {
db_add_primary_key('locales_target', array('language', 'lid'));
}
/**
* Add column to track customized string status to locales_target.
*/
function locale_update_8006() {
$spec = array(
'type' => 'int',
'not null' => TRUE,
'default' => 0, // LOCALE_NOT_CUSTOMIZED
'description' => 'Boolean indicating whether the translation is custom to this site.',
);
db_add_field('locales_target', 'customized', $spec);
}
/**
* @} End of "addtogroup updates-7.x-to-8.x"
* The next series of updates should start at 9000.
......
......@@ -124,7 +124,8 @@ function locale_menu() {
);
$items['admin/config/regional/translate/export'] = array(
'title' => 'Export',
'page callback' => 'locale_translate_export_screen', // possibly multiple forms concatenated
'page callback' => 'drupal_get_form',
'page arguments' => array('locale_translate_export_form'),
'access arguments' => array('translate interface'),
'weight' => 30,
'type' => MENU_LOCAL_TASK,
......
......@@ -29,6 +29,7 @@ function _locale_translate_seek() {
$query = array(
'translation' => 'all',
'language' => 'all',
'customized' => 'all',
'string' => '',
);
}
......@@ -36,13 +37,16 @@ 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', 'context', 'lid'));
$sql_query->fields('t', array('translation', 'language'));
$sql_query->fields('t', array('translation', 'language', 'customized'));
// Compute LIKE section.
switch ($query['translation']) {
case 'translated':
$sql_query->condition('t.translation', '%' . db_like($query['string']) . '%', 'LIKE');
$sql_query->orderBy('t.translation', 'DESC');
if ($query['customized'] != 'all') {
$sql_query->condition('t.customized', $query['customized']);
}
break;
case 'untranslated':
$sql_query->condition(db_and()
......@@ -134,7 +138,7 @@ function _locale_translate_seek_query() {
$query = &drupal_static(__FUNCTION__);
if (!isset($query)) {
$query = array();
$fields = array('string', 'language', 'translation');
$fields = array('string', 'language', 'translation', 'customized');
foreach ($fields as $field) {
if (isset($_SESSION['locale_translation_filter'][$field])) {
$query[$field] = $_SESSION['locale_translation_filter'][$field];
......@@ -172,7 +176,25 @@ function locale_translation_filters() {
$filters['translation'] = array(
'title' => t('Search in'),
'options' => array('all' => t('Both translated and untranslated strings'), 'translated' => t('Only translated strings'), 'untranslated' => t('Only untranslated strings')),
'options' => array(
'all' => t('Both translated and untranslated strings'),
'translated' => t('Only translated strings'),
'untranslated' => t('Untranslated strings')
),
);
$filters['customized'] = array(
'title' => t('Translation type'),
'options' => array(
'all' => t('All'),
LOCALE_NOT_CUSTOMIZED => t('Non-customized translation'),
LOCALE_CUSTOMIZED => t('Customized translation'),
),
'states' => array(
'visible' => array(
':input[name=translation]' => array('value' => 'translated'),
)
),
);
return $filters;
......@@ -210,6 +232,9 @@ function locale_translation_filter_form() {
'#size' => 0,
'#options' => $filter['options'],
);
if (isset($filter['states'])) {
$form['filters']['status'][$key]['#states'] = $filter['states'];
}
}
if (!empty($_SESSION['locale_translation_filter'][$key])) {
$form['filters']['status'][$key]['#default_value'] = $_SESSION['locale_translation_filter'][$key];
......@@ -435,21 +460,23 @@ function locale_translate_edit_form_submit($form, &$form_state) {
}
if ($has_translation) {
// Only update or insert if we have a value to use.
if (!empty($translation)) {
if (!empty($translation) && $translation != $value) {
db_update('locales_target')
->fields(array(
'translation' => $value,
'customized' => LOCALE_CUSTOMIZED,
))
->condition('lid', $lid)
->condition('language', $langcode)
->execute();
}
else {
if (empty($translation)) {
db_insert('locales_target')
->fields(array(
'lid' => $lid,
'translation' => $value,
'language' => $langcode,
'customized' => LOCALE_CUSTOMIZED,
))
->execute();
}
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment