DEV Community

Süleyman Özgür Özarpacı
Süleyman Özgür Özarpacı

Posted on • Edited on

How to Stop FilamentPHP Actions On Certain Conditions

In some cases, FilamentPHP processes need to be stopped based on certain conditions. To achieve this, we can use the cancel()method of an action. This article demonstrates how to use cancel() effectively and includes notifications to provide meaningful feedback to users.

You can also use halt() but halt does not close modals.

Example Scenario:
Consider a scenario where we want to prevent force-deleting a user if they have active orders. We will use a ForceDeleteBulkAction and its before callback to perform the necessary checks and notify the user accordingly.

Tables\Actions\ForceDeleteBulkAction::make()
    ->before(
        function ($records, Tables\Actions\ForceDeleteBulkAction $action) {
            // code goes here
        }
    )
Enter fullscreen mode Exit fullscreen mode

Checking for Active Orders and Canceling the Process:
To check for active orders, query the relevant data and cancel the process if any orders are found. We can achieve this as follows:

Tables\Actions\ForceDeleteBulkAction::make()
    ->before(
        function ($records, Tables\Actions\ForceDeleteBulkAction $action) {
+            $ids = $records->pluck('id')->toArray();
+            $exists = Order::whereIn('user_id', $ids)->exists();
+            if ($exists) {
+                $action->cancel();
+            }
        }
    )
Enter fullscreen mode Exit fullscreen mode

Cancel does not show notification about why process canceled. Use Notification documentation.

+use Filament\Notifications\Notification;

Tables\Actions\ForceDeleteBulkAction::make()
    ->before(
        function ($records, Tables\Actions\ForceDeleteBulkAction $action) {
            $ids = $record->orders()->pluck('id')->toArray();
            $exists = Order::whereIn('user_id', $ids)->exists();
            if ($exists) {
+                Notification::make()
+                    ->title('Errors!')
+                    ->body("You can't force delete users because someone has orders.")
+                    ->status('danger')
+                    ->send();
                $action->cancel();
           }
        }
    )

Enter fullscreen mode Exit fullscreen mode

By using the cancel() method in FilamentPHP, we can effectively halt an action based on specific conditions. In the example provided, we prevent force-deleting users with active orders and enhance the user experience by sending a notification explaining the reason for the process cancellation. This approach ensures that users are informed about the constraints and can take appropriate actions accordingly.

Top comments (3)

Collapse
 
jhonatan_bianchi_caeed044 profile image
Jhonatan Bianchi

Very nice, but how can that be tested?

With halt we can use:

it('delete will halt if user is the account owner', function () {
    $accountOwner = User::first();

    livewire(UserResource\Pages\ListUsers::class)
        ->callTableAction(DeleteAction::class, $accountOwner)
        ->assertTableActionHalted(DeleteAction::class);

    $this->assertModelExists($accountOwner);
});
Enter fullscreen mode Exit fullscreen mode
Collapse
 
biostate profile image
Süleyman Özgür Özarpacı

This is amazing!

Collapse
 
yclbng profile image
Yücel Bengü

Thank you Süleyman.Just now I was looking something like this.