2024-06-02 22:03:59 -04:00
|
|
|
<?php
|
|
|
|
|
2025-01-30 00:23:55 -05:00
|
|
|
declare(strict_types=1);
|
|
|
|
|
2024-06-02 22:03:59 -04:00
|
|
|
namespace App\Livewire;
|
|
|
|
|
|
|
|
use App\Models\Mod;
|
2024-07-03 17:47:02 -04:00
|
|
|
use App\Models\User;
|
2024-09-12 13:19:52 -04:00
|
|
|
use Illuminate\Support\Collection;
|
2024-07-03 17:47:02 -04:00
|
|
|
use Illuminate\Support\Str;
|
2024-06-02 22:03:59 -04:00
|
|
|
use Illuminate\View\View;
|
2024-09-24 00:42:26 -04:00
|
|
|
use Livewire\Attributes\Locked;
|
2024-06-02 22:03:59 -04:00
|
|
|
use Livewire\Component;
|
|
|
|
|
|
|
|
class GlobalSearch extends Component
|
|
|
|
{
|
2024-07-03 17:47:02 -04:00
|
|
|
/**
|
|
|
|
* The search query.
|
|
|
|
*/
|
2024-06-02 22:03:59 -04:00
|
|
|
public string $query = '';
|
|
|
|
|
2024-07-03 17:47:02 -04:00
|
|
|
/**
|
2024-09-24 00:42:26 -04:00
|
|
|
* The search results.
|
2025-01-30 20:49:56 -05:00
|
|
|
*
|
|
|
|
* @var array<string, Collection<int, mixed>>
|
2024-07-03 17:47:02 -04:00
|
|
|
*/
|
2024-09-24 00:42:26 -04:00
|
|
|
#[Locked]
|
|
|
|
public array $result = [];
|
2024-07-03 17:47:02 -04:00
|
|
|
|
|
|
|
/**
|
2024-09-24 00:42:26 -04:00
|
|
|
* The total number of search results.
|
2024-07-03 17:47:02 -04:00
|
|
|
*/
|
2024-09-24 00:42:26 -04:00
|
|
|
#[Locked]
|
|
|
|
public int $count = 0;
|
2024-07-03 17:47:02 -04:00
|
|
|
|
2024-09-24 00:42:26 -04:00
|
|
|
/**
|
|
|
|
* Render the component.
|
|
|
|
*/
|
2024-06-02 22:03:59 -04:00
|
|
|
public function render(): View
|
|
|
|
{
|
2024-09-24 00:42:26 -04:00
|
|
|
$this->result = $this->executeSearch($this->query);
|
|
|
|
$this->count = $this->countTotalResults($this->result);
|
|
|
|
|
|
|
|
return view('livewire.global-search');
|
2024-06-02 22:03:59 -04:00
|
|
|
}
|
2024-07-03 17:47:02 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Execute the search against each of the searchable models.
|
2025-01-30 20:49:56 -05:00
|
|
|
*
|
|
|
|
* @return array<string, Collection<int, mixed>>
|
2024-07-03 17:47:02 -04:00
|
|
|
*/
|
|
|
|
protected function executeSearch(string $query): array
|
|
|
|
{
|
|
|
|
$query = Str::trim($query);
|
|
|
|
|
2024-09-12 13:19:52 -04:00
|
|
|
if (Str::length($query) > 0) {
|
2024-09-24 00:42:26 -04:00
|
|
|
return [
|
2024-09-12 13:19:52 -04:00
|
|
|
'user' => $this->fetchUserResults($query),
|
|
|
|
'mod' => $this->fetchModResults($query),
|
2024-07-03 17:47:02 -04:00
|
|
|
];
|
|
|
|
}
|
|
|
|
|
2024-09-24 00:42:26 -04:00
|
|
|
return [];
|
2024-07-03 17:47:02 -04:00
|
|
|
}
|
|
|
|
|
2024-09-12 13:19:52 -04:00
|
|
|
/**
|
|
|
|
* Fetch the user search results.
|
2025-01-30 20:49:56 -05:00
|
|
|
*
|
|
|
|
* @return Collection<int, mixed>
|
2024-09-12 13:19:52 -04:00
|
|
|
*/
|
|
|
|
protected function fetchUserResults(string $query): Collection
|
|
|
|
{
|
2025-01-30 20:49:56 -05:00
|
|
|
/** @var Collection<int, mixed> $searchHits */
|
|
|
|
$searchHits = User::search($query)->raw()['hits'];
|
|
|
|
|
|
|
|
return collect($searchHits);
|
2024-09-12 13:19:52 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Fetch the mod search results.
|
2025-01-30 20:49:56 -05:00
|
|
|
*
|
|
|
|
* @return Collection<int, mixed>
|
2024-09-12 13:19:52 -04:00
|
|
|
*/
|
|
|
|
protected function fetchModResults(string $query): Collection
|
|
|
|
{
|
2025-01-30 20:49:56 -05:00
|
|
|
/** @var Collection<int, mixed> $searchHits */
|
|
|
|
$searchHits = Mod::search($query)->raw()['hits'];
|
|
|
|
|
|
|
|
return collect($searchHits);
|
2024-09-12 13:19:52 -04:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:47:02 -04:00
|
|
|
/**
|
|
|
|
* Count the total number of results across all models.
|
2025-01-30 20:49:56 -05:00
|
|
|
*
|
|
|
|
* @param array<string, Collection<int, mixed>> $results
|
2024-07-03 17:47:02 -04:00
|
|
|
*/
|
2024-09-12 13:19:52 -04:00
|
|
|
protected function countTotalResults(array $results): int
|
2024-07-03 17:47:02 -04:00
|
|
|
{
|
2025-01-30 20:49:56 -05:00
|
|
|
return (int) collect($results)->reduce(fn (int $carry, Collection $result): int => $carry + $result->count(), 0);
|
2024-07-03 17:47:02 -04:00
|
|
|
}
|
2024-06-02 22:03:59 -04:00
|
|
|
}
|