Overview
The WorkflowStub class provides the primary interface for creating, starting, querying, and controlling workflow instances. It acts as a handle to interact with both new and existing workflows.
Traits Used
Awaits - Provides methods for awaiting conditions
AwaitWithTimeouts - Adds timeout support to await operations
Continues - Enables workflow continuation
Fakes - Provides testing/mocking support
Macroable - Allows dynamic method addition
SideEffects - Handles non-deterministic operations
Timers - Provides timer functionality
Versions - Supports workflow versioning
Constants
The default version number for workflows
Static Methods
make()
public static function make($class): static
Creates a new workflow instance without starting it.
The fully qualified workflow class name
Returns: A new WorkflowStub instance
Example
use Workflow\WorkflowStub;
$workflow = WorkflowStub::make(OrderWorkflow::class);
$workflow->start($order);
load()
public static function load($id)
Loads an existing workflow by ID.
The workflow instance ID (UUID)
Returns: A WorkflowStub instance for the loaded workflow
Example
$workflow = WorkflowStub::load('01234567-89ab-cdef-0123-456789abcdef');
$status = $workflow->status();
fromStoredWorkflow()
public static function fromStoredWorkflow(StoredWorkflow $storedWorkflow): static
Creates a workflow stub from an existing StoredWorkflow model.
The stored workflow model instance
Returns: A new WorkflowStub instance
Example
$stored = StoredWorkflow::where('class', OrderWorkflow::class)->first();
$workflow = WorkflowStub::fromStoredWorkflow($stored);
getContext()
public static function getContext(): \stdClass
Returns the current workflow execution context.
Returns: Object with properties: storedWorkflow, index, now, replaying
Example
public function execute()
{
$context = WorkflowStub::getContext();
$isReplaying = $context->replaying;
$currentIndex = $context->index;
}
setContext()
public static function setContext($context): void
Sets the workflow execution context.
Context object with workflow execution state
Example
WorkflowStub::setContext([
'storedWorkflow' => $storedWorkflow,
'index' => 0,
'now' => Carbon::now(),
'replaying' => false,
]);
now()
public static function now()
Returns the current deterministic timestamp for the workflow.
Returns: Carbon instance representing the workflow’s current time
Example
public function execute()
{
// Don't use Carbon::now() - use WorkflowStub::now()
$currentTime = WorkflowStub::now();
yield ActivityStub::make(ScheduleReminder::class, $currentTime->addHours(24));
}
connection()
public static function connection()
Returns the queue connection for the current workflow.
Returns: String connection name or null
queue()
public static function queue()
Returns the queue name for the current workflow.
Returns: String queue name or null
isUpdateMethod()
public static function isUpdateMethod(string $class, string $method): bool
Checks if a method is marked with the UpdateMethod attribute.
Returns: Boolean indicating if the method is an update method
getDefaultProperties()
public static function getDefaultProperties(string $class): array
Returns default property values for a workflow class.
Returns: Array of property names and default values
Instance Methods
id()
Returns the workflow instance ID.
Returns: String UUID
Example
$workflow = WorkflowStub::make(OrderWorkflow::class);
$workflow->start($order);
$id = $workflow->id();
// Returns: "01234567-89ab-cdef-0123-456789abcdef"
start()
public function start(...$arguments): void
Starts the workflow with the provided arguments.
Variable arguments passed to the workflow execute method
Example
$workflow = WorkflowStub::make(OrderWorkflow::class);
$workflow->start($order, new WorkflowOptions(
connection: 'redis',
queue: 'high-priority'
));
startAsChild()
public function startAsChild(
StoredWorkflow $parentWorkflow,
int $index,
$now,
...$arguments
): void
Starts the workflow as a child of another workflow.
The parent workflow’s stored model
The parent workflow’s execution index
The parent workflow’s current timestamp
Arguments for the child workflow
status()
public function status(): string|bool
Returns the workflow’s current status class.
Returns: Fully qualified status class name
Example
$status = $workflow->status();
if ($status === WorkflowCompletedStatus::class) {
echo "Workflow completed!";
}
completed()
public function completed(): bool
Checks if the workflow has completed successfully.
Returns: Boolean
Example
if ($workflow->completed()) {
$result = $workflow->output();
}
created()
public function created(): bool
Checks if the workflow is in created state (not yet started).
Returns: Boolean
failed()
public function failed(): bool
Checks if the workflow has failed.
Returns: Boolean
Example
if ($workflow->failed()) {
$exceptions = $workflow->exceptions();
foreach ($exceptions as $exception) {
Log::error('Workflow error', ['error' => $exception]);
}
}
running()
public function running(): bool
Checks if the workflow is currently running (not completed or failed).
Returns: Boolean
output()
Returns the workflow’s output value after completion.
Returns: Mixed value returned by the workflow’s execute method, or null if not completed
Example
$workflow = WorkflowStub::load($workflowId);
if ($workflow->completed()) {
$result = $workflow->output();
echo "Order total: " . $result['total'];
}
logs()
Returns the workflow’s execution logs.
Returns: Collection of log entries
exceptions()
public function exceptions()
Returns exceptions that occurred during workflow execution.
Returns: Collection of exception records
fresh()
public function fresh(): static
Refreshes the workflow state from the database.
Returns: The workflow stub instance
Example
$workflow->fresh()->status();
resume()
public function resume(): void
Resumes a paused workflow by dispatching it to the queue.
Example
$workflow = WorkflowStub::load($workflowId);
$workflow->resume();
fail()
public function fail($exception): void
Manually fails the workflow with an exception.
The exception that caused the failure
Example
try {
// Some operation
} catch (\Exception $e) {
$workflow->fail($e);
}
next()
public function next(
$index,
$now,
$class,
$result,
bool $shouldSignal = true
): void
Records the next step in workflow execution history.
The timestamp for this step
The class that was executed
The result of the execution
Whether to dispatch the workflow to continue
Magic Methods
__call()
public function __call($method, $arguments)
Handles signal, query, and update method calls dynamically.
- Signal Methods: Send asynchronous signals to the workflow
- Query Methods: Read workflow state without side effects
- Update Methods: Modify workflow state and optionally trigger execution
Example
use Workflow\Workflow;
use Workflow\SignalMethod;
use Workflow\QueryMethod;
use Workflow\UpdateMethod;
class OrderWorkflow extends Workflow
{
private string $status = 'pending';
private int $quantity = 0;
#[SignalMethod]
public function cancelOrder(): void
{
$this->status = 'cancelled';
}
#[QueryMethod]
public function getStatus(): string
{
return $this->status;
}
#[UpdateMethod]
public function updateQuantity(int $qty): void
{
$this->quantity = $qty;
}
}
// Using the workflow stub
$workflow = WorkflowStub::make(OrderWorkflow::class);
$workflow->start($order);
// Call signal method
$workflow->cancelOrder();
// Call query method
$status = $workflow->getStatus();
// Call update method
$workflow->updateQuantity(5);
Complete Example
use Workflow\WorkflowStub;
use App\Workflows\OrderWorkflow;
use App\Models\Order;
// Create and start a new workflow
$order = Order::find(1);
$workflow = WorkflowStub::make(OrderWorkflow::class);
$workflow->start($order);
// Store the workflow ID
$workflowId = $workflow->id();
// Later, load and check status
$workflow = WorkflowStub::load($workflowId);
if ($workflow->running()) {
echo "Order is being processed...";
}
// Query current state
$status = $workflow->getStatus(); // Calls query method
// Send a signal
$workflow->cancelOrder(); // Calls signal method
// Check if completed
if ($workflow->completed()) {
$result = $workflow->output();
echo "Order completed: " . json_encode($result);
}
// Handle failures
if ($workflow->failed()) {
$exceptions = $workflow->exceptions();
foreach ($exceptions as $exception) {
Log::error('Workflow failed', [
'workflow_id' => $workflowId,
'error' => $exception,
]);
}
}