You are here

function _locale_import_read_po in Drupal 4

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

Parses Gettext Portable Object file into an array

@author Jacobo Tarrio

Parameters

$file Object with properties of local file to parse:

1 call to _locale_import_read_po()
_locale_import_po in includes/locale.inc
Parses Gettext Portable Object file information and inserts into database

File

includes/locale.inc, line 491
Admin-related functions for locale.module.

Code

function _locale_import_read_po($file, $mode, $lang) {
  $message = theme('placeholder', $file->filename);
  $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;
  }
  $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
    $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($current, $mode, $lang);
        $current = array();
        $current["#"][] = substr($line, 1);
        $context = "COMMENT";
      }
      else {

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

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

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

        // Already in this context? Parse error
        drupal_set_message(t('The translation file %filename contains an error: "msgid" is unexpected on line %line.', array(
          '%filename' => $message,
          '%line' => $lineno,
        )), 'error');
        return FALSE;
      }
      $line = trim(substr($line, 5));
      $quoted = _locale_import_parse_quoted($line);
      if ($quoted === false) {
        drupal_set_message(t('The translation file %filename contains a syntax error on line %line.', array(
          '%filename' => $message,
          '%line' => $lineno,
        )), 'error');
        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[]
        drupal_set_message(t('The translation file %filename contains an error: "msgstr[]" is unexpected on line %line.', array(
          '%filename' => $message,
          '%line' => $lineno,
        )), 'error');
        return FALSE;
      }
      if (strpos($line, "]") === false) {
        drupal_set_message(t('The translation file %filename contains a syntax error on line %line.', array(
          '%filename' => $message,
          '%line' => $lineno,
        )), 'error');
        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) {
        drupal_set_message(t('The translation file %filename contains a syntax error on line %line.', array(
          '%filename' => $message,
          '%line' => $lineno,
        )), 'error');
        return FALSE;
      }
      $current["msgstr"][$plural] = $quoted;
      $context = "MSGSTR_ARR";
    }
    elseif (!strncmp("msgstr", $line, 6)) {
      if ($context != "MSGID") {

        // Should come just after a msgid block
        drupal_set_message(t('The translation file %filename contains an error: "msgstr" is unexpected on line %line.', array(
          '%filename' => $message,
          '%line' => $lineno,
        )), 'error');
        return FALSE;
      }
      $line = trim(substr($line, 6));
      $quoted = _locale_import_parse_quoted($line);
      if ($quoted === false) {
        drupal_set_message(t('The translation file %filename contains a syntax error on line %line.', array(
          '%filename' => $message,
          '%line' => $lineno,
        )), 'error');
        return FALSE;
      }
      $current["msgstr"] = $quoted;
      $context = "MSGSTR";
    }
    elseif ($line != "") {
      $quoted = _locale_import_parse_quoted($line);
      if ($quoted === false) {
        drupal_set_message(t('The translation file %filename contains a syntax error on line %line.', array(
          '%filename' => $message,
          '%line' => $lineno,
        )), 'error');
        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 {
        drupal_set_message(t('The translation file %filename contains an error: there is an unexpected string on line %line.', array(
          '%filename' => $message,
          '%line' => $lineno,
        )), 'error');
        return FALSE;
      }
    }
  }

  // End of PO file, flush last entry
  if ($context == "MSGSTR" || $context == "MSGSTR_ARR") {
    _locale_import_one_string($current, $mode, $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;
  }
}