Sepia\PoParser::parse PHP Method

parse() public method

Reads and parses strings of a .po file.
public parse ( sepia\InterfaceHandler $handle = null ) : array.
$handle sepia\InterfaceHandler
return array.
    public function parse(InterfaceHandler $handle = null)
    {
        if ($handle === null) {
            if ($this->sourceHandle === null) {
                throw new \InvalidArgumentException('Must provide a valid InterfaceHandler');
            } else {
                $handle = $this->sourceHandle;
            }
        }
        $headers = array();
        $hash = array();
        $entry = array();
        $justNewEntry = false;
        // A new entry has been just inserted.
        $firstLine = true;
        $lastPreviousKey = null;
        // Used to remember last key in a multiline previous entry.
        $state = null;
        $lineNumber = 0;
        while (!$handle->ended()) {
            $line = trim($handle->getNextLine());
            $split = preg_split('/\\s+/ ', $line, 2);
            $key = $split[0];
            // If a blank line is found, or a new msgid when already got one
            if ($line === '' || $key == 'msgid' && isset($entry['msgid'])) {
                // Two consecutive blank lines
                if ($justNewEntry) {
                    $lineNumber++;
                    continue;
                }
                if ($firstLine) {
                    $firstLine = false;
                    if (self::isHeader($entry)) {
                        array_shift($entry['msgstr']);
                        $headers = $entry['msgstr'];
                    } else {
                        $hash[] = $entry;
                    }
                } else {
                    // A new entry is found!
                    $hash[] = $entry;
                }
                $entry = array();
                $state = null;
                $justNewEntry = true;
                $lastPreviousKey = null;
                if ($line === '') {
                    $lineNumber++;
                    continue;
                }
            }
            $justNewEntry = false;
            $data = isset($split[1]) ? $split[1] : null;
            switch ($key) {
                // Flagged translation
                case '#,':
                    $entry['flags'] = preg_split('/,\\s*/', $data);
                    break;
                    // # Translator comments
                // # Translator comments
                case '#':
                    $entry['tcomment'] = !isset($entry['tcomment']) ? array() : $entry['tcomment'];
                    $entry['tcomment'][] = $data;
                    break;
                    // #. Comments extracted from source code
                // #. Comments extracted from source code
                case '#.':
                    $entry['ccomment'] = !isset($entry['ccomment']) ? array() : $entry['ccomment'];
                    $entry['ccomment'][] = $data;
                    break;
                    // Reference
                // Reference
                case '#:':
                    $entry['reference'][] = addslashes($data);
                    break;
                case '#|':
                    // #| Previous untranslated string
                // #| Previous untranslated string
                case '#~':
                    // #~ Old entry
                // #~ Old entry
                case '#~|':
                    // #~| Previous-Old untranslated string. Reported by @Cellard
                    switch ($key) {
                        case '#|':
                            $key = 'previous';
                            break;
                        case '#~':
                            $key = 'obsolete';
                            break;
                        case '#~|':
                            $key = 'previous-obsolete';
                            break;
                    }
                    $tmpParts = explode(' ', $data);
                    $tmpKey = $tmpParts[0];
                    if (!in_array($tmpKey, array('msgid', 'msgid_plural', 'msgstr', 'msgctxt'))) {
                        $tmpKey = $lastPreviousKey;
                        // If there is a multiline previous string we must remember what key was first line.
                        $str = $data;
                    } else {
                        $str = implode(' ', array_slice($tmpParts, 1));
                    }
                    $entry[$key] = isset($entry[$key]) ? $entry[$key] : array('msgid' => array(), 'msgstr' => array());
                    if (strpos($key, 'obsolete') !== false) {
                        $entry['obsolete'] = true;
                        switch ($tmpKey) {
                            case 'msgid':
                                $entry['msgid'][] = $str;
                                $lastPreviousKey = $tmpKey;
                                break;
                            case 'msgstr':
                                if ($str == "\"\"") {
                                    $entry['msgstr'][] = trim($str, '"');
                                } else {
                                    $entry['msgstr'][] = $str;
                                }
                                $lastPreviousKey = $tmpKey;
                                break;
                            default:
                                break;
                        }
                    }
                    if ($key !== 'obsolete') {
                        switch ($tmpKey) {
                            case 'msgid':
                            case 'msgid_plural':
                            case 'msgstr':
                                $entry[$key][$tmpKey][] = $str;
                                $lastPreviousKey = $tmpKey;
                                break;
                            default:
                                $entry[$key][$tmpKey] = $str;
                                break;
                        }
                    }
                    break;
                    // context
                    // Allows disambiguations of different messages that have same msgid.
                    // Example:
                    //
                    // #: tools/observinglist.cpp:700
                    // msgctxt "First letter in 'Scope'"
                    // msgid "S"
                    // msgstr ""
                    //
                    // #: skycomponents/horizoncomponent.cpp:429
                    // msgctxt "South"
                    // msgid "S"
                    // msgstr ""
                // context
                // Allows disambiguations of different messages that have same msgid.
                // Example:
                //
                // #: tools/observinglist.cpp:700
                // msgctxt "First letter in 'Scope'"
                // msgid "S"
                // msgstr ""
                //
                // #: skycomponents/horizoncomponent.cpp:429
                // msgctxt "South"
                // msgid "S"
                // msgstr ""
                case 'msgctxt':
                    // untranslated-string
                // untranslated-string
                case 'msgid':
                    // untranslated-string-plural
                // untranslated-string-plural
                case 'msgid_plural':
                    $state = $key;
                    $entry[$state][] = $data;
                    break;
                    // translated-string
                // translated-string
                case 'msgstr':
                    $state = 'msgstr';
                    $entry[$state][] = $data;
                    break;
                default:
                    if (strpos($key, 'msgstr[') !== false) {
                        // translated-string-case-n
                        $state = $key;
                        $entry[$state][] = $data;
                    } else {
                        // "multiline" lines
                        switch ($state) {
                            case 'msgctxt':
                            case 'msgid':
                            case 'msgid_plural':
                            case strpos($state, 'msgstr[') !== false:
                                if (is_string($entry[$state])) {
                                    // Convert it to array
                                    $entry[$state] = array($entry[$state]);
                                }
                                $entry[$state][] = $line;
                                break;
                            case 'msgstr':
                                // Special fix where msgid is ""
                                if ($entry['msgid'] == "\"\"") {
                                    $entry['msgstr'][] = trim($line, '"');
                                } else {
                                    $entry['msgstr'][] = $line;
                                }
                                break;
                            default:
                                throw new \Exception('PoParser: Parse error! Unknown key "' . $key . '" on line ' . ($lineNumber + 1));
                        }
                    }
                    break;
            }
            $lineNumber++;
        }
        $handle->close();
        // add final entry
        if ($state == 'msgstr') {
            $hash[] = $entry;
        }
        // - Cleanup header data
        $this->headers = array();
        foreach ($headers as $header) {
            $header = $this->clean($header);
            $this->headers[] = "\"" . preg_replace("/\\n/", '\\n', $header) . "\"";
        }
        // - Cleanup data,
        // - merge multiline entries
        // - Reindex hash for ksort
        $temp = $hash;
        $this->entries = array();
        foreach ($temp as $entry) {
            foreach ($entry as &$v) {
                $or = $v;
                $v = $this->clean($v);
                if ($v === false) {
                    // parse error
                    throw new \Exception('PoParser: Parse error! poparser::clean returned false on "' . htmlspecialchars($or) . '"');
                }
            }
            // check if msgid and a key starting with msgstr exists
            if (isset($entry['msgid']) && count(preg_grep('/^msgstr/', array_keys($entry)))) {
                $id = $this->getEntryId($entry);
                $this->entries[$id] = $entry;
            }
        }
        return $this->entries;
    }

Usage Example

Exemplo n.º 1
0
 /**
  * function define language and parse PO file
  * 
  * @param String $lang language code
  */
 public static function defineLanguage($lang = "")
 {
     //get language from browser if not set
     if (!$lang) {
         $lang = Lang::getLanguage();
     }
     $poparser = new PoParser();
     // path to lang file
     $filePath["en"] = PATH . "lang/en.po";
     $filePath["de"] = PATH . "lang/de.po";
     // set default language if language is not available
     if (!isset($filePath[$lang])) {
         $lang = "en";
     }
     // returns array
     $po_output = $poparser->parse($filePath[$lang]);
     // convert array to $l_ array
     foreach ($po_output as $po_o) {
         if (isset($po_o["msgid"]) && isset($po_o["msgstr"])) {
             Lang::$lang_output[$po_o["msgid"][0]] = "";
             foreach ($po_o["msgstr"] as $msg_str) {
                 Lang::$lang_output[$po_o["msgid"][0]] .= $msg_str;
             }
         }
     }
 }
All Usage Examples Of Sepia\PoParser::parse