Livewire 3 not working with Spatie Enums & CastsAttributes out of the box
Since upgrading to Livewire 3, we've been having issues sorting out our Model casts. Firstly, Spatie Enums aren't support, and we're now looking at re-writing them into PHP Backed Enums, but this seems like a lot of work for very little gain.
Managed to come across this synth example, but it isn't working flawlessly for all our Enums. Some lose their values when reloaded into view for example. Has anyone found a solution that works all the time?
<?php
namespace App\Synthesizers;
use Livewire\Mechanisms\HandleComponents\Synthesizers\EnumSynth as BaseEnumSynth;
use Spatie\Enum\Enum;
class EnumSynth extends BaseEnumSynth
{
public static $key = 'spatie-enum';
public static function match($target): bool
{
return $target instanceof Enum;
}
}
My bigger issue is that I don't have a solution for custom casts binded to the model (CastsAttributes).
An example of a cast is below. This cast is simply taking an int monetary value in cents from our database and converting it into a price that has decimal points (i.e. converting 1000 into 10.00). Sometimes we refer to price of item, otherwise amount. The construct handles the naming of the column.
<?php
namespace App\Casts;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Illuminate\Database\Eloquent\Model;
class HumanPrice implements CastsAttributes
{
public function __construct(
protected string $attribute = 'price',
) {
}
/**
* Cast the given value.
*
* @return mixed
*/
public function get(Model $model, string $key, mixed $value, array $attributes)
{
return ($attributes[$this->attribute] ?? null) !== null
? (string) \round($attributes[$this->attribute] / 100, 2)
: '';
}
/**
* Prepare the given value for storage.
*
* @return mixed
*/
public function set(Model $model, string $key, mixed $value, array $attributes)
{
return [
$this->attribute => (empty($value))
? null
: \intval(\floatval($value) * 100),
];
}
}
I was wondering if using Livewire's Wireable would work, but I'm having issues implementing it. I understand I need to add the implements Wireable and add the functions:
// Example from Livewire docs
public function toLivewire()
{
return [
'name' => $this->name,
'age' => $this->age,
];
}
public static function fromLivewire($value)
{
$value = $value['name'];
$age = $value['age'];
return new static($name, $age);
}
But without referencing the model (you cannot change/add to the functions variables), I'm not sure how to update the cast to effectively use the required Wireable functions. Does anyone know how this would work?
Has anyone seen something similar or have a few examples for casts and Livewire 3, that would be great.
Any help appreciated, thanks.
Please or to participate in this conversation.