Skip to content

fix: Entity::normalizeValue() must handle UnitEnum before toArray() #10137

Open
maniaba wants to merge 2 commits intocodeigniter4:developfrom
maniaba:bug-entity
Open

fix: Entity::normalizeValue() must handle UnitEnum before toArray() #10137
maniaba wants to merge 2 commits intocodeigniter4:developfrom
maniaba:bug-entity

Conversation

@maniaba
Copy link
Copy Markdown
Contributor

@maniaba maniaba commented Apr 24, 2026

Description

Moves the UnitEnum instanceof check before JsonSerializable and method_exists($data, 'toArray') in Entity::normalizeValue(), so that enums implementing toArray() are always normalized as enums rather than as generic objects.

Fixes #10136

  • fix test: correct toRawArray() assertion for injected enum

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:

  • Securely signed commits
  • Component(s) with PHPDoc blocks, only if necessary or adds value (without duplication)
  • Unit testing, with >80% coverage
  • User guide updated
  • Conforms to style guide

* fix: Entity::normalizeValue() must handle UnitEnum before toArray()

Moves the `UnitEnum` instanceof check before `JsonSerializable` and
`method_exists($data, 'toArray')` in Entity::normalizeValue(), so that
enums implementing toArray() are always normalized as enums rather than
as generic objects.

Fixes codeigniter4#10136

Agent-Logs-Url: https://github.com/maniaba/CodeIgniter4/sessions/d5c8c660-329b-4872-8633-dd918674e4ac

Co-authored-by: maniaba <61078470+maniaba@users.noreply.github.com>

* fix test: correct toRawArray() assertion for injected enum

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()).

Fixes the failing test from the previous commit.

Agent-Logs-Url: https://github.com/maniaba/CodeIgniter4/sessions/d86b9a68-aee9-4178-a8b8-cf1bac285359

Co-authored-by: maniaba <61078470+maniaba@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: maniaba <61078470+maniaba@users.noreply.github.com>
@patel-vansh
Copy link
Copy Markdown
Contributor

You need to add this fix in v4.7.3 changelog

Agent-Logs-Url: https://github.com/maniaba/CodeIgniter4/sessions/40f33833-bf97-486e-a6d8-5d95bff1bf50

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: maniaba <61078470+maniaba@users.noreply.github.com>
public function toArray(): array
{
return array_column(self::cases(), 'value');
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You're returning scalar strings, so this test does not test the reported recursion path.

Comment on lines +1049 to +1065
public function testInjectRawDataWithEnumThatHasToArrayMethod(): void
{
// Regression test for https://github.com/codeigniter4/CodeIgniter4/issues/10136
// Enums implementing toArray() must still be handled by the UnitEnum branch in
// normalizeValue(), so hasChanged() does not incorrectly report a change after
// injectRawData() stores the same enum value.
$entity = new class () extends Entity {};

$entity->injectRawData(['state' => StateEnum::DRAFT]);

// toRawArray() returns raw attributes, so the enum object is returned as-is.
$this->assertSame(StateEnum::DRAFT, $entity->toRawArray()['state']);

// The key assertion: normalizeValue() must treat the enum as a UnitEnum
// (not call toArray() on it), so the original and current normalized forms match.
$this->assertFalse($entity->hasChanged('state'));
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please remove all these comments, and just add in the docblock:

@see https://github.com/codeigniter4/CodeIgniter4/issues/10136

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.

Bug: Entity::normalizeValue incorrectly handles enums when they implement toArray()

4 participants