Skip to content

Commit

Permalink
feat: support playlist folders (closes koel#1476)
Browse files Browse the repository at this point in the history
  • Loading branch information
phanan committed Sep 2, 2022
1 parent 1a35a7d commit 52dd323
Show file tree
Hide file tree
Showing 78 changed files with 1,494 additions and 374 deletions.
4 changes: 2 additions & 2 deletions app/Http/Controllers/API/PlaylistController.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public function store(PlaylistStoreRequest $request)

public function update(PlaylistUpdateRequest $request, Playlist $playlist)
{
$this->authorize('owner', $playlist);
$this->authorize('own', $playlist);

$playlist->update($request->only('name', 'rules'));

Expand All @@ -51,7 +51,7 @@ public function update(PlaylistUpdateRequest $request, Playlist $playlist)

public function destroy(Playlist $playlist)
{
$this->authorize('owner', $playlist);
$this->authorize('own', $playlist);

$playlist->delete();

Expand Down
6 changes: 3 additions & 3 deletions app/Http/Controllers/API/PlaylistSongController.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ class PlaylistSongController extends Controller
public function __construct(
private SmartPlaylistService $smartPlaylistService,
private PlaylistService $playlistService,
private Authenticatable $user
private ?Authenticatable $user
) {
}

public function index(Playlist $playlist)
{
$this->authorize('owner', $playlist);
$this->authorize('own', $playlist);

return response()->json(
$playlist->is_smart
Expand All @@ -34,7 +34,7 @@ public function index(Playlist $playlist)
/** @deprecated */
public function update(PlaylistSongUpdateRequest $request, Playlist $playlist)
{
$this->authorize('owner', $playlist);
$this->authorize('own', $playlist);

abort_if($playlist->is_smart, 403, 'A smart playlist cannot be populated manually.');

Expand Down
2 changes: 1 addition & 1 deletion app/Http/Controllers/Download/PlaylistController.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public function __construct(private DownloadService $downloadService)

public function show(Playlist $playlist)
{
$this->authorize('owner', $playlist);
$this->authorize('own', $playlist);

return response()->download($this->downloadService->from($playlist));
}
Expand Down
7 changes: 4 additions & 3 deletions app/Http/Controllers/V6/API/DataController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
namespace App\Http\Controllers\V6\API;

use App\Http\Controllers\Controller;
use App\Http\Resources\PlaylistFolderResource;
use App\Http\Resources\PlaylistResource;
use App\Http\Resources\UserResource;
use App\Models\User;
use App\Repositories\PlaylistRepository;
use App\Repositories\SettingRepository;
use App\Repositories\SongRepository;
use App\Services\ApplicationInformationService;
Expand All @@ -20,7 +21,6 @@ class DataController extends Controller
public function __construct(
private ITunesService $iTunesService,
private SettingRepository $settingRepository,
private PlaylistRepository $playlistRepository,
private SongRepository $songRepository,
private ApplicationInformationService $applicationInformationService,
private ?Authenticatable $user
Expand All @@ -31,7 +31,8 @@ public function index()
{
return response()->json([
'settings' => $this->user->is_admin ? $this->settingRepository->getAllAsKeyValueArray() : [],
'playlists' => $this->playlistRepository->getAllByCurrentUser(),
'playlists' => PlaylistResource::collection($this->user->playlists),
'playlist_folders' => PlaylistFolderResource::collection($this->user->playlist_folders),
'current_user' => UserResource::make($this->user, true),
'use_last_fm' => LastfmService::used(),
'use_you_tube' => YouTubeService::enabled(),
Expand Down
60 changes: 60 additions & 0 deletions app/Http/Controllers/V6/API/PlaylistController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

namespace App\Http\Controllers\V6\API;

use App\Http\Controllers\Controller;
use App\Http\Requests\API\PlaylistStoreRequest;
use App\Http\Requests\API\PlaylistUpdateRequest;
use App\Http\Resources\PlaylistResource;
use App\Models\Playlist;
use App\Models\User;
use App\Services\PlaylistService;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Support\Arr;

class PlaylistController extends Controller
{
/** @param User $user */
public function __construct(private PlaylistService $playlistService, private ?Authenticatable $user)
{
}

public function index()
{
return PlaylistResource::collection($this->user->playlists);
}

public function store(PlaylistStoreRequest $request)
{
$playlist = $this->playlistService->createPlaylist(
$request->name,
$this->user,
Arr::wrap($request->songs),
$request->rules
);

return PlaylistResource::make($playlist);
}

public function update(PlaylistUpdateRequest $request, Playlist $playlist)
{
$this->authorize('own', $playlist);

return PlaylistResource::make(
$this->playlistService->updatePlaylist(
$playlist,
$request->name,
Arr::wrap($request->rules)
)
);
}

public function destroy(Playlist $playlist)
{
$this->authorize('own', $playlist);

$playlist->delete();

return response()->noContent();
}
}
41 changes: 41 additions & 0 deletions app/Http/Controllers/V6/API/PlaylistFolderController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

namespace App\Http\Controllers\V6\API;

use App\Http\Controllers\Controller;
use App\Http\Controllers\V6\Requests\PlaylistFolderStoreRequest;
use App\Http\Controllers\V6\Requests\PlaylistFolderUpdateRequest;
use App\Http\Resources\PlaylistFolderResource;
use App\Models\PlaylistFolder;
use App\Models\User;
use App\Services\PlaylistFolderService;
use Illuminate\Contracts\Auth\Authenticatable;

class PlaylistFolderController extends Controller
{
/** @param User $user */
public function __construct(private PlaylistFolderService $service, private ?Authenticatable $user)
{
}

public function store(PlaylistFolderStoreRequest $request)
{
return PlaylistFolderResource::make($this->service->createFolder($this->user, $request->name));
}

public function update(PlaylistFolder $playlistFolder, PlaylistFolderUpdateRequest $request)
{
$this->authorize('own', $playlistFolder);

return PlaylistFolderResource::make($this->service->updateFolder($playlistFolder, $request->name));
}

public function destroy(PlaylistFolder $playlistFolder)
{
$this->authorize('own', $playlistFolder);

$playlistFolder->delete();

return response()->noContent();
}
}
35 changes: 35 additions & 0 deletions app/Http/Controllers/V6/API/PlaylistFolderPlaylistController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace App\Http\Controllers\V6\API;

use App\Http\Controllers\Controller;
use App\Http\Controllers\V6\Requests\PlaylistFolderPlaylistDestroyRequest;
use App\Http\Controllers\V6\Requests\PlaylistFolderPlaylistStoreRequest;
use App\Models\PlaylistFolder;
use App\Services\PlaylistFolderService;
use Illuminate\Support\Arr;

class PlaylistFolderPlaylistController extends Controller
{
public function __construct(private PlaylistFolderService $service)
{
}

public function store(PlaylistFolder $playlistFolder, PlaylistFolderPlaylistStoreRequest $request)
{
$this->authorize('own', $playlistFolder);

$this->service->addPlaylistsToFolder($playlistFolder, Arr::wrap($request->playlists));

return response()->noContent();
}

public function destroy(PlaylistFolder $playlistFolder, PlaylistFolderPlaylistDestroyRequest $request)
{
$this->authorize('own', $playlistFolder);

$this->service->movePlaylistsToRootLevel(Arr::wrap($request->playlists));

return response()->noContent();
}
}
10 changes: 5 additions & 5 deletions app/Http/Controllers/V6/API/PlaylistSongController.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public function __construct(

public function index(Playlist $playlist)
{
$this->authorize('owner', $playlist);
$this->authorize('own', $playlist);

return SongResource::collection(
$playlist->is_smart
Expand All @@ -36,9 +36,9 @@ public function index(Playlist $playlist)
);
}

public function add(Playlist $playlist, AddSongsToPlaylistRequest $request)
public function store(Playlist $playlist, AddSongsToPlaylistRequest $request)
{
$this->authorize('owner', $playlist);
$this->authorize('own', $playlist);

abort_if($playlist->is_smart, Response::HTTP_FORBIDDEN);

Expand All @@ -47,9 +47,9 @@ public function add(Playlist $playlist, AddSongsToPlaylistRequest $request)
return response()->noContent();
}

public function remove(Playlist $playlist, RemoveSongsFromPlaylistRequest $request)
public function destroy(Playlist $playlist, RemoveSongsFromPlaylistRequest $request)
{
$this->authorize('owner', $playlist);
$this->authorize('own', $playlist);

abort_if($playlist->is_smart, Response::HTTP_FORBIDDEN);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
namespace App\Http\Controllers\V6\Requests;

use App\Http\Requests\API\Request;
use App\Models\Song;
use Illuminate\Validation\Rule;

/**
* @property-read array<string> $songs
Expand All @@ -14,7 +16,7 @@ public function rules(): array
{
return [
'songs' => 'required|array',
'songs.*' => 'exists:songs,id',
'songs.*' => [Rule::exists(Song::class, 'id')],
];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace App\Http\Controllers\V6\Requests;

use App\Http\Requests\API\Request;
use App\Models\Playlist;
use App\Rules\AllPlaylistsBelongToUser;
use Illuminate\Validation\Rule;

/**
* @property-read array<int>|int $playlists
*/
class PlaylistFolderPlaylistDestroyRequest extends Request
{
/** @return array<mixed> */
public function rules(): array
{
return [
'playlists' => ['required', 'array', new AllPlaylistsBelongToUser($this->user())],
'playlists.*' => [Rule::exists(Playlist::class, 'id')],
];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace App\Http\Controllers\V6\Requests;

use App\Http\Requests\API\Request;
use App\Models\Playlist;
use App\Rules\AllPlaylistsBelongToUser;
use Illuminate\Validation\Rule;

/**
* @property-read array<int>|int $playlists
*/
class PlaylistFolderPlaylistStoreRequest extends Request
{
/** @return array<mixed> */
public function rules(): array
{
return [
'playlists' => ['required', 'array', new AllPlaylistsBelongToUser($this->user())],
'playlists.*' => [Rule::exists(Playlist::class, 'id')],
];
}
}
19 changes: 19 additions & 0 deletions app/Http/Controllers/V6/Requests/PlaylistFolderStoreRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace App\Http\Controllers\V6\Requests;

use App\Http\Requests\API\Request;

/**
* @property-read string $name
*/
class PlaylistFolderStoreRequest extends Request
{
/** @return array<mixed> */
public function rules(): array
{
return [
'name' => 'required|string|max:191',
];
}
}
19 changes: 19 additions & 0 deletions app/Http/Controllers/V6/Requests/PlaylistFolderUpdateRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace App\Http\Controllers\V6\Requests;

use App\Http\Requests\API\Request;

/**
* @property-read string $name
*/
class PlaylistFolderUpdateRequest extends Request
{
/** @return array<mixed> */
public function rules(): array
{
return [
'name' => 'required|string|max:191',
];
}
}
4 changes: 4 additions & 0 deletions app/Http/Requests/API/PlaylistUpdateRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

use App\Rules\ValidSmartPlaylistRulePayload;

/**
* @property-read $name
* @property-read array $rules
*/
class PlaylistUpdateRequest extends Request
{
/** @return array<mixed> */
Expand Down
26 changes: 26 additions & 0 deletions app/Http/Resources/PlaylistFolderResource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace App\Http\Resources;

use App\Models\PlaylistFolder;
use Illuminate\Http\Resources\Json\JsonResource;

class PlaylistFolderResource extends JsonResource
{
public function __construct(private PlaylistFolder $folder)
{
parent::__construct($folder);
}

/** @return array<mixed> */
public function toArray($request): array
{
return [
'type' => 'playlist_folders',
'id' => $this->folder->id,
'name' => $this->folder->name,
'user_id' => $this->folder->user_id,
'created_at' => $this->folder->created_at,
];
}
}
Loading

0 comments on commit 52dd323

Please sign in to comment.