koel/app/Services/SearchService.php

81 lines
2.6 KiB
PHP
Raw Normal View History

2020-12-24 12:41:18 +00:00
<?php
namespace App\Services;
2023-06-05 21:46:41 +00:00
use App\Builders\SongBuilder;
use App\Models\Album;
use App\Models\Artist;
use App\Models\Podcast;
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;
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
{
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-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(
2024-10-17 15:04:51 +00:00
ids: $repository->modelClass::search($keywords)->get()->take($count)->pluck('id')->all(), // @phpstan-ignore-line
2024-06-08 18:15:24 +00:00
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)
->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
}