feat: add many playlist for music

This commit is contained in:
2026-06-01 00:40:32 +03:30
parent 695efcc452
commit b3a7edf3a5
8 changed files with 162 additions and 51 deletions
+60 -37
View File
@@ -15,7 +15,7 @@ public function getAllMusic()
{
$userId = auth()->id();
$music = Music::with(['image', 'playlist'])
$music = Music::with(['image', 'playlists'])
->where('type', 'public')
->orWhere(function($query) use ($userId) {
$query->where('type', 'private')
@@ -33,7 +33,7 @@ public function index()
{
$userId = auth()->id();
$music = Music::with(['image', 'playlist'])
$music = Music::with(['image', 'playlists'])
->where('type', 'public')
->orWhere(function($query) use ($userId) {
$query->where('type', 'private')
@@ -51,19 +51,19 @@ public function index()
public function getMusicByPlaylist($playlistId)
{
$playlist = MusicPlaylist::findOrFail($playlistId);
$music = Music::where('playlist_id', $playlistId)
->where('is_active', true)
$music = $playlist->musics()
->where('music.is_active', true)
->with(['image', 'tags'])
->orderBy('order')
->orderBy('music_playlist.order')
->get();
return response()->json([
'playlist' => $playlist->load('image'),
'musics' => $music
]);
}
public function addToPlaylist(Request $request, $musicId)
{
$music = Music::where('id', $musicId)
@@ -72,48 +72,57 @@ public function addToPlaylist(Request $request, $musicId)
->orWhere('user_id', auth()->id());
})
->firstOrFail();
$data = $request->validate([
'playlist_id' => 'required|exists:music_playlists,id',
'order' => 'nullable|integer',
]);
$music->update([
'playlist_id' => $data['playlist_id'],
'order' => $data['order'] ?? $music->order,
$order = $data['order'] ?? $this->getNextOrderInPlaylist($data['playlist_id']);
// Add (or update its order) without removing the music from other playlists.
$music->playlists()->syncWithoutDetaching([
$data['playlist_id'] => ['order' => $order],
]);
return response()->json([
'message' => 'Music added to playlist successfully',
'music' => $music->load(['image', 'playlist'])
'music' => $music->load(['image', 'playlists'])
]);
}
public function removeFromPlaylist($musicId)
public function removeFromPlaylist(Request $request, $musicId)
{
$music = Music::where('id', $musicId)
->where('user_id', auth()->id())
->firstOrFail();
$music->update(['playlist_id' => null]);
$data = $request->validate([
'playlist_id' => 'required|exists:music_playlists,id',
]);
$music->playlists()->detach($data['playlist_id']);
return response()->json(['message' => 'Music removed from playlist']);
}
public function updateOrder(Request $request)
{
$data = $request->validate([
'playlist_id' => 'required|exists:music_playlists,id',
'musics' => 'required|array',
'musics.*.id' => 'required|exists:music,id',
'musics.*.order' => 'required|integer',
]);
$playlist = MusicPlaylist::findOrFail($data['playlist_id']);
foreach ($data['musics'] as $item) {
Music::where('id', $item['id'])
->where('user_id', auth()->id())
->update(['order' => $item['order']]);
$playlist->musics()->updateExistingPivot($item['id'], [
'order' => $item['order'],
]);
}
return response()->json(['message' => 'Order updated successfully']);
}
// ✅ Upload music
@@ -126,7 +135,9 @@ public function store(Request $request)
'file' => 'required|mimes:mp3,wav,ogg,flac|max:20971520',
'type' => 'nullable|in:public,private',
'image_id' => 'nullable|exists:images,id',
'playlist_id' => 'nullable|exists:music_playlists,id',
'playlist_id' => 'nullable|exists:music_playlists,id', // single (backward compatible)
'playlist_ids' => 'nullable|array', // multiple
'playlist_ids.*' => 'integer|exists:music_playlists,id',
'duration' => 'nullable|integer|min:1', // validates mm:ss or hh:mm:ss
]);
@@ -161,15 +172,26 @@ public function store(Request $request)
'file_path' => $path,
'type' => $data['type'] ?? 'private',
'image_id' => $data['image_id'] ?? null,
'playlist_id' => $data['playlist_id'] ?? null,
'duration' => $data['duration'] ?? null, // Store as string
'order' => $this->getNextOrderInPlaylist($data['playlist_id'] ?? null),
'is_active' => true,
]);
// Merge single + multiple playlist inputs into a unique list.
$playlistIds = collect($data['playlist_ids'] ?? [])
->push($data['playlist_id'] ?? null)
->filter()
->unique()
->values();
foreach ($playlistIds as $playlistId) {
$music->playlists()->syncWithoutDetaching([
$playlistId => ['order' => $this->getNextOrderInPlaylist($playlistId)],
]);
}
return response()->json([
'message' => 'Music uploaded successfully',
'music' => $music->load(['image', 'playlist', 'tags']),
'music' => $music->load(['image', 'playlists', 'tags']),
'url' => asset('storage/' . $path),
], 201);
@@ -192,8 +214,11 @@ private function getNextOrderInPlaylist($playlistId)
if (!$playlistId) {
return 0;
}
$maxOrder = Music::where('playlist_id', $playlistId)->max('order');
$maxOrder = \DB::table('music_playlist')
->where('playlist_id', $playlistId)
->max('order');
return ($maxOrder ?? -1) + 1;
}
@@ -209,9 +234,7 @@ public function update(Request $request, $id)
'type' => 'nullable|in:public,private',
'file' => 'nullable|mimes:mp3,wav,ogg,flac|max:20971520',
'image_id' => 'nullable|exists:images,id',
'playlist_id' => 'nullable|exists:music_playlists,id',
'duration' => 'nullable|integer|min:1',
'order' => 'nullable|integer',
'is_active' => 'nullable|boolean',
]);
@@ -228,7 +251,7 @@ public function update(Request $request, $id)
return response()->json([
'message' => 'Music updated successfully',
'music' => $music->load(['image', 'playlist', 'tags']),
'music' => $music->load(['image', 'playlists', 'tags']),
'url' => asset('storage/' . $music->file_path),
]);
@@ -247,8 +270,8 @@ public function show($id)
$userId = auth()->id();
$music = Music::with([
'image',
'playlist',
'image',
'playlists',
'tags',
'comments' => function($query) {
$query->with('user')->latest()->limit(10);