Browse Source

Merge pull request #11508 from cakephp/bug/plural-issues

Fixing plural/singular issues in the po parser
Mark Story 8 years ago
parent
commit
b0f5a5917a

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

@@ -14,6 +14,8 @@
  */
 namespace Cake\I18n\Parser;
 
+use Cake\I18n\Translator;
+
 /**
  * Parses file in PO format
  *
@@ -23,7 +25,6 @@ namespace Cake\I18n\Parser;
  */
 class PoFileParser
 {
-
     /**
      * Parses portable object (PO) format.
      *
@@ -166,9 +167,9 @@ class PoFileParser
             $key = stripcslashes($item['ids']['plural']);
 
             if ($context !== null) {
-                $messages[$key]['_context'][$context] = $plurals;
+                $messages[Translator::PLURAL_PREFIX . $key]['_context'][$context] = $plurals;
             } else {
-                $messages[$key]['_context'][''] = $plurals;
+                $messages[Translator::PLURAL_PREFIX . $key]['_context'][''] = $plurals;
             }
         }
     }

+ 14 - 1
src/I18n/Translator.php

@@ -22,6 +22,8 @@ use Aura\Intl\Translator as BaseTranslator;
 class Translator extends BaseTranslator
 {
 
+    const PLURAL_PREFIX = 'p:';
+
     /**
      * Translates the message formatting any placeholders
      *
@@ -33,7 +35,18 @@ class Translator extends BaseTranslator
      */
     public function translate($key, array $tokensValues = [])
     {
-        $message = $this->getMessage($key);
+        if (isset($tokensValues['_count'])) {
+            $message = $this->getMessage(static::PLURAL_PREFIX . $key);
+            if (!$message) {
+                $message = $this->getMessage($key);
+            }
+        } else {
+            $message = $this->getMessage($key);
+            if (!$message) {
+                $message = $this->getMessage(static::PLURAL_PREFIX . $key);
+            }
+        }
+
         if (!$message) {
             // Fallback to the message key
             $message = $key;

+ 34 - 9
tests/TestCase/I18n/Parser/PoFileParserTest.php

@@ -65,8 +65,8 @@ class PoFileParserTest extends TestCase
         $expected = [
             'Plural Rule 1' => [
                 '_context' => [
-                    '' => 'Plural Rule 1 (translated)',
-                ],
+                    '' => 'Plural Rule 1 (translated)'
+                ]
             ],
             '%d = 1' => [
                 '_context' => [
@@ -74,7 +74,7 @@ class PoFileParserTest extends TestCase
                     'Another Context' => '%d = 1 (translated)'
                 ]
             ],
-            '%d = 0 or > 1' => [
+            'p:%d = 0 or > 1' => [
                 '_context' => [
                     'Another Context' => [
                         0 => '%d = 1 (translated)',
@@ -84,10 +84,10 @@ class PoFileParserTest extends TestCase
             ],
             '%-5d = 1' => [
                 '_context' => [
-                    '' => '%-5d = 1 (translated)',
-                ],
+                    '' => '%-5d = 1 (translated)'
+                ]
             ],
-            '%-5d = 0 or > 1' => [
+            'p:%-5d = 0 or > 1' => [
                 '_context' => [
                     '' => [
                         0 => '%-5d = 1 (translated)',
@@ -95,9 +95,9 @@ class PoFileParserTest extends TestCase
                         2 => '',
                         3 => '',
                         4 => '%-5d = 0 or > 1 (translated)'
-                    ],
-                ],
-            ],
+                    ]
+                ]
+            ]
         ];
         $this->assertEquals($expected, $messages);
     }
@@ -188,4 +188,29 @@ class PoFileParserTest extends TestCase
         $this->assertSame('Titel mit anderem Kontext', __x('another_context', 'title'));
         $this->assertSame('Titel ohne Kontext', __('title'));
     }
+
+    /**
+     * Test parsing plurals
+     *
+     * @return void
+     */
+    public function testPlurals()
+    {
+        $parser = new PoFileParser();
+        $file = APP . 'Locale' . DS . 'de' . DS . 'wa.po';
+        $messages = $parser->parse($file);
+
+        I18n::translator('default', 'de_DE', function () use ($messages) {
+            $package = new Package('default');
+            $package->setMessages($messages);
+
+            return $package;
+        });
+
+        // Check translated messages
+        I18n::locale('de_DE');
+        $this->assertEquals('Standorte', __d('wa', 'Locations'));
+        I18n::locale('en_EN');
+        $this->assertEquals('Locations', __d('wa', 'Locations'));
+    }
 }