2020-12-24 12:41:18 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace App\Services;
|
|
|
|
|
2023-06-05 21:46:41 +00:00
|
|
|
use App\Builders\SongBuilder;
|
2020-12-25 11:52:28 +00:00
|
|
|
use App\Models\Album;
|
|
|
|
use App\Models\Artist;
|
2024-05-31 05:40:34 +00:00
|
|
|
use App\Models\Podcast;
|
2020-12-25 11:52:28 +00:00
|
|
|
use App\Models\Song;
|
2023-06-05 21:46:41 +00:00
|
|
|
use App\Models\User;
|
2020-12-24 12:41:18 +00:00
|
|
|
use App\Repositories\AlbumRepository;
|
|
|
|
use App\Repositories\ArtistRepository;
|
2024-05-19 05:49:42 +00:00
|
|
|
use App\Repositories\PodcastRepository;
|
2024-06-08 18:15:24 +00:00
|
|
|
use App\Repositories\Repository;
|
2020-12-24 12:41:18 +00:00
|
|
|
use App\Repositories\SongRepository;
|
2023-06-05 21:46:41 +00:00
|
|
|
use App\Values\ExcerptSearchResult;
|
2020-12-25 11:52:28 +00:00
|
|
|
use Illuminate\Support\Collection;
|
2024-06-08 18:15:24 +00:00
|
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
use Throwable;
|
2020-12-24 12:41:18 +00:00
|
|
|
|
|
|
|
class SearchService
|
|
|
|
{
|
2020-12-25 11:52:28 +00:00
|
|
|
public const DEFAULT_EXCERPT_RESULT_COUNT = 6;
|
2023-06-05 21:46:41 +00:00
|
|
|
public const DEFAULT_MAX_SONG_RESULT_COUNT = 500;
|
2020-12-25 11:52:28 +00:00
|
|
|
|
2020-12-24 12:41:18 +00:00
|
|
|
public function __construct(
|
2024-04-18 14:36:28 +00:00
|
|
|
private readonly SongRepository $songRepository,
|
|
|
|
private readonly AlbumRepository $albumRepository,
|
2024-05-19 05:49:42 +00:00
|
|
|
private readonly ArtistRepository $artistRepository,
|
|
|
|
private readonly PodcastRepository $podcastRepository
|
2020-12-24 12:41:18 +00:00
|
|
|
) {
|
|
|
|
}
|
|
|
|
|
2023-06-05 21:46:41 +00:00
|
|
|
public function excerptSearch(
|
|
|
|
string $keywords,
|
|
|
|
int $count = self::DEFAULT_EXCERPT_RESULT_COUNT
|
|
|
|
): ExcerptSearchResult {
|
|
|
|
return ExcerptSearchResult::make(
|
2024-06-08 18:15:24 +00:00
|
|
|
self::excerptScoutSearch($keywords, $count, $this->songRepository),
|
|
|
|
self::excerptScoutSearch($keywords, $count, $this->artistRepository),
|
|
|
|
self::excerptScoutSearch($keywords, $count, $this->albumRepository),
|
|
|
|
self::excerptScoutSearch($keywords, $count, $this->podcastRepository),
|
2023-06-05 21:46:41 +00:00
|
|
|
);
|
2020-12-24 12:41:18 +00:00
|
|
|
}
|
2020-12-24 22:35:39 +00:00
|
|
|
|
2024-06-08 18:15:24 +00:00
|
|
|
/**
|
|
|
|
* @param SongRepository|AlbumRepository|ArtistRepository|PodcastRepository $repository
|
|
|
|
*
|
|
|
|
* @return Collection|array<array-key, Song|Artist|Album|Podcast>
|
|
|
|
*/
|
|
|
|
private static function excerptScoutSearch(string $keywords, int $count, Repository $repository): Collection
|
|
|
|
{
|
|
|
|
try {
|
|
|
|
return $repository->getMany(
|
|
|
|
ids: $repository->model::search($keywords)->get()->take($count)->pluck('id')->all(),
|
|
|
|
preserveOrder: true,
|
|
|
|
);
|
|
|
|
} catch (Throwable $e) {
|
|
|
|
Log::error('Scout search failed', ['exception' => $e]);
|
|
|
|
|
|
|
|
return new Collection();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-05 21:46:41 +00:00
|
|
|
/** @return Collection|array<array-key, Song> */
|
|
|
|
public function searchSongs(
|
|
|
|
string $keywords,
|
|
|
|
?User $scopedUser = null,
|
|
|
|
int $limit = self::DEFAULT_MAX_SONG_RESULT_COUNT
|
|
|
|
): Collection {
|
|
|
|
return Song::search($keywords)
|
2024-06-05 15:49:23 +00:00
|
|
|
->query(
|
|
|
|
static fn (SongBuilder $builder) => $builder
|
|
|
|
->forUser($scopedUser ?? auth()->user())
|
|
|
|
->withMeta()
|
|
|
|
->limit($limit)
|
|
|
|
)
|
2023-06-05 21:46:41 +00:00
|
|
|
->get();
|
2020-12-24 22:35:39 +00:00
|
|
|
}
|
2020-12-24 12:41:18 +00:00
|
|
|
}
|