moirei/laravel-state

轻松管理模型状态。

0.1.0 2022-11-16 10:34 UTC

This package is auto-updated.

Last update: 2024-09-06 06:57:20 UTC


README

与Laravel中的许多事物一样,管理模型状态应该是一件简单的事情。

在PHP枚举出现之前,已经有一些解决方案,然而,这个包试图实现管理Laravel中严格状态的感觉。

文档

所有文档可在文档网站找到。

特性

  • 严格定义的状态和转换
  • PHP枚举支持 💪
  • 将状态转换为多个属性

基本示例

use MOIREI\State\State;

/**
 * @property State $status
 */
class Order extends Model{
    protected function status(): Attribute{
        return State::make([
            State::on('created', 'paid'),
            State::on('paid', ['created', 'completed'])
            State::on('completed', 'archived')
        ]);
    }
}

现在转换状态

dump($order->status->value); // `created`

$order->status->transitionTo('paid');

dump($order->status->value); // `paid`

使用PHP枚举

use MOIREI\State\Traits\CastsEnumAttributesState;
use MOIREI\State\Traits\HasEnumState;
use MOIREI\State\State;

...

enum OrderStatus: string{
    use HasEnumState;

    case PENDING = 'pending';
    case PAID = 'paid';
    case CLOSED = 'closed';

    public static function states(){
        return [
            State::on(self::PENDING, [self::PAID, self::CLOSED]),
            State::on(self::PAID, self::CLOSED),
        ];
    }
}

...

/**
 * @property OrderStatus $status
 */
class Order extends Model{
    use CastsEnumAttributesState; // only if using casts

    protected $casts = [
        'status' => OrderStatus::class
    ];

    // or

    protected function status(): Attribute{
        return OrderStatus::useAttribute();
    }
}

...

// accepts enum value but fails if invalid
if($order->status->is('pending')){
    $order->status->transitionTo(OrderStatus::PAID);
}

// should throw
if($order->status->is('closed')){
    $order->status->transitionTo(...);
}

使用状态对象

use MOIREI\State\State;

...

final class OrderStatus extends State{
    const PENDING = 'pending';
    const PAID = 'paid';
    const CLOSED = 'closed';

    public static function states(){
        return [
            State::on(static::PENDING, [static::PAID, static::CLOSED]),
            State::on(static::PAID, static::CLOSED),
        ];
    }
}

...

/**
 * @property OrderStatus $status
 */
class Order extends Model{

    protected $casts = [
        'status' => OrderStatus::class
    ];

    // or

    protected function status(): Attribute{
        return OrderStatus::useAttribute();
    }
}

...

// same as with enum above
if($order->status->is('pending')){
    $order->status->transitionTo('paid');
}

安装

composer require moirei/laravel-state

测试

composer test