Description
The allow_not_iterable option of ArrayFirstTransformer works the other way round:
- by default (
allow_not_iterable: false), a non-iterable input is returned unchanged;
- with
allow_not_iterable: true, reset() is called on the raw value, which throws a \TypeError for a scalar or null input (and returns the first public property of an object).
So the option can only be used to trigger an error.
History
The option was added in 2019 (00257de, v2.0.6) with the expected meaning:
if ($options['allow_not_iterable'] && !is_iterable($value)) {
return $value;
}
It was inverted by the refactoring of #142 (b7afaab, 2024-10-18), released in v4.0.0:
if (false === $options['allow_not_iterable'] && !is_iterable($value)) {
return $value;
}
ArrayFirstTransformerTest was then written against the inverted behaviour, and the reference documentation (#145) describes it as is.
Reproduction
transformers:
array_first: ~ # 'abc' => 'abc' (returned unchanged)
transformers:
array_first:
allow_not_iterable: true # 'abc' => TypeError: reset(): Argument #1 ($array) must be of type array, string given
Tested on main (ba31efc), PHP 8.5, Symfony 7.4.
Proposed fix (v6.0)
Restore the meaning of the option (as in v2 / v3), which changes the default behaviour, hence for v6.0:
allow_not_iterable: false (default): a non-iterable input throws an explicit \UnexpectedValueException (instead of being returned unchanged);
allow_not_iterable: true: a non-iterable input is returned unchanged (instead of throwing a \TypeError);
Traversable inputs return their first element (reset() on an object returns its first property, and is deprecated since PHP 8.1);
allow_not_iterable must be a bool;
- rewrite
ArrayFirstTransformerTest, update docs/reference/transformers/array_first_transformer.md and the CHANGELOG (BC breaks).
array_first is not used by the other cleverage bundles nor by the demo project.
Requirements
Breaking changes
Major (v6.0): with the default options, a non-iterable input now throws an \UnexpectedValueException instead of being returned unchanged. Configurations relying on this must set allow_not_iterable: true. Configurations setting allow_not_iterable: true currently always fail on non-iterable values, so they cannot break.
Description
The
allow_not_iterableoption ofArrayFirstTransformerworks the other way round:allow_not_iterable: false), a non-iterable input is returned unchanged;allow_not_iterable: true,reset()is called on the raw value, which throws a\TypeErrorfor a scalar ornullinput (and returns the first public property of an object).So the option can only be used to trigger an error.
History
The option was added in 2019 (
00257de, v2.0.6) with the expected meaning:It was inverted by the refactoring of #142 (
b7afaab, 2024-10-18), released in v4.0.0:ArrayFirstTransformerTestwas then written against the inverted behaviour, and the reference documentation (#145) describes it as is.Reproduction
Tested on
main(ba31efc), PHP 8.5, Symfony 7.4.Proposed fix (v6.0)
Restore the meaning of the option (as in v2 / v3), which changes the default behaviour, hence for v6.0:
allow_not_iterable: false(default): a non-iterable input throws an explicit\UnexpectedValueException(instead of being returned unchanged);allow_not_iterable: true: a non-iterable input is returned unchanged (instead of throwing a\TypeError);Traversableinputs return their first element (reset()on an object returns its first property, and is deprecated since PHP 8.1);allow_not_iterablemust be abool;ArrayFirstTransformerTest, updatedocs/reference/transformers/array_first_transformer.mdand the CHANGELOG (BC breaks).array_firstis not used by the other cleverage bundles nor by the demo project.Requirements
Breaking changes
Major (v6.0): with the default options, a non-iterable input now throws an
\UnexpectedValueExceptioninstead of being returned unchanged. Configurations relying on this must setallow_not_iterable: true. Configurations settingallow_not_iterable: truecurrently always fail on non-iterable values, so they cannot break.