Index: includes/locale.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/locale.inc,v retrieving revision 1.205 diff -u -p -r1.205 locale.inc --- includes/locale.inc 22 Feb 2009 17:55:29 -0000 1.205 +++ includes/locale.inc 23 Feb 2009 23:02:13 -0000 @@ -2605,6 +2605,8 @@ function locale_batch_by_language($langc // Collect all files to import for all enabled modules and themes. $files = array(); $components = array(); + + $language_with_fallbacks = _locale_get_language_with_fallbacks($langcode); $query = db_select('system', 's'); $query->fields('s', array('name', 'filename')); $query->condition('s.status', 1); @@ -2613,11 +2615,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$/', array('recurse' => FALSE))); + // Iterate through a language and its potential fallbacks. + // We need to do this in order to ensure that the language takes + // precedence over its fallback. + foreach ($language_with_fallbacks as $language) { + // Collect all files for all components, names as $language.po or + // with names ending with $language.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$/', array('recurse' => FALSE)); + // Whether for the original or a 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; } @@ -2640,16 +2653,32 @@ 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$/', array('recurse' => FALSE))); + foreach (array_keys($languages[1]) as $langcode) { + $language_with_fallbacks = _locale_get_language_with_fallbacks($langcode); + // Collect all files to import for all $components. + $query = db_select('system', 's'); + $query->fields('s', array('name', 'filename')); + $query->condition('s.status', 1); + $result = $query->execute(); + foreach ($result as $component) { + if (in_array($component->name, $components)) { + // Iterate through a language and its potential fallbacks. + // We need to do this in order to ensure that the language takes + // precedence over its fallback. + foreach ($language_with_fallbacks as $language) { + // Collect all files for this component in all enabled languages, named + // as $language.po or with names ending with $language.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$/', array('recurse' => FALSE)); + // Whether for the original or a 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); @@ -2675,7 +2704,7 @@ 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->filepath)); + $operations[] = array('_locale_batch_import', array($file->filepath, $file->langcode)); } $batch = array( 'operations' => $operations, @@ -2700,15 +2729,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; } } @@ -2734,5 +2766,21 @@ function _locale_batch_language_finished } /** + * Return an array of a language and its fallbacks, if any. + * + * By default, if a language code has more than two digits, the first + * two digits are used as a fallback. + */ +function _locale_get_language_with_fallbacks($langcode) { + $langcodes = array($langcode); + if (strlen($langcode) > 2) { + $langcodes[] = substr($langcode, 0, 2); + } + // Allow other modules to alter the language fallbacks. + drupal_alter('locale_language_fallbacks', $langcodes, $langcode); + return $langcodes; +} + +/** * @} End of "locale-autoimport" */