Browse Source

Suppress notice errors in PO file parsing.

Suppress the notice errors when PO files include duplicate msgid
elements that have context and context-free variants. In these cases,
the context-free definition 'wins'.

Ideally we could add a '' context that is used by default. I tried this,
but it broke a significant number of tests which made me concerned about
backwards compatibility with userland message parsers.

Refs #8337
Mark Story 10 years ago
parent
commit
59211333d3

+ 3 - 2
src/I18n/Parser/PoFileParser.php

@@ -142,9 +142,10 @@ class PoFileParser
 
         $translation = stripcslashes($translation);
 
-        if ($context) {
+        if ($context && (!isset($messages[$singular]) || is_array($messages[$singular]))) {
             $messages[$singular]['_context'][$context] = $translation;
-        } else {
+        }
+        if ($context === null) {
             $messages[$singular] = $translation;
         }
 

+ 26 - 0
tests/TestCase/I18n/Parser/PoFileParserTest.php

@@ -14,6 +14,8 @@
  */
 namespace Cake\Test\TestCase\I18n\Parser;
 
+use Aura\Intl\Package;
+use Cake\I18n\I18n;
 use Cake\I18n\Parser\PoFileParser;
 use Cake\TestSuite\TestCase;
 
@@ -90,4 +92,28 @@ class PoFileParserTest extends TestCase
 
         $this->assertTextEquals('this is a "quoted string" (translated)', $messages['this is a "quoted string"']);
     }
+
+    /**
+     * Test parsing a file with message context on some msgid values.
+     *
+     * This behavior is not ideal, but more thorough solutions
+     * would break compatibility. Perhaps this is something we can
+     * reconsider in 4.x
+     *
+     * @return void
+     */
+    public function testParseContextOnSomeMessages()
+    {
+        $parser = new PoFileParser();
+        $file = APP . 'Locale' . DS . 'en' . DS . 'context.po';
+        $messages = $parser->parse($file);
+
+        I18n::translator('default', 'en_US', function () use ($messages) {
+            $package = new Package('default');
+            $package->setMessages($messages);
+            return $package;
+        });
+        $this->assertTextEquals('En cours', $messages['Pending']);
+        $this->assertTextEquals('En resolved', $messages['Resolved']);
+    }
 }

+ 15 - 0
tests/test_app/TestApp/Locale/en/context.po

@@ -0,0 +1,15 @@
+#: Bare message first
+msgid "Pending"
+msgstr "En cours"
+
+msgctxt "Pay status"
+msgid "Pending"
+msgstr "En cours - context"
+
+#: Context message first
+msgctxt "Pay status"
+msgid "Resolved"
+msgstr "En resolved - context"
+
+msgid "Resolved"
+msgstr "En resolved"