Completed
Push — master ( 5c55d7...79e99a )
by Fèvre
28s queued 15s
created

Categories   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 254
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 72
c 1
b 0
f 0
dl 0
loc 254
rs 10
wmc 20

12 Methods

Rating   Name   Duplication   Size   Complexity  
A rules() 0 10 1
A mount() 0 4 1
A generateSlug() 0 3 1
A create() 0 11 2
A generateColor() 0 3 1
A save() 0 10 2
A getRowsQueryProperty() 0 6 1
A getRowsProperty() 0 4 1
A fireFlash() 0 26 6
A render() 0 4 1
A edit() 0 11 2
A makeBlankModel() 0 3 1
1
<?php
2
3
namespace Xetaravel\Http\Livewire\Admin\Discuss;
4
5
use Illuminate\Contracts\Database\Query\Builder;
6
use Illuminate\Contracts\View\View;
7
use Illuminate\Pagination\LengthAwarePaginator;
8
use Illuminate\Support\Str;
9
use Livewire\Component;
10
use Livewire\WithPagination;
11
use Xetaravel\Http\Livewire\Traits\WithCachedRows;
12
use Xetaravel\Http\Livewire\Traits\WithSorting;
13
use Xetaravel\Http\Livewire\Traits\WithBulkActions;
14
use Xetaravel\Http\Livewire\Traits\WithPerPagePagination;
15
use Xetaravel\Models\DiscussCategory;
16
17
class Categories extends Component
18
{
19
    use WithPagination;
0 ignored issues
show
Bug introduced by
The trait Livewire\WithPagination requires the property $paginationTheme which is not provided by Xetaravel\Http\Livewire\Admin\Discuss\Categories.
Loading history...
20
    use WithSorting;
21
    use WithCachedRows;
22
    use WithBulkActions;
0 ignored issues
show
introduced by
The trait Xetaravel\Http\Livewire\Traits\WithBulkActions requires some properties which are not provided by Xetaravel\Http\Livewire\Admin\Discuss\Categories: $selectedRowsQuery, $rows, $rowsQuery
Loading history...
23
    use WithPerPagePagination;
0 ignored issues
show
Bug introduced by
The trait Xetaravel\Http\Livewire\...s\WithPerPagePagination requires the property $paginationTheme which is not provided by Xetaravel\Http\Livewire\Admin\Discuss\Categories.
Loading history...
24
25
    /**
26
     * The string to search.
27
     *
28
     * @var string
29
     */
30
    public string $search = '';
31
32
    /**
33
     * Used to update in URL the query string.
34
     *
35
     * @var string[]
36
     */
37
    protected $queryString = [
38
        'sortField' => ['as' => 'f'],
39
        'sortDirection' => ['as' => 'd'],
40
        'search' => ['except' => '', 'as' => 's']
41
    ];
42
43
    /**
44
     * The model used in the component.
45
     *
46
     * @var DiscussCategory
47
     */
48
    public DiscussCategory $model;
49
50
    /**
51
     * Used to show the Edit/Create modal.
52
     *
53
     * @var bool
54
     */
55
    public bool $showModal = false;
56
57
    /**
58
     * Used to show the delete modal.
59
     *
60
     * @var bool
61
     */
62
    public bool $showDeleteModal = false;
63
64
    /**
65
     * Used to set the modal to Create action (true) or Edit action (false).
66
     * @var bool
67
     */
68
    public bool $isCreating = false;
69
70
    /**
71
     * Number of rows displayed on a page.
72
     * @var int
73
     */
74
    public int $perPage = 10;
75
76
    /**
77
     * The color of the category displayed in the modal in realtime.
78
     *
79
     * @var string
80
     */
81
    public $color = '#dddddd';
82
83
    /**
84
     * The Livewire Component constructor.
85
     *
86
     * @return void
87
     */
88
    public function mount(): void
89
    {
90
        $this->model = $this->makeBlankModel();
91
        $this->perPage = config('xetaravel.pagination.blog.article_per_page');
92
    }
93
94
    /**
95
     * Rules used for validating the model.
96
     *
97
     * @return string[]
98
     */
99
    public function rules()
100
    {
101
        return [
102
            'model.title' => 'required|min:5',
103
            'model.slug' => 'unique:discuss_categories,slug,' . $this->model->id,
104
            'model.description' => 'required|min:10',
105
            'model.color' => 'min:7|max:9',
106
            'model.icon' => 'required',
107
            'model.level' => 'required|integer',
108
            'model.is_locked' => 'required|boolean',
109
        ];
110
    }
111
112
    /**
113
     * Generate the slug from the `slugStrategy()` function and assign it to the model.
114
     *
115
     * @return void
116
     */
117
    public function generateSlug(): void
118
    {
119
        $this->model->slug = Str::slug($this->model->{$this->model->slugStrategy()});
120
    }
121
122
    /**
123
     * Set the color from the color model to display the color in the modal.
124
     *
125
     * @return void
126
     */
127
    public function generateColor(): void
128
    {
129
        $this->color = $this->model->color;
130
    }
131
132
    /**
133
     * Create a blank model and return it.
134
     *
135
     * @return DiscussCategory
136
     */
137
    public function makeBlankModel(): DiscussCategory
138
    {
139
        return DiscussCategory::make();
140
    }
141
142
    /**
143
     * Function to render the component.
144
     *
145
     * @return View
146
     */
147
    public function render()
148
    {
149
        return view('livewire.admin.discuss.categories', [
150
            'categories' => $this->rows
0 ignored issues
show
Bug Best Practice introduced by
The property rows does not exist on Xetaravel\Http\Livewire\Admin\Discuss\Categories. Since you implemented __get, consider adding a @property annotation.
Loading history...
151
        ]);
152
    }
153
154
    /**
155
     * Create and return the query for the items.
156
     *
157
     * @return Builder
158
     */
159
    public function getRowsQueryProperty(): Builder
160
    {
161
        $query = DiscussCategory::query()
162
            ->search('title', $this->search);
163
164
        return $this->applySorting($query);
165
    }
166
167
    /**
168
     * Build the query or get it from the cache and paginate it.
169
     *
170
     * @return LengthAwarePaginator
171
     */
172
    public function getRowsProperty(): LengthAwarePaginator
173
    {
174
        return $this->cache(function () {
175
            return $this->applyPagination($this->rowsQuery);
0 ignored issues
show
Bug Best Practice introduced by
The property rowsQuery does not exist on Xetaravel\Http\Livewire\Admin\Discuss\Categories. Since you implemented __get, consider adding a @property annotation.
Loading history...
176
        });
177
    }
178
179
    /**
180
     * Create a blank model and assign it to the model. (Used in create modal)
181
     *
182
     * @return void
183
     */
184
    public function create(): void
185
    {
186
        $this->isCreating = true;
187
        $this->useCachedRows();
188
189
        // Reset the model to a blank model before showing the creating modal.
190
        if ($this->model->getKey()) {
191
            $this->model = $this->makeBlankModel();
192
            $this->color = '#dddddd';
193
        }
194
        $this->showModal = true;
195
    }
196
197
    /**
198
     * Set the model (used in modal) to the category we want to edit.
199
     *
200
     * @param DiscussCategory $category The category id to update.
201
     * (Livewire will automatically fetch the model by the id)
202
     *
203
     * @return void
204
     */
205
    public function edit(DiscussCategory $category): void
206
    {
207
        $this->isCreating = false;
208
        $this->useCachedRows();
209
210
        // Set the model to the category we want to edit.
211
        if ($this->model->isNot($category)) {
212
            $this->model = $category;
213
            $this->color = $category->color;
214
        }
215
        $this->showModal = true;
216
    }
217
218
    /**
219
     * Validate and save the model.
220
     *
221
     * @return void
222
     */
223
    public function save(): void
224
    {
225
        $this->validate();
226
227
        if ($this->model->save()) {
228
            $this->fireFlash('save', 'success');
229
        } else {
230
            $this->fireFlash('save', 'danger');
231
        }
232
        $this->showModal = false;
233
    }
234
235
    /**
236
     * Display a flash message regarding the action that fire it and the type of the message, then emit an
237
     * `alert ` event.
238
     *
239
     * @param string $action The action that fire the flash message.
240
     * @param string $type The type of the message, success or danger.
241
     * @param int $deleteCount If set, the number of categories that has been deleted.
242
     *
243
     * @return void
244
     */
245
    public function fireFlash(string $action, string $type, int $deleteCount = 0)
246
    {
247
        switch ($action) {
248
            case 'save':
249
                if ($type == 'success') {
250
                    session()->flash(
251
                        'success',
252
                        $this->isCreating ? "The category has been created successfully !" :
253
                            "The category <b>{$this->model->title}</b> has been edited successfully !"
254
                    );
255
                } else {
256
                    session()->flash('danger', "An error occurred while saving the category !");
257
                }
258
                break;
259
260
            case 'delete':
261
                if ($type == 'success') {
262
                    session()->flash('success', "<b>{$deleteCount}</b> categories has been deleted successfully !");
263
                } else {
264
                    session()->flash('danger', "An error occurred while deleting the categories !");
265
                }
266
                break;
267
        }
268
269
        // Emit the alert event to the front so the DIsmiss can trigger the flash message.
270
        $this->emit('alert');
271
    }
272
}
273