Files
UNIT3D-Community-Edition/app/Http/Livewire/ForumTopicSearch.php
Roardom eda5f28d4c update: set default topic state filter per forum
Useful for forums dedicated to fixing bugs or adding suggestions. This way, topics can be closed when bugs are fixed or suggestions are implemented, and opening the forum only shows relevant bugs/suggestions by default. Topics with different states can be accessed by changing the filter back to `Any`.
2024-03-06 12:02:23 +00:00

131 lines
4.1 KiB
PHP

<?php
/**
* NOTICE OF LICENSE.
*
* UNIT3D Community Edition is open-sourced software licensed under the GNU Affero General Public License v3.0
* The details is bundled with this project in the file LICENSE.txt.
*
* @project UNIT3D Community Edition
*
* @author Roardom <roardom@protonmail.com>
* @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0
*/
namespace App\Http\Livewire;
use App\Models\Forum;
use App\Models\Subscription;
use App\Models\Topic;
use Livewire\Attributes\Computed;
use Livewire\Attributes\Url;
use Livewire\Component;
use Livewire\WithPagination;
class ForumTopicSearch extends Component
{
use WithPagination;
#[Url]
public string $search = '';
#[Url]
public string $sortField = 'last_post_created_at';
#[Url]
public string $sortDirection = 'desc';
#[Url]
public string $label = '';
#[Url]
public string $state = '';
#[Url]
public string $subscribed = '';
#[Url]
public string $read = '';
public Forum $forum;
public ?Subscription $subscription;
final public function mount(Forum $forum): void
{
$this->forum = $forum;
$this->subscription = Subscription::where('user_id', '=', auth()->id())->where('forum_id', '=', $forum->id)->first();
$this->state = $this->forum->default_topic_state_filter ?: '';
}
final public function updatingSearch(): void
{
$this->resetPage();
}
/**
* @return \Illuminate\Contracts\Pagination\LengthAwarePaginator<Topic>
*/
#[Computed]
final public function topics(): \Illuminate\Contracts\Pagination\LengthAwarePaginator
{
return Topic::query()
->select('topics.*')
->with([
'user.group',
'latestPoster',
'forum:id,name',
'reads' => fn ($query) => $query->whereBelongsto(auth()->user()),
])
->where('topics.forum_id', '=', $this->forum->id)
->authorized(canReadTopic: true)
->when($this->search !== '', fn ($query) => $query->where('name', 'LIKE', '%'.$this->search.'%'))
->when($this->label !== '', fn ($query) => $query->where($this->label, '=', 1))
->when($this->state !== '', fn ($query) => $query->where('state', '=', $this->state))
->when(
$this->subscribed === 'include',
fn ($query) => $query
->whereRelation('subscribedUsers', 'users.id', '=', auth()->id())
)
->when(
$this->subscribed === 'exclude',
fn ($query) => $query
->whereDoesntHave('subscribedUsers', fn ($query) => $query->where('users.id', '=', auth()->id()))
)
->when(
$this->read === 'some',
fn ($query) => $query
->whereHas(
'reads',
fn ($query) => $query
->whereBelongsto(auth()->user())
->whereColumn('last_post_id', '>', 'last_read_post_id')
)
)
->when(
$this->read === 'all',
fn ($query) => $query
->whereHas(
'reads',
fn ($query) => $query
->whereBelongsto(auth()->user())
->whereColumn('last_post_id', '=', 'last_read_post_id')
)
)
->when(
$this->read === 'none',
fn ($query) => $query
->whereDoesntHave('reads', fn ($query) => $query->whereBelongsTo(auth()->user()))
)
->orderByDesc('pinned')
->orderBy($this->sortField, $this->sortDirection)
->paginate(25);
}
final public function render(): \Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Contracts\Foundation\Application
{
return view('livewire.forum-topic-search', [
'topics' => $this->topics,
]);
}
}