Konekt Enum Eloquent Bindings
, (*1)
This package provides support for auto casting konekt enum fields in Eloquent models., (*2)
Supported Konekt Enum versions are 2.x, 3.x and 4.x with Eloquent (Laravel) 8 - 12, (*3)
Changelog, (*4)
Installation
composer require konekt/enum-eloquent, (*5)
Usage
- Add the
CastsEnums trait to your model
- Define the attributes to be casted via the
protected $enums property on the model
Example
The Enum:, (*6)
namespace App;
use Konekt\Enum\Enum;
class OrderStatus extends Enum
{
const __DEFAULT = self::PENDING;
// const __default = self::PENDING; // usage of default in v2.x
const PENDING = 'pending';
const CANCELLED = 'cancelled';
const COMPLETED = 'completed';
}
The Model:, (*7)
namespace App;
use Illuminate\Database\Eloquent\Model;
use Konekt\Enum\Eloquent\CastsEnums;
class Order extends Model
{
use CastsEnums;
protected $enums = [
'status' => OrderStatus::class
];
}
Client code:, (*8)
$order = Order::create([
'status' => 'pending'
]);
// The status attribute will be an enum object:
echo get_class($order->status);
// output: App\OrderStatus
echo $order->status->value();
// output: 'pending'
echo $order->status->isPending() ? 'yes' : 'no';
// output: yes
echo $order->status->isCancelled() ? 'yes' : 'no';
// output: no
// You can assign an enum object as attribute value:
$order->status = OrderStatus::COMPLETED();
echo $order->status->value();
// output: 'completed'
// It also works with mass assignment:
$order = Order::create([
'status' => OrderStatus::COMPLETED()
]);
echo $order->status->value();
// output 'completed'
// It still accepts scalar values:
$order->status = 'completed';
echo $order->status->isCompleted() ? 'yes' : 'no';
// output: yes
// But it doesn't accept scalar values that aren't in the enum:
$order->status = 'negotiating';
// throws UnexpectedValueException
// Given value (negotiating) is not in enum `App\OrderStatus`
Resolving Enum Class Runtime
It is possible to defer the resolution of an Enum class to runtime., (*9)
It happens using the ClassName@method notation known from Laravel., (*10)
This is useful for libraries, so you can 'late-bind' the actual enum class and let the user to extend it., (*11)
Example
The Model:, (*12)
namespace App;
use Illuminate\Database\Eloquent\Model;
use Konekt\Enum\Eloquent\CastsEnums;
class Order extends Model
{
use CastsEnums;
protected $enums = [
'status' => 'OrderStatusResolver@enumClass'
];
}
The Resolver:, (*13)
namespace App;
class OrderStatusResolver
{
/**
* Returns the enum class to use as order status enum
*
* @return string
*/
public static function enumClass()
{
return config('app.order.status.class', OrderStatus::class);
}
}
This way the enum class becomes configurable without the need to modify the Model code., (*14)
Laravel Collective Forms Package provides the
Form facade known from Laravel v4.x., (*15)
In case you want to use the Forms package with this one, you need to add the
EnumsAreCompatibleWithLaravelForms trait to your model, next to CastsEnums., (*16)
This will fix a problem where the forms package detects the enum label instead of its actual value
as the value of the field., (*17)
It is being done by adding the (undocumented) getFormValue() method to the model, that is being
used by the forms library to obtain form field value., (*18)
Enjoy!, (*19)
For detailed usage of konekt enums refer to the Konekt Enum Documentation., (*20)