From 7eed69725d5d321af82b9cd5cc9053ab91d9b98b Mon Sep 17 00:00:00 2001 From: kj Date: Fri, 19 Jun 2026 14:46:30 -0300 Subject: [PATCH] refactor(model): extract type casting logic into helper methods --- src/Libs/Model.php | 95 +++++++++++++++++++++++++++++----------------- 1 file changed, 60 insertions(+), 35 deletions(-) diff --git a/src/Libs/Model.php b/src/Libs/Model.php index 0fdee88..5fda117 100644 --- a/src/Libs/Model.php +++ b/src/Libs/Model.php @@ -289,29 +289,20 @@ class Model */ protected static function getInstance(array $elem = []): static { - $class = get_called_class(); - $instance = new $class(); - $reflection = new ReflectionClass($instance); - $properties = $reflection->getProperties(); - $propertyNames = array_map(function ($property) { - return static::camelCaseToSnakeCase($property->name); - }, $properties); + $class = get_called_class(); + $instance = new $class(); + $reflection = new ReflectionClass($instance); + $properties = $reflection->getProperties(); + + $map = []; + foreach ($properties as $prop) { + $map[static::camelCaseToSnakeCase($prop->name)] = $prop; + } foreach ($elem as $key => $value) { - $index = array_search($key, $propertyNames); - if (is_numeric($index)) { - $type = $properties[$index]->getType(); - if (enum_exists($type->getName())) { - if (method_exists($type->getName(), 'tryFrom')) { - $instance->{$properties[$index]->name} = $type->getName()::tryfrom($value); - } elseif ( - in_array($value, array_column($type->getName()::cases(), 'name')) - ) { - $instance->{$properties[$index]->name} = $type->getName()::{$value}; - } - } else { - $instance->{$properties[$index]->name} = $value; - } + if (isset($map[$key])) { + $property = $map[$key]; + $instance->{$property->name} = static::castValue($property, $value); } else { $instance->{static::snakeCaseToCamelCase($key)} = $value; } @@ -322,6 +313,32 @@ class Model return $instance; } + /** + * Handles type casting for properties, especially for Enums. + * + * @param ReflectionProperty $property + * @param mixed $value + * + * @return mixed + */ + protected static function castValue(ReflectionProperty $property, mixed $value): mixed + { + $type = $property->getType(); + if (!$type || !enum_exists($typeName = $type->getName())) { + return $value; + } + + if (method_exists($typeName, 'tryFrom')) { + return $typeName::tryFrom($value); + } + + if (in_array($value, array_column($typeName::cases(), 'name'))) { + return $typeName::{$value}; + } + + return $value; + } + /** * Returns the attributes to be saved for the current class. * Attributes will be those that are public and not excluded in static::$ignoreSave, @@ -338,29 +355,37 @@ class Model foreach ($properties as $property) { if (!in_array($property->name, static::$dbIgnoreSave)) { - $result[$this->camelCaseToSnakeCase($property->name)] = isset($this->{$property->name}) - ? $this->{$property->name} : null; + $name = $this->camelCaseToSnakeCase($property->name); + $result[$name] = $this->castToDbValue($this->{$property->name}); } } foreach (static::$dbForceSave as $value) { - $result[$value] = isset($this->$value) - ? $this->$value : null; - } - - foreach ($result as $i => $property) { - if (gettype($property) == 'boolean') { - $result[$i] = $property ? '1' : '0'; - } - - if ($property instanceof \UnitEnum) { - $result[$i] = $property->value ?? $property->name; - } + $result[$value] = $this->castToDbValue($this->$value); } return $result; } + /** + * Converts a PHP value to a database-compatible value. + * + * @param mixed $value + * @return mixed + */ + protected function castToDbValue(mixed $value): mixed + { + if (is_bool($value)) { + return $value ? '1' : '0'; + } + + if ($value instanceof \UnitEnum) { + return $value->value ?? $value->name; + } + + return $value; + } + /** * Returns the name of the current class, even if it's an extended class. *