telkins / laravel-pending-action
一个(有点主观的)Laravel 包,帮助简化准备和执行动作,使其更加统一和简单。
Requires
- php: ^7.4
- laravel/framework: ^6.0|^7.0|^8.0
Requires (Dev)
- orchestra/testbench: ^4.0|^5.0|^6.0
- phpunit/phpunit: ^9.0|^9.3
- symfony/var-dumper: ^4.0|^5.0
README
本包灵感来源于几位人士。请查看以下链接,了解灵感的来源:
有时,您可能需要在应用程序或代码的不同部分执行任务或动作,而这些地方没有现成的Laravel解决方案。这很可能与您的业务逻辑有关。一个常用的例子是创建发票。这可能是在您的应用程序中需要执行的动作。它可能需要一些参数,并且可能由更小的动作组成。
本包的目标是提供一种(有点主观的)方法来创建、定义和使用动作。您可以创建Action
类,然后当您想要执行该动作时,您可以“准备”该类:$myAction = MyAction::prep();
。您将获得一个待处理动作对象,您可以根据需要定义它,这允许您提供执行动作所需的参数。准备好后,您调用execute()
。
以下是一个示例...借鉴自Freek的视频
CreateSubscriber::prep() ->withEmail('me@mydomain.com') ->forList($emailList) ->withAttributes($attributes) ->skipConfirmation() ->doNotSendWelcomeMail() ->execute();
安装
您可以通过composer安装此包
composer require telkins/laravel-pending-action
使用方法
目前,必须手动创建Action
和PendingAction
类。未来的版本将包括通过php artisan
创建Action
和PendingAction
类的能力。
创建一个动作
创建动作类主要有两种方式,具体取决于您的需求
- 一种完全处理待处理动作准备,但可能需要额外的代码才能与您的IDE良好配合
- 一种与您的IDE良好配合,但需要在动作类之间编写一些重复的代码
创建一个“轻量级”动作
创建动作的方法需要最少的代码。因此,您可以将其称为“轻量级”动作类。这样的类可以完美地工作。但是,由于prep()
方法的签名显示了返回类型为PendingAction
的接口,您的IDE将不知道您得到的是什么对象,并且当与待处理动作对象一起工作时,代码补全将有限。您可能能够向您的IDE提供信息,以便对待处理动作对象进行完整的代码补全,但这需要额外的工作。
尽管如此,这可能对您来说已经足够好了。如果您想创建这样的动作类,只需创建一个类,它扩展了抽象的Action
类,如下所示,并添加一个接受待处理动作对象的execute()
方法
use Telkins\LaravelPendingAction\Action; class CreateSubscriber extends Action { public function execute(CreateSubscriberPendingAction $pendingAction) { // code to perform action, using $pendingAction as needed... } // supporting methods, if needed... }
创建一个“IDE友好型”动作
此方法为每个动作类创建少量额外代码。然而,这些额外代码将很好地与您的IDE配合,如果可用,将允许代码补全。
如果您想创建这样的动作类,只需创建一个如上所示的“轻量级”动作类,然后添加一个prep()
方法,如下所示:
use Telkins\LaravelPendingAction\Action; class CreateSubscriber extends Action { public static function prep(): CreateSubscriberPendingAction { return self::autoPrep(); } public function execute(CreateSubscriberPendingAction $pendingAction) { // code to perform action, using $pendingAction as needed... } // supporting methods, if needed... }
注意:autoPrep()
方法为您处理待处理动作对象的准备。
待处理动作类命名规范
默认情况下,每个Action
类都会查找一个具有相同FQCN并在其后添加PendingAction
的待处理动作类。所以,对于我们的示例CreateSubscriber
类,它将查找CreateSubscriberPendingAction
。
要覆盖此行为,您可以在您的Action
类中指定待处理动作类的名称,如下所示:
use Telkins\LaravelPendingAction\Action; use My\Custom\Namespace\UnconventionalCreateSubscriberPendingAction; class CreateSubscriber extends Action { // override default pending action class protected static $pendingActionClass = UnconventionalCreateSubscriberPendingAction::class; // ... }
创建待处理动作
要创建待处理动作类,只需扩展PendingAction
,如下所示,提供构建待处理动作对象的流畅方法,该对象将被用来执行动作:
use App\EmailList; use Telkins\LaravelPendingAction\PendingAction; class CreateSubscriberPendingAction extends PendingAction { public string $email; public EmailList $list; public array $attributes = []; public bool $skipConfirmation = false; public bool $sendWelcomeMail = true; public function withEmail(string $email): self { $this->email = $email; return $this; } public function forList(EmailList $list): self { $this->list = $list; return $this; } public function withAttributes(array $attributes): self { $this->attributes = $attributes; return $this; } public function skipConfirmation(): self { $this->skipConfirmation = true; return $this; } public function doNotSendWelcomeMail(): self { $this->sendWelcomeMail = false; return $this; } }
"准备"您的动作,执行它
一旦您构建了动作和待处理动作类,您就可以开始使用它们。准备并执行动作有三个主要步骤:
- 在您的
Action
类上调用静态prep()
方法。这将返回待处理动作对象。 - 使用待处理动作对象,提供动作所需的参数。
- 最后,在待处理动作对象上调用
execute()
方法。
以下是一次性准备和执行动作的示例
UpdateLeaderboard::prep() ->leaderboard($leaderboard) ->forPlayer($player) ->withScore($score) ->execute();
以下是如何使用待处理动作对象提供不同参数以在不同场景下执行动作的示例
$pendingUpdateLeaderboard = UpdateLeaderboard::prep() ->leaderboard($leaderboard); $pendingUpdateLeaderboard->forPlayer($greg) ->withScore($gregsScore) ->execute(); $pendingUpdateLeaderboard->forPlayer($peter) ->withScore($petersScore) ->execute();
添加待处理动作构造函数以改进"准备"过程
有时您可能不想在代码中添加一些重复或不明显的调用。例如,如果您有一个旨在更新排行榜的动作类,那么您可能不希望必须专门调用一个leaderboard()
方法。通过在您的待处理动作类上创建构造函数,您可以通过动作的prep()
方法传递排行榜。
以下是如何利用此功能构建您的待处理动作类的示例
class UpdateLeaderboardPendingAction extends PendingAction { public Leaderboard $leaderboard; public function __construct(Leaderboard $leaderboard) { $this->leaderboard = $leaderboard; } // ... }
然后您可以这样使用它
UpdateLeaderboard::prep($leaderboard) ->forPlayer($player) ->withScore($score) ->execute();
注意:此功能对IDE不友好,开发者将负责通过prep()
正确地以正确的顺序传递正确的类型参数给构造函数。
测试
composer test
变更日志
请参阅变更日志以获取有关最近更改的更多信息。
贡献
请参阅贡献指南以获取详细信息。
安全
如果您发现任何安全相关的问题,请使用问题跟踪器。
致谢
许可证
MIT许可证(MIT)。有关更多信息,请参阅许可证文件。