Parameters
Actions, conditionals, and workflow events can declare the parameters they accept by implementing the DefinesParameters interface. This enables discovery, validation, and UI rendering for workflow builders.
Declaring Parameters
Implement the DefinesParameters interface and return an array of Parameter objects from the parameters() method:
use Workflowable\Workflowable\Contracts\DefinesParameters;
use Workflowable\Workflowable\Support\Parameters\TextParameter;
use Workflowable\Workflowable\Support\Parameters\SelectParameter;
use Workflowable\Workflowable\Support\Parameters\ModelParameter;
class SendEmail implements DefinesParameters
{
public static function parameters(): array
{
return [
SelectParameter::make('template', 'Email Template')
->options([
'order-confirmation' => 'Order Confirmation',
'invoice-reminder' => 'Invoice Reminder',
]),
TextParameter::make('subject', 'Subject Line')
->optional()
->default('Notification')
->placeholder('Enter email subject...')
->description('Supports {{variable}} interpolation'),
ModelParameter::make('recipient_id', 'Recipient')
->route('api.users.search')
->labelKey('name'),
];
}
public function handle(ExecutionContext $context): array
{
$template = $context->getStepConfig('template');
$subject = $context->getStepConfig('subject', 'Notification');
return ['email_sent' => true];
}
}Parameter values are passed as step config keys in the workflow definition and read at runtime via $context->getStepConfig().
Workflow Event Parameters
WorkflowEvent implements DefinesParameters automatically. By default, the parameter schema is generated from the constructor's promoted properties — no extra code needed:
use Workflowable\Workflowable\Abstracts\WorkflowEvent;
class OrderSubmitted extends WorkflowEvent
{
public function __construct(
public readonly int $orderId,
public readonly float $amount,
public readonly string $customerEmail,
) {}
}
OrderSubmitted::parameterSchema();
// [
// ['name' => 'orderId', 'type' => 'int', 'label' => 'Order Id', 'required' => true],
// ['name' => 'amount', 'type' => 'float', 'label' => 'Amount', 'required' => true],
// ['name' => 'customerEmail', 'type' => 'string', 'label' => 'Customer Email', 'required' => true],
// ]For more control, override parameters() to return explicit Parameter objects instead:
class OrderSubmitted extends WorkflowEvent
{
public function __construct(
public readonly int $orderId,
public readonly float $amount,
public readonly string $customerEmail,
) {}
public static function parameters(): array
{
return [
NumberParameter::make('orderId', 'Order ID')->required(),
NumberParameter::make('amount', 'Order Amount')->min(0),
TextParameter::make('customerEmail', 'Customer Email')
->rules(['email']),
];
}
}When parameters() returns a non-empty array, parameterSchema() uses those explicit definitions instead of the auto-generated schema.
Available Parameter Types
| Type | Class | Purpose |
|---|---|---|
| Text | TextParameter | Text input with placeholder(), multiline() |
| Number | NumberParameter | Numeric input with min(), max(), step() |
| Boolean | BooleanParameter | Toggle / checkbox |
| Select | SelectParameter | Dropdown with static options(), multiple() |
| Model | ModelParameter | Typeahead search via route(), valueKey(), labelKey() |
| Date | DateParameter | Date picker with withTime(), min(), max() |
Common Builder Methods
All parameter types share these methods from the base Parameter class:
| Method | Description |
|---|---|
make($name, $label) | Static factory (on each subclass) |
required() / optional() | Set whether the parameter is required (default: required) |
default($value) | Set a default value |
description($text) | Help text for the workflow designer |
rules($array) | Laravel validation rules, checked at definition time |
when($condition, $callback) | Conditional builder chain (via Conditionable) |
Validation Rules
Parameters can declare Laravel validation rules that are checked when a workflow definition is created:
TextParameter::make('email', 'Recipient Email')
->rules(['email', 'max:255']),
NumberParameter::make('quantity', 'Quantity')
->rules(['integer', 'min:1', 'max:100']),If a step definition fails validation, an InvalidWorkflowDefinitionException is thrown at definition time.
ModelParameter and Data Sources
ModelParameter is for selecting from large datasets where a static options list isn't practical. Instead of embedding options, you point it to an application-owned search endpoint:
ModelParameter::make('customer_id', 'Customer')
->route('api.customers.search') // Laravel named route
->valueKey('id') // Field to store
->labelKey('name') // Field to display
->searchParam('q') // Query parameter name (default: 'q')The package resolves the named route to a URL in the serialized schema. The search endpoint is owned by your application — the package doesn't query models directly.
Schema Serialization
Parameters serialize to a standardized JSON format via toArray(). The registry schema() methods return the full catalog including parameter schemas:
$actionSchema = app(ActionRegistry::class)->schema();
$conditionalSchema = app(ConditionalRegistry::class)->schema();This schema can be consumed by a frontend workflow builder to render the appropriate form controls for each handler's configuration.
Extending with Macros
The base Parameter class uses Laravel's Macroable trait. Add custom builder methods without subclassing:
// In a service provider
TextParameter::macro('currency', function () {
return $this->placeholder('0.00')->rules(['numeric', 'min:0']);
});
// In a handler
TextParameter::make('amount', 'Amount')->currency();Custom Parameter Types
For entirely new input types, extend Parameter directly:
use Workflowable\Workflowable\Abstracts\Parameter;
class ColorParameter extends Parameter
{
public static function make(string $name, string $label): static
{
return new static($name, $label);
}
public function type(): string
{
return 'color';
}
}