function phpmo_clean_helper($x) { if (is_array($x)) { foreach ($x as $k => $v) { $x[$k] = phpmo_clean_helper($v); } } else { if ($x[0] == '"') { $x = substr($x, 1, -1); } $x = str_replace("\"\n\"", '', $x); $x = str_replace('$', '\\$', $x); $x = @eval("return \"{$x}\";"); } return $x; }
function phpmo_parse_po_file($in) { // read .po file $fc = file_get_contents($in); // normalize newlines $fc = str_replace(array("\r\n", "\r"), array("\n", "\n"), $fc); // results array $hash = array(); // temporary array $temp = array(); // state $state = null; $fuzzy = false; // iterate over lines foreach (explode("\n", $fc) as $line) { $line = trim($line); if ($line === '') { continue; } list($key, $data) = explode(' ', $line, 2); switch ($key) { case '#,': // flag... $fuzzy = in_array('fuzzy', preg_split('/,\\s*/', $data)); case '#': // translator-comments // translator-comments case '#.': // extracted-comments // extracted-comments case '#:': // reference... // reference... case '#~': // reference... // reference... case '#|': // msgid previous-untranslated-string // start a new entry if (sizeof($temp) && array_key_exists('msgid', $temp) && array_key_exists('msgstr', $temp)) { if (!$fuzzy) { $hash[] = $temp; } $temp = array(); $state = null; $fuzzy = false; } break; case 'msgctxt': // context // context case 'msgid': // untranslated-string // untranslated-string case 'msgid_plural': // untranslated-string-plural $state = $key; $temp[$state] = $data; break; case 'msgstr': // translated-string $state = 'msgstr'; if ($data) { $temp[$state][] = $data; } break; // default : // if (strpos($key, 'msgstr[') !== FALSE) { // // translated-string-case-n // $state = 'msgstr'; // $temp[$state][] = $data; // } else { // // continued lines // switch ($state) { // case 'msgctxt' : // case 'msgid' : // case 'msgid_plural' : // $temp[$state] .= "\n" . $line; // break; // case 'msgstr' : // $temp[$state][sizeof($temp[$state]) - 1] .= "\n" . $line; // break; // default : // // parse error // return FALSE; // } // } // break; } } // add final entry if ($state == 'msgstr') { $hash[] = $temp; } // Cleanup data, merge multiline entries, reindex hash for ksort $temp = $hash; $hash = array(); foreach ($temp as $entry) { foreach ($entry as &$v) { $v = phpmo_clean_helper($v); if ($v === FALSE) { // parse error continue; // return FALSE; } } $hash[$entry['msgid']] = $entry; } return $hash; }
function phpmo_parse_po_file($in) { // read .po file $fh = fopen($in, 'r'); if ($fh === false) { // Could not open file resource return false; } // results array $hash = array(); // temporary array $temp = array(); // state $state = null; $fuzzy = false; // iterate over lines while (($line = fgets($fh, 65536)) !== false) { $line = trim($line); if ($line === '') { continue; } list($key, $data) = preg_split('/\\s/', $line, 2); switch ($key) { case '#,': // flag... $fuzzy = in_array('fuzzy', preg_split('/,\\s*/', $data)); case '#': // translator-comments // translator-comments case '#.': // extracted-comments // extracted-comments case '#:': // reference... // reference... case '#|': // msgid previous-untranslated-string // start a new entry if (sizeof($temp) && array_key_exists('msgid', $temp) && array_key_exists('msgstr', $temp)) { if (!$fuzzy) { $hash[] = $temp; } $temp = array(); $state = null; $fuzzy = false; } break; case 'msgctxt': // context // context case 'msgid': // untranslated-string // untranslated-string case 'msgid_plural': // untranslated-string-plural $state = $key; $temp[$state] = $data; break; case 'msgstr': // translated-string $state = 'msgstr'; $temp[$state][] = $data; break; default: if (strpos($key, 'msgstr[') !== FALSE) { // translated-string-case-n $state = 'msgstr'; $temp[$state][] = $data; } else { // continued lines switch ($state) { case 'msgctxt': case 'msgid': case 'msgid_plural': $temp[$state] .= "\n" . $line; break; case 'msgstr': $temp[$state][sizeof($temp[$state]) - 1] .= "\n" . $line; break; default: // parse error fclose($fh); return FALSE; } } break; } } fclose($fh); // add final entry if ($state == 'msgstr') { $hash[] = $temp; } // Cleanup data, merge multiline entries, reindex hash for ksort $temp = $hash; $hash = array(); foreach ($temp as $entry) { foreach ($entry as &$v) { $v = phpmo_clean_helper($v); if ($v === FALSE) { // parse error return FALSE; } } $hash[$entry['msgid']] = $entry; } return $hash; }