Skip to content

[config] Fix issue when key removed and left value only #14082

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

Closed

Conversation

zerustech
Copy link
Contributor

Q A
Bug fix? yes
New feature? no
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets #15270
License MIT
Doc PR n/a

When a key attribute is mapped and the key is removed from the value array, if
only 'value' element is left in the array, it should replace its wrapper
array.

Assume the original value array is as follows (key attribute is 'id').

array(
    'things' => array(
        array('id' => 'option1', 'value' => 'value1'),
        array('id' => 'option2', 'value' => 'value2')
    )
)

After normalized, the above shall be converted to the following array.

array(
    'things' => array(
        'option1' => 'value1',
        'option2' => 'value2'
    )
)

It's also possible to mix 'value-only' and 'none-value-only' elements in
the array:

array(
    'things' => array(
        array('id' => 'option1', 'value' => 'value1'),
        array('id' => 'option2', 'value' => 'value2', 'foo' => 'foo2')
    )
)

The above shall be converted to the following array.

array(
    'things' => array(
        'option1' => 'value1',
        'option2' => array('value' => 'value2','foo' => 'foo2')
    )
)

The 'value' element can also be array:

array(
    'things' => array(
        array(
            'id' => 'option1',
            'value' => array('foo'=>'foo1', 'bar' => 'bar1')
        )
    )
)

The above shall be converted to the following array.

array(
    'things' => array(
        'option1' => array('foo' => 'foo1', 'bar' => 'bar1')
    )
)

When using VariableNode for value element, it's also possible to mix
different types of value elements:

array(
    'things' => array(
        array('id' => 'option1', 'value' => array('foo'=>'foo1', 'bar' => 'bar1')),
        array('id' => 'option2', 'value' => 'value2')
    )
)

The above shall be converted to the following array.

array(
    'things' => array(
        'option1' => array('foo'=>'foo1', 'bar' => 'bar1'),
        'option2' => 'value2'
    )
)

@zerustech zerustech force-pushed the config-attribute-as-key-value-only branch from 1d67c56 to 96f65cc Compare March 27, 2015 15:53
@zerustech zerustech closed this Mar 27, 2015
@zerustech zerustech reopened this Mar 27, 2015
@zerustech zerustech force-pushed the config-attribute-as-key-value-only branch from 96f65cc to 4e750d8 Compare March 30, 2015 11:27
@zerustech zerustech closed this Mar 30, 2015
@zerustech zerustech reopened this Mar 30, 2015
@zerustech zerustech force-pushed the config-attribute-as-key-value-only branch from 4e750d8 to 260cac4 Compare March 30, 2015 11:30
@zerustech zerustech closed this Mar 30, 2015
@zerustech zerustech reopened this Mar 30, 2015
@zerustech zerustech force-pushed the config-attribute-as-key-value-only branch 2 times, most recently from beda431 to 28d2fbb Compare July 8, 2015 11:41
@zerustech zerustech force-pushed the config-attribute-as-key-value-only branch from 28d2fbb to 7859855 Compare July 14, 2015 09:21
@fabpot fabpot added the Config label Oct 5, 2015
*
* @return mixed The prototype instance
*/
protected function getPrototypeForChild($key)
Copy link
Member

Choose a reason for hiding this comment

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

This method should be private.

@fabpot
Copy link
Member

fabpot commented Mar 2, 2016

The examples you give in the description seems good to me.

@fabpot
Copy link
Member

fabpot commented Mar 2, 2016

Apart from the minor formatting comments, 👍

@zerustech Can you rebase on current 2.3 so that tests can be re-run? Thanks.

@zerustech zerustech force-pushed the config-attribute-as-key-value-only branch from 7859855 to d4b2a2f Compare March 3, 2016 08:44
@zerustech
Copy link
Contributor Author

@fabpot Done, please check. Thanks.

@fabpot
Copy link
Member

fabpot commented Mar 3, 2016

@zerustech Thanks, it looks like it breaks some tests. Can you check?

@zerustech
Copy link
Contributor Author

@fabpot Looks like it was caused by TwigBundle :

Testing src/Symfony/Bundle/TwigBundle
.....EEF.......EE.......

Time: 17.06 seconds, Memory: 13.25Mb

@xabbuh
Copy link
Member

xabbuh commented Mar 7, 2016

@zerustech Yeah, but this happens when the bunde's config is evaluated and the failures are related to the prototype handling from this PR.

Status: Needs work

@zerustech zerustech force-pushed the config-attribute-as-key-value-only branch from d4b2a2f to 66bd18d Compare March 10, 2016 12:19
@zerustech
Copy link
Contributor Author

@xabbuh @fabpot Fixed the following issues:

  1. When the 'value' element in an array is null, it does not replace its wrapper array, because isset() returns false on null element.
  2. TwigBundle manipulates its configuration values with the normalization closures of its prototype nodes. For example, under the globals node, "foo" is changed to array("value" => "foo") and etc, so TwigBundle always expects the 'value' key to present. When a PrototypedArrayNode node replaces the wrapper array with its 'value' element, the 'value' key disappears and the actual prototype node will be replaced as well: array("value" => "foo") becomes "foo" and PrototypedArrayNode becomes VariableNode, so when normalizing the element, the original normalization closures are gone, "foo" won't be changed back to array("value" => "foo"), which will result in errors. To fix this issue, we can copy the original normalization closures into the new prototype node. I know it's not the perfect solution, but at this moment, it's the least-worst solution.

