ibrostudio / laravel-piped-tasks
通过 Laravel Pipes 管理任务工作流
1.1.0
2024-09-22 19:39 UTC
Requires
- php: ^8.2
- illuminate/contracts: ^11.0
- michael-rubel/laravel-enhanced-pipeline: ^4.0
- spatie/laravel-package-tools: ^1.14.0
- spatie/laravel-queueable-action: ^2.14
Requires (Dev)
- larastan/larastan: ^2.0.1
- laravel/pint: ^1.0
- nunomaduro/collision: ^8.0
- orchestra/testbench: ^9.0
- pestphp/pest: ^2.20
- pestphp/pest-plugin-arch: ^2.5
- pestphp/pest-plugin-laravel: ^2.0
- phpstan/extension-installer: ^1.1
- phpstan/phpstan-deprecation-rules: ^1.0
- phpstan/phpstan-phpunit: ^1.0
README
通过 Laravel Pipes 管理任务工作流。
概念
过程 定义了通过管道执行的任务顺序。
每个过程都与一个 有效负载 相关联。有效负载是一个可变对象,传递给每个任务以检索、添加或更新数据。
安装
通过 composer 安装此包
composer require ibrostudio/laravel-piped-tasks
用法
1. 创建过程
首先,您需要生成一个过程
php artisan make:piped-process CreateOrderProcess
将过程命名为此格式:<操作><域>Process
2. 定义有效负载
您可以在 App\Processes\Payloads
中找到与您的过程相关联的有效负载,以及在 App\Processes\Payloads\Contracts
中的其接口。根据您的流程添加属性和方法
<?php namespace App\Processes\Payloads\Contracts; use App\Models\Cart; use App\Models\Invoice; use App\Models\Order; use App\Models\Payment; interface TenantPayload { public function getCart(): Cart; public function setOrder(Order $order): void; public function getOrder(): Order|null; public function setPayment(Payment $payment): void; public function getPayment(): Payment|null; public function setInvoice(Invoice $invoice): void; public function getInvoice(): Invoice|null } --------------------------- namespace App\Processes\Payloads; use App\Models\Cart; use App\Models\Invoice; use App\Models\Order; use App\Models\Payment; final class CreateOrderPayload implements Payload, OrderPayload { public function __construct( protected Cart $cart, protected ?Order $order = null, protected ?Payment $payment = null, protected ?Invoice $invoice = null, ) {} public function getCart(): Cart { return $this->cart; } public function setOrder(Order $order): void { $this->order = $order; } public function getOrder(): Order|null { return $this->order; } public function setPayment(Payment $payment): void { $this->payment = $payment; } public function getPayment(): Payment|null { return $this->payment; } public function setInvoice(Invoice $invoice): void { $this->invoice = $invoice; } public function getInvoice(): Invoice|null { return $this->invoice; } }
为了可重用性,方法可以通过将它们放置在 traits 中来由有效负载共享
<?php namespace App\Processes\Payloads\Concerns; use App\Models\Cart; use App\Models\Invoice; use App\Models\Order; use App\Models\Payment; trait OrderPayloadMethods { public function getCart(): Cart { return $this->cart; } public function setOrder(Order $order): void { $this->order = $order; } public function getOrder(): Order|null { return $this->order; } (...) --------------------------- namespace App\Processes\Payloads; use App\Processes\Payloads\Concerns\OrderPayloadMethods; use App\Models\Cart; use App\Models\Invoice; use App\Models\Order; use App\Models\Payment; final class CreateOrderPayload implements Payload, OrderPayload { use OrderPayloadMethods; public function __construct( protected Cart $cart, protected ?Order $order = null, protected ?Payment $payment = null, protected ?Invoice $invoice = null, ) {} } --------------------------- namespace App\Processes\Payloads; use App\Processes\Payloads\Concerns\OrderPayloadMethods; use App\Models\Cart; use App\Models\Invoice; use App\Models\Order; use App\Models\Payment; final class RebillOrderPayload implements Payload, OrderPayload { use OrderPayloadMethods; public function __construct( protected Order $order, protected ?Payment $payment = null, protected ?Invoice $invoice = null, ) {} }
3. 创建任务
使用此命令生成您的任务
php artisan make:piped-process MakePaymentTask
将过程命名为此格式:<操作><域>Task
为了方便和可重用性,任务使用操作(来自 Spatie 的 Laravel Queuable Action)
<?php namespace App\Processes\Tasks; use App\Actions\MakePaymentAction; use App\Processes\Payloads\Contracts\OrderPayload; use IBroStudio\User\Actions\CreateUserAction; use IBroStudio\User\Processes\Payloads\Contracts\UserPayload; use Closure; final readonly class MakePaymentTask { public function __construct( private MakePaymentAction $action, ) {} public function __invoke(OrderPayload $payload, Closure $next): mixed { $payload->setPayment( $this->action->execute($payload->getOrder()) ); return $next($payload); } } --------------------------- namespace App\Actions; use App\Models\Order; use App\Models\Payment; use Spatie\QueueableAction\QueueableAction; final class MakePaymentAction { use QueueableAction; public function execute(Order $order): Payment { $payment = 'Process payment and return model'; return $payment; } }
4. 将任务添加到过程中
在底层,过程使用 Michael Rubel 的 Laravel Enhanced Pipeline,并支持它所有的特性,如数据库事务或事件
<?php namespace App\Processes; use App\Processes\Payloads\CreateOrderPayload; use App\Processes\Tasks\CreateOrderTask; use App\Processes\Tasks\GenerateInvoiceTask; use App\Processes\Tasks\MakePaymentTask; use App\Processes\Tasks\NewOrderNotificationTask; use App\Processes\Tasks\SendInvoiceToCustomerTask; use Closure; use IBroStudio\PipedTasks\Payload; use IBroStudio\PipedTasks\Process; class CreateOrderProcess extends Process { protected array $tasks = [ CreateOrderTask::class, MakePaymentTask::class, GenerateInvoiceTask::class, SendInvoiceToCustomerTask::class, NewOrderNotificationTask::class, ]; protected bool $withTransaction = true; public function onSuccess(): static { $this->onSuccess = function (CreateOrderPayload|Payload $payload) { // return $payload; }; return $this; } public function onFailure(): static { $this->onFailure = function (CreateOrderPayload|Payload $payload, $exception) { // return $payload; }; return $this; } public function __invoke(Payload $payload, Closure $next): mixed { $this->run($payload); return $next($payload); } }
5. 执行过程
<?php use App\Processes\CreateOrderProcess; use App\Processes\Payloads\CreateOrderPayload; $process = (new CreateOrderProcess) ->run( new CreateOrderPayload( cart: 'your cart model' ) ); $process->getOrder();
测试
composer test
许可证
MIT 许可证(MIT)。有关更多信息,请参阅许可证文件。