Skip to content

ArrayFirstTransformer: the allow_not_iterable option is inverted since v4.0 #234

Description

@njoubert-cleverage

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

  • Documentation updates
    • Reference
    • Cookbooks
    • Changelog
  • Unit tests

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions