digitalcloud/eloquent-custom-actions

Laravel Eloquent 自定义动作,使模拟 eloquent 事件以执行自定义动作更加容易。

v0.2 2019-01-02 09:29 UTC

This package is auto-updated.

Last update: 2024-09-23 19:30:56 UTC


README

该包的灵感来源于 Laravel Eloquent 事件功能性和 Eloquent Scope 代码风格。如果你喜欢事件驱动开发方法,这个包可以极大地清理你的模型代码。

安装

你可以通过 composer 安装此包

composer require digitalcloud/eloquent-custom-actions

使用示例

如果没有这个包,要模拟 eloquent 事件,你将得到以下结果

class User extends Authenticatable
    
    public function verify($mobile)
    {
        $userMobile = new UserMobile([
            'mobile' => $mobile, 'status' => self::STATUS_VERIFIED
        ]);

        if(app()->events->until(
            event(new MobileVerifying($userMobile)) !== false
        )){
            $userMobile = $this->mobiles()->save($userMobile);
            event(new MobileVerified($userMobile));
            return $userMobile;
        }
        
        return false;
    }
}

为了简化你的 User 模型,声明 action{MethodName} 方法并删除所有与事件相关的代码,当调用 $user->verify($mobile) 时,包将自动触发 before{Method}after{Method} 事件。

<?php

class User extends Authenticatable
{
    
    public function actionVerify($mobile) {
        return $userMobile = $this->mobiles()->save([
            'mobile' => $mobile, 'status' => self::STATUS_VERIFIED
        ]);
    }
}

使用 dispatchesEvents

作为 eloquent 事件,你可以使用 $dispatchesEvents 属性来映射已派发的事件

<?php

class User extends Authenticatable
{
    
    public function actionVerify($mobile) { }
    
    protected $dispatchesEvents = [
        'beforeVerify' => MobileVerifying::class,
        'afterVerify' => MobileVerified::class
    ];
}

使用 EventServiceProvider

你可以在 EventServiceProvider 中像通常一样将事件映射到监听器,你可以使用字符串事件名或来自 dispatchesEvents 的映射事件

<?php

namespace App\Providers;

use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;

class EventServiceProvider extends ServiceProvider
{
    // ...
    
    protected $listen = [
        MobileVerifying::class => [ SomeListener::class ],
        MobileVerified::class => [ SomeListener::class ],
        
        // or
        
        'eloquent.beforeVerify: App\User' => [ SomeListener::class ],
        'eloquent.afterVerify: App\User' => [ SomeListener::class ],
    ];
    
    // ...
}

使用 Model Observer

作为 eloquent 可观察对象,你可以使用 $observables 属性来映射可观察事件

<?php

class User extends Authenticatable
{
    
    public function actionVerify($mobile) { }
    
    protected $observables = [
        'beforeVerify', 'afterVerify'
    ];
}

然后你可以在 ModelObserver 类中添加 beforeVerify 和 afterVerify 函数,就像其他 eloquent 函数一样。

<?php

namespace App\Observers;

use App\User;

class UserObserver
{
    // Default eloquent actions
    public function created(User $user){ }

    // Custom eloquent actions
    public function beforeVerify(User $user){ }

    public function afterVerify(User $user){ }
}

阻止事件的传播

如 Laravel 文档所述

有时,你可能希望停止事件传播到其他监听器。你可以通过从监听器的 handle 方法返回 false 来做到这一点。

如果任何 before{Action} 监听器返回 false,则进程将停止,并且实际操作将不会执行。

路线图

我们目前正在做的

  • 支持模型启动方法
  • 支持模型策略
  • 如果一个监听器返回 false,则回滚 before{Action} 的效果