ibrostudio/laravel-piped-tasks

通过 Laravel Pipes 管理任务工作流

1.1.0 2024-09-22 19:39 UTC

This package is auto-updated.

Last update: 2024-09-22 19:40:09 UTC


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)。有关更多信息,请参阅许可证文件