Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Translator] Deprecated transChoice and moved it away from contracts #28375

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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 6, 2018

Conversation

Nyholm
Copy link
Member

@Nyholm Nyholm commented Sep 5, 2018

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#10264

This 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.

Copy link
Member Author

@Nyholm Nyholm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added some comments that I think will help the review.

UPGRADE-4.2.md Outdated
@@ -155,6 +155,7 @@ Translation
-----------

* The `TranslatorInterface` has been deprecated in favor of `Symfony\Contracts\Translation\TranslatorInterface`
* The `Translator::transChoice()` has been deprecated in favor of using `Translator::trans()` with intl message format
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I choose to use the implementation (Translator) here. We already say that the full interface is deprecated.

* @param int $number The number of items represented for the message
* @param string $locale The locale to use for choosing
* @param string $message The message being translated
* @param int|float $number The number of items represented for the message
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We actually support floats.

private function getPluralizationRule(int $number, string $locale): int
{
return PluralizationRules::get($number, $locale, false);
return strtr($this->selector->choose((string) $id, $number, $locale ?: $this->getLocale()), $parameters);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI: In 4.1 we use (int) $number.

@@ -20,4 +20,193 @@ public function getTranslator()
{
return new IdentityTranslator();
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests are moved from Contracts.

*/
interface TranslatorInterface extends BaseTranslatorInterface
{
/**
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved this back from Contracts

/**
* {@inheritdoc}
*/
public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function was removed. It was a replacement for the deprecated MessageSelector. I do not think it is needed anymore, right?

Copy link
Member

@nicolas-grekas nicolas-grekas Sep 6, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right, same for getPluralizationRule below

Copy link
Member

@nicolas-grekas nicolas-grekas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Open questions:

  • what should happen when the intl extension is not installed?
  • should be ship a command converting from one format to the other in this PR?

/**
* {@inheritdoc}
*/
public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null)
Copy link
Member

@nicolas-grekas nicolas-grekas Sep 6, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right, same for getPluralizationRule below

@Nyholm
Copy link
Member Author

Nyholm commented Sep 6, 2018

what should happen when the intl extension is not installed?

I think we should ship with "SimpleIntlFormat" that maybe covers some use cases.

should be ship a command converting from one format to the other in this PR?

I think that is a good idea. But that is not a requirement for this PR (nor for 4.2). But the sooner the better.

@nicolas-grekas
Copy link
Member

I think it would be friendly to make migrating to the new format as seamless as possible, running a command to update existing catalogs would be awesome. It should be shipped at the same time as the deprecation to me. If doable of course.

We should also deprecate the twig helpers btw! (as highlighted by the CI ;) )

@Nyholm
Copy link
Member Author

Nyholm commented Sep 6, 2018

Okey. I'll will not do it in this PR. It is a lot of code and hard to review already. I will work on a migration script now and add that in a other PR.

We should also deprecate the twig helpers btw! (as highlighted by the CI ;) )

Thank you. I saw those now. 👍

Label: Needs work

@stof
Copy link
Member

stof commented Sep 6, 2018

Well, you cannot deprecate the transChoice API if catalogues are still using the old format.

And we also need to figure out the migration path between format.
And that path should take into account bundles which might need to keep support for 3.4 and 4.1. Forcing bundles to either use the deprecated API or drop support for 3.4 and 4.1 is hurting the upgrade path for bundles (dropping support for the LTS is often not an option for them)

