Commit dbbdfee9 authored by catch's avatar catch

Issue #1260586 by Gábor Hojtsy, tstoeckler, good_man: Consolidate .po file...

Issue #1260586 by Gábor Hojtsy, tstoeckler, good_man: Consolidate .po file import to one directory..
parent ecff4bd2
......@@ -1125,21 +1125,31 @@ function install_select_profile_form($form, &$form_state, $profile_files) {
}
/**
* Find all .po files for the current profile.
* Find all .po files useful for the installer.
*/
function install_find_locales($profilename) {
$locales = file_scan_directory('./profiles/' . $profilename . '/translations', '/\.po$/', array('recurse' => FALSE));
array_unshift($locales, (object) array('name' => 'en'));
foreach ($locales as $key => $locale) {
// The locale (file name) might be drupal-7.2.cs.po instead of cs.po.
$locales[$key]->langcode = preg_replace('!^(.+\.)?([^\.]+)$!', '\2', $locale->name);
function install_find_locales() {
$files = install_find_locale_files();
// English does not need a translation file.
array_unshift($files, (object) array('name' => 'en'));
foreach ($files as $key => $file) {
// Strip off the file name component before the language code.
$files[$key]->langcode = preg_replace('!^(.+\.)?([^\.]+)$!', '\2', $file->name);
// Language codes cannot exceed 12 characters to fit into the {languages}
// table.
if (strlen($locales[$key]->langcode) > 12) {
unset($locales[$key]);
if (strlen($files[$key]->langcode) > 12) {
unset($files[$key]);
}
}
return $locales;
return $files;
}
/**
* Find installer translations either for a specific langcode or all languages.
*/
function install_find_locale_files($langcode = NULL) {
$directory = variable_get('locale_translate_file_directory', conf_path() . '/files/translations');
$files = file_scan_directory($directory, '!install\.' . (!empty($langcode) ? '\.' . preg_quote($langcode, '!') : '[^\.]+') . '\.po$!', array('recurse' => FALSE));
return $files;
}
/**
......@@ -1409,10 +1419,8 @@ function install_import_locales(&$install_state) {
}
// Collect files to import for this language.
$batch = locale_batch_by_language($install_locale, NULL);
$batch = locale_translate_batch_import_files($install_locale);
if (!empty($batch)) {
// Remember components we cover in this batch set.
variable_set('install_locale_batch_components', $batch['#components']);
return $batch;
}
}
......@@ -1479,23 +1487,22 @@ function install_configure_form($form, &$form_state, &$install_state) {
}
/**
* Installation task; import remaining languages via a batch process.
* Installation task; finish importing files at end of installation.
*
* @param $install_state
* An array of information about the current installation state.
*
* @return
* The batch definition, if there are language files to import.
*
* @todo
* This currently does the same as the first import step. Need to revisit
* once we have l10n_update functionality integrated. See
* http://drupal.org/node/1191488.
*/
function install_import_locales_remaining(&$install_state) {
include_once DRUPAL_ROOT . '/includes/locale.inc';
// Collect files to import for this language. Skip components already covered
// in the initial batch set.
$install_locale = $install_state['parameters']['locale'];
$batch = locale_batch_by_language($install_locale, NULL, variable_get('install_locale_batch_components', array()));
// Remove temporary variable.
variable_del('install_locale_batch_components');
return $batch;
include_once drupal_get_path('module', 'locale') . '/locale.bulk.inc';
return locale_translate_batch_import_files($install_state['parameters']['locale']);
}
/**
......
......@@ -1103,14 +1103,14 @@ function st($string, array $args = array(), array $options = array()) {
$locale_strings = array();
if (isset($install_state['parameters']['profile']) && isset($install_state['parameters']['locale'])) {
// If the given locale was selected, there should be at least one .po file
// with its name ending in {$install_state['parameters']['locale']}.po
// with its name ending in install.{$install_state['parameters']['locale']}.po
// This might or might not be the entire filename. It is also possible
// that multiple files end with the same extension, even if unlikely.
$po_files = file_scan_directory('./profiles/' . $install_state['parameters']['profile'] . '/translations', '/'. $install_state['parameters']['locale'] .'\.po$/', array('recurse' => FALSE));
if (count($po_files)) {
$locale_files = install_find_locale_files($install_state['parameters']['locale']);
if (!empty($locale_files)) {
require_once DRUPAL_ROOT . '/includes/gettext.inc';
foreach ($po_files as $po_file) {
_locale_import_read_po('mem-store', $po_file);
foreach ($locale_files as $locale_file) {
_locale_import_read_po('mem-store', $locale_file);
}
$locale_strings = _locale_import_one_string('mem-report');
}
......
......@@ -379,7 +379,7 @@ function locale_languages_add_set_batch($langcode) {
// See if we have language files to import for the newly added
// language, collect and import them.
include_once drupal_get_path('module', 'locale') . '/locale.bulk.inc';
if ($batch = locale_batch_by_language($langcode, '_locale_batch_language_finished')) {
if ($batch = locale_translate_batch_import_files($langcode, TRUE)) {
batch_set($batch);
}
}
......
......@@ -167,99 +167,42 @@ function locale_translate_export_po_form_submit($form, &$form_state) {
}
/**
* Prepare a batch to import translations for all enabled
* modules in a given language.
* Prepare a batch to import all translations.
*
* @param $langcode
* Language code to import translations for.
* @param $finished
* Optional finished callback for the batch.
* @param $skip
* Array of component names to skip. Used in the installer for the
* second pass import, when most components are already imported.
* (optional) Language code to limit files being imported.
* @param $finish_feedback
* (optional) Whether to give feedback to the user when finished.
*
* @return
* A batch structure or FALSE if no files found.
* @todo
* Integrate with update status to identify projects needed and integrate
* l10n_update functionality to feed in translation files alike.
* See http://drupal.org/node/1191488.
*/
function locale_batch_by_language($langcode, $finished = NULL, $skip = array()) {
// Collect all files to import for all enabled modules and themes.
$files = array();
$components = array();
$query = db_select('system', 's');
$query->fields('s', array('name', 'filename'));
$query->condition('s.status', 1);
if (count($skip)) {
$query->condition('name', $skip, 'NOT IN');
}
$result = $query->execute();
foreach ($result as $component) {
// Collect all files for all components, names as $langcode.po or
// with names ending with $langcode.po. This allows for filenames
// like node-module.de.po to let translators use small files and
// be able to import in smaller chunks.
$files = array_merge($files, file_scan_directory(dirname($component->filename) . '/translations', '/(^|\.)' . $langcode . '\.po$/', array('recurse' => FALSE)));
$components[] = $component->name;
}
return _locale_batch_build($files, $finished, $components);
}
/**
* Prepare a batch to run when installing modules or enabling themes.
*
* This batch will import translations for the newly added components
* in all the languages already set up on the site.
*
* @param $components
* An array of component (theme and/or module) names to import
* translations for.
* @param $finished
* Optional finished callback for the batch.
*/
function locale_batch_by_component($components, $finished = '_locale_batch_system_finished') {
$files = array();
$languages = language_list('enabled');
if (!locale_translate_english()) {
unset($languages[1]['en']);
}
if (count($languages[1])) {
$language_list = join('|', array_keys($languages[1]));
// Collect all files to import for all $components.
$result = db_query("SELECT name, filename FROM {system} WHERE status = 1");
foreach ($result as $component) {
if (in_array($component->name, $components)) {
// Collect all files for this component in all enabled languages, named
// as $langcode.po or with names ending with $langcode.po. This allows
// for filenames like node-module.de.po to let translators use small
// files and be able to import in smaller chunks.
$files = array_merge($files, file_scan_directory(dirname($component->filename) . '/translations', '/(^|\.)(' . $language_list . ')\.po$/', array('recurse' => FALSE)));
}
}
return _locale_batch_build($files, $finished);
}
return FALSE;
function locale_translate_batch_import_files($langcode = NULL, $finish_feedback = FALSE) {
$directory = variable_get('locale_translate_file_directory', conf_path() . '/files/translations');
$files = file_scan_directory($directory, '!' . (!empty($langcode) ? '\.' . preg_quote($langcode, '!') : '') . '\.po$!', array('recurse' => FALSE));
return locale_translate_batch_build($files, $finish_feedback);
}
/**
* Build a locale batch from an array of files.
*
* @param $files
* Array of files to import.
* @param $finished
* Optional finished callback for the batch.
* @param $components
* Optional list of component names the batch covers. Used in the installer.
* Array of file objects to import.
* @param $finish_feedback
* (optional) Whether to give feedback to the user when finished.
*
* @return
* A batch structure.
* A batch structure or FALSE if $files was empty.
*/
function _locale_batch_build($files, $finished = NULL, $components = array()) {
function locale_translate_batch_build($files, $finish_feedback = FALSE) {
$t = get_t();
if (count($files)) {
$operations = array();
foreach ($files as $file) {
// We call _locale_batch_import for every batch operation.
$operations[] = array('_locale_batch_import', array($file->uri));
// We call locale_translate_batch_import for every batch operation.
$operations[] = array('locale_translate_batch_import', array($file->uri));
}
$batch = array(
'operations' => $operations,
......@@ -267,12 +210,9 @@ function _locale_batch_build($files, $finished = NULL, $components = array()) {
'init_message' => $t('Starting import'),
'error_message' => $t('Error importing interface translations'),
'file' => drupal_get_path('module', 'locale') . '/locale.bulk.inc',
// This is not a batch API construct, but data passed along to the
// installer, so we know what did we import already.
'#components' => $components,
);
if (isset($finished)) {
$batch['finished'] = $finished;
if ($finish_feedback) {
$batch['finished'] = 'locale_translate_batch_finished';
}
return $batch;
}
......@@ -287,7 +227,7 @@ function _locale_batch_build($files, $finished = NULL, $components = array()) {
* @param $results
* Contains a list of files imported.
*/
function _locale_batch_import($filepath, &$context) {
function locale_translate_batch_import($filepath, &$context) {
// The filename is either {langcode}.po or {prefix}.{langcode}.po, so
// we can extract the language code to use for the import from the end.
if (preg_match('!(/|\.)([^\./]+)\.po$!', $filepath, $langcode)) {
......@@ -299,20 +239,9 @@ function _locale_batch_import($filepath, &$context) {
/**
* Finished callback of system page locale import batch.
* Inform the user of translation files imported.
*/
function _locale_batch_system_finished($success, $results) {
if ($success) {
drupal_set_message(format_plural(count($results), 'One translation file imported for the newly installed modules.', '@count translation files imported for the newly installed modules.'));
}
}
/**
* Finished callback of language addition locale import batch.
* Inform the user of translation files imported.
*/
function _locale_batch_language_finished($success, $results) {
function locale_translate_batch_finished($success, $results) {
if ($success) {
drupal_set_message(format_plural(count($results), 'One translation file imported for the enabled modules.', '@count translation files imported for the enabled modules.'));
drupal_set_message(format_plural(count($results), 'One translation file imported.', '@count translation files imported.'));
}
}
......@@ -851,10 +851,16 @@ function locale_themes_enabled($themes) {
* @param $components
* An array of component (theme and/or module) names to import
* translations for.
*
* @todo
* This currently imports all .po files available, independent of
* $components. Once we integrated with update status for project
* identification, we should revisit and only import files for the
* identified projects for the components.
*/
function locale_system_update($components) {
include_once drupal_get_path('module', 'locale') . '/locale.bulk.inc';
if ($batch = locale_batch_by_component($components)) {
if ($batch = locale_translate_batch_import_files(NULL, TRUE)) {
batch_set($batch);
}
}
......@@ -1146,3 +1152,23 @@ function locale_form_locale_languages_edit_form_alter_submit($form, $form_state)
function locale_translate_english() {
return variable_get('locale_translate_english', FALSE);
}
/**
* Implements hook_form_FORM_ID_alter() for system_file_system_settings().
*
* Add interface translation directory setting to directories configuration.
*/
function locale_form_system_file_system_settings_alter(&$form, $form_state) {
$form['locale_translate_file_directory'] = array(
'#type' => 'textfield',
'#title' => t('Interface translations directory'),
'#default_value' => variable_get('locale_translate_file_directory', conf_path() . '/files/translations'),
'#maxlength' => 255,
'#description' => t('A local file system path where interface translation files are looked for. This directory must exist.'),
'#after_build' => array('system_check_directory'),
'#weight' => 10,
);
if ($form['file_default_scheme']) {
$form['file_default_scheme']['#weight'] = 20;
}
}
......@@ -720,6 +720,9 @@ class LocaleImportFunctionalTest extends DrupalWebTestCase {
function setUp() {
parent::setUp('locale', 'locale_test');
// Set the translation file directory.
variable_set('locale_translate_file_directory', drupal_get_path('module', 'locale_test'));
$this->admin_user = $this->drupalCreateUser(array('administer languages', 'translate interface', 'access administration pages'));
$this->drupalLogin($this->admin_user);
}
......@@ -830,7 +833,7 @@ class LocaleImportFunctionalTest extends DrupalWebTestCase {
// Ensure the translation file was automatically imported when language was
// added.
$this->assertText(t('One translation file imported for the enabled modules.'), t('Language file automatically imported.'));
$this->assertText(t('One translation file imported.'), t('Language file automatically imported.'));
// Ensure strings were successfully imported.
$search = array(
......
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