2018-11-03 23:25:08 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace App\Services;
|
|
|
|
|
2024-01-12 14:41:02 +00:00
|
|
|
use App\Builders\SongBuilder;
|
2021-10-08 16:23:45 +00:00
|
|
|
use App\Exceptions\NonSmartPlaylistException;
|
2024-01-12 14:41:02 +00:00
|
|
|
use App\Facades\License;
|
2018-11-03 23:25:08 +00:00
|
|
|
use App\Models\Playlist;
|
|
|
|
use App\Models\Song;
|
2022-08-01 11:03:58 +00:00
|
|
|
use App\Models\User;
|
2022-11-08 17:38:28 +00:00
|
|
|
use App\Values\SmartPlaylistRule as Rule;
|
|
|
|
use App\Values\SmartPlaylistRuleGroup as RuleGroup;
|
|
|
|
use App\Values\SmartPlaylistSqlElements as SqlElements;
|
2021-10-08 16:23:45 +00:00
|
|
|
use Illuminate\Support\Collection;
|
2018-11-03 23:25:08 +00:00
|
|
|
|
|
|
|
class SmartPlaylistService
|
|
|
|
{
|
2022-07-06 11:05:21 +00:00
|
|
|
/** @return Collection|array<array-key, Song> */
|
2022-08-01 11:03:58 +00:00
|
|
|
public function getSongs(Playlist $playlist, ?User $user = null): Collection
|
2018-11-03 23:25:08 +00:00
|
|
|
{
|
2021-10-08 16:23:45 +00:00
|
|
|
throw_unless($playlist->is_smart, NonSmartPlaylistException::create($playlist));
|
2018-11-03 23:25:08 +00:00
|
|
|
|
2024-01-12 14:41:02 +00:00
|
|
|
$query = Song::query()
|
|
|
|
->withMetaFor($user ?? $playlist->user)
|
|
|
|
->when(
|
|
|
|
$playlist->own_songs_only && License::isPlus(),
|
|
|
|
static fn (SongBuilder $query) => $query->where('songs.owner_id', $playlist->user_id)
|
|
|
|
);
|
2018-11-03 23:25:08 +00:00
|
|
|
|
2022-11-08 17:38:28 +00:00
|
|
|
$playlist->rule_groups->each(static function (RuleGroup $group, int $index) use ($query): void {
|
2024-01-12 14:41:02 +00:00
|
|
|
$whereClosure = static function (SongBuilder $subQuery) use ($group): void {
|
2022-11-08 17:38:28 +00:00
|
|
|
$group->rules->each(static function (Rule $rule) use ($subQuery): void {
|
|
|
|
$tokens = SqlElements::fromRule($rule);
|
|
|
|
$subQuery->{$tokens->clause}(...$tokens->parameters);
|
2021-10-08 16:23:45 +00:00
|
|
|
});
|
2024-01-12 14:41:02 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
$query->when(
|
|
|
|
$index === 0,
|
|
|
|
static fn (SongBuilder $query) => $query->where($whereClosure),
|
|
|
|
static fn (SongBuilder $query) => $query->orWhere($whereClosure)
|
|
|
|
);
|
2018-11-03 23:25:08 +00:00
|
|
|
});
|
2018-11-18 21:50:03 +00:00
|
|
|
|
2022-07-06 11:05:21 +00:00
|
|
|
return $query->orderBy('songs.title')->get();
|
2018-11-03 23:25:08 +00:00
|
|
|
}
|
|
|
|
}
|