Install & Publish:
composer require monzer/filament-workflows
php artisan vendor:publish --provider="Monzer\FilamentWorkflows\FilamentWorkflowsServiceProvider" --tag="migrations"
php artisan migrate
Run php artisan vendor:publish --provider="Monzer\FilamentWorkflows\FilamentWorkflowsServiceProvider" --tag="config" if customizing defaults.
Access the Workflow Resource:
Navigate to /admin/resources/workflows in your Filament admin panel to create your first workflow.
First Use Case: Model Event Trigger
Order).model.created (or any other event like model.updated).{model.name}) to dynamically bind data.Model Event Automation:
created, updated, deleted) via the Filament UI.User is created.
// In your Workflow definition (via UI):
// Trigger: User created
// Action: Send Email (to: {model.email}, subject: "Welcome!")
Scheduled Tasks:
0 0 * * * for daily at midnight).Custom Event Integration:
// In your event listener:
event(new OrderPaid($order));
// In Filament Workflows UI:
// Trigger: OrderPaid (custom event)
// Action: Update inventory ({model.product_id}, quantity: -{event.amount})
Chaining Actions:
Webhook Integrations:
{model.id}).Magic Attributes:
{model.attribute} (e.g., {model.name}){event.data} (for custom events){workflow.name} (metadata)Custom Actions:
namespace App\Actions;
use Monzer\FilamentWorkflows\Actions\Action;
class CustomAction extends Action
{
public static function getName(): string
{
return 'Custom Logic';
}
public function handle(): void
{
// Your custom logic here
\Log::info('Custom action triggered for model: ' . $this->model->id);
}
}
config/filament-workflows.php under actions.custom.Conditional Logic:
model.status === 'paid').{model.status} === 'active').Error Handling:
Testing:
php artisan tinker
>>> \App\Models\User::create(['name' => 'Test User']);
Magic Attribute Parsing:
{model.non_existent} will break workflows.{model.attribute|default:'fallback'}).Circular Dependencies:
Performance:
Webhook Timeouts:
Permission Issues:
Execution Logs:
/admin/resources/workflows/{workflow}/logs for errors or successful runs.Event Listeners:
// Add a temporary listener for debugging:
\Event::listen(\App\Events\OrderPaid::class, function ($event) {
\Log::info('OrderPaid event fired for order: ' . $event->order->id);
});
Magic Attribute Debugging:
{{ dump({model}) }} in Blade templates (if applicable) to inspect model data.Custom Triggers:
Trigger class to support custom event sources (e.g., database changes via Laravel Observers).namespace App\Triggers;
use Monzer\FilamentWorkflows\Triggers\Trigger;
class DatabaseChangeTrigger extends Trigger
{
public static function getName(): string
{
return 'Database Change';
}
public function shouldRun(): bool
{
return \DB::table('changes')->where('model', $this->model)->exists();
}
}
config/filament-workflows.php under triggers.custom.Action Metadata:
class SendEmailAction extends Action
{
public static function getName(): string
{
return 'Send Email';
}
public static function getDescription(): string
{
return 'Send an email using the model data.';
}
public static function getIcon(): string
{
return 'heroicon-o-envelope';
}
}
Workflow Hooks:
workflow.starting, workflow.failed) via Laravel Events:
\Event::listen(\Monzer\FilamentWorkflows\Events\WorkflowStarting::class, function ($event) {
\Log::info("Workflow {$event->workflow->name} is starting for model {$event->model->id}");
});
Localization:
php artisan vendor:publish --provider="Monzer\FilamentWorkflows\FilamentWorkflowsServiceProvider" --tag="lang"
resources/lang/en/filament-workflows.php.Queue Configuration:
// config/filament-workflows.php
'queue' => [
'enabled' => true,
'connection' => 'redis',
],
php artisan queue:work).Default Workflow Settings:
config/filament-workflows.php:
'defaults' => [
'stop_on_failure' => true,
'max_retries' => 3,
],
Model Binding:
ModelNotFound errors.App\Models\User).How can I help you explore Laravel packages today?