. */ namespace Poniverse\Ponyfm\Http\Controllers\Api\Web; use Illuminate\Database\Eloquent\ModelNotFoundException; use Poniverse\Ponyfm\Commands\AddTrackToPlaylistCommand; use Poniverse\Ponyfm\Commands\CreatePlaylistCommand; use Poniverse\Ponyfm\Commands\DeletePlaylistCommand; use Poniverse\Ponyfm\Commands\EditPlaylistCommand; use Poniverse\Ponyfm\Commands\RemoveTrackFromPlaylistCommand; use Poniverse\Ponyfm\Http\Controllers\ApiControllerBase; use Poniverse\Ponyfm\Models\Image; use Poniverse\Ponyfm\Models\Playlist; use Poniverse\Ponyfm\Models\ResourceLogItem; use Auth; use Input; use Response; use Poniverse\Ponyfm\Models\Track; class PlaylistsController extends ApiControllerBase { public function postCreate() { return $this->execute(new CreatePlaylistCommand(Input::all())); } public function postEdit($id) { return $this->execute(new EditPlaylistCommand($id, Input::all())); } public function postDelete($id) { return $this->execute(new DeletePlaylistCommand($id, Input::all())); } public function postAddTrack($id) { return $this->execute(new AddTrackToPlaylistCommand($id, Input::get('track_id'))); } public function postRemoveTrack($id) { return $this->execute(new RemoveTrackFromPlaylistCommand($id, Input::get('track_id'))); } public function getIndex() { $page = Input::has('page') ? Input::get('page') : 1; $query = Playlist::summary() ->with('user', 'user.avatar', 'tracks', 'tracks.cover', 'tracks.user', 'tracks.user.avatar', 'tracks.album', 'tracks.album.user') ->userDetails() // A playlist with only one track is not much of a list. ->where('track_count', '>', 1) ->whereIsPublic(true); $this->applyFilters($query); $count = $query->count(); $perPage = 40; $query->skip(($page - 1) * $perPage)->take($perPage); $playlists = []; foreach ($query->get() as $playlist) { $playlists[] = Playlist::mapPublicPlaylistSummary($playlist); } return Response::json([ "playlists" => $playlists, "current_page" => $page, "total_pages" => ceil($count / $perPage) ], 200); } public function getShow($id) { $playlist = Playlist::with([ 'tracks.user', 'tracks.genre', 'tracks.cover', 'tracks.album', 'tracks' => function ($query) { $query->userDetails(); }, 'tracks.trackFiles', 'comments', 'comments.user' ])->userDetails()->find($id); if (!$playlist || !$playlist->canView(Auth::user())) { App::abort('404'); } if (Input::get('log')) { ResourceLogItem::logItem('playlist', $id, ResourceLogItem::VIEW); $playlist->view_count++; } return Response::json(Playlist::mapPublicPlaylistShow($playlist), 200); } public function getCachedPlaylist($id, $format) { // Validation try { /** @var $playlist Playlist */ $playlist = Playlist::with('tracks.trackFiles')->findOrFail($id); } catch (ModelNotFoundException $e) { return $this->notFound('Playlist not found!'); } if ((!$playlist->is_public && !Auth::check()) || (!$playlist->is_public && ($playlist->user_id !== Auth::user()->id))) { return $this->notFound('Playlist not found!'); } if (!in_array($format, Track::$CacheableFormats)) { return $this->notFound('Format not found!'); } $trackCount = $playlist->countDownloadableTracks($format); $availableFilesCount = $playlist->countAvailableTrackFiles($format); if ($trackCount === $availableFilesCount) { $url = $playlist->getDownloadUrl($format); } else { $playlist->encodeCacheableTrackFiles($format); $url = null; } return Response::json(['url' => $url], 200); } public function getPinned() { $query = Playlist ::userDetails() ->with('tracks', 'tracks.cover', 'tracks.user', 'user') ->join('pinned_playlists', function ($join) { $join->on('playlist_id', '=', 'playlists.id'); }) ->where('pinned_playlists.user_id', '=', Auth::user()->id) ->orderBy('title', 'asc') ->select('playlists.*') ->get(); $playlists = []; foreach ($query as $playlist) { $mapped = Playlist::mapPublicPlaylistSummary($playlist); $mapped['description'] = $playlist->description; $mapped['is_pinned'] = true; $playlists[] = $mapped; } return Response::json($playlists, 200); } public function getOwned() { $query = Playlist::summary() ->with('pins', 'tracks', 'tracks.cover') ->where('user_id', Auth::user()->id) ->orderBy('title', 'asc') ->get(); $playlists = []; foreach ($query as $playlist) { $playlists[] = [ 'id' => $playlist->id, 'title' => $playlist->title, 'slug' => $playlist->slug, 'created_at' => $playlist->created_at, 'description' => $playlist->description, 'url' => $playlist->url, 'covers' => [ 'small' => $playlist->getCoverUrl(Image::SMALL), 'normal' => $playlist->getCoverUrl(Image::NORMAL) ], 'is_pinned' => $playlist->hasPinFor(Auth::user()->id), 'is_public' => $playlist->is_public == 1, 'track_ids' => $playlist->tracks->pluck('id') ]; } return Response::json($playlists, 200); } private function applyFilters($query) { if (Input::has('order')) { $order = \Input::get('order'); $parts = explode(',', $order); $query->orderBy($parts[0], $parts[1]); } return $query; } }