You are here

function _locale_import_read_po in Drupal 6

Same name and namespace in other branches
  1. 4 includes/locale.inc \_locale_import_read_po()
  2. 5 includes/locale.inc \_locale_import_read_po()
  3. 7 includes/locale.inc \_locale_import_read_po()

Parses Gettext Portable Object file into an array

Parameters

$op: Storage operation type: db-store or mem-store

$file: Drupal file object corresponding to the PO file to import

$mode: Should existing translations be replaced LOCALE_IMPORT_KEEP or LOCALE_IMPORT_OVERWRITE

$lang: Language code

$group: Text group to import PO file into (eg. 'default' for interface translations)

Related topics

3 calls to _locale_import_read_po()
st in includes/install.inc
Hardcoded function for doing the equivalent of t() during the install process, when database, theme, and localization system is possibly not yet available.
_locale_batch_import in includes/locale.inc
Perform interface translation import as a batch step.
_locale_import_po in includes/locale.inc
Parses Gettext Portable Object file information and inserts into database

File

includes/locale.inc, line 1095
Administration functions for locale.module.

Code

function _locale_import_read_po($op, $file, $mode = NULL, $lang = NULL, $group = 'default') {
  $fd = fopen($file->filepath, "rb");

  // File will get closed by PHP on return
  if (!$fd) {
    _locale_import_message('The translation import failed, because the file %filename could not be read.', $file);
    return FALSE;
  }
  $context = "COMMENT";

  // Parser context: COMMENT, MSGID, MSGID_PLURAL, MSGSTR and MSGSTR_ARR
  $current = array();

  // Current entry being read
  $plural = 0;

  // Current plural form
  $lineno = 0;

  // Current line
  while (!feof($fd)) {
    $line = fgets($fd, 10 * 1024);

    // A line should not be this long
    if ($lineno == 0) {

      // The first line might come with a UTF-8 BOM, which should be removed.
      $line = str_replace("", '', $line);
    }
    $lineno++;
    $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
        _locale_import_one_string($op, $current, $mode, $lang, $file, $group);
        $current = array();
        $current["#"][] = substr($line, 1);
        $context = "COMMENT";
      }
      else {

        // Parse error
        _locale_import_message('The translation file %filename contains an error: "msgstr" was expected but not found on line %line.', $file, $lineno);
        return FALSE;
      }
    }
    elseif (!strncmp("msgid_plural", $line, 12)) {
      if ($context != "MSGID") {

        // Must be plural form for current entry
        _locale_import_message('The translation file %filename contains an error: "msgid_plural" was expected but not found on line %line.', $file, $lineno);
        return FALSE;
      }
      $line = trim(substr($line, 12));
      $quoted = _locale_import_parse_quoted($line);
      if ($quoted === FALSE) {
        _locale_import_message('The translation file %filename contains a syntax error on line %line.', $file, $lineno);
        return FALSE;
      }
      $current["msgid"] = $current["msgid"] . "\0" . $quoted;
      $context = "MSGID_PLURAL";
    }
    elseif (!strncmp("msgid", $line, 5)) {
      if ($context == "MSGSTR" || $context == "MSGSTR_ARR") {

        // End current entry, start a new one
        _locale_import_one_string($op, $current, $mode, $lang, $file, $group);
        $current = array();
      }
      elseif ($context == "MSGID") {

        // Already in this context? Parse error
        _locale_import_message('The translation file %filename contains an error: "msgid" is unexpected on line %line.', $file, $lineno);
        return FALSE;
      }
      $line = trim(substr($line, 5));
      $quoted = _locale_import_parse_quoted($line);
      if ($quoted === FALSE) {
        _locale_import_message('The translation file %filename contains a syntax error on line %line.', $file, $lineno);
        return FALSE;
      }
      $current["msgid"] = $quoted;
      $context = "MSGID";
    }
    elseif (!strncmp("msgstr[", $line, 7)) {
      if ($context != "MSGID" && $context != "MSGID_PLURAL" && $context != "MSGSTR_ARR") {

        // Must come after msgid, msgid_plural, or msgstr[]
        _locale_import_message('The translation file %filename contains an error: "msgstr[]" is unexpected on line %line.', $file, $lineno);
        return FALSE;
      }
      if (strpos($line, "]") === FALSE) {
        _locale_import_message('The translation file %filename contains a syntax error on line %line.', $file, $lineno);
        return FALSE;
      }
      $frombracket = strstr($line, "[");
      $plural = substr($frombracket, 1, strpos($frombracket, "]") - 1);
      $line = trim(strstr($line, " "));
      $quoted = _locale_import_parse_quoted($line);
      if ($quoted === FALSE) {
        _locale_import_message('The translation file %filename contains a syntax error on line %line.', $file, $lineno);
        return FALSE;
      }
      $current["msgstr"][$plural] = $quoted;
      $context = "MSGSTR_ARR";
    }
    elseif (!strncmp("msgstr", $line, 6)) {
      if ($context != "MSGID") {

        // Should come just after a msgid block
        _locale_import_message('The translation file %filename contains an error: "msgstr" is unexpected on line %line.', $file, $lineno);
        return FALSE;
      }
      $line = trim(substr($line, 6));
      $quoted = _locale_import_parse_quoted($line);
      if ($quoted === FALSE) {
        _locale_import_message('The translation file %filename contains a syntax error on line %line.', $file, $lineno);
        return FALSE;
      }
      $current["msgstr"] = $quoted;
      $context = "MSGSTR";
    }
    elseif ($line != "") {
      $quoted = _locale_import_parse_quoted($line);
      if ($quoted === FALSE) {
        _locale_import_message('The translation file %filename contains a syntax error on line %line.', $file, $lineno);
        return FALSE;
      }
      if ($context == "MSGID" || $context == "MSGID_PLURAL") {
        $current["msgid"] .= $quoted;
      }
      elseif ($context == "MSGSTR") {
        $current["msgstr"] .= $quoted;
      }
      elseif ($context == "MSGSTR_ARR") {
        $current["msgstr"][$plural] .= $quoted;
      }
      else {
        _locale_import_message('The translation file %filename contains an error: there is an unexpected string on line %line.', $file, $lineno);
        return FALSE;
      }
    }
  }

  // End of PO file, flush last entry
  if ($context == "MSGSTR" || $context == "MSGSTR_ARR") {
    _locale_import_one_string($op, $current, $mode, $lang, $file, $group);
  }
  elseif ($context != "COMMENT") {
    _locale_import_message('The translation file %filename ended unexpectedly at line %line.', $file, $lineno);
    return FALSE;
  }
}