#152670 by myself: refactor PO generation to decouple data collection, file generation and HTTP download; fix a bug with plural exports along the way
parent
17e97036ae
commit
bedf78d558
|
@ -731,7 +731,12 @@ function locale_translate_export_pot_form() {
|
|||
*/
|
||||
function locale_translate_export_po_form_submit($form, &$form_state) {
|
||||
// If template is required, language code is not given.
|
||||
_locale_export_po(isset($form_state['values']['langcode']) ? $form_state['values']['langcode'] : NULL, $form_state['values']['group']);
|
||||
$language = NULL;
|
||||
if (isset($form_state['values']['langcode'])) {
|
||||
$languages = language_list();
|
||||
$language = $languages[$form_state['values']['langcode']];
|
||||
}
|
||||
_locale_export_po($language, _locale_export_po_generate($language, _locale_export_get_strings($language, $form_state['values']['group'])));
|
||||
}
|
||||
/**
|
||||
* @} End of "locale-translate-export"
|
||||
|
@ -1683,109 +1688,115 @@ function _locale_parse_js_file($filepath) {
|
|||
*/
|
||||
|
||||
/**
|
||||
* Exports a Portable Object (Template) file for a language
|
||||
* Generates a structured array of all strings with translations in
|
||||
* $language, if given. This array can be used to generate an export
|
||||
* of the string in the database.
|
||||
*
|
||||
* @param $language
|
||||
* Language code to generate the output for, or NULL if generating
|
||||
* Language object to generate the output for, or NULL if generating
|
||||
* translation template.
|
||||
* @param $group
|
||||
* Text group to export PO file from (eg. 'default' for interface translations)
|
||||
*/
|
||||
function _locale_export_po($language = NULL, $group = 'default') {
|
||||
global $user;
|
||||
$header = '';
|
||||
// Get language specific strings, or all strings
|
||||
function _locale_export_get_strings($language = NULL, $group = 'default') {
|
||||
if (isset($language)) {
|
||||
$meta = db_fetch_object(db_query("SELECT * FROM {languages} WHERE language = '%s'", $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 WHERE t.language = '%s' AND s.textgroup = '%s' ORDER BY t.plid, t.plural", $language, $group);
|
||||
$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 WHERE t.language = '%s' AND s.textgroup = '%s' ORDER BY t.plid, t.plural", $language->language, $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 = '%s' ORDER BY t.plid, t.plural", $group);
|
||||
}
|
||||
|
||||
// Build array out of the database results
|
||||
$parent = array();
|
||||
$strings = array();
|
||||
while ($child = db_fetch_object($result)) {
|
||||
if ($child->source != '') {
|
||||
$parent[$child->lid]['comment'] = $child->location;
|
||||
$parent[$child->lid]['msgid'] = $child->source;
|
||||
$parent[$child->lid]['translation'] = isset($child->translation) ? $child->translation : '';
|
||||
if ($child->plid) {
|
||||
$parent[$child->lid]['child'] = 1;
|
||||
$parent[$child->plid]['plural'] = $child->lid;
|
||||
$string = array(
|
||||
'comment' => $child->location,
|
||||
'source' => $child->source,
|
||||
'translation' => isset($child->translation) ? $child->translation : ''
|
||||
);
|
||||
if ($child->plid) {
|
||||
// Has a parent lid. Since we process in the order of plids,
|
||||
// we already have the parent in the array, so we can add the
|
||||
// lid to the next plural version to it. This builds a linked
|
||||
// list of plurals.
|
||||
$string['child'] = TRUE;
|
||||
$strings[$child->plid]['plural'] = $child->lid;
|
||||
}
|
||||
$strings[$child->lid] = $string;
|
||||
}
|
||||
return $strings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the PO(T) file contents for given strings.
|
||||
*
|
||||
* @param $language
|
||||
* Language object to generate the output for, or NULL if generating
|
||||
* translation template.
|
||||
* @param $strings
|
||||
* Array of strings to export. See _locale_export_get_strings()
|
||||
* on how it should be formatted.
|
||||
* @param $header
|
||||
* The header portion to use for the output file. Defaults
|
||||
* are provided for PO and POT files.
|
||||
*/
|
||||
function _locale_export_po_generate($language = NULL, $strings = array(), $header = NULL) {
|
||||
global $user;
|
||||
|
||||
if (!isset($header)) {
|
||||
if (isset($language)) {
|
||||
$header = '# '. $language->name .' translation of '. variable_get('site_name', 'Drupal') ."\n";
|
||||
$header .= '# Generated by '. $user->name .' <'. $user->mail .">\n";
|
||||
$header .= "#\n";
|
||||
$header .= "msgid \"\"\n";
|
||||
$header .= "msgstr \"\"\n";
|
||||
$header .= "\"Project-Id-Version: PROJECT VERSION\\n\"\n";
|
||||
$header .= "\"POT-Creation-Date: ". date("Y-m-d H:iO") ."\\n\"\n";
|
||||
$header .= "\"PO-Revision-Date: ". date("Y-m-d H:iO") ."\\n\"\n";
|
||||
$header .= "\"Last-Translator: NAME <EMAIL@ADDRESS>\\n\"\n";
|
||||
$header .= "\"Language-Team: LANGUAGE <EMAIL@ADDRESS>\\n\"\n";
|
||||
$header .= "\"MIME-Version: 1.0\\n\"\n";
|
||||
$header .= "\"Content-Type: text/plain; charset=utf-8\\n\"\n";
|
||||
$header .= "\"Content-Transfer-Encoding: 8bit\\n\"\n";
|
||||
if ($language->formula && $language->plurals) {
|
||||
$header .= "\"Plural-Forms: nplurals=". $language->plurals ."; plural=". strtr($language->formula, array('$' => '')) .";\\n\"\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Generating Portable Object file for a language
|
||||
if (isset($language)) {
|
||||
$filename = $language .'.po';
|
||||
$header = "# $meta->name translation of ". variable_get('site_name', 'Drupal') ."\n";
|
||||
$header .= '# Copyright (c) '. date('Y') .' '. $user->name .' <'. $user->mail .">\n";
|
||||
$header .= "#\n";
|
||||
$header .= "msgid \"\"\n";
|
||||
$header .= "msgstr \"\"\n";
|
||||
$header .= "\"Project-Id-Version: PROJECT VERSION\\n\"\n";
|
||||
$header .= "\"POT-Creation-Date: ". date("Y-m-d H:iO") ."\\n\"\n";
|
||||
$header .= "\"PO-Revision-Date: ". date("Y-m-d H:iO") ."\\n\"\n";
|
||||
$header .= "\"Last-Translator: ". $user->name .' <'. $user->mail .">\\n\"\n";
|
||||
$header .= "\"Language-Team: ". $meta->name .' <'. $user->mail .">\\n\"\n";
|
||||
$header .= "\"MIME-Version: 1.0\\n\"\n";
|
||||
$header .= "\"Content-Type: text/plain; charset=utf-8\\n\"\n";
|
||||
$header .= "\"Content-Transfer-Encoding: 8bit\\n\"\n";
|
||||
if ($meta->formula && $meta->plurals) {
|
||||
$header .= "\"Plural-Forms: nplurals=". $meta->plurals ."; plural=". strtr($meta->formula, array('$' => '')) .";\\n\"\n";
|
||||
else {
|
||||
$header = "# LANGUAGE translation of PROJECT\n";
|
||||
$header .= "# Copyright (c) YEAR NAME <EMAIL@ADDRESS>\n";
|
||||
$header .= "#\n";
|
||||
$header .= "msgid \"\"\n";
|
||||
$header .= "msgstr \"\"\n";
|
||||
$header .= "\"Project-Id-Version: PROJECT VERSION\\n\"\n";
|
||||
$header .= "\"POT-Creation-Date: ". date("Y-m-d H:iO") ."\\n\"\n";
|
||||
$header .= "\"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\\n\"\n";
|
||||
$header .= "\"Last-Translator: NAME <EMAIL@ADDRESS>\\n\"\n";
|
||||
$header .= "\"Language-Team: LANGUAGE <EMAIL@ADDRESS>\\n\"\n";
|
||||
$header .= "\"MIME-Version: 1.0\\n\"\n";
|
||||
$header .= "\"Content-Type: text/plain; charset=utf-8\\n\"\n";
|
||||
$header .= "\"Content-Transfer-Encoding: 8bit\\n\"\n";
|
||||
$header .= "\"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\\n\"\n";
|
||||
}
|
||||
$header .= "\n";
|
||||
watchdog('locale', 'Exported %locale translation file: %filename.', array('%locale' => $meta->name, '%filename' => $filename));
|
||||
}
|
||||
|
||||
// Generating Portable Object Template
|
||||
else {
|
||||
$filename = 'drupal.pot';
|
||||
$header = "# LANGUAGE translation of PROJECT\n";
|
||||
$header .= "# Copyright (c) YEAR NAME <EMAIL@ADDRESS>\n";
|
||||
$header .= "#\n";
|
||||
$header .= "msgid \"\"\n";
|
||||
$header .= "msgstr \"\"\n";
|
||||
$header .= "\"Project-Id-Version: PROJECT VERSION\\n\"\n";
|
||||
$header .= "\"POT-Creation-Date: ". date("Y-m-d H:iO") ."\\n\"\n";
|
||||
$header .= "\"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\\n\"\n";
|
||||
$header .= "\"Last-Translator: NAME <EMAIL@ADDRESS>\\n\"\n";
|
||||
$header .= "\"Language-Team: LANGUAGE <EMAIL@ADDRESS>\\n\"\n";
|
||||
$header .= "\"MIME-Version: 1.0\\n\"\n";
|
||||
$header .= "\"Content-Type: text/plain; charset=utf-8\\n\"\n";
|
||||
$header .= "\"Content-Transfer-Encoding: 8bit\\n\"\n";
|
||||
$header .= "\"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\\n\"\n";
|
||||
$header .= "\n";
|
||||
watchdog('locale', 'Exported translation file: %filename.', array('%filename' => $filename));
|
||||
}
|
||||
|
||||
// Start download process
|
||||
header("Content-Disposition: attachment; filename=$filename");
|
||||
header("Content-Type: text/plain; charset=utf-8");
|
||||
|
||||
print $header;
|
||||
|
||||
foreach ($parent as $lid => $message) {
|
||||
if (!isset($message['child'])) {
|
||||
if ($message['comment']) {
|
||||
print '#: '. $message['comment'] ."\n";
|
||||
|
||||
$output = $header ."\n";
|
||||
|
||||
foreach ($strings as $lid => $string) {
|
||||
// Only process non-children, children are output below their parent.
|
||||
if (!isset($string['child'])) {
|
||||
if ($string['comment']) {
|
||||
$output .= '#: '. $string['comment'] ."\n";
|
||||
}
|
||||
print 'msgid '. _locale_export_print($message['msgid']);
|
||||
if (!empty($message['plural'])) {
|
||||
$plural = $message['plural'];
|
||||
print 'msgid_plural '. _locale_export_print($parent[$plural]['msgid']);
|
||||
$output .= 'msgid '. _locale_export_string($string['source']);
|
||||
if (!empty($string['plural'])) {
|
||||
$plural = $string['plural'];
|
||||
$output .= 'msgid_plural '. _locale_export_string($strings[$plural]['source']);
|
||||
if (isset($language)) {
|
||||
$translation = $message['translation'];
|
||||
for ($i = 0; $i < $meta->plurals; $i++) {
|
||||
print 'msgstr['. $i .'] '. _locale_export_print($translation);
|
||||
$translation = $string['translation'];
|
||||
for ($i = 0; $i < $language->plurals; $i++) {
|
||||
$output .= 'msgstr['. $i .'] '. _locale_export_string($translation);
|
||||
if ($plural) {
|
||||
$translation = $parent[$plural]['translation'];
|
||||
if ($i > 1) {
|
||||
$translation = _locale_export_remove_plural($translation);
|
||||
}
|
||||
$plural = $parent[$plural]['plural'];
|
||||
$translation = _locale_export_remove_plural($strings[$plural]['translation']);
|
||||
$plural = isset($strings[$plural]['plural']) ? $strings[$plural]['plural'] : 0;
|
||||
}
|
||||
else {
|
||||
$translation = '';
|
||||
|
@ -1793,28 +1804,50 @@ function _locale_export_po($language = NULL, $group = 'default') {
|
|||
}
|
||||
}
|
||||
else {
|
||||
print 'msgstr[0] ""'."\n";
|
||||
print 'msgstr[1] ""'."\n";
|
||||
$output .= 'msgstr[0] ""'."\n";
|
||||
$output .= 'msgstr[1] ""'."\n";
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (isset($language)) {
|
||||
print 'msgstr '. _locale_export_print($message['translation']);
|
||||
}
|
||||
else {
|
||||
print 'msgstr ""'."\n";
|
||||
}
|
||||
$output .= 'msgstr '. _locale_export_string($string['translation']);
|
||||
}
|
||||
print "\n";
|
||||
$output .= "\n";
|
||||
}
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a generated PO or POT file to the output.
|
||||
*
|
||||
* @param $language
|
||||
* Language object to generate the output for, or NULL if generating
|
||||
* translation template.
|
||||
* @param $output
|
||||
* The PO(T) file to output as a string. See _locale_export_generate_po()
|
||||
* on how it can be generated.
|
||||
*/
|
||||
function _locale_export_po($language = NULL, $output = NULL) {
|
||||
// Log the export event.
|
||||
if (isset($language)) {
|
||||
$filename = $language->language .'.po';
|
||||
watchdog('locale', 'Exported %locale translation file: %filename.', array('%locale' => $language->name, '%filename' => $filename));
|
||||
}
|
||||
else {
|
||||
$filename = 'drupal.pot';
|
||||
watchdog('locale', 'Exported translation file: %filename.', array('%filename' => $filename));
|
||||
}
|
||||
// Download the file fo the client.
|
||||
header("Content-Disposition: attachment; filename=$filename");
|
||||
header("Content-Type: text/plain; charset=utf-8");
|
||||
print $output;
|
||||
die();
|
||||
}
|
||||
|
||||
/**
|
||||
* Print out a string on multiple lines
|
||||
*/
|
||||
function _locale_export_print($str) {
|
||||
function _locale_export_string($str) {
|
||||
$stri = addcslashes($str, "\0..\37\\\"");
|
||||
$parts = array();
|
||||
|
||||
|
|
Loading…
Reference in New Issue