diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index d4b01b1..0000000 Binary files a/.DS_Store and /dev/null differ diff --git a/.gitignore b/.gitignore index a7f372d..e26945a 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ phpstan.neon testbench.yaml vendor node_modules +.DS_Store diff --git a/README.md b/README.md index cf551f3..90a84d2 100644 --- a/README.md +++ b/README.md @@ -95,3 +95,45 @@ class ParentComponent extends Component } ``` + +## Handling Form Deletion with Custom Relations + +If your project has custom relations to the `FilamentForm` model (like tests, surveys, etc.), you can handle their deletion by listening to the `FilamentFormForceDeletingEvent` event. This event is fired before a form is force deleted. + +```php +namespace App\Listeners; + +use Tapp\FilamentFormBuilder\Events\FilamentFormForceDeletingEvent; + +class HandleCustomFormDeletion +{ + public function handle(FilamentFormForceDeletingEvent $event): void + { + // Access the form being deleted + $form = $event->form; + + // Delete your custom relations + $form->tests()->delete(); + $form->surveys()->delete(); + // ... etc + } +} +``` + +Register the listener in your `EventServiceProvider`: + +```php +protected $listen = [ + \Tapp\FilamentFormBuilder\Events\FilamentFormForceDeletingEvent::class => [ + \App\Listeners\HandleCustomFormDeletion::class, + ], +]; +``` + +This way, when a form is force deleted: +1. The package will fire the `FilamentFormForceDeletingEvent` +2. Your listener will handle the deletion of custom relations +3. The package will then delete its own relations (form fields and form users) +4. Finally, the form itself will be deleted + +This approach keeps the package clean and project-agnostic while allowing you to handle custom relations in your project. diff --git a/src/Events/FilamentFormForceDeletingEvent.php b/src/Events/FilamentFormForceDeletingEvent.php new file mode 100644 index 0000000..b246cbb --- /dev/null +++ b/src/Events/FilamentFormForceDeletingEvent.php @@ -0,0 +1,17 @@ +id.'/edit'); }), + Action::make('delete') + ->requiresConfirmation() + ->form([ + Forms\Components\Checkbox::make('force_delete') + ->label('Force delete') + ->helperText('This will delete the form and all related records. This action cannot be undone.'), + ]) + ->action(function (FilamentForm $record, array $data) { + try { + DB::beginTransaction(); + + // Fire a "before delete" event that projects can listen to + if ($data['force_delete'] ?? false) { + event(new \Tapp\FilamentFormBuilder\Events\FilamentFormForceDeletingEvent($record)); + + // Only delete relations that are part of the package + $record->filamentFormFields()->delete(); + $record->filamentFormUsers()->delete(); + } + + $record->delete(); + + DB::commit(); + + Notification::make() + ->success() + ->title('Form deleted') + ->send(); + } catch (QueryException $e) { + DB::rollBack(); + + if (! ($data['force_delete'] ?? false) && str_contains($e->getMessage(), 'foreign key constraint fails')) { + Notification::make() + ->warning() + ->title('Cannot delete form') + ->body('This form has related records. Use force delete to remove all related records.') + ->persistent() + ->send(); + + return; + } + + throw $e; + } + }), ]) ->bulkActions([ BulkActionGroup::make([