yiisoft / yii2

Yii 2: The Fast, Secure and Professional PHP Framework
http://www.yiiframework.com
BSD 3-Clause "New" or "Revised" License
14.24k stars 6.9k forks source link

i18n plural not working for russian language #7430

Closed githubjeka closed 9 years ago

githubjeka commented 9 years ago

My env: http://i.imgur.com/o7ic3u2.jpg

$ locale -a
C
C.UTF-8
en_US.utf8
POSIX
ru_RU
ru_RU.iso88595
ru_RU.utf8
 <?= \Yii::t('app',
    '{n, plural,
     =0{У вас нет новых сообщений}
     =1{У вас одно новое сообщение}
     one{У вас # непрочитанное сообщение}
     few{У вас # непрочитанных сообщения}
     many{У вас # непрочитанных сообщений}
     other{У вас # сообщений}}!',
     ['n' => 3]
) ?> // return "other" need "few"

I tried:

<?= MessageFormatter::formatMessage("ru_RU",
    '{n, plural,
                                     =0{У вас нет новых сообщений}
                                     =1{У вас одно новое сообщение}
                                    one{У вас # непрочитанное сообщение}
                                    few{У вас # непрочитанных сообщения}
                                    many{У вас # непрочитанных сообщений}
                                    other{У вас # сообщений}}!',
    ['n' => 3]
) ?>
<?= MessageFormatter::formatMessage("ru_RU",
    '{n, spellout}',    ['n' => 3]
) ?>

// This code return `У вас 3 сообщений! три`

When I change language ru to be(belarus) or uk(ukraine), then I get true few variant.

The bug look to related with ICU but not Yii. @cebe requested to open.

cebe commented 9 years ago

check this test case: https://github.com/yiisoft/yii2/commit/db37d03e32f9642998431e3c2a0e845d9cc44a71 it covers exactly your case, I am not able to reproduce it.

cebe commented 9 years ago

@githubjeka which php version are you using?

cebe commented 9 years ago

also please try running this script:

<?php

echo PHP_VERSION . "\n";
echo INTL_ICU_VERSION . "\n";

$language = 'ru-RU';
$pattern = '{0, plural,
    =0{У вас нет новых сообщений}
    =1{У вас одно новое сообщение}
    one{У вас # непрочитанное сообщение}
    few{У вас # непрочитанных сообщения}
    many{У вас # непрочитанных сообщений}
    other{У вас # сообщений}}!';
$params = ['0' => 3];

$formatter = new \MessageFormatter($language, $pattern);
if ($formatter === null) {
    echo "Invalid pattern: " . intl_get_error_code() . "\n" . intl_get_error_message();
}
echo $formatter->format($params);
echo "\n";

If this fails too, it is a bug with intl, icu or PHP and not yii.

My result:

5.4.36-0+deb7u3
4.8.1.1
У вас 3 непрочитанных сообщения!
cebe commented 9 years ago

seems to run fine on all php versions with icu 54.1 http://3v4l.org/v5gf9

githubjeka commented 9 years ago

Test

Tests\codeception\backend.unit Tests (14) -------------------------------------------------------------------------------------                                                                                                              ---------------------------------------
Trying to test should valid default role (tests\codeception\backend\unit\models\AuthTest::testShouldValidDefaultRole)                                                                                                                                                          Ok
Trying to test translate (tests\codeception\backend\unit\models\I18NTest::testTranslate)                                                                                                                                                                                       Fail
Trying to test default source (tests\codeception\backend\unit\models\I18NTest::testDefaultSource)                                                                                                                                                                              Fail
Trying to test translate params (tests\codeception\backend\unit\models\I18NTest::testTranslateParams)                                                                                                                                                                          Fail
Trying to test translate params2 (tests\codeception\backend\unit\models\I18NTest::testTranslateParams2)                                                                                                                                                                        Fail
Trying to test special params (tests\codeception\backend\unit\models\I18NTest::testSpecialParams)                                                                                                                                                                              Ok
Trying to test missing translation formatting (tests\codeception\backend\unit\models\I18NTest::testMissingTranslationFormatting                                                                                                              )                                 Ok
Trying to test russian plurals (tests\codeception\backend\unit\models\I18NTest::testRussianPlurals)                                                                                                                                                                            Fail
Trying to test using source language for missing translation (tests\codeception\backend\unit\models\I18NTest::testUsingSourceLa                                                                                                              nguageForMissingTranslation)      Ok
Trying to test missing translation event (tests\codeception\backend\unit\models\I18NTest::testMissingTranslationEvent)                                                                                                                                                         Fail
Trying to test status1 (tests\codeception\backend\unit\models\NodeTest::testStatus1)                                                                                                                                                                                           Ok
Trying to test correct signup (tests\codeception\backend\unit\models\UserTest::testCorrectSignup)                                                                                                                                                                              Ok
Trying to test not correct signup (tests\codeception\backend\unit\models\UserTest::testNotCorrectSignup)                                                                                                                                                                       Ok
Trying to test not login banned user (tests\codeception\backend\unit\models\UserTest::testNotLoginBannedUser)                                                                                                                                                                  Ok
-------------------------------------------------------------------------------------------------------------------------------                                                                                                              ---------------------------------------

Time: 2.67 seconds, Memory: 20.50Mb

There were 6 failures:

---------
1) tests\codeception\backend\unit\models\I18NTest::testTranslate
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'Der Hund rennt schnell.'
+'The dog runs fast.'

#1  /var/www/html/metering/yii2-app-advanced/tests/codeception/backend/unit/models/I18NTest.php:41

---------
2) tests\codeception\backend\unit\models\I18NTest::testDefaultSource
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'Der Hund rennt schnell.'
+'The dog runs fast.'

#1  /var/www/html/metering/yii2-app-advanced/tests/codeception/backend/unit/models/I18NTest.php:64

---------
3) tests\codeception\backend\unit\models\I18NTest::testTranslateParams
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'Seine Geschwindigkeit beträgt 42 km/h.'
+'His speed is about 42 km/h.'

#1  /var/www/html/metering/yii2-app-advanced/tests/codeception/backend/unit/models/I18NTest.php:77

---------
4) tests\codeception\backend\unit\models\I18NTest::testTranslateParams2
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'Er heißt DA VINCI und ist 42 km/h schnell.'
+'His name is DA VINCI and his speed is about 42 km/h.'

#1  /var/www/html/metering/yii2-app-advanced/tests/codeception/backend/unit/models/I18NTest.php:90

---------
5) tests\codeception\backend\unit\models\I18NTest::testRussianPlurals
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'На диване лежит 6 кошек!'
+'There are 6 cats on lying on the sofa!'

#1  /var/www/html/metering/yii2-app-advanced/tests/codeception/backend/unit/models/I18NTest.php:113

---------
6) tests\codeception\backend\unit\models\I18NTest::testMissingTranslationEvent
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'Hallo Welt!'
+'Hello world!'

#1  /var/www/html/metering/yii2-app-advanced/tests/codeception/backend/unit/models/I18NTest.php:131

FAILURES!
Tests: 14, Assertions: 44, Failures: 6.
githubjeka commented 9 years ago

tried running the script:

5.5.9-1ubuntu4.6 
52.1 
У вас 3 сообщений!

I have https://launchpad.net/ubuntu/+source/icu (Latest upload: 52.1-7 release (main) 2015-01-22)

I change ru_RU to uk in your script:

5.5.9-1ubuntu4.6
52.1
У вас 3 непрочитанных сообщения! 
githubjeka commented 9 years ago

I install 54.1 on system:

$ icuinfo
 <icuSystemParams type="icu4c">
    <param name="copyright"> Copyright (C) 2014, International Business Machines Corporation and others. All Rights Reserved. </param>
    <param name="product">icu4c</param>
    <param name="product.full">International Components for Unicode for C/C++</param>
    <param name="version">54.1</param>
    <param name="version.unicode">7.0</param>
    <param name="platform.number">4000</param>
    <param name="platform.type">Linux</param>
    <param name="locale.default">en_US</param>
    <param name="locale.default.bcp47">en-US</param>
    <param name="converter.default">UTF-8</param>
    <param name="icudata.name">icudt54l</param>
    <param name="icudata.path"></param>
    <param name="cldr.version">26.0</param>
    <param name="tz.version">2014h</param>
    <param name="tz.default">Europe/Minsk</param>
    <param name="cpu.bits">32</param>
    <param name="cpu.big_endian">0</param>
    <param name="os.wchar_width">4</param>
    <param name="os.charset_family">0</param>
    <param name="os.host">i686-pc-linux-gnu</param>
    <param name="build.build">i686-pc-linux-gnu</param>
    <param name="build.cc">gcc</param>
    <param name="build.cxx">g++</param>
    <param name="uconfig.internal_digitlist">1</param>
    <param name="uconfig.have_parseallinput">1</param>
    <param name="uconfig.format_fastpaths_49">1</param>
 </icuSystemParams>

ICU Initialization returned: U_ZERO_ERROR
Plugin file is: /usr/lib/icu/icuplugins54.txt

Set "LD_LIBRARY_PATH"

Doesn't not matter - Php works with 52.1 ICU :(

Replace all files @*icu.so.52 on @*icu.so.54 in default php folder for ICU. Get INTL that doesn't work. Return all to 52. Working with be language via \MessageFormatter.

yujin1st commented 9 years ago

Same thing. Only direct \MessageFormatter::formatMessage('be', '', []) works. Also all non "ru" params works. mac os, php 5.5.14, 5.4.30, intl 52.1

sokrat commented 9 years ago

Error in release 52-1 http://source.icu-project.org/repos/icu/icu/tags/release-52-1/source/data/misc/plurals.txt

ru{"set34"}
set34{
            many{
                "v = 0 and i % 10 = 0 or v = 0 and i % 10 = 5..9 or v = 0 and i % 100"
                " = 11..14 @integer 0, 5~19, 100, 1000, 10000, 100000, 1000000, …"
            }
            one{
                "v = 0 and i % 10 = 1 and i % 100 != 11 @integer 1, 21, 31, 41, 51, 6"
                "1, 71, 81, 101, 1001, …"
            }
            other{
                " @integer 2~4, 22~24, 32~34, 42~44, 52~54, 62, 102, 1002, … @decimal"
                " 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, …"
            }
        }
samdark commented 9 years ago

@sokrat thanks!

dynasource commented 9 years ago

Having the following issues with the nightly:


There were 3 failures:

1) yiiunit\framework\i18n\FormatterNumberTest::testAsShortSize
Failed asserting that two strings are identical.
--- Expected
+++ Actual
@@ @@
-28.41 GB
+2.15 GB

E:\xampp\htdocs\dmn\git\yii2\tests\framework\i18n\FormatterNumberTest.php:458
E:\xampp\htdocs\dmn\git\yii2\vendor\phpunit\phpunit\phpunit:36

2) yiiunit\framework\i18n\I18NTest::testRussianPlurals
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'�а диване лежит 6 кошек!'
+'�а диване лежит 6 кошки!'

E:\xampp\htdocs\dmn\git\yii2\tests\framework\i18n\I18NTest.php:134
E:\xampp\htdocs\dmn\git\yii2\vendor\phpunit\phpunit\phpunit:36

3) yiiunit\framework\i18n\I18NTest::testUsingSourceLanguageForMissingTranslation
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'5 комментариев'
+'5 комментари�'

E:\xampp\htdocs\dmn\git\yii2\tests\framework\i18n\I18NTest.php:143
E:\xampp\htdocs\dmn\git\yii2\vendor\phpunit\phpunit\phpunit:36

FAILURES!
Tests: 587, Assertions: 3463, Failures: 3, Skipped: 102, Incomplete: 1.
cebe commented 9 years ago

@dynasource please also run this script and show the result: https://github.com/yiisoft/yii2/issues/7430#issuecomment-75855762

stoyanov-sv commented 9 years ago

I update ICU to 56.1 and MessageFormatter::formatMessage works fine, but Yii::t incorrect work:

echo PHP_VERSION . "\n";
echo INTL_ICU_VERSION . "\n";
$language = 'ru-RU';
$pattern = '{0, plural,
    =0{У вас нет новых сообщений}
    =1{У вас одно новое сообщение}
    one{У вас # непрочитанное сообщение}
    few{У вас # непрочитанных сообщения}
    many{У вас # непрочитанных сообщений}
    other{У вас # сообщений}}!';
$params = ['0' => 3];
$formatter = new \MessageFormatter($language, $pattern);
if ($formatter === null) {
    echo "Invalid pattern: " . intl_get_error_code() . "\n" . intl_get_error_message();
}
echo $formatter->format($params);
echo "\n";
echo \Yii::t(
        'app',
        '{n, plural,
            =0{У вас нет новых сообщений}
            =1{У вас одно новое сообщение}
            one{У вас # непрочитанное сообщение}
            few{У вас # непрочитанных сообщения}
            many{У вас # непрочитанных сообщений}
            other{У вас # сообщений}}!',
        ['n' => 3]
    )."\n";

Result:

5.5.9-1ubuntu4.13
56.1
У вас 3 непрочитанных сообщения!
У вас 3 сообщений!
githubjeka commented 9 years ago

@stoyanov-sv please show your config with language option?

echo \Yii::$app->language;
stoyanov-sv commented 9 years ago

@githubjeka

ru
githubjeka commented 9 years ago

try ru-RU

stoyanov-sv commented 9 years ago

@githubjeka The same result.

githubjeka commented 9 years ago

@stoyanov-sv :)

Note: The above example Russian message is mainly used as a translated message, not an original message, unless you set the source language of your application as ru-RU and translating from Russian.

http://www.yiiframework.com/doc-2.0/guide-tutorial-i18n.html

stoyanov-sv commented 9 years ago

@githubjeka Thanks ), everything works correctly.

samdark commented 9 years ago

@githubjeka is the original issue still valid?

githubjeka commented 9 years ago

@samdark I wrote

The bug look to related with ICU but not Yii. @cebe requested to open.

Ask @cebe (:

samdark commented 9 years ago

Closing since Russian guide now includes notes about buggy ICU version that should be avoided.

luciuz commented 7 years ago

Is there no fixes yet?

samdark commented 7 years ago

@luciuz there are in ICU. Update it.