diff options
author | Dries Buytaert <dries@buytaert.net> | 2006-02-05 15:42:56 +0000 |
---|---|---|
committer | Dries Buytaert <dries@buytaert.net> | 2006-02-05 15:42:56 +0000 |
commit | 941139bf2af4b0a7c33a340ccdc59c7b63e72b72 (patch) | |
tree | e33c0c49644baea8d4025151a16cc2f7b1caaa3a /includes/locale.inc | |
parent | f0e6aa0506c0254cbd7bbd6ab1302eada755a90c (diff) | |
download | brdo-941139bf2af4b0a7c33a340ccdc59c7b63e72b72.tar.gz brdo-941139bf2af4b0a7c33a340ccdc59c7b63e72b72.tar.bz2 |
- Patch #47610 by Goba: reduced locale memory requirements
Diffstat (limited to 'includes/locale.inc')
-rw-r--r-- | includes/locale.inc | 265 |
1 files changed, 134 insertions, 131 deletions
diff --git a/includes/locale.inc b/includes/locale.inc index bafe1105f..d146e76a5 100644 --- a/includes/locale.inc +++ b/includes/locale.inc @@ -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++; + } + } + } + } } /** |