Skip to content

Fix false positives in EntityColumnRule for json columns with enumType - #806

Open
oriolvinals wants to merge 1 commit into
phpstan:2.1.xfrom
oriolvinals:fix-json-enum-array-false-positives
Open

oriolvinals wants to merge 1 commit into
phpstan:2.1.xfrom
oriolvinals:fix-json-enum-array-false-positives

Conversation

@oriolvinals

Copy link
Copy Markdown

Doctrine ORM supports enumType on json columns holding arrays: each value is hydrated with Enum::from() via array_map, which preserves keys. EntityColumnRule reports two false positives for such mappings:

enum DayOfWeek: int { case Monday = 1; case Tuesday = 2; }

#[ORM\Entity]
class Foo
{
    /** @var list<DayOfWeek> */
    #[ORM\Column(type: 'json', enumType: DayOfWeek::class)]
    private array $weekDays = [];
}
doctrine.enumType:   Property Foo::$weekDays type mapping mismatch: backing type int of enum DayOfWeek does not match value type mixed of the database type array|bool|float|int|JsonSerializable|stdClass|string|null.
doctrine.columnType: Property Foo::$weekDays type mapping mismatch: database can contain array<DayOfWeek> but property expects list<DayOfWeek>.

Cause

Both come from the array branch of the enumType handling added in #605:

  1. The backing type of the enum is compared against the iterable value type of the descriptor's types. For json that value type is mixed, so the comparison can never succeed.
  2. JsonType::getWritableToPropertyType() returns NeverType ("don't check"), but the branch replaces it with array<key, Enum> intersected with the accessory types of NeverType. As there is no AccessoryArrayListType to keep, the result is a plain array<Enum>, which then fails against list<Enum>. This second error does not happen with simple_array, whose descriptor returns list<string> so the list accessory is preserved.

Fix

  • Skip the backing type comparison when the descriptor's array value type is mixed, consistent with the existing "If the type descriptor does not precise the types inside the array, don't report errors" logic in the same rule.
  • Leave $writableToPropertyType untouched when it is NeverType. $writableToDatabaseType is still rebuilt as before, so mismatches like a list<string> property on a json + enumType column are still reported.

Tests

The new json + enumType cases in enum-type.php (list<Enum>, array<Enum>, Enum[]) fail on 2.1.x with both errors above, and a list<string> property on such a column is still reported. The existing simple_array cases are unchanged. I also checked by hand that the usual mutants on the changed lines (instanceof, !, &&, !== null) are caught, since I couldn't run Infection locally. ODM tests were not run here (no ext-mongodb).

Fixes #628

@oriolvinals
oriolvinals marked this pull request as ready for review October 30, 2026 14:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Array of enums as Json array not supported

1 participant