### Install Laravel Flow Source: https://github.com/sergiumhi/laravel-flow/blob/main/README.md Install the package using Composer. After installation, run the migrations to set up the necessary database tables for the flow engine. ```bash composer require sergiumhi/laravel-flow php artisan migrate ``` -------------------------------- ### Start a Defined Flow Source: https://github.com/sergiumhi/laravel-flow/blob/main/README.md After defining a flow class, you can start an instance of it by calling the static start() method with the desired initial payload. ```php GreetingFlow::start(['name' => 'Ada']); ``` -------------------------------- ### Start a Flow with a JSON Payload Source: https://github.com/sergiumhi/laravel-flow/blob/main/README.md Use the `flow:run` artisan command to start a flow by its name and provide a JSON payload for initial data. Ensure your queue driver is set up to process jobs. ```bash php artisan flow:run order --payload='{"order_id":1,"requires_review":true}' ``` -------------------------------- ### Start and Interact with a Flow Source: https://github.com/sergiumhi/laravel-flow/blob/main/README.md Initiate a flow with an initial payload and retrieve its public ID and status. You can also find a flow later using its public ID. ```php use App\Flows\GreetingFlow; use Sergiumhi\LaravelFlow\Flow; // Start a flow with an input payload. $flow = GreetingFlow::start(['name' => 'Ada']); $flow->publicId(); // "flow_01J..." $flow->status(); // FlowStatus enum // Look one up later by its public id. $flow = Flow::find('flow_01J...'); ``` -------------------------------- ### Orchestrator Lifecycle: Start Flow Source: https://github.com/sergiumhi/laravel-flow/blob/main/README.md The orchestrator lifecycle begins with `OrderFlow::start()`, which creates a flow row, seeds preview rows for the DAG, and dispatches the `FlowOrchestratorJob`. ```php 1. OrderFlow::start(['order_id' => 1]) → creates a flows row (status: pending) → statically analyses run() to seed every top-level yield (both sides of conditionals) as preview rows — for full DAG visibility up front → dispatches FlowOrchestratorJob ``` -------------------------------- ### Manual Flow Control Methods Source: https://github.com/sergiumhi/laravel-flow/blob/main/README.md Provides examples of various methods to manually control a running Laravel Flow instance, including retrying tasks, skipping tasks, and cancelling or reverting the flow. ```php $flow = Flow::find($publicId); // Re-dispatch the failed task from scratch. $flow->retryCurrentTask(); // Skip the failed task and advance. $flow->skipCurrentTask(); // Re-run only the failed children of a failed subtask parent (keep the rest). $flow->retryFailedSubtasks(); // Reset a task and everything after it, then re-run from there. $flow->retryFromTask($taskPublicId); // Halt without reverting: remaining tasks → cancelled, flow → cancelled. $flow->cancel(); // Halt and run revert tasks in reverse: flow → reverted. $flow->cancelAndRevert(); // Resume a flow that is waiting on a signal. $flow->signal('manual_approval', ['approved_by' => 7]); ``` -------------------------------- ### Statically Analyzing Flow DAG Source: https://github.com/sergiumhi/laravel-flow/blob/main/README.md The framework uses `nikic/php-parser` to statically analyze the `run()` method at `start()`. This process identifies all yields, including both sides of conditionals, to pre-seed the flow's DAG for visibility. ```php At `start()`, the framework statically analyses `run()` (via `nikic/php-parser`) — parsing every `yield SomeTask::init(...)` and `yield Signal::waitFor(...)` in source order, including **both sides of every conditional branch**. Each becomes a *seed row* that the orchestrator *promotes* to a real execution row as the generator actually reaches it. Branches never taken are marked `abandoned`. This gives the full shape of the flow up front, before anything runs. ``` -------------------------------- ### Task API: Initializing and configuring tasks Source: https://github.com/sergiumhi/laravel-flow/blob/main/README.md Tasks are initialized using init() and can be configured with payloads, revert tasks, and failure behaviors. ```php use Sergiumhi\LaravelFlow\OnFailure; // No payload yield ProcessPaymentTask::init(); // With a payload — handle() reads it via $this->payload yield ProcessPaymentTask::init(['amount' => 100]); // Register a compensating task for revert yield ProcessPaymentTask::init($payload)->revert(RefundPaymentTask::class); // Declare failure behaviour (default is OnFailure::PAUSE) yield SyncAnalyticsTask::init($payload)->onFailure(OnFailure::SKIP); ``` -------------------------------- ### Define a Greeting Flow Source: https://github.com/sergiumhi/laravel-flow/blob/main/README.md Extend the base Flow class and implement the run() method as a generator. Tasks are yielded within the run() method, and their outputs can be chained to subsequent tasks. ```php namespace App\Flows; use App\Tasks\BuildGreetingTask; use App\Tasks\RecordGreetingTask; use App\Tasks\ShoutGreetingTask; use Generator; use Sergiumhi\LaravelFlow\Flow; class GreetingFlow extends Flow { public function run(array $payload): Generator { // run() receives the array passed to start(). Pass it (or any subset) // explicitly to each task via init() — tasks do not receive the flow // payload implicitly. $payload is also yours to branch on directly. $built = yield BuildGreetingTask::init($payload); // Later tasks are fed from the previous result (output chaining). $shouted = yield ShoutGreetingTask::init(['text' => $built['greeting']]); yield RecordGreetingTask::init(['message' => $shouted['shout']]); } } ``` -------------------------------- ### Run Tests Source: https://github.com/sergiumhi/laravel-flow/blob/main/README.md Execute the test suite for the laravel-flow package using Composer. This command runs the tests on an in-memory SQLite database with the sync queue. ```bash composer test ``` -------------------------------- ### Configure Extended Flow Model Source: https://github.com/sergiumhi/laravel-flow/blob/main/README.md Update the `flow_model` key in your `config/flow.php` file to point to your custom Flow model. ```php 'flow_model' => \App\Models\Flow::class, ``` -------------------------------- ### Publish Configuration Source: https://github.com/sergiumhi/laravel-flow/blob/main/README.md Optionally, publish the configuration file for Laravel Flow to customize its settings. This step is not required for basic functionality. ```bash php artisan vendor:publish --tag=flow-config ``` -------------------------------- ### Define a Task with a handle method Source: https://github.com/sergiumhi/laravel-flow/blob/main/README.md Tasks are the core units of work. The logic resides in the handle() method, which reads inputs from $this->payload and returns an array. ```php namespace App\Tasks; use Sergiumhi\LaravelFlow\Task; class ProcessPaymentTask extends Task { public function handle(): array { // ... do the work, reading inputs from $this->payload ... return ['charge_id' => 'ch_1', 'requiresManualReview' => false]; } } ``` -------------------------------- ### Task Retries Configuration Source: https://github.com/sergiumhi/laravel-flow/blob/main/README.md Override the tries() method to specify the number of times a task should be retried before being considered failed. The framework manages retries automatically. ```php class ChargeCardTask extends Task { public function tries(): int { return 3; } public function handle(): array { /* ... */ } } ``` -------------------------------- ### Passing data between tasks via output chaining Source: https://github.com/sergiumhi/laravel-flow/blob/main/README.md The return value of a task's handle() method becomes the result of its yield expression, allowing it to be passed as input to the next task. ```php $a = yield BuildGreetingTask::init($payload); // returns ['greeting' => '...'] yield ShoutGreetingTask::init(['text' => $a['greeting']]); ``` -------------------------------- ### Sequential Subtasks Execution Source: https://github.com/sergiumhi/laravel-flow/blob/main/README.md Tasks can be executed sequentially by returning a SubTaskCollection with tasks ordered appropriately. The parent task aggregates the outputs in order. ```php return SubTaskCollection::sequential([ BuildSectionTask::init(['section' => 'intro']), BuildSectionTask::init(['section' => 'body']), ]); ``` -------------------------------- ### Inspect Flow Status Source: https://github.com/sergiumhi/laravel-flow/blob/main/README.md Use the `flow:status` artisan command to inspect the DAG, statuses, and timing of a specific flow run. ```bash php artisan flow:status flow_01J... ``` -------------------------------- ### Extend Flow Model Source: https://github.com/sergiumhi/laravel-flow/blob/main/README.md You can extend the default `FlowModel` by creating your own model class and configuring it in `config/flow.php`. ```php use Sergiumhi\LaravelFlow\Models\FlowModel; class Flow extends FlowModel { // your relationships, scopes, casts... } ``` -------------------------------- ### Resume a Flow Waiting on a Signal Source: https://github.com/sergiumhi/laravel-flow/blob/main/README.md Use the `flow:signal` artisan command to resume a flow that is currently waiting for an external signal. You can optionally provide a JSON payload with signal data. ```bash php artisan flow:signal flow_01J... manual_approval --payload='{"approved_by":7}' ``` -------------------------------- ### Revert Task Payload Access Source: https://github.com/sergiumhi/laravel-flow/blob/main/README.md Demonstrates how a revert task can access the output of the original task. Associative outputs are merged into the flow payload, while raw output is available under the 'output' key. ```php class RefundPaymentTask extends Task { public function handle(): array { return ['refunded' => $this->payload['charge_id']]; // directly accessible } } ``` -------------------------------- ### Setting Task Failure Behavior Source: https://github.com/sergiumhi/laravel-flow/blob/main/README.md Define how a task should behave when it fails after exhausting retries using the onFailure() method. The default behavior is to pause the flow. ```php yield ProcessPaymentTask::init($payload)->onFailure(OnFailure::PAUSE); // default yield SyncAnalyticsTask::init($payload)->onFailure(OnFailure::SKIP); // non-critical yield ChargeCardTask::init($payload)->onFailure(OnFailure::REVERT); // roll everything back ``` -------------------------------- ### Aggregated output from Subtasks Source: https://github.com/sergiumhi/laravel-flow/blob/main/README.md The aggregated output from subtasks is available on the parent task's yield. This aggregated output can then be passed to subsequent tasks. ```php $chunks = yield ProcessCsvTask::init($payload); // [['rows_processed' => 3], ...] yield GenerateReportTask::init(['chunks' => $chunks]); ``` -------------------------------- ### Parallel Subtasks Execution Source: https://github.com/sergiumhi/laravel-flow/blob/main/README.md A task can spawn multiple child tasks to run in parallel using SubTaskCollection::parallel(). The parent task aggregates the outputs of all subtasks. ```php use Sergiumhi\LaravelFlow\SubTaskCollection; use Sergiumhi\LaravelFlow\Task; class ProcessCsvTask extends Task { public function handle(): SubTaskCollection { $chunks = array_chunk($this->payload['rows'], $this->payload['chunk_size']); return SubTaskCollection::parallel( array_map(fn ($chunk) => ProcessChunkTask::init(['chunk' => $chunk]), $chunks), ); } } ``` -------------------------------- ### Pausing flow execution with Signals Source: https://github.com/sergiumhi/laravel-flow/blob/main/README.md Use Signal::waitFor() to pause a flow until an external signal is received. The flow status changes to 'waiting'. ```php use Sergiumhi\LaravelFlow\Signal; // Inside run() — pause until 'manual_approval' arrives. $approval = yield Signal::waitFor('manual_approval'); // $approval is the payload that was sent, e.g. ['approved_by' => 7] ``` -------------------------------- ### Prune Old Flow Runs Source: https://github.com/sergiumhi/laravel-flow/blob/main/README.md Use the `flow:prune` artisan command to delete finished flow runs older than a specified number of days. This helps manage database storage. ```bash php artisan flow:prune --days=30 ``` -------------------------------- ### Sending a signal to a waiting flow Source: https://github.com/sergiumhi/laravel-flow/blob/main/README.md External callers can send signals to waiting flows using Flow::find($publicId)->signal(). ```php Flow::find($publicId)->signal('manual_approval', ['approved_by' => $user->id]); ``` -------------------------------- ### Orchestrator Lifecycle: Task Job Source: https://github.com/sergiumhi/laravel-flow/blob/main/README.md The `FlowTaskJob` executes a task's `handle()` method. Task completion leads to advancing the flow, while returning `SubTaskCollection` dispatches child tasks. Throwing an exception triggers retries or failure handling. ```php 3. FlowTaskJob (run a task) → calls handle() → returns array → task completed, dispatch FlowOrchestratorJob → returns SubTaskCollection → persist children, dispatch them → throws → retry if attempts remain, else route by OnFailure ``` -------------------------------- ### Default Flow Configuration Source: https://github.com/sergiumhi/laravel-flow/blob/main/README.md This is the default configuration file for the Laravel Flow package. It allows customization of models, flow folders, and pruning behavior. ```php return [ // Swap these for your own subclasses to extend the engine's models. 'flow_model' => \Sergiumhi\LaravelFlow\Models\FlowModel::class, 'flow_tasks_model' => \Sergiumhi\LaravelFlow\Models\FlowTask::class, // The namespace segment under app/ that holds your flow classes (App\Flows). // Used by flow:run to resolve a flow from a short name. 'flows_folder' => 'Flows', 'prune' => [ 'command' => \Sergiumhi\LaravelFlow\Console\Commands\FlowPruneCommand::class, 'retention_days' => 30, // Set to true to register the daily prune on the scheduler automatically. // Off by default so the package never deletes data without opt-in. 'schedule' => false, ], ]; ``` -------------------------------- ### Orchestrator Lifecycle: Subtask Completion Source: https://github.com/sergiumhi/laravel-flow/blob/main/README.md When subtasks finish, their completion is aggregated to potentially complete the parent task and advance the flow. Sequential subtasks trigger the dispatch of the next sibling. ```php 4. Subtask finishes → all siblings done → aggregate output, complete parent, advance the flow → sequential → dispatch the next sibling ``` -------------------------------- ### Orchestrator Lifecycle: Orchestrator Job Source: https://github.com/sergiumhi/laravel-flow/blob/main/README.md The `FlowOrchestratorJob` rebuilds the generator, replays completed steps, and reconciles the DAG. It dispatches `FlowTaskJob` for tasks or marks the flow as waiting for signals. ```php 2. FlowOrchestratorJob (advance) → rebuilds the generator, replays completed steps, reconciles the DAG → next yield is a Task → mark running, dispatch FlowTaskJob → next yield is a Signal → mark waiting, record signal_waited_at, stop → generator exhausted → mark the flow completed ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.