Index: locale.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/locale.inc,v retrieving revision 1.199 diff -u -p -r1.199 locale.inc --- locale.inc 6 Jan 2009 13:20:17 -0000 1.199 +++ locale.inc 16 Jan 2009 17:03:56 -0000 @@ -2517,6 +2517,7 @@ function locale_batch_by_language($langc // Collect all files to import for all enabled modules and themes. $files = array(); $components = array(); + $languages = _locale_get_language_with_fallback($langcode); $query = db_select('system', 's'); $query->fields('s', array('name', 'filename')); $query->condition('s.status', 1); @@ -2525,11 +2526,22 @@ function locale_batch_by_language($langc } $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$/', '/(\.\.?|CVS)$/', 0, FALSE)); + // Iterate through a language and its potential two-digit fallback. + // We need to do this in order to ensure that the language takes + // precedence over its fallback. + foreach ($languages as $language) { + // 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. + $new_files = file_scan_directory(dirname($component->filename) . '/translations', '/(^|\.)' . $language . '\.po$/', '/(\.\.?|CVS)$/', 0, FALSE); + // Whether for the original or the fallback language, the imports + // need to be assigned to the original language. + foreach (array_keys($new_files) as $key) { + $new_files[$key]->langcode = $langcode; + } + $files = array_merge($files, $new_files); + } $components[] = $component->name; } @@ -2552,16 +2564,29 @@ function locale_batch_by_component($comp $languages = language_list('enabled'); 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"); - while ($component = db_fetch_object($result)) { - 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$/', '/(\.\.?|CVS)$/', 0, FALSE)); + foreach (array_keys($languages[1]) as $langcode) { + $languages = _locale_get_language_with_fallback($langcode); + // Collect all files to import for all $components. + $result = db_query("SELECT name, filename FROM {system} WHERE status = 1"); + while ($component = db_fetch_object($result)) { + if (in_array($component->name, $components)) { + // Iterate through a language and its potential two-digit fallback. + // We need to do this in order to ensure that the language takes + // precedence over its fallback. + foreach ($languages as $language) { + // 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. + $new_files = file_scan_directory(dirname($component->filename) . '/translations', '/(^|\.)' . $language . '\.po$/', '/(\.\.?|CVS)$/', 0, FALSE); + // Whether for the original or the fallback language, the imports + // need to be assigned to the original language. + foreach (array_keys($new_files) as $key) { + $new_files[$key]->langcode = $langcode; + } + $files = array_merge($files, $new_files); + } + } } } return _locale_batch_build($files, $finished); @@ -2587,20 +2612,21 @@ function _locale_batch_build($files, $fi $operations = array(); foreach ($files as $file) { // We call _locale_batch_import for every batch operation. - $operations[] = array('_locale_batch_import', array($file->filename)); } - $batch = array( - 'operations' => $operations, - 'title' => $t('Importing interface translations'), - 'init_message' => $t('Starting import'), - 'error_message' => $t('Error importing interface translations'), - 'file' => 'includes/locale.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; - } + $operations[] = array('_locale_batch_import', array($file->filename, $file->langcode)); + } + $batch = array( + 'operations' => $operations, + 'title' => $t('Importing interface translations'), + 'init_message' => $t('Starting import'), + 'error_message' => $t('Error importing interface translations'), + 'file' => 'includes/locale.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; + } return $batch; } return FALSE; @@ -2611,15 +2637,18 @@ function _locale_batch_build($files, $fi * * @param $filepath * Path to a file to import. - * @param $results + * @param $langcode_override + * A language code to be set to the imported strings. Enables the use + * of language import fallbacks. + * @param $context * Contains a list of files imported. */ -function _locale_batch_import($filepath, &$context) { +function _locale_batch_import($filepath, $langcode_override, &$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)) { $file = (object) array('filename' => basename($filepath), 'filepath' => $filepath); - _locale_import_read_po('db-store', $file, LOCALE_IMPORT_KEEP, $langcode[2]); + _locale_import_read_po('db-store', $file, LOCALE_IMPORT_KEEP, $langcode_override ? $langcode_override : $langcode[2]); $context['results'][] = $filepath; } } @@ -2645,5 +2674,16 @@ function _locale_batch_language_finished } /** + * Return an array of a language and its two-digit fallback, if any. + */ +function _locale_get_language_with_fallback($langcode) { + $langcodes = array($langcode); + if (strlen($langcode) > 2) { + $langcodes[] = substr($langcode, 0, 2); + } + return $langcodes; +} + +/** * @} End of "locale-autoimport" */