/**
* @var NodeInterface[] An array of the prototypes of the simplified value children
*/
protected $valuePrototypes = array();
Copy link
Member

Choose a reason for hiding this comment

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

should be private IMO

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@fabpot Fixed, please test.

@fabpot
Copy link
Member

fabpot commented Sep 14, 2016

👍 for merge in 2.7 after the small asked change.

When a key attribute is mapped and the key is removed from the value array, if
only 'value' element is left in the array, it should replace its wrapper
array.

Assume the original value array is as follows (key attribute is 'id').

```php
array(
    'things' => array(
        array('id' => 'option1', 'value' => 'value1'),
        array('id' => 'option2', 'value' => 'value2')
    )
)
```

After normalized, the above shall be converted to the following array.

```php
array(
    'things' => array(
        'option1' => 'value1',
        'option2' => 'value2'
    )
)
```

It's also possible to mix 'value-only' and 'none-value-only' elements in
the array:

```php
array(
    'things' => array(
        array('id' => 'option1', 'value' => 'value1'),
        array('id' => 'option2', 'value' => 'value2', 'foo' => 'foo2')
    )
)
```

The above shall be converted to the following array.
```php
array(
    'things' => array(
        'option1' => 'value1',
        'option2' => array('value' => 'value2','foo' => 'foo2')
    )
)
```

The 'value' element can also be array:

```php
array(
    'things' => array(
        array(
            'id' => 'option1',
            'value' => array('foo'=>'foo1', 'bar' => 'bar1')
        )
    )
)
```
The above shall be converted to the following array.
```php
array(
    'things' => array(
        'option1' => array('foo' => 'foo1', 'bar' => 'bar1')
    )
)
```

When using VariableNode for value element, it's also possible to mix
different types of value elements:
```php
array(
    'things' => array(
        array('id' => 'option1', 'value' => array('foo'=>'foo1', 'bar' => 'bar1')),
        array('id' => 'option2', 'value' => 'value2')
    )
)
```

The above shall be converted to the following array.
```php
array(
    'things' => array(
        'option1' => array('foo'=>'foo1', 'bar' => 'bar1'),
        'option2' => 'value2'
    )
)
```

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | symfony#15270
| License       | MIT
| Doc PR        | n/a
@zerustech zerustech force-pushed the config-attribute-as-key-value-only branch from 66bd18d to 12488c5 Compare September 19, 2016 07:34
@nicolas-grekas nicolas-grekas added this to the 2.7 milestone Dec 6, 2016
@fabpot
Copy link
Member

fabpot commented Dec 14, 2016

Thank you @zerustech.

fabpot added a commit that referenced this pull request Dec 14, 2016
…erustech)

This PR was submitted for the 2.3 branch but it was merged into the 2.7 branch instead (closes #14082).

Discussion
----------

[config] Fix issue when key removed and left value only

| Q | A |
| --- | --- |
| Bug fix? | yes |
| New feature? | no |
| BC breaks? | no |
| Deprecations? | no |
| Tests pass? | yes |
| Fixed tickets | #15270 |
| License | MIT |
| Doc PR | n/a |

When a key attribute is mapped and the key is removed from the value array, if
only 'value' element is left in the array, it should replace its wrapper
array.

Assume the original value array is as follows (key attribute is 'id').

``` php
array(
    'things' => array(
        array('id' => 'option1', 'value' => 'value1'),
        array('id' => 'option2', 'value' => 'value2')
    )
)
```

After normalized, the above shall be converted to the following array.

``` php
array(
    'things' => array(
        'option1' => 'value1',
        'option2' => 'value2'
    )
)
```

It's also possible to mix 'value-only' and 'none-value-only' elements in
the array:

``` php
array(
    'things' => array(
        array('id' => 'option1', 'value' => 'value1'),
        array('id' => 'option2', 'value' => 'value2', 'foo' => 'foo2')
    )
)
```

The above shall be converted to the following array.

``` php
array(
    'things' => array(
        'option1' => 'value1',
        'option2' => array('value' => 'value2','foo' => 'foo2')
    )
)
```

The 'value' element can also be array:

``` php
array(
    'things' => array(
        array(
            'id' => 'option1',
            'value' => array('foo'=>'foo1', 'bar' => 'bar1')
        )
    )
)
```

The above shall be converted to the following array.

``` php
array(
    'things' => array(
        'option1' => array('foo' => 'foo1', 'bar' => 'bar1')
    )
)
```

When using VariableNode for value element, it's also possible to mix
different types of value elements:

``` php
array(
    'things' => array(
        array('id' => 'option1', 'value' => array('foo'=>'foo1', 'bar' => 'bar1')),
        array('id' => 'option2', 'value' => 'value2')
    )
)
```

The above shall be converted to the following array.

``` php
array(
    'things' => array(
        'option1' => array('foo'=>'foo1', 'bar' => 'bar1'),
        'option2' => 'value2'
    )
)
```

Commits
-------

b587a72 [config] Fix issue when key removed and left value only
@fabpot fabpot closed this Dec 14, 2016
@zerustech
Copy link
Contributor Author

@fabpot It's my pleasure.

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.

6 participants