Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork9.7k
[Translation] Added intl message formatter.#27399
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
| */ | ||
| publicfunctionformat($message,$locale,array$parameters =array()) | ||
| { | ||
| $formatter =new \MessageFormatter($locale,$message); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
When the parsing of this message fails you get a very non-descriptive exception message (Constructor failed). Might be good for DX to rethrow a more descriptive one.
| */ | ||
| privatefunctiongetFormatter(string$domain) | ||
| { | ||
| if (isset($this->formatters[$domain])) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
this could be reduced to:
return$this->formatters[$domain] ??$this->formatters['_default'];
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
And we can declare return type also
| publicfunctiontestFormatWithNamedArguments() | ||
| { | ||
| if (PHP_VERSION_ID <50500 ||version_compare(INTL_ICU_VERSION,'4.8','<')) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Checking for php version is redundant
Line 19 inf557f94
| "php":"^7.1.3", |
Nyholm commentedJun 8, 2018
I've rebased this PR and updated according to feedback. |
| /** | ||
| * @param string $domain | ||
| * @param MessageFormatterInterface $formatter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
to be removed :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Thank you. I added: void as return type.
| /** | ||
| * @param string $domain | ||
| * | ||
| * @return MessageFormatterInterface |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
to be removed (and a real return type be used instead)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Thank you
Nyholm commentedJul 23, 2018
Anything I can do to help review this? |
artursvonda commentedAug 1, 2018
Love the change and allowing to get rid of special case of transChoice (over time). The original PR mentioned something about storing format with the messages and I actually tend to agree with it. The format IS information that's directly coupled with actual messages (basically, a meta information about contents of the file). This becomes even more important if translations are coming from external source and are not part of source files. There already have been talks about allowing different caching mechanisms and sources (like database) so coupling domain to format in config would not allow for changes in message format without deployment (and would make syncing changes hard anyway). |
nicolas-grekas commentedAug 24, 2018
Added to project "Contracts" after comment#28210 (comment) |
| */ | ||
| publicfunctionchoiceFormat($message,$number,$locale,array$parameters =array()) | ||
| { | ||
| return$this->format($message,$locale,$parameters); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Is this kind of implementation right? Argumentnumber is unused.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I think we shouldn't implement theChoiceMessageFormatterInterface instead, it will disallow using thetransChoice method which is right since we should only use thetrans method for intl-formated message.
| }catch (\Throwable$e) { | ||
| thrownew \InvalidArgumentException('Invalid message format.',$e); | ||
| } | ||
| if (null ===$formatter) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
It will never be null here
nicolas-grekas commentedAug 30, 2018
I like it, but I would make the new formatter accessible only through |
nicolas-grekas commentedAug 31, 2018
Some description of the format here: |
7358b74 todaaceb0CompareNyholm commentedSep 3, 2018
I've updated this PR. With the fallback formatter we can support both "Symfony style plural" and intl messages at the same time. This will make sure we have a zero config solution for adding support for this new feature while all the old formats still works as expected. Possible update: I could make the |
| if (!\extension_loaded('intl')) { | ||
| $this->markTestSkipped( | ||
| 'The Intl extension is not available.' | ||
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
should be on one line
| class IntlMessageFormatterTestextends \PHPUnit\Framework\TestCase | ||
| { | ||
| publicfunctionsetUp() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
should be protected
| ); | ||
| } | ||
| privatefunctiongetMessageFormatter() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I think this can be inlined instead.
| * Started using ICU parent locales as fallback locales. | ||
| * deprecated`TranslatorInterface` in favor of`Symfony\Contracts\Translation\TranslatorInterface` | ||
| * deprecated`MessageSelector`,`Interval` and`PluralizationRules`; use`IdentityTranslator` instead | ||
| * Added`IntlMessageFormatter` and`FallbackMessageFormatter` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
missing space afterand.
| * file that was distributed with this source code. | ||
| */ | ||
| declare(strict_types=1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
AFAIK, we are not using this anywhere else, this should be removed.
| return$this->secondFormatter->choiceFormat($message,$number,$locale,$parameters); | ||
| } | ||
| thrownewLogicException(sprintf('The no formatter support plural translations.')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
The message is not so clear to me :) I suppose you meantNo formatters support plural translations.
| try { | ||
| $formatter =new \MessageFormatter($locale,$message); | ||
| }catch (\Throwable$e) { | ||
| thrownewInvalidArgumentException(sprintf('Invalid message format. Reason: %s (error #%d)',intl_get_error_message(),intl_get_error_code()),0,$e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
As an exception should end with a dot, I suggest to useInvalid message format (%s, error #%d). Same below
Nyholm commentedSep 4, 2018
Thank you for the review, Ive updated the PR |
| { | ||
| try { | ||
| $result =$this->firstFormatter->format($message,$locale,$parameters); | ||
| }catch (\Throwable$e) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Can we be more specific here? We should be as much as possible IMHO (same below.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
Do we want to be more specific?
I know the IntlMesaageFormatter only throws InvalidArgument, but isn’t it a good idea to catch everything to give the second formatter a change to run?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
I agree with@nicolas-grekas
fabpot left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
With one small comment. In a followup PR, we should deprecate the old way, deprecatetransChoice and probably try to write a script that converts our proprietary format to the intl one. WDYT?
| useSymfony\Component\Translation\Formatter\FallbackFormatter; | ||
| useSymfony\Component\Translation\Formatter\MessageFormatterInterface; | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
should be removed
| useSymfony\Component\Translation\Formatter\FallbackFormatter; | ||
| useSymfony\Component\Translation\Formatter\MessageFormatterInterface; | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others.Learn more.
should be reverted
nicolas-grekas commentedSep 4, 2018
💯 for both! |
Nyholm commentedSep 4, 2018
Thank you. PR updated. I agree to deprecate transChoice |
fabpot commentedSep 4, 2018
Thank you@Nyholm. |
…, Nyholm)This PR was merged into the 4.2-dev branch.Discussion----------[Translation] Added intl message formatter.| Q | A| ------------- | ---| Branch? | master| Bug fix? | no| New feature? | yes| BC breaks? | no| Deprecations? | no| Tests pass? | yes| Fixed tickets | replaces#20007| License | MIT| Doc PR |This PR will replace#20007 and continue the work from the original author.I've have tried to address all comments made in the original PR.Commits-------2a90931 csfb30c77 Be more specific with what exception we catchb1aa004 Only use the default translator if intl extension is loadedf88153f Updates according to feedback597a15d Use FallbackFormatter instead of support for multiple formatters2aa7181 Fixes according to feedbacka325a44 Allow config for different domain specific formattersb43fe21 Add support for multiple formattersc2b3dc0 [Translation] Added intl message formatter.19e8e69 use error940d440 Make it a warning
…from contracts (Nyholm, nicolas-grekas)This PR was merged into the 4.2-dev branch.Discussion----------[Translator] Deprecated transChoice and moved it away from contracts| Q | A| ------------- | ---| Branch? | master| Bug fix? | no| New feature? | no| BC breaks? | no| Deprecations? | yes| Tests pass? | yes| Fixed tickets | n/a| License | MIT| Doc PR | Issue:symfony/symfony-docs#10264This will address comment made here:#27399 (review)This PR moves the `transChoice()` method away from Contracts and back to the component. I also reverted changes in the `IdentityTranslator`. I will still use the deprecated `MessageSelector` but this is not fine since `transChoice()` is also deprecated.Commits-------dc5f3bf Make trans + %count% parameter resolve pluralsd870a85 [Translator] Deprecated transChoice and moved it away from contracts
This PR will replace#20007 and continue the work from the original author.
I've have tried to address all comments made in the original PR.