louishrg / state-flow
Laravel 状态机的简单实现
1.4
2023-11-08 22:52 UTC
Requires
- php: ^7.2|^8.1
- laravel/framework: ^7.2|^8.0|^9.0|^10.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^2.16
- orchestra/testbench: ~3.8.0|^4.0|^5.0|^6.0
- phpunit/phpunit: ^8.0|^9.0
README
为您的 Laravel 应用提供简单状态机/弹性状态!
安装
您可以通过 composer 安装此包
composer require louishrg/state-flow
使用 artisan 创建您的状态类
为每个可用的状态创建文件是重复的,因此此包提供了一个 artisan 命令来加快处理过程
php artisan states:new
简单状态,也称为 Stack
Stack 是一个不需要注册转换的简单状态机。这是为您的模型添加硬编码类型或类别的非常方便的方式。
如何使用
您至少需要一个变量:key,这是数据库列的实际值。
如果您想使用其他变量作为键,您可以在创建状态 Stack 时提供变量的名称(见下文)
- 第一个参数是您所有可用的状态数组。
- 第二个参数是创建模型时的默认值(可选)。
- 第三个参数用于覆盖默认键值(可选)。
new Stack(self::$status, Pending::class, 'key'),
在您选择的目录中声明您的状态类,例如
namespace App\Models\States\User; use Louishrg\StateFlow\StateAbstract; class Active extends StateAbstract { public $key = 'active'; public $label = 'Active'; public $color = 'green'; // and everything you want ! // public function computedField() { return $this->$label.$this->color; } }
现在,在您的模型中添加所有需要的声明
<?php ... // Import all your states use App\Models\States\Active; use App\Models\States\Banned; use App\Models\States\Inactive; // Import the classes use Louishrg\StateFlow\Traits\WithState; use Louishrg\StateFlow\Casts\StateCast; use Louishrg\StateFlow\Stack; class User { // Add WithState trait use WithState, ...; ... // You can register all available states for a namespace in a var for example protected static $status = [ Active::class, Banned::class, Inactive::class, ]; // register your states as a Stack for the namespace "status" protected static function registerStates(){ return [ 'status' => new Stack(self::$status), ]; } ... // Add the cast for your column and that's it ! protected $casts = [ 'status' => StateCast::class, ]; }
现在您可以通过以下方式获取您的状态
$user->status; // It'll give you the state object with all your defined constants in it.
如果您想更新/创建具有状态的对象
$user = new User; // Simply pass the state class and that's it. $user->status = Pending::class;
Laravel Nova
如果您想在 nova 中使用此包,应按以下方式使用
使用选择框的示例
Select::make('Statut', 'status') ->options(GearRequest::getState('status')->pluck('label', 'key')->toArray()) ->displayUsing(fn($item) => $item->label) ->resolveUsing(fn($item) => $item->key) // Use the magic setter in the fillUsing method ->fillUsing(fn($request, $model) => ($model->_status = $request->status)),
有用的方法
如果您想比较状态的一个当前值与另一个,可以使用
$user->status->equal(Banned::class);
此外,您可以直接获取当前状态的类
$user->status->is();
如果您想检索在命名空间中注册的所有状态作为一个集合
User::getState('status')
复杂状态,也称为 Flow
如果您想在您的应用程序中使用真实的状态机模式,您可以添加注册如下
// Import the Flow class use Louishrg\StateFlow\Flow; ... protected static function registerStates(){ return [ // use a custom method in your model for better readability 'status' => self::myFlow(), ]; } // You need to use the Flow class protected static function myFlow(){ // We'll use the data from above return (new Flow(self::$status)) // Add a transition, here your state can go from Pending to either Accepted or Refused. ->add(Pending::class, [ Accepted::class, Refused::class ]) ->add(Refused::class, [ Pending::class ]) ->add(Accepted::class, [ Pending::class, Canceled::class, CanceledByAdmin::class ]) ->default(Pending::class); // You can specify a default class, when creating you don't need to provide value. }
Flow 的方法
当使用 flows 时,您可以检查是否可以转换到另一个状态如下
$user->status->canBe(Banned::class);
或者您可以获取当前状态的所有可能转换
$user->status->allowedTo();
状态的方法
当您从数据库检索行时,您需要实例化状态来获取键
$users = User::where('status', (new Active)->key)->get();
为了简化语法,每个状态值都扩展了提供魔法方法的 StateAbstract
$users = User::where('status', Active::key())->get();
魔法方法可以获取您的状态中定义的每个属性
即将推出的功能
- 在状态类中使用 getter & setters 的可能性
- 测试
测试
composer test
变更日志
有关最近更改的更多信息,请参阅变更日志
贡献
有关详细信息,请参阅贡献指南
安全性
如果您发现任何安全相关的问题,请通过电子邮件 dev@narah.io 而不是使用问题跟踪器。
鸣谢
许可证
MIT 许可证 (MIT)。请参阅 许可证文件 了解更多信息。
laravel 包模板
此包使用 Laravel 包模板 生成。