Commit 941139bf authored by Dries's avatar Dries
Browse files

- Patch #47610 by Goba: reduced locale memory requirements

parent f0e6aa05
......@@ -156,123 +156,14 @@ function _locale_import_po($file, $lang, $mode) {
return FALSE;
}
// Check if we can get the strings from the file
if (!($strings = _locale_import_read_po($file))) {
drupal_set_message(t('The translation file %filename appears to contain errors and could not be read.', array('%filename' => theme('placeholder', $file->filename))), 'error');
return FALSE;
}
// Get strings from file (returns on failure after a partial import, or on success)
_locale_import_read_po($file, $lang);
// Strip out header from the string pairs
$header = $strings[""]["msgstr"];
unset($strings[""]);
// Get status information on import process
list($headerdone, $additions, $updates) = _locale_import_one_string('report');
// Get information from the header into the database
if ($header) {
$hdr = _locale_import_parse_header($header);
// Get the plural formula
if ($hdr["Plural-Forms"] && $p = _locale_import_parse_plural_forms($hdr["Plural-Forms"], $file->filename)) {
list($nplurals, $plural) = $p;
db_query("UPDATE {locales_meta} SET plurals = %d, formula = '%s' WHERE locale = '%s'", $nplurals, $plural, $lang);
}
else {
db_query("UPDATE {locales_meta} SET plurals = %d, formula = '%s' WHERE locale = '%s'", 0, '', $lang);
}
}
else {
if (!$headerdone) {
drupal_set_message(t('The translation file %filename appears to have a missing or malformed header.', array('%filename' => theme('placeholder', $file->filename))), 'error');
return FALSE;
}
$additions = 0;
$updates = 0;
foreach ($strings as $value) {
$comments = _locale_import_shorten_comments($value['#']);
// Handle a translation for some plural string
if (strpos($value['msgid'], "\0")) {
$english = explode("\0", $value['msgid'], 2);
$entries = array_keys($value['msgstr']);
for ($i = 3; $i <= count($entries); $i++) {
$english[] = $english[1];
}
$translation = array_map('_locale_import_append_plural', $value['msgstr'], $entries);
$english = array_map('_locale_import_append_plural', $english, $entries);
foreach ($translation as $key => $trans) {
if ($key == 0) {
$plid = 0;
}
$loc = db_fetch_object(db_query("SELECT lid FROM {locales_source} WHERE source = '%s'", $english[$key]));
if ($loc->lid) { // a string exists
$lid = $loc->lid;
// update location field
db_query("UPDATE {locales_source} SET location = '%s' WHERE lid = %d", $comments, $lid);
$trans2 = db_fetch_object(db_query("SELECT lid, translation, plid, plural FROM {locales_target} WHERE lid = %d AND locale = '%s'", $lid, $lang));
if (!$trans2->lid) { // no translation in current language
db_query("INSERT INTO {locales_target} (lid, locale, translation, plid, plural) VALUES (%d, '%s', '%s', %d, %d)", $lid, $lang, $trans, $plid, $key);
$additions++;
} // translation exists
else if ($mode == 'overwrite' || $trans2->translation == '') {
db_query("UPDATE {locales_target} SET translation = '%s', plid = %d, plural = %d WHERE locale = '%s' AND lid = %d", $trans, $plid, $key, $lang, $lid);
if ($trans2->translation == '') {
$additions++;
}
else {
$updates++;
}
}
}
else { // no string
db_query("INSERT INTO {locales_source} (location, source) VALUES ('%s', '%s')", $comments, $english[$key]);
$loc = db_fetch_object(db_query("SELECT lid FROM {locales_source} WHERE source = '%s'", $english[$key]));
$lid = $loc->lid;
db_query("INSERT INTO {locales_target} (lid, locale, translation, plid, plural) VALUES (%d, '%s', '%s', %d, %d)", $lid, $lang, $trans, $plid, $key);
if ($trans != '') {
$additions++;
}
}
$plid = $lid;
}
}
// A simple translation
else {
$english = $value['msgid'];
$translation = $value['msgstr'];
$loc = db_fetch_object(db_query("SELECT lid FROM {locales_source} WHERE source = '%s'", $english));
if ($loc->lid) { // a string exists
$lid = $loc->lid;
// update location field
db_query("UPDATE {locales_source} SET location = '%s' WHERE source = '%s'", $comments, $english);
$trans = db_fetch_object(db_query("SELECT lid, translation FROM {locales_target} WHERE lid = %d AND locale = '%s'", $lid, $lang));
if (!$trans->lid) { // no translation in current language
db_query("INSERT INTO {locales_target} (lid, locale, translation) VALUES (%d, '%s', '%s')", $lid, $lang, $translation);
$additions++;
} // translation exists
else if ($mode == 'overwrite') { //overwrite in any case
db_query("UPDATE {locales_target} SET translation = '%s' WHERE locale = '%s' AND lid = %d", $translation, $lang, $lid);
if ($trans->translation == '') {
$additions++;
}
else {
$updates++;
}
} // overwrite if empty string
else if ($trans->translation == '') {
db_query("UPDATE {locales_target} SET translation = '%s' WHERE locale = '%s' AND lid = %d", $translation, $lang, $lid);
$additions++;
}
}
else { // no string
db_query("INSERT INTO {locales_source} (location, source) VALUES ('%s', '%s')", $comments, $english);
$loc = db_fetch_object(db_query("SELECT lid FROM {locales_source} WHERE source = '%s'", $english));
$lid = $loc->lid;
db_query("INSERT INTO {locales_target} (lid, locale, translation) VALUES (%d, '%s', '%s')", $lid, $lang, $translation);
if ($translation != '') {
$additions++;
}
}
}
}
// rebuild locale cache
......@@ -292,38 +183,31 @@ function _locale_import_po($file, $lang, $mode) {
* @param $file Object with properties of local file to parse
* @author Jacobo Tarrio
*/
function _locale_import_read_po($file) {
function _locale_import_read_po($file, $lang) {
$message = theme('placeholder', $file->filename);
$fd = fopen($file->filepath, "rb");
$fd = fopen($file->filepath, "rb"); // File will get closed by PHP on return
if (!$fd) {
drupal_set_message(t('The translation import failed, because the file %filename could not be read.', array('%filename' => $message)), 'error');
return FALSE;
}
$info = fstat($fd);
$len = $info["size"];
$po = fread($fd, $len);
fclose($fd);
$context = "COMMENT"; // Parser context: COMMENT, MSGID, MSGID_PLURAL, MSGSTR and MSGSTR_ARR
$current = array(); // Current entry being read
$strings = array(); // List of entries read
$plural = 0; // Current plural form
$lineno = 0; // Current line
$po = strtr($po, array("\\\n" => ""));
$lines = explode("\n", $po);
$lineno = 0;
foreach ($lines as $line) {
while (!feof($fd)) {
$line = fgets($fd, 10*1024); // A line should not be this long
$lineno++;
$line = trim($line);
$line = trim(strtr($line, array("\\\n" => "")));
if (!strncmp("#", $line, 1)) { // A comment
if ($context == "COMMENT") { // Already in comment context: add
$current["#"][] = substr($line, 1);
}
elseif (($context == "MSGSTR") || ($context == "MSGSTR_ARR")) { // End current entry, start a new one
$strings[$current["msgid"]] = $current;
_locale_import_one_string($current, $lang);
$current = array();
$current["#"][] = substr($line, 1);
$context = "COMMENT";
......@@ -349,7 +233,7 @@ function _locale_import_read_po($file) {
}
elseif (!strncmp("msgid", $line, 5)) {
if ($context == "MSGSTR") { // End current entry, start a new one
$strings[$current["msgid"]] = $current;
_locale_import_one_string($current, $lang);
$current = array();
}
elseif ($context == "MSGID") { // Already in this context? Parse error
......@@ -423,14 +307,133 @@ function _locale_import_read_po($file) {
// End of PO file, flush last entry
if (($context == "MSGSTR") || ($context == "MSGSTR_ARR")) {
$strings[$current["msgid"]] = $current;
_locale_import_one_string($current, $lang);
}
elseif ($context != "COMMENT") {
drupal_set_message(t('The translation file %filename ended unexpectedly at line %line.', array('%filename' => $message, '%line' => $lineno)), 'error');
return FALSE;
}
return $strings;
}
/**
* Imports a string into the database
*
* @param $value Information about the string
* @author Jacobo Tarrio
*/
function _locale_import_one_string($value, $lang = NULL) {
static $additions = 0;
static $updates = 0;
static $headerdone = FALSE;
// Report the changes made (called at end of import)
if ($value == 'report') {
return array($headerdone, $additions, $updates);
}
// Current string is the header information
elseif ($value['msgid'] == '') {
$hdr = _locale_import_parse_header($value);
// Get the plural formula
if ($hdr["Plural-Forms"] && $p = _locale_import_parse_plural_forms($hdr["Plural-Forms"], $file->filename)) {
list($nplurals, $plural) = $p;
db_query("UPDATE {locales_meta} SET plurals = %d, formula = '%s' WHERE locale = '%s'", $nplurals, $plural, $lang);
}
else {
db_query("UPDATE {locales_meta} SET plurals = %d, formula = '%s' WHERE locale = '%s'", 0, '', $lang);
}
$headerdone = TRUE;
}
// Some real string to import
else {
$comments = _locale_import_shorten_comments($value['#']);
// Handle a translation for some plural string
if (strpos($value['msgid'], "\0")) {
$english = explode("\0", $value['msgid'], 2);
$entries = array_keys($value['msgstr']);
for ($i = 3; $i <= count($entries); $i++) {
$english[] = $english[1];
}
$translation = array_map('_locale_import_append_plural', $value['msgstr'], $entries);
$english = array_map('_locale_import_append_plural', $english, $entries);
foreach ($translation as $key => $trans) {
if ($key == 0) {
$plid = 0;
}
$loc = db_fetch_object(db_query("SELECT lid FROM {locales_source} WHERE source = '%s'", $english[$key]));
if ($loc->lid) { // a string exists
$lid = $loc->lid;
// update location field
db_query("UPDATE {locales_source} SET location = '%s' WHERE lid = %d", $comments, $lid);
$trans2 = db_fetch_object(db_query("SELECT lid, translation, plid, plural FROM {locales_target} WHERE lid = %d AND locale = '%s'", $lid, $lang));
if (!$trans2->lid) { // no translation in current language
db_query("INSERT INTO {locales_target} (lid, locale, translation, plid, plural) VALUES (%d, '%s', '%s', %d, %d)", $lid, $lang, $trans, $plid, $key);
$additions++;
} // translation exists
else if ($mode == 'overwrite' || $trans2->translation == '') {
db_query("UPDATE {locales_target} SET translation = '%s', plid = %d, plural = %d WHERE locale = '%s' AND lid = %d", $trans, $plid, $key, $lang, $lid);
if ($trans2->translation == '') {
$additions++;
}
else {
$updates++;
}
}
}
else { // no string
db_query("INSERT INTO {locales_source} (location, source) VALUES ('%s', '%s')", $comments, $english[$key]);
$loc = db_fetch_object(db_query("SELECT lid FROM {locales_source} WHERE source = '%s'", $english[$key]));
$lid = $loc->lid;
db_query("INSERT INTO {locales_target} (lid, locale, translation, plid, plural) VALUES (%d, '%s', '%s', %d, %d)", $lid, $lang, $trans, $plid, $key);
if ($trans != '') {
$additions++;
}
}
$plid = $lid;
}
}
// A simple translation
else {
$english = $value['msgid'];
$translation = $value['msgstr'];
$loc = db_fetch_object(db_query("SELECT lid FROM {locales_source} WHERE source = '%s'", $english));
if ($loc->lid) { // a string exists
$lid = $loc->lid;
// update location field
db_query("UPDATE {locales_source} SET location = '%s' WHERE source = '%s'", $comments, $english);
$trans = db_fetch_object(db_query("SELECT lid, translation FROM {locales_target} WHERE lid = %d AND locale = '%s'", $lid, $lang));
if (!$trans->lid) { // no translation in current language
db_query("INSERT INTO {locales_target} (lid, locale, translation) VALUES (%d, '%s', '%s')", $lid, $lang, $translation);
$additions++;
} // translation exists
else if ($mode == 'overwrite') { //overwrite in any case
db_query("UPDATE {locales_target} SET translation = '%s' WHERE locale = '%s' AND lid = %d", $translation, $lang, $lid);
if ($trans->translation == '') {
$additions++;
}
else {
$updates++;
}
} // overwrite if empty string
else if ($trans->translation == '') {
db_query("UPDATE {locales_target} SET translation = '%s' WHERE locale = '%s' AND lid = %d", $translation, $lang, $lid);
$additions++;
}
}
else { // no string
db_query("INSERT INTO {locales_source} (location, source) VALUES ('%s', '%s')", $comments, $english);
$loc = db_fetch_object(db_query("SELECT lid FROM {locales_source} WHERE source = '%s'", $english));
$lid = $loc->lid;
db_query("INSERT INTO {locales_target} (lid, locale, translation) VALUES (%d, '%s', '%s')", $lid, $lang, $translation);
if ($translation != '') {
$additions++;
}
}
}
}
}
/**
......
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