@@ -43,15 +41,11 @@ public function __construct(MessageSelector $selector = null)
*/
public function transChoice($id, $number, array $parameters = array(), $domain = null, $locale = null)
{
if ($this->selector) {
return strtr($this->selector->choose((string) $id, (int) $number, $locale ?: $this->getLocale()), $parameters);
@trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.1, use the "trans()" method with intl formatted messages instead.', __METHOD__), E_USER_DEPRECATED);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4.1 ? That's too late for that

@Nyholm
Copy link
Member Author

Nyholm commented Sep 17, 2018

This PR is blocked by #28486 and related to #28492.

@nicolas-grekas
Copy link
Member

I just rebased+squashed the PR by pushing on your fork.
There is now #28523 we need to take care of.
I'd suggest moving forward the implementation as if MessageFormatter was always available.
We'll then be able to move #28486 forward independently.

@Nyholm Nyholm force-pushed the transchoice-deprecation branch from 868e9bd to 39fcccf Compare September 22, 2018 10:45
if ($this->translator instanceof LegacyTranslatorInterface) {
$trans = $this->translator->transChoice($id, $number, $parameters, $domain, $locale);
} else {
$trans = $this->doTransChoice($id, $number, $parameters, $domain, $locale);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this correct to use the trait here and in the DataCollector?

@@ -141,7 +142,7 @@ public function setCause($cause)
*/
public function addViolation()
{
if (null === $this->plural) {
if (null === $this->plural || !$this->translator instanceof LegacyTranslatorInterface) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will cause some deprecations. How can I know if I should use transChoice or not?

@Nyholm
Copy link
Member Author

Nyholm commented Sep 22, 2018

@stof Thank you for the review.

Well, you cannot deprecate the transChoice API if catalogues are still using the old format.

The migration path would be to run the translation:convert-to-intl-message. See #28486

About supporting both formats: That is a fair point, do you have any suggestions?

Status: needs review

@nicolas-grekas nicolas-grekas force-pushed the transchoice-deprecation branch 4 times, most recently from 562bdff to 7cdef58 Compare October 1, 2018 19:35
@nicolas-grekas
Copy link
Member

nicolas-grekas commented Oct 1, 2018

I pushed a new approach here, see 2nd commit: I think we should not deprecate the current plural format as this would create a too steep migration path for devs. Instead, I think we should make "trans()" able to resolve plurals. That's already the case when using the INTL message format, so let's make it work with the Symfony format.

What is proposed now is to make the %count% parameter special: when it is defined and is numeric, then the message is parsed using the plural rules.

For Twig, {% transchoice 5 %} is replaced by {% trans count 5 %} or {% trans with {"%count%": 5} %}
and {{ 'message'|transchoice(5) }} by {{ 'message'|trans(count=5) }} or {{ 'message'|trans({"%count%": 5}) }}

There is a potential for conflicts with existing messages when these two conditions are met together:

  1. a %count% parameter is used with trans(),
  2. the message embeds a pipe character (|).

We could choose another special parameter name if we think the risk is unreasonable (to me it's OK).
WDYT?

Ready for review.

@nicolas-grekas nicolas-grekas force-pushed the transchoice-deprecation branch from 7cdef58 to 943f23b Compare October 1, 2018 19:47
@nicolas-grekas nicolas-grekas modified the milestones: next, 4.2 Oct 1, 2018
@nicolas-grekas nicolas-grekas force-pushed the transchoice-deprecation branch from 943f23b to 54421ed Compare October 6, 2018 08:01
Copy link
Member Author

@Nyholm Nyholm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've reviewed this carefully. I think it looks alright.

About %count%. I was considering to use # because that is that INTL is using. However, the potential conflicts are larger and we do not need to take this step towards INTL format right now.

👍

$trans = $this->translator->transChoice($id, $number, $parameters, $domain, $locale);
$this->collectMessage($locale, $domain, $id, $trans, $parameters, $number);

$this->collectMessage($locale, $domain, $id, $trans, array('%count%' => $number) + $parameters);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've always got problems when adding arrays. Shouldn't we use the more easy-to-read array_merge?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

array_merge is a function call, personally I prefer using the language directly.

{
if (null !== $translator && !$translator instanceof LegacyTranslatorInterface && !$translator instanceof TranslatorInterface) {
throw new \TypeError(sprintf('Argument 5 passed to %s() must be an instance of %s, %s given', __METHOD__, TranslatorInterface::class, \is_object($translator) ? \get_class($translator) : \gettype($translator)));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing . at the end of the exception message.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are many other occurrences.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oups, now all of them are fixed

@nicolas-grekas nicolas-grekas force-pushed the transchoice-deprecation branch from 54421ed to 211e8af Compare October 6, 2018 16:16
@nicolas-grekas nicolas-grekas force-pushed the transchoice-deprecation branch from 211e8af to dc5f3bf Compare October 6, 2018 16:22
@fabpot
Copy link
Member

fabpot commented Oct 6, 2018

Thank you @Nyholm.

@fabpot fabpot merged commit dc5f3bf into symfony:master Oct 6, 2018
fabpot added a commit that referenced this pull request Oct 6, 2018
…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#10264

This 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 plurals
d870a85 [Translator] Deprecated transChoice and moved it away from contracts
This was referenced Nov 3, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants