[Feature Request] Add enum collection cast
florianJacques opened this issue · 1 comments
florianJacques commented
Hello, I propose a cast that could be interesting to add to the library.
<?php
namespace App\Casts;
use Illuminate\Contracts\Database\Eloquent\Castable;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Illuminate\Support\Collection;
class AsEnumCollection implements Castable
{
/**
* @param array $arguments
* @return CastsAttributes
*/
public static function castUsing(array $arguments): CastsAttributes
{
return new class($arguments) implements CastsAttributes
{
protected array $arguments;
public function __construct(array $arguments)
{
$this->arguments = $arguments;
}
public function get($model, $key, $value, $attributes): ?Collection
{
if (! isset($attributes[$key])) {
return null;
}
$data = $attributes[$key];
if (! is_array($data)) {
return null;
}
$enumClass = $this->arguments[0];
return (new Collection($data))->map(function ($value) use ($enumClass) {
return is_subclass_of($enumClass, \BackedEnum::class)
? $enumClass::from($value)
: constant($enumClass.'::'.$value);
});
}
public function set($model, $key, $value, $attributes): array
{
$value = $value !== null
? (new Collection($value))->map(function ($enum) {
return $this->getStorableEnumValue($enum);
})->jsonSerialize()
: null;
return [$key => $value];
}
protected function getStorableEnumValue($enum)
{
if (is_string($enum) || is_int($enum)) {
return $enum;
}
return $enum instanceof \BackedEnum ? $enum->value : $enum->name;
}
};
}
/**
* Specify the Enum for the cast.
*
* @param class-string $class
* @return string
*/
public static function of(string $class): string
{
return static::class.':'.$class;
}
}
Usage:
use App\Enums\ServerStatus;
use Illuminate\Database\Eloquent\Casts\AsEnumCollection;
/**
* Get the attributes that should be cast.
*
* @return array<string, string>
*/
protected function casts(): array
{
return [
'statuses' => AsEnumCollection::of(ServerStatus::class),
];
}
davidvandertuijn commented
Is the cast() method already implemented in this library?
I can only see the $casts variable approach in the documentation: