From f2e9adf7f187404eeda642e0552979395988b196 Mon Sep 17 00:00:00 2001 From: Amirmahdi Nourkazemi Date: Fri, 12 Jun 2026 16:55:19 +0330 Subject: [PATCH] feat: add group media and music --- app/Http/Controllers/CategoryController.php | 27 +++++++++++++++ .../Controllers/MusicCategoryController.php | 34 +++++++++++++++++++ routes/api.php | 4 +++ 3 files changed, 65 insertions(+) diff --git a/app/Http/Controllers/CategoryController.php b/app/Http/Controllers/CategoryController.php index cc30392..315fb99 100644 --- a/app/Http/Controllers/CategoryController.php +++ b/app/Http/Controllers/CategoryController.php @@ -65,6 +65,33 @@ public function show($id) return response()->json($category); } + // Category with each of its sub-categories and that sub-category's medias. + public function grouped($id) + { + $category = Category::with(['subcategories' => function ($q) { + $q->orderBy('name')->with(['media' => function ($m) { + $m->with(['image', 'detailImage', 'tags'])->latest(); + }]); + }])->findOrFail($id); + + return response()->json([ + 'category' => [ + 'id' => $category->id, + 'title' => $category->name, + 'description' => $category->description, + 'icon_url' => $category->icon_url, + ], + 'sub_categories' => $category->subcategories->map(fn ($sub) => [ + 'sub_category' => [ + 'id' => $sub->id, + 'title' => $sub->name, + 'description' => $sub->description, + ], + 'medias' => $sub->media, + ])->values(), + ]); + } + public function update(Request $request, $id) { $category = Category::findOrFail($id); diff --git a/app/Http/Controllers/MusicCategoryController.php b/app/Http/Controllers/MusicCategoryController.php index 273e427..bcf9370 100644 --- a/app/Http/Controllers/MusicCategoryController.php +++ b/app/Http/Controllers/MusicCategoryController.php @@ -89,6 +89,40 @@ public function show($id) return response()->json($category); } + // Category with each of its sub-categories and that sub-category's playlists. + public function grouped($id) + { + $category = MusicCategory::with([ + 'image', + 'subcategories' => function ($q) { + $q->orderBy('order')->with([ + 'image', + 'playlists' => function ($p) { + $p->where('is_active', true)->with('image')->orderBy('order'); + }, + ]); + }, + ])->findOrFail($id); + + return response()->json([ + 'category' => [ + 'id' => $category->id, + 'title' => $category->name, + 'description' => $category->description, + 'image_url' => $category->image?->url, + ], + 'sub_categories' => $category->subcategories->map(fn ($sub) => [ + 'sub_category' => [ + 'id' => $sub->id, + 'title' => $sub->name, + 'description' => $sub->description, + 'image_url' => $sub->image?->url, + ], + 'playlists' => $sub->playlists, + ])->values(), + ]); + } + public function update(Request $request, $id) { $category = MusicCategory::findOrFail($id); diff --git a/routes/api.php b/routes/api.php index 1d0ff16..72d3904 100644 --- a/routes/api.php +++ b/routes/api.php @@ -241,6 +241,8 @@ Route::post('/media/{id}/note', [MediaController::class, 'storeNote']); // Media categories + // Category with its sub-categories, each carrying its medias. + Route::get('categories/{id}/grouped', [CategoryController::class, 'grouped']); // Explicit POST update so an icon image can be uploaded (multipart can't ride a PUT). Route::post('categories/{id}', [CategoryController::class, 'update']); Route::apiResource('categories', CategoryController::class); @@ -252,6 +254,8 @@ // Music Categories + // Category with its sub-categories, each carrying its playlists. + Route::get('music-categories/{id}/grouped', [MusicCategoryController::class, 'grouped']); Route::apiResource('music-categories', MusicCategoryController::class); Route::get('public/music-categories', [MusicCategoryController::class, 'index']);