AsEnumCollection.php
TLDR
This file contains a class AsEnumCollection
that implements the Castable
interface in the Illuminate\Database\Eloquent\Casts
namespace. It is used to cast attributes to a collection of enums and vice versa.
Methods
castUsing
This method is a static function that returns an anonymous class that implements the CastsAttributes
interface. The anonymous class's constructor receives an array of arguments and assigns it to its $arguments
property. This method is responsible for casting attributes from the database to a collection of enums. It decodes the attribute value from JSON format and maps each value to an enum instance, based on the enum class specified in the arguments.
set
This method is used to set the value of an attribute in the database. It encodes the collection of enum values into JSON format, each value is obtained by calling the getStorableEnumValue
method on the enum. It returns an array with the attribute key and its value.
serialize
This method is used to serialize the attribute value. It maps each enum value in the collection to its storable representation by calling the getStorableEnumValue
method. It returns an array of the transformed enum values.
getStorableEnumValue
This method is a helper method used to determine the storable representation of an enum value. If the value is a string or an integer, it returns the value itself. If the value is an instance of BackedEnum
, it returns the value
property. Otherwise, it returns the name
property of the enum.
Classes
None
<?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 \Illuminate\Contracts\Database\Eloquent\CastsAttributes<\Illuminate\Support\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]);
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
? Json::encode((new Collection($value))->map(function ($enum) {
return $this->getStorableEnumValue($enum);
})->jsonSerialize())
: 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;
}
};
}
/**
* Specify the Enum for the cast.
*
* @param class-string $class
* @return string
*/
public static function of($class)
{
return static::class.':'.$class;
}
}