diff --git a/shared/lib/Json/JsonSerializableCollection.php b/shared/lib/Json/JsonSerializableCollection.php index 4335398..8c75df3 100644 --- a/shared/lib/Json/JsonSerializableCollection.php +++ b/shared/lib/Json/JsonSerializableCollection.php @@ -34,7 +34,7 @@ abstract class JsonSerializableCollection extends CollectionAbstract implements if (in_array($this->typeValue, $this->primitiveTypes)) { if ($this->associative) { foreach ($data as $key => $value) { - $this[$key] = $value; + $this[$this->normalizeKey($key)] = $value; } } else { foreach ($data as $value) { @@ -43,14 +43,24 @@ abstract class JsonSerializableCollection extends CollectionAbstract implements } } - if (!in_array($this->typeValue, $this->primitiveTypes) && class_exists($this->typeValue)) { + if (!in_array($this->typeValue, $this->primitiveTypes) && is_subclass_of($this->typeValue, \BackedEnum::class)) { + if ($this->associative) { + foreach ($data as $key => $value) { + $this[$this->normalizeKey($key)] = ($this->typeValue)::from($value); + } + } else { + foreach ($data as $value) { + $this[] = ($this->typeValue)::from($value); + } + } + } elseif (!in_array($this->typeValue, $this->primitiveTypes) && class_exists($this->typeValue)) { $reflection = new \ReflectionClass($this->typeValue); if ($reflection->implementsInterface(JsonDeserializable::class)) { if ($this->associative) { foreach ($data as $key => $value) { $instance = $reflection->newInstance(); /** @var JsonDeserializable $instance */ - $this[$key] = $instance->jsonDeserialize($value); + $this[$this->normalizeKey($key)] = $instance->jsonDeserialize($value); } } else { foreach ($data as $value) { @@ -65,4 +75,13 @@ abstract class JsonSerializableCollection extends CollectionAbstract implements return $this; } + /** + * JSON round trips turn numeric string keys into integers (and list-shaped + * payloads carry integer keys), which a string-keyed collection would + * otherwise reject on offsetSet. + */ + private function normalizeKey(int|string $key): int|string { + return $this->typeKey === self::TYPE_STRING ? (string)$key : $key; + } + } \ No newline at end of file