feat: adapt like/unlike songs to Plus

This commit is contained in:
Phan An 2024-01-06 23:28:31 +01:00
parent a8c78adf65
commit 31f0992512
8 changed files with 44 additions and 41 deletions

View file

@ -5,6 +5,7 @@ namespace App\Http\Controllers\API\Interaction;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\BatchInteractionRequest;
use App\Models\User;
use App\Repositories\SongRepository;
use App\Services\InteractionService;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Arr;
@ -12,19 +13,28 @@ use Illuminate\Support\Arr;
class BatchLikeController extends Controller
{
/** @param User $user */
public function __construct(private InteractionService $interactionService, protected ?Authenticatable $user)
{
public function __construct(
private SongRepository $songRepository,
private InteractionService $interactionService,
private ?Authenticatable $user
) {
}
public function store(BatchInteractionRequest $request)
{
$interactions = $this->interactionService->batchLike((array) $request->songs, $this->user);
$this->songRepository->getMany(ids: $request->songs, scopedUser: $this->user)
->each(fn ($song) => $this->authorize('interact', $song));
$interactions = $this->interactionService->batchLike(Arr::wrap($request->songs), $this->user);
return response()->json($interactions);
}
public function destroy(BatchInteractionRequest $request)
{
$this->songRepository->getMany(ids: $request->songs, scopedUser: $this->user)
->each(fn ($song) => $this->authorize('interact', $song));
$this->interactionService->batchUnlike(Arr::wrap($request->songs), $this->user);
return response()->noContent();

View file

@ -4,7 +4,9 @@ namespace App\Http\Controllers\API\Interaction;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\ToggleLikeSongRequest;
use App\Http\Resources\InteractionResource;
use App\Models\User;
use App\Repositories\SongRepository;
use App\Services\InteractionService;
use Illuminate\Contracts\Auth\Authenticatable;
@ -13,9 +15,13 @@ class ToggleLikeSongController extends Controller
/** @param User $user */
public function __invoke(
ToggleLikeSongRequest $request,
SongRepository $songRepository,
InteractionService $interactionService,
Authenticatable $user
?Authenticatable $user
) {
return response()->json($interactionService->toggleLike($request->song, $user));
$song = $songRepository->getOne($request->song, $user);
$this->authorize('interact', $song);
return InteractionResource::make($interactionService->toggleLike($request->song, $user));
}
}

View file

@ -50,6 +50,9 @@ class SongController extends Controller
public function update(SongUpdateRequest $request)
{
$this->songRepository->getMany(ids: $request->songs, scopedUser: $this->user)
->each(fn (Song $song) => $this->authorize('edit', $song));
$updatedSongs = $this->songService->updateSongs($request->songs, SongUpdateData::fromRequest($request));
$albums = $this->albumRepository->getMany($updatedSongs->pluck('album_id')->toArray());
@ -70,6 +73,9 @@ class SongController extends Controller
public function destroy(DeleteSongsRequest $request)
{
$this->songRepository->getMany(ids: $request->songs, scopedUser: $this->user)
->each(fn (Song $song) => $this->authorize('delete', $song));
$this->songService->deleteSongs($request->songs);
return response()->noContent();

View file

@ -11,7 +11,7 @@ class BatchInteractionRequest extends Request
public function rules(): array
{
return [
'songs' => 'required|array',
'songs' => 'required|array|exists:songs,id',
];
}
}

View file

@ -2,9 +2,6 @@
namespace App\Http\Requests\API;
use App\Facades\License;
use App\Models\Song;
/** @property-read array<string> $songs */
class DeleteSongsRequest extends Request
{
@ -15,16 +12,4 @@ class DeleteSongsRequest extends Request
'songs' => 'required|array|exists:songs,id',
];
}
public function authorize(): bool
{
if (License::isCommunity()) {
return $this->user()->is_admin;
}
return Song::query()
->whereIn('id', $this->songs)
->get()
->every(fn (Song $song): bool => $song->owner_id === $this->user()->id);
}
}

View file

@ -2,9 +2,6 @@
namespace App\Http\Requests\API;
use App\Facades\License;
use App\Models\Song;
/**
* @property array<string> $songs
* @property array<mixed> $data
@ -19,16 +16,4 @@ class SongUpdateRequest extends Request
'songs' => 'required|array|exists:songs,id',
];
}
public function authorize(): bool
{
if (License::isCommunity()) {
return $this->user()->is_admin;
}
return Song::query()
->whereIn('id', $this->songs)
->get()
->every(fn (Song $song): bool => $song->owner_id === $this->user()->id);
}
}

View file

@ -2,11 +2,7 @@
namespace App\Http\Requests\API;
use App\Models\Song;
/**
* @property Song $song
*/
/** @property-read string $song */
class ToggleLikeSongRequest extends Request
{
}

View file

@ -12,4 +12,19 @@ class SongPolicy
{
return License::isCommunity() || $song->is_public || $song->owner_id === $user->id;
}
public function interact(User $user, Song $song): bool
{
return License::isCommunity() || $song->is_public || $song->owner_id === $user->id;
}
public function delete(User $user, Song $song): bool
{
return (License::isCommunity() && $user->is_admin) || $song->owner_id === $user->id;
}
public function edit(User $user, Song $song): bool
{
return (License::isCommunity() && $user->is_admin) || $song->owner_id === $user->id;
}
}