-
Notifications
You must be signed in to change notification settings - Fork 2k
fix: convert DateTimeInterface objects to strings in Entity::toRawArray #10402
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -261,84 +261,93 @@ public function toRawArray(bool $onlyChanged = false, bool $recursive = false): | |
|
|
||
| // When returning everything | ||
| if (! $onlyChanged) { | ||
| return $recursive | ||
| ? array_map($convert, $this->attributes) | ||
| : $this->attributes; | ||
| } | ||
|
|
||
| // When filtering by changed values only | ||
| $return = []; | ||
|
|
||
| foreach ($this->attributes as $key => $value) { | ||
| // Special handling for arrays of entities in recursive mode | ||
| // Skip hasChanged() and do per-entity comparison directly | ||
| if ($recursive && is_array($value) && $this->containsOnlyEntities($value)) { | ||
| $originalValue = $this->original[$key] ?? null; | ||
| $result = array_map($convert, $this->attributes); | ||
| } else { | ||
| // When filtering by changed values only | ||
| $result = []; | ||
|
|
||
| foreach ($this->attributes as $key => $value) { | ||
| // Special handling for arrays of entities in recursive mode | ||
| // Skip hasChanged() and do per-entity comparison directly | ||
| if ($recursive && is_array($value) && $this->containsOnlyEntities($value)) { | ||
| $originalValue = $this->original[$key] ?? null; | ||
|
|
||
| if (! is_string($originalValue)) { | ||
| // No original or invalid format, export all entities | ||
| $converted = []; | ||
|
|
||
| foreach ($value as $idx => $item) { | ||
| $converted[$idx] = $item->toRawArray(false, true); | ||
| } | ||
| $result[$key] = $converted; | ||
|
|
||
| continue; | ||
| } | ||
|
|
||
| if (! is_string($originalValue)) { | ||
| // No original or invalid format, export all entities | ||
| $converted = []; | ||
| // Decode original array structure for per-entity comparison | ||
| $originalArray = json_decode($originalValue, true); | ||
| $converted = []; | ||
|
|
||
| foreach ($value as $idx => $item) { | ||
| $converted[$idx] = $item->toRawArray(false, true); | ||
| // Compare current entity against its original state | ||
| $currentNormalized = $this->normalizeValue($item); | ||
| $originalNormalized = $originalArray[$idx] ?? null; | ||
|
|
||
| // Only include if changed, new, or can't determine | ||
| if ($originalNormalized === null || $currentNormalized !== $originalNormalized) { | ||
| $converted[$idx] = $item->toRawArray(false, true); | ||
| } | ||
| } | ||
| $return[$key] = $converted; | ||
|
|
||
| continue; | ||
| } | ||
|
|
||
| // Decode original array structure for per-entity comparison | ||
| $originalArray = json_decode($originalValue, true); | ||
| $converted = []; | ||
|
|
||
| foreach ($value as $idx => $item) { | ||
| // Compare current entity against its original state | ||
| $currentNormalized = $this->normalizeValue($item); | ||
| $originalNormalized = $originalArray[$idx] ?? null; | ||
|
|
||
| // Only include if changed, new, or can't determine | ||
| if ($originalNormalized === null || $currentNormalized !== $originalNormalized) { | ||
| $converted[$idx] = $item->toRawArray(false, true); | ||
| // Only include this property if at least one entity changed | ||
| if ($converted !== []) { | ||
| $result[$key] = $converted; | ||
| } | ||
| } | ||
|
|
||
| // Only include this property if at least one entity changed | ||
| if ($converted !== []) { | ||
| $return[$key] = $converted; | ||
| continue; | ||
| } | ||
|
|
||
| continue; | ||
| } | ||
| // For all other cases, use hasChanged() | ||
| if (! $this->hasChanged($key)) { | ||
| continue; | ||
| } | ||
|
|
||
| // For all other cases, use hasChanged() | ||
| if (! $this->hasChanged($key)) { | ||
| continue; | ||
| } | ||
| if ($recursive) { | ||
| // Special handling for arrays (mixed or not all entities) | ||
| if (is_array($value)) { | ||
| $converted = []; | ||
|
|
||
| if ($recursive) { | ||
| // Special handling for arrays (mixed or not all entities) | ||
| if (is_array($value)) { | ||
| $converted = []; | ||
| foreach ($value as $idx => $item) { | ||
| $converted[$idx] = $item instanceof self ? $item->toRawArray(false, true) : $convert($item); | ||
| } | ||
| $result[$key] = $converted; | ||
|
|
||
| foreach ($value as $idx => $item) { | ||
| $converted[$idx] = $item instanceof self ? $item->toRawArray(false, true) : $convert($item); | ||
| continue; | ||
| } | ||
| $return[$key] = $converted; | ||
|
|
||
| // default recursive conversion | ||
| $result[$key] = $convert($value); | ||
|
|
||
| continue; | ||
| } | ||
|
|
||
| // default recursive conversion | ||
| $return[$key] = $convert($value); | ||
|
|
||
| continue; | ||
| // non-recursive changed value | ||
| $result[$key] = $convert($value); | ||
| } | ||
| } | ||
|
|
||
| // Convert DateTime objects to string for user-facing calls | ||
| if (! $recursive) { | ||
| $result = array_map(static function ($value) { | ||
| if ($value instanceof DateTimeInterface) { | ||
| return method_exists($value, '__toString') ? (string) $value : $value->format('Y-m-d H:i:s'); | ||
| } | ||
|
Comment on lines
+339
to
+344
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now every top-level |
||
|
|
||
| // non-recursive changed value | ||
| $return[$key] = $value; | ||
| return $value; | ||
| }, $result); | ||
| } | ||
|
|
||
| return $return; | ||
| return $result; | ||
| } | ||
|
|
||
| /** | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,6 +30,8 @@ Deprecations | |
| Bugs Fixed | ||
| ********** | ||
|
|
||
| - **Entity:** Fixed a bug where ``toRawArray()`` returned ``Time`` objects instead of ISO-8601 strings for date fields. | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Even now, we don't return ISO-8601 strings. |
||
|
|
||
| - **Logger:** Fixed a bug where interpolating a log message with array or non-stringable context values could raise PHP warnings or errors. | ||
|
|
||
| See the repo's | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| # total 212 errors | ||
| # total 205 errors | ||
|
|
||
| parameters: | ||
| ignoreErrors: | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| # total 1819 errors | ||
| # total 1812 errors | ||
|
|
||
| includes: | ||
| - argument.type.neon | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now relative values such as "tomorrow" are accepted, which broadens the caster's behavior beyond this fix.