fix: Entity::normalizeValue() must handle UnitEnum before toArray()#10137
fix: Entity::normalizeValue() must handle UnitEnum before toArray()#10137maniaba wants to merge 1 commit intocodeigniter4:developfrom
Entity::normalizeValue() must handle UnitEnum before toArray()#10137Conversation
|
You need to add this fix in v4.7.3 changelog |
This comment was marked as resolved.
This comment was marked as resolved.
| } elseif (method_exists($data, 'toArray')) { | ||
| $objectData = $data->toArray(); |
There was a problem hiding this comment.
This change creates a change in behavior for classes implementing both toArray() and either Traversable or DateTimeInterface. Previously, toArray() won. But now, this changes the picture. If this change is desirable, we should document this in the changelog as well. A couple of tests locking this new behavior would be nice, too.
There was a problem hiding this comment.
That's a good point. I think toArray() should stay where it was previously.
| // Check for Entity instance (use raw values, recursive) | ||
| if ($data instanceof self) { | ||
| $objectData = $data->toRawArray(false, true); | ||
| } elseif ($data instanceof UnitEnum) { |
There was a problem hiding this comment.
Since ordering has changed, it might be worthwhile to add in the phpdoc the order of resolution?
There was a problem hiding this comment.
I'm not sure if we should promise a specific normalization order or payload shape. This is purely an internal state.
There was a problem hiding this comment.
Then, I guess, we can instead pin down the behavior via tests.
| } elseif ($data instanceof UnitEnum) { | ||
| return [ | ||
| '__class' => $data::class, | ||
| '__enum' => $data instanceof BackedEnum ? $data->value : $data->name, |
There was a problem hiding this comment.
For completeness, can we additionally test a UnitEnum with toArray()? Currently, it's just a backed enum with toArray().
Entity::normalizeValue() must handle UnitEnum before toArray()
Description
Moves the
UnitEnuminstanceof check beforeJsonSerializableandmethod_exists($data, 'toArray')in Entity::normalizeValue(), so that enums implementing toArray() are always normalized as enums rather than as generic objects.Fixes #10136
toRawArray() returns raw $this->attributes, so an injected enum object stays as an enum object — not the backing string value. The real regression is that hasChanged() must return false (normalizeValue() handles UnitEnum before toArray()).
Checklist: