From ad791614f4a8f6fc83f9868bc1a9105b6795104d Mon Sep 17 00:00:00 2001 From: filip Date: Tue, 25 Aug 2015 23:11:12 +0200 Subject: bugfix for mga#14899 (proper handling of gettext files) details in bug report --- php-mo.php | 159 +++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 112 insertions(+), 47 deletions(-) diff --git a/php-mo.php b/php-mo.php index 470ce80..6f635c2 100644 --- a/php-mo.php +++ b/php-mo.php @@ -1,29 +1,68 @@ - * - * NB: - * - If no $output_file specified, output filename is same as $input_file (but .mo) - * - Returns true/false for success/failure - * - No warranty, but if it breaks, please let me know - * - * More info: - * https://github.com/josscrowcroft/php.mo - * - * Based on php-msgfmt by Matthias Bauer (Copyright © 2007), a command-line PHP tool - * for converting .po files to .mo. - * (http://wordpress-soc-2007.googlecode.com/svn/trunk/moeffju/php-msgfmt/msgfmt.php) - * - * License: GPL v3 http://www.opensource.org/licenses/gpl-3.0.html - */ +* Changes from php.mo: +* supress the error if there's no file +* fixed "fuzzy flag first line" bug which didn't saved previous proper string at all +* fix the warning if list finds no $data +* added case for commented unused string +* proper handling of msgctxt +* better storing of same msgid +* corrected data structure for correct counting of plural msgstr +* don't add last translation if it's fuzzy +* removed unedeed phpmo_convert and phpmo_write_mo_file +* more info on https://bugs.mageia.org/show_bug.cgi?id=14899 +* +* it returns array of translations: +* $dictionary = phpmo_parse_po_file('input.po'); +* +* $dictionary = array ( +* '' => array ( +* 'msgid' => '', +* 'msgstr' => array ( +* 0 => 'Project-Id-Version: ...', +* ), +* ), +* 'string for translation 1' => array ( +* 'msgid' => 'string for translation 1', +* 'msgstr' => array ( +* 0 => 'translated string 1', +* ), +* ), +* 'string for translation 2' => array ( +* 'msgid' => 'string for translation 2', +* 'msgstr' => array ( +* 0 => 'translated string 2', +* 1 => 'translated string 2 but different context', +* 2 => 'another translated string 2 with different context', +* ), +* 'msgctxt' => array ( +* 1 => 'context explanation for msgstr[1]', +* 2 => 'context explanation for msgstr[2]', +* ), +* ), +* 'string for translation 3' => array ( +* 'msgid' => 'string for translation 3', +* 'msgid_plural' => 'plural string for translation 3', +* 'msgstr' => array ( +* 0 => array ( +* 0 => 'translated string 3 for nplurals 0', +* 1 => 'translated string 3 for nplurals 1', +* 2 => 'translated string 3 for nplurals 2', +* ), +* ), +* ), +* ); +* +**************************************************************************************** +* +* based on php.mo 0.1 by Joss Crowcroft (http://www.josscrowcroft.com) +* which is +* Based on php-msgfmt by Matthias Bauer (Copyright © 2007), a command-line PHP tool +* for converting .po files to .mo. +* (http://wordpress-soc-2007.googlecode.com/svn/trunk/moeffju/php-msgfmt/msgfmt.php) +* +* License: GPL v3 http://www.opensource.org/licenses/gpl-3.0.html +*/ function phpmo_clean_helper($x) { if (is_array($x)) { @@ -60,34 +99,29 @@ function phpmo_parse_po_file($in) { // iterate over lines while(($line = fgets($fh, 65536)) !== false) { $line = trim($line); - if ($line === '') { - // save stored entry on empty line - // block moved to fix "fuzzy flag first line" bug which didn't saved previous proper string at all - if (sizeof($temp) && array_key_exists('msgid', $temp) && array_key_exists('msgstr', $temp)) { - if (!$fuzzy) - $hash[] = $temp; - $temp = array (); - $state = null; - $fuzzy = false; - } + if ($line === '') continue; - } + $array_of_splited_string = preg_split('/\s/', $line, 2); $key = $array_of_splited_string[0]; $data = (isset($array_of_splited_string[1]) ? $array_of_splited_string[1] : ''); - switch ($key) { case '#,' : // flag... - $fuzzy = in_array('fuzzy', preg_split('/,\s*/', $data)); case '#' : // translator-comments case '#.' : // extracted-comments case '#:' : // reference... case '#|' : // msgid previous-untranslated-string - break; case '#~' : // commented-unused-string - $temp = array (); - $state = null; - $fuzzy = false; + // 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; + } + if ($key == '#,') + $fuzzy = in_array('fuzzy', preg_split('/,\s*/', $data)); break; case 'msgctxt' : // context @@ -96,7 +130,23 @@ function phpmo_parse_po_file($in) { case 'msgid_plural' : // untranslated-string-plural $state = $key; - $temp[$state] = $data; + // store previous entry if it exists + if (sizeof($temp) && array_key_exists('msgid', $temp) && array_key_exists('msgstr', $temp)) { + if (!$fuzzy) + $hash[] = $temp; + $temp = array (); + $fuzzy = false; + } + if ($key == 'msgctxt') { + if (array_key_exists('msgstr', $temp)) { + $msgctxt_index = count($temp['msgstr']); + } else { + $msgctxt_index = 0; + } + $temp['msgctxt'][$msgctxt_index] = $data; + } else { + $temp[$state] = $data; + } break; case 'msgstr' : // translated-string @@ -111,11 +161,11 @@ function phpmo_parse_po_file($in) { } else { // continued lines switch ($state) { - case 'msgctxt' : case 'msgid' : case 'msgid_plural' : $temp[$state] .= "\n" . $line; break; + case 'msgctxt' : case 'msgstr' : $temp[$state][sizeof($temp[$state]) - 1] .= "\n" . $line; break; @@ -132,7 +182,8 @@ function phpmo_parse_po_file($in) { // add final entry if ($state == 'msgstr') - $hash[] = $temp; + if (!$fuzzy) + $hash[] = $temp; // Cleanup data, merge multiline entries, reindex hash for ksort $temp = $hash; @@ -145,10 +196,24 @@ function phpmo_parse_po_file($in) { return FALSE; } } - $hash[$entry['msgid']] = $entry; + // if there's already same msgid we need to store it there + if (array_key_exists($entry['msgid'], $hash)) { + $index = count($hash[$entry['msgid']]['msgstr']); + $hash[$entry['msgid']]['msgstr'][$index] = $entry['msgstr'][0]; + // is different msgctxt present also? + if (array_key_exists('msgctxt', $entry)) { + $hash[$entry['msgid']]['msgctxt'][$index] = $entry['msgctxt'][0]; + } + } else { + // if msgid_plural exists we need to store msgstr to subarray for proper counting of l10n completion + if (array_key_exists('msgid_plural', $entry)) { + $msgstr_plural = $entry['msgstr']; + $entry['msgstr'] = array(); + $entry['msgstr'][] = $msgstr_plural; + } + $hash[$entry['msgid']] = $entry; + } } return $hash; } - -?> \ No newline at end of file -- cgit v1.2.1