Passed
Push — 5.0.0 ( 49e1c0...87aae2 )
by Fèvre
06:22
created

WithBulkActions::renderingWithBulkActions()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 2
nc 2
nop 0
dl 0
loc 4
rs 10
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Xetaravel\Livewire\Traits;
6
7
use Illuminate\Database\Eloquent\Builder;
8
use Illuminate\Support\Collection;
9
use Illuminate\Support\Facades\DB;
10
use Masmerise\Toaster\Toastable;
11
use Throwable;
12
13
trait WithBulkActions
14
{
15
    use Toastable;
16
17
    /**
18
     * Whatever the current page of rows are all selected or not.
19
     *
20
     * @var bool
21
     */
22
    public bool $selectPage = false;
23
24
    /**
25
     * Whatever the user has selected all rows or not.
26
     *
27
     * @var bool
28
     */
29
    public bool $selectAll = false;
30
31
    /**
32
     * The id array of selected rows.
33
     *
34
     * @var Collection
35
     */
36
    public Collection $selected;
37
38
    /**
39
     * Filter the field on component mount regarding the allowed fields.
40
     *
41
     * @return void
42
     */
43
    public function mountWithBulkActions(): void
44
    {
45
        $this->selected = collect();
46
    }
47
48
    /**
49
     * If the selectAll is true, we need to select (and check the checkbox) of all rows
50
     * rendering in the current page.
51
     *
52
     * @return void
53
     */
54
    public function renderingWithBulkActions(): void
55
    {
56
        if ($this->selectAll) {
57
            $this->selectPageRows();
58
        }
59
    }
60
61
    /**
62
     * Whenever the user unselect a checkbox, we need to disable the selectAll option and selectPage.
63
     *
64
     * @return void
65
     */
66
    public function updatedSelected(): void
67
    {
68
        $this->selectAll = false;
69
        $this->selectPage = false;
70
    }
71
72
    /**
73
     * Whatever we have selected all rows in the current page.
74
     *
75
     * @param mixed $value The current page where all rows get selected.
76
     *
77
     * @return void|null
78
     */
79
    public function updatedSelectPage($value)
80
    {
81
        if ($value) {
82
            $this->selectPageRows();
83
84
            return;
85
        }
86
87
        $this->selectAll = false;
88
        $this->selected = collect();
89
    }
90
91
    /**
92
     * Convert the selected rows id into string type.
93
     *
94
     * @return void
95
     */
96
    public function selectPageRows(): void
97
    {
98
        $this->selected = $this->rows->pluck('id')->map(fn ($id) => (string) $id);
99
    }
100
101
    /**
102
     * Set selectAll to true.
103
     *
104
     * @return void
105
     */
106
    public function setSelectAll(): void
107
    {
108
        $this->selectAll = true;
109
    }
110
111
    /**
112
     * Get all select rows by their id, preparing for deleting them.
113
     *
114
     * @eturn Builder
115
     */
116
    public function getSelectedRowsQueryProperty(): Builder
117
    {
118
119
        return app($this->model)
120
            ->unless($this->selectAll, function ($query) {
0 ignored issues
show
introduced by
The method unless() does not exist on Illuminate\Container\Container. Are you sure you never get this type here, but always one of the subclasses? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

120
            ->/** @scrutinizer ignore-call */ unless($this->selectAll, function ($query) {
Loading history...
121
                return $query->whereKey($this->selected->values());
122
            });
123
    }
124
125
    /**
126
     * Delete all selected rows and display a flash message.
127
     *
128
     * @return bool
129
     *
130
     * @throws Throwable
131
     */
132
    public function deleteSelected(): bool
133
    {
134
        $models = collect(
135
            $this->selectedRowsQuery
0 ignored issues
show
Bug introduced by
The property selectedRowsQuery does not exist on Xetaravel\Livewire\Traits\WithBulkActions. Did you mean selected?
Loading history...
136
                ->get()
137
                ->pluck('id')
138
                ->toArray()
139
        );
140
141
        if ($models->count() <= 0) {
142
            return false;
143
        }
144
145
        // For each id, we fetch the model and check the permission related to the model.
146
        // If one fail, then they all won't be deleted.
147
        $models->each(function ($id) {
148
            $model = app($this->model)->where('id', $id)->first();
0 ignored issues
show
introduced by
The method where() does not exist on Illuminate\Container\Container. Are you sure you never get this type here, but always one of the subclasses? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

148
            $model = app($this->model)->/** @scrutinizer ignore-call */ where('id', $id)->first();
Loading history...
149
150
            $this->authorize('delete', $model);
0 ignored issues
show
Bug introduced by
It seems like authorize() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

150
            $this->/** @scrutinizer ignore-call */ 
151
                   authorize('delete', $model);
Loading history...
151
        });
152
153
        $model = $this->model;
154
155
        $result = DB::transaction(function () use ($model, $models) {
156
            return app($model)->destroy($models->toArray());
0 ignored issues
show
introduced by
The method destroy() does not exist on Illuminate\Container\Container. Are you sure you never get this type here, but always one of the subclasses? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

156
            return app($model)->/** @scrutinizer ignore-call */ destroy($models->toArray());
Loading history...
157
        });
158
159
        if ($result) {
160
            $this->selected = collect();
161
162
            return true;
163
        }
164
165
        return false;
166
    }
167
}
168