Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
4 / 4
CRAP
100.00% covered (success)
100.00%
1 / 1
Delete
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
4 / 4
7
100.00% covered (success)
100.00%
1 / 1
 delete
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
4
 modifyDeleteQuery
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 beforeDelete
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 afterDelete
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace DevToolbelt\LaravelFastCrud\Actions;
6
7use Illuminate\Database\Eloquent\Builder;
8use Illuminate\Database\Eloquent\Model;
9use Illuminate\Http\JsonResponse;
10use Illuminate\Support\Str;
11use Psr\Http\Message\ResponseInterface;
12
13/**
14 * Provides the delete (DELETE by ID) action for CRUD controllers.
15 *
16 * Deletes a model instance by its identifier field (configurable).
17 * Supports soft deletes if the model uses the SoftDeletes trait.
18 *
19 * @method string modelClassName() Returns the Eloquent model class name
20 * @method JsonResponse|ResponseInterface answerInvalidUuid() Returns invalid UUID error response
21 * @method JsonResponse|ResponseInterface answerRecordNotFound() Returns not found error response
22 * @method JsonResponse|ResponseInterface answerNoContent() Returns 204 No Content response
23 */
24trait Delete
25{
26    /**
27     * Deletes a record by its identifier field.
28     *
29     * @param string $id The identifier value of the record to delete
30     * @return JsonResponse|ResponseInterface 204 No Content on success, or error response
31     */
32    public function delete(string $id): JsonResponse|ResponseInterface
33    {
34        $findField = config('devToolbelt.fast-crud.delete.find_field')
35            ?? config('devToolbelt.fast-crud.global.find_field', 'id');
36
37        $isUuid = config('devToolbelt.fast-crud.delete.find_field_is_uuid')
38            ?? config('devToolbelt.fast-crud.global.find_field_is_uuid', false);
39
40        if ($isUuid && !Str::isUuid($id)) {
41            return $this->answerInvalidUuid();
42        }
43
44        $modelName = $this->modelClassName();
45        $query = $modelName::query()->where($findField, $id);
46        $this->modifyDeleteQuery($query);
47
48        /** @var Model|null $record */
49        $record = $query->first();
50
51        if ($record === null) {
52            return $this->answerRecordNotFound();
53        }
54
55        $this->beforeDelete($record);
56        $record->delete();
57        $this->afterDelete($record);
58
59        return $this->answerNoContent();
60    }
61
62    /**
63     * Hook to modify the delete query before fetching the record.
64     *
65     * Override this method to add additional conditions or scopes,
66     * such as ensuring the user owns the record.
67     *
68     * @param Builder $query The query builder instance
69     *
70     * @example
71     * ```php
72     * protected function modifyDeleteQuery(Builder $query): void
73     * {
74     *     $query->where('user_id', auth()->id());
75     * }
76     * ```
77     */
78    protected function modifyDeleteQuery(Builder $query): void
79    {
80    }
81
82    /**
83     * Hook called before the record is deleted.
84     *
85     * Override this method to perform actions before deletion,
86     * such as logging, validation, or cleanup of related data.
87     *
88     * @param Model $record The model instance about to be deleted
89     */
90    protected function beforeDelete(Model $record): void
91    {
92    }
93
94    /**
95     * Hook called after the record has been deleted.
96     *
97     * Override this method to perform post-deletion actions,
98     * such as clearing cache, dispatching events, or audit logging.
99     *
100     * @param Model $record The deleted model instance
101     */
102    protected function afterDelete(Model $record): void
103    {
104    }
105}