HighSpeaker/vendor/illuminate/database/Eloquent/Casts/AsEnumCollection.php

81 lines
2.5 KiB
PHP
Raw Normal View History

2024-02-05 00:00:23 +08:00
<?php
namespace Illuminate\Database\Eloquent\Casts;
use BackedEnum;
use Illuminate\Contracts\Database\Eloquent\Castable;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Illuminate\Support\Collection;
class AsEnumCollection implements Castable
{
/**
* Get the caster class to use when casting from / to this cast target.
*
* @template TEnum of \UnitEnum|\BackedEnum
*
* @param array{class-string<TEnum>} $arguments
* @return CastsAttributes<Collection<array-key, TEnum>, iterable<TEnum>>
*/
public static function castUsing(array $arguments)
{
return new class($arguments) implements CastsAttributes
{
protected $arguments;
public function __construct(array $arguments)
{
$this->arguments = $arguments;
}
public function get($model, $key, $value, $attributes)
{
if (! isset($attributes[$key]) || is_null($attributes[$key])) {
return;
}
$data = json_decode($attributes[$key], true);
if (! is_array($data)) {
return;
}
$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)
{
$value = $value !== null
? (new Collection($value))->map(function ($enum) {
return $this->getStorableEnumValue($enum);
})->toJson()
: null;
return [$key => $value];
}
public function serialize($model, string $key, $value, array $attributes)
{
return (new Collection($value))->map(function ($enum) {
return $this->getStorableEnumValue($enum);
})->toArray();
}
protected function getStorableEnumValue($enum)
{
if (is_string($enum) || is_int($enum)) {
return $enum;
}
return $enum instanceof BackedEnum ? $enum->value : $enum->name;
}
};
}
}