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

Skip to content

[Messenger] Fix merging PrototypedArrayNode associative values #39847

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 1 commit into from
May 22, 2021

Conversation

svitiashchuk
Copy link
Contributor

@svitiashchuk svitiashchuk commented Jan 14, 2021

Now keys will not be considered as irrelevant.

Q A
Branch? 4.4
Bug fix? yes
New feature? no
Deprecations? no
Tickets Fix #39846, fix #36874
License MIT
Doc PR

The problem was because in ConfigTree options are defined as arrayNode and has a prototype('variable'). So for combining config together PrototypedArrayNode::mergeValues() was called. And there was a trouble - for that PrototypedArrayNode $rightSide values were added without keys:

\Symfony\Component\Config\Definition\PrototypedArrayNode::mergeValues

foreach ($rightSide as $k => $v) {
    // prototype, and key is irrelevant, append the element
    if (null === $this->keyAttribute) {
        $leftSide[] = $v;
        continue;
    }

@carsonbot
Copy link

Hey!

I see that this is your first PR. That is great! Welcome!

Symfony has a contribution guide which I suggest you to read.

In short:

  • Always add tests
  • Keep backward compatibility (see https://symfony.com/bc).
  • Bug fixes must be submitted against the lowest maintained branch where they apply (see https://symfony.com/releases)
  • Features and deprecations must be submitted against the 5.x branch.

Review the GitHub status checks of your pull request and try to solve the reported issues. If some tests are failing, try to see if they are failing because of this change.

When two Symfony core team members approve this change, it will be merged and you will become an official Symfony contributor!
If this PR is merged in a lower version branch, it will be merged up to all maintained branches within a few days.

I am going to sit back now and wait for the reviews.

Cheers!

Carsonbot

Copy link
Member

@jderusse jderusse left a comment

Choose a reason for hiding this comment

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

could you please add a test?

see https://github.com/symfony/symfony/pull/39686/files for similar PR

@svitiashchuk
Copy link
Contributor Author

Test added

@jderusse
Copy link
Member

looks like the failed tests is related to your change

@svitiashchuk
Copy link
Contributor Author

Yes, it was. Now, I've changed the argument $name value of method ArrayNodeDefinition::useAttributeAsKey to 'option'. Because in fixture config messenger_transports.php there was a piece:

'options' => ['queue' => ['name' => 'Queue']],

for which 'name' => 'Queue' was considered as key for option, and therefore, rewritten the original key 'queue' with 'Queue'. Now that problem solved.

P.S. I'm not sure about that, but is that a normal behaviour that original key replaced when attributeAsKey is set and original key is present in config simultaneously. Should I create another one issue?

@jderusse
Copy link
Member

Indeed, the attributeAsKey should not be an expected subkey of the array.

@OskarStark
Copy link
Contributor

CleanShot 2021-01-15 at 15 49 24

It looks like your committer email is not associated with your Github account 🤔

@svitiashchuk
Copy link
Contributor Author

@OskarStark yes, thanks for pointing. Did it in different environment, but now fixed it.

Copy link
Member

@xabbuh xabbuh left a comment

Choose a reason for hiding this comment

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

I am not convinced that this will always work. What if there is a queue where one option is named option?

Copy link
Contributor Author

@svitiashchuk svitiashchuk left a comment

Choose a reason for hiding this comment

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

@xabbuh I've added an option key inside test config options array to prove that this will work.

@xabbuh
Copy link
Member

xabbuh commented Jan 18, 2021

@svityashchuk If you change your example to something like this, you will experience the same behavior:

'options' => [
    'auto_setup' => true,
    'queue' => [
        'name' => 'Queue',
        'option' => 'foo',
    ],
],

@svitiashchuk
Copy link
Contributor Author

@xabbuh thank you for providing an example. I've got that behaviour. So, in the circumstances I see the only possibility to use another keyword as keyAttribute. Otherwise, I won't be able to pass this check at \Symfony\Component\Config\Definition\PrototypedArrayNode::mergeValues:

foreach ($rightSide as $k => $v) {
    // prototype, and key is irrelevant, append the element
    if (null === $this->keyAttribute) {
        $leftSide[] = $v;
        continue;
    }

Moreover, now it seems for me like this condition null === $this->keyAttribute is not enough to decide to append value as plain array item (I mean, not an associative array element). Therefore, I think we need to add an additional condition, like it is done in \Symfony\Component\Config\Definition\PrototypedArrayNode::normalizeValue. There we can see the next lines:

protected function normalizeValue($value)
{
//...
$isAssoc = array_keys($value) !== range(0, \count($value) - 1);
//...
foreach ($value as $k => $v) {
    //...
    if (null !== $this->keyAttribute || $isAssoc) {
        $normalized[$k] = $prototype->normalize($v);
    } else {
        $normalized[] = $prototype->normalize($v);
    }

Pay attention that $isAssoc variable affects the way normalized value is added to resulting $normalized array.
If you wouldn't mind, I will provide corresponding changes.

@xabbuh
Copy link
Member

xabbuh commented Jan 20, 2021

This sounds like a solution that could work. Let's give that a try. For 5.x I have pending changes locally that allow to configure list and map nodes explicitly which would allow an easier solution. But that's of course not something we can use here for the bugfix.

@svitiashchuk
Copy link
Contributor Author

Now it seems like everything is ok :)
Thanks to my colleague I realized that I had written test in different bundle. Therefore, on Travis CI check it was impossible to test changes that I had provided. So I've removed that test and wrote another one in relevant directory.

I would be very happy if this is merged.
@xabbuh could you please take a look at it?

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.

Please update the PR title - it's not about Messenger :)

@svitiashchuk svitiashchuk changed the title [Messenger] Messenger options were merged with numbers as keys. [Config Component] Merging PrototypedArrayNode associative values Feb 16, 2021
@Sscorpion9991
Copy link

Hi! Is this PR going to be merged? I have the same issue.

@nicolas-grekas nicolas-grekas changed the title [Config Component] Merging PrototypedArrayNode associative values [Config] Merging PrototypedArrayNode associative values Apr 20, 2021
@nicolas-grekas nicolas-grekas changed the title [Config] Merging PrototypedArrayNode associative values [Config] Fix merging PrototypedArrayNode associative values Apr 20, 2021
@carsonbot carsonbot changed the title [Config] Fix merging PrototypedArrayNode associative values [Messenger] Fix merging PrototypedArrayNode associative values Apr 20, 2021
@derrabus
Copy link
Member

Thank you @svityashchuk.

@derrabus derrabus merged commit 53d9b10 into symfony:4.4 May 22, 2021
This was referenced May 31, 2021
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.

9 participants