Skip to content

Extending Workflowable

Workflowable is designed to be extended at multiple points.

Custom Step Types

Create your own step types for domain-specific logic by implementing the StepType interface. See the full Custom Step Types documentation for a complete guide with examples, the interface reference, and registration instructions.

Custom Action Handlers

For simpler cases where you just need to run some business logic within an action step, register action handlers instead of creating full step types.

Via Config

php
// In config/workflowable.php
'actions' => [
    'send_slack_notification' => \App\Actions\SendSlackNotification::class,
],

Handler Class

php
use Workflowable\Workflowable\Engine\ExecutionContext;

class SendSlackNotification
{
    public function handle(ExecutionContext $context): array
    {
        $message = $context->getVariable('notification_message');
        Slack::send($message);
        return ['slack_sent' => true];
    }
}

Via Service Provider

php
use Workflowable\Workflowable\Registries\ActionRegistry;

public function boot(): void
{
    $registry = app(ActionRegistry::class);
    $registry->register('send_slack', SendSlackNotification::class);
}

Action handlers are used with the built-in Action step type and don't require implementing the StepType interface. See the action docs for the full handler resolution order and dependency injection details.

Declaring Parameters

Action handlers can declare what configuration they accept by implementing DefinesParameters. This makes the action self-describing for workflow builders:

php
use Workflowable\Workflowable\Contracts\DefinesParameters;
use Workflowable\Workflowable\Support\Parameters\TextParameter;
use Workflowable\Workflowable\Support\Parameters\SelectParameter;

class SendSlackNotification implements DefinesParameters
{
    public static function parameters(): array
    {
        return [
            SelectParameter::make('channel', 'Slack Channel')
                ->options([
                    'general' => '#general',
                    'alerts' => '#alerts',
                    'engineering' => '#engineering',
                ]),
            TextParameter::make('message_prefix', 'Message Prefix')
                ->optional()
                ->default('[Workflow]'),
        ];
    }

    public function handle(ExecutionContext $context): array
    {
        $channel = $context->getStepConfig('channel', 'general');
        $prefix = $context->getStepConfig('message_prefix', '[Workflow]');
        $message = $context->getVariable('notification_message');

        Slack::to($channel)->send("{$prefix} {$message}");
        return ['slack_sent' => true];
    }
}

See the Action Parameters documentation for the full list of parameter types and builder methods.

Event Listeners

React to workflow lifecycle events for notifications, logging, and integrations. See the Events Reference for the full event list and examples.

php
use Workflowable\Workflowable\Events\WorkflowCompleted;

Event::listen(WorkflowCompleted::class, function ($event) {
    Log::info("Workflow completed: {$event->instance->id}");
});