Issues (264)

app/Livewire/Discuss/Conversation.php (5 issues)

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Xetaravel\Livewire\Discuss;
6
7
use Illuminate\Contracts\Database\Query\Builder;
8
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
9
use Illuminate\Pagination\LengthAwarePaginator;
10
use Illuminate\Support\Collection;
11
use Livewire\Attributes\Url;
12
use Livewire\Component;
13
use Livewire\WithPagination;
14
use Masmerise\Toaster\Toastable;
15
use Psr\Container\ContainerExceptionInterface;
16
use Psr\Container\NotFoundExceptionInterface;
17
use Xetaravel\Livewire\Traits\WithCachedRows;
18
use Xetaravel\Livewire\Traits\WithSorting;
19
use Xetaravel\Models\DiscussCategory;
20
use Xetaravel\Models\DiscussConversation;
21
22
class Conversation extends Component
23
{
24
    use AuthorizesRequests;
25
    use Toastable;
26
    use WithCachedRows;
27
    use WithPagination;
28
    use WithSorting;
29
30
    /**
31
     * Categories used for sorting.
32
     *
33
     * @var Collection
34
     */
35
    public Collection $categories;
36
37
    /**
38
     * The default number used to limit conversations per page.
39
     *
40
     * @var int[]
41
     */
42
    public array $perPage = [
43
        10,
44
        25,
45
        50
46
    ];
47
48
    /**
49
     * The field to sort by.
50
     *
51
     * @var string
52
     */
53
    #[Url(as: 'f', except: 'created_at')]
54
    public string $sortField = 'created_at';
55
56
    /**
57
     * The direction of the ordering.
58
     *
59
     * @var string
60
     */
61
    #[Url(as: 'd')]
62
    public string $sortDirection = 'desc';
63
64
    /**
65
     * The number of conversation limited per page.
66
     *
67
     * @var null|int
68
     */
69
    #[Url(as: 'l', except: 15)]
70
    public ?int $limit = null;
71
72
    /**
73
     * The category selected in the select menu.
74
     *
75
     * 0 = all categories
76
     *
77
     * @var int
78
     */
79
    #[Url(as: 'c', except: 0)]
80
    public int $category = 0;
81
82
    /**
83
     * The string to search.
84
     *
85
     * @var string
86
     */
87
    #[Url(as: 's', except: '')]
88
    public string $search = '';
89
90
    /**
91
     * Array of allowed fields.
92
     *
93
     * @var array
94
     */
95
    public array $allowedFields = [
96
        'post_count',
97
        'is_locked',
98
        'is_solved',
99
        'created_at'
100
    ];
101
102
    public function mount(): void
103
    {
104
        // Create the categories list for the select and push the `All Categories` into it at the first position.
105
        $categories = collect();
106
        $categories->push([
0 ignored issues
show
array('id' => 0, 'icon' ...lor' => 'currentColor') of type array<string,integer|string> is incompatible with the type Illuminate\Support\TValue expected by parameter $values of Illuminate\Support\Collection::push(). ( Ignorable by Annotation )

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

106
        $categories->push(/** @scrutinizer ignore-type */ [
Loading history...
107
            'id' => 0,
108
            'icon' => 'fas-list',
109
            'title' => 'All Categories',
110
            'color' => 'currentColor'
111
        ]);
112
113
        // Get and push all the discuss categories.
114
        $categoriesAll = DiscussCategory::orderBy('id')->get();
115
        $categoriesAll->each(function ($item) use ($categories) {
116
            $categories->push([
0 ignored issues
show
array('id' => $item->id,...color' => $item->color) of type array is incompatible with the type Illuminate\Support\TValue expected by parameter $values of Illuminate\Support\Collection::push(). ( Ignorable by Annotation )

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

116
            $categories->push(/** @scrutinizer ignore-type */ [
Loading history...
117
                'id' => $item->id,
118
                'icon' => $item->icon,
119
                'title' => $item->title,
120
                'color' => $item->color
121
            ]);
122
        });
123
        // Reorder the collection by `id` key and convert to array.
124
        $this->categories = $categories->keyBy('id');
125
126
        // Add the default perPage setting to the array.
127
        $this->perPage[] = config('xetaravel.pagination.discuss.conversation_per_page');
128
        // Re-order the array by `asc`.
129
        sort($this->perPage);
130
131
        // Set the limit to the default config if the limit is not in the array.
132
        if (!in_array($this->limit, $this->perPage)) {
133
            $this->limit = config('xetaravel.pagination.discuss.conversation_per_page');
134
        }
135
136
        // Check if the category exist, else set the all categories.
137
        if (!$this->categories->has($this->category)) {
138
            $this->category = 0;
139
        }
140
    }
141
142
    public function render()
143
    {
144
        return view('livewire.discuss.conversation', [
145
            'conversations' => $this->rows
0 ignored issues
show
Bug Best Practice introduced by
The property rows does not exist on Xetaravel\Livewire\Discuss\Conversation. Since you implemented __get, consider adding a @property annotation.
Loading history...
146
        ]);
147
    }
148
149
    /**
150
     * Create and return the query for the items.
151
     *
152
     * @return Builder
153
     */
154
    public function getRowsQueryProperty(): Builder
155
    {
156
        $query = DiscussConversation::query()
157
            ->with(['user', 'category', 'firstPost', 'lastPost', 'lastPost.user', 'lastPost.user.account', 'users', 'users.user', 'users.user.account'])
158
            ->when($this->search, function ($query, $search) {
159
                return $query->where('title', 'LIKE', '%' . $search . '%')
160
                    ->orWhereHas('posts', function ($query) use ($search) {
161
                        return $query->where('content', 'like', '%' . $search . '%');
162
                    });
163
            })
164
            // If the `category` == 0, we display all categories so no condition applied.
165
            ->when($this->category, function ($query, $category) {
166
                return $query->where('category_id', $category);
167
            })
168
            ->orderBy('is_pinned', 'desc');
169
170
        return $this->applySorting($query);
0 ignored issues
show
It seems like $query can also be of type Illuminate\Database\Eloq...gHasThroughRelationship; however, parameter $query of Xetaravel\Livewire\Discu...rsation::applySorting() does only seem to accept Illuminate\Contracts\Database\Query\Builder, maybe add an additional type check? ( Ignorable by Annotation )

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

170
        return $this->applySorting(/** @scrutinizer ignore-type */ $query);
Loading history...
171
    }
172
173
    /**
174
     * Build the query and paginate it.
175
     *
176
     * @return LengthAwarePaginator
177
     *
178
     * @throws ContainerExceptionInterface
179
     * @throws NotFoundExceptionInterface
180
     */
181
    public function getRowsProperty(): LengthAwarePaginator
182
    {
183
        return $this->cache(function () {
184
            return $this->rowsQuery->paginate($this->limit);
0 ignored issues
show
Bug Best Practice introduced by
The property rowsQuery does not exist on Xetaravel\Livewire\Discuss\Conversation. Since you implemented __get, consider adding a @property annotation.
Loading history...
185
        });
186
    }
187
188
    /**
189
     *  Check the value received by the front if it's a valid value, else set the default value.
190
     *
191
     * @param mixed $limit
192
     *
193
     * @return void
194
     */
195
    public function updatedLimit(int $limit): void
196
    {
197
        // Set the limit to the default config if the limit is not in the array.
198
        // Prevent people that modify the HTML value of the <option> to set a high value.
199
        if (!in_array($limit, $this->perPage)) {
200
            $this->limit = config('xetaravel.pagination.discuss.conversation_per_page');
201
        }
202
    }
203
}
204