diff --git a/changelog.md b/changelog.md index e652738..5f7de29 100644 --- a/changelog.md +++ b/changelog.md @@ -2,6 +2,20 @@ All notable changes to `Enum` will be documented in this file. -## Version 1.0 +## Version 0.0.1 ### Initial release + +## Version 0.0.2 + +### - Add +- Enum cast in Models + + usage: + Put this in your model + + use CastsEnums; + + protected $enumCasts = [ + 'status' => OrderStatus::class // This is a class that extends \Kwaadpepper\Enum\BaseEnum + ]; diff --git a/src/Traits/CastsEnums.php b/src/Traits/CastsEnums.php new file mode 100644 index 0000000..93bc3e8 --- /dev/null +++ b/src/Traits/CastsEnums.php @@ -0,0 +1,94 @@ +hasEnumCast($key)) { + $value = $this->castToEnum($key, $value); + } + + return $value; + } + + /** + * Set a given attribute on the model. + * + * @param string $key + * @param mixed $value + * @return $this + */ + public function setAttribute($key, $value) + { + if ($value !== null && $this->hasEnumCast($key)) { + /** @var \App\Enums\BaseEnum $enum */ + $enum = $this->enumCasts[$key]; + + if ($value instanceof $enum) { + $this->attributes[$key] = $value->value; + } else { + if ($this->hasCast($key)) { + $value = $this->castAttribute($key, $value); + } + // try cast to int if is int + $value = is_numeric($value) && floatval(intval($value)) === floatval($value) ? (int)$value : $value; + $this->attributes[$key] = $enum::make($value)->value; + } + + return $this; + } + + return parent::setAttribute($key, $value); + } + + /** + * Determine whether an attribute should be cast to a enum. + * + * @param string $key + * @return bool + */ + public function hasEnumCast($key): bool + { + // This can happen if this trait is added to the model + // but no enum casts have been added yet + if ($this->enumCasts === null) { + return false; + } + + return array_key_exists($key, $this->enumCasts); + } + + /** + * Casts the given key to an enum instance + * + * @param string $key + * @param mixed $value + * @return \App\Enums\BaseEnum|null + */ + protected function castToEnum($key, $value): ?BaseEnum + { + /** @var \App\Enums\BaseEnum $enum */ + $enum = $this->enumCasts[$key]; + + if ($value === null || $value instanceof BaseEnum) { + return $value; + } else { + return $enum::make($value); + } + } +}