From f2e9adf7f187404eeda642e0552979395988b196 Mon Sep 17 00:00:00 2001 From: Amirmahdi Nourkazemi Date: Fri, 12 Jun 2026 16:55:19 +0330 Subject: [PATCH 1/4] 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']); From b3ce699159c75465b1b7bce5a0543480cdd73b42 Mon Sep 17 00:00:00 2001 From: Amirmahdi Nourkazemi Date: Fri, 12 Jun 2026 20:13:52 +0330 Subject: [PATCH 2/4] feat: add type --- app/Http/Controllers/CategoryController.php | 1 + app/Http/Controllers/MusicCategoryController.php | 1 + 2 files changed, 2 insertions(+) diff --git a/app/Http/Controllers/CategoryController.php b/app/Http/Controllers/CategoryController.php index 315fb99..33209c8 100644 --- a/app/Http/Controllers/CategoryController.php +++ b/app/Http/Controllers/CategoryController.php @@ -80,6 +80,7 @@ public function grouped($id) 'title' => $category->name, 'description' => $category->description, 'icon_url' => $category->icon_url, + 'type' => $category->type, ], 'sub_categories' => $category->subcategories->map(fn ($sub) => [ 'sub_category' => [ diff --git a/app/Http/Controllers/MusicCategoryController.php b/app/Http/Controllers/MusicCategoryController.php index bcf9370..b4e2d50 100644 --- a/app/Http/Controllers/MusicCategoryController.php +++ b/app/Http/Controllers/MusicCategoryController.php @@ -110,6 +110,7 @@ public function grouped($id) 'title' => $category->name, 'description' => $category->description, 'image_url' => $category->image?->url, + 'type' => 'playlist', ], 'sub_categories' => $category->subcategories->map(fn ($sub) => [ 'sub_category' => [ From 81aba7232a544b41184d7f2927e5d689ee9174ac Mon Sep 17 00:00:00 2001 From: Amirmahdi Nourkazemi Date: Fri, 12 Jun 2026 20:32:35 +0330 Subject: [PATCH 3/4] fix --- app/Http/Controllers/CategoryController.php | 4 ++-- app/Http/Controllers/MusicCategoryController.php | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/Http/Controllers/CategoryController.php b/app/Http/Controllers/CategoryController.php index 33209c8..5b3fc79 100644 --- a/app/Http/Controllers/CategoryController.php +++ b/app/Http/Controllers/CategoryController.php @@ -77,7 +77,7 @@ public function grouped($id) return response()->json([ 'category' => [ 'id' => $category->id, - 'title' => $category->name, + 'name' => $category->name, 'description' => $category->description, 'icon_url' => $category->icon_url, 'type' => $category->type, @@ -85,7 +85,7 @@ public function grouped($id) 'sub_categories' => $category->subcategories->map(fn ($sub) => [ 'sub_category' => [ 'id' => $sub->id, - 'title' => $sub->name, + 'name' => $sub->name, 'description' => $sub->description, ], 'medias' => $sub->media, diff --git a/app/Http/Controllers/MusicCategoryController.php b/app/Http/Controllers/MusicCategoryController.php index b4e2d50..7f3ac64 100644 --- a/app/Http/Controllers/MusicCategoryController.php +++ b/app/Http/Controllers/MusicCategoryController.php @@ -107,15 +107,15 @@ public function grouped($id) return response()->json([ 'category' => [ 'id' => $category->id, - 'title' => $category->name, + 'name' => $category->name, 'description' => $category->description, - 'image_url' => $category->image?->url, + 'icon_url' => $category->image?->url, 'type' => 'playlist', ], 'sub_categories' => $category->subcategories->map(fn ($sub) => [ 'sub_category' => [ 'id' => $sub->id, - 'title' => $sub->name, + 'name' => $sub->name, 'description' => $sub->description, 'image_url' => $sub->image?->url, ], From eca1756e76295980c1bf3d5a535183d0741bbdab Mon Sep 17 00:00:00 2001 From: Amirmahdi Nourkazemi Date: Fri, 12 Jun 2026 20:54:03 +0330 Subject: [PATCH 4/4] feat: add media get route newest --- app/Http/Controllers/MediaController.php | 28 +++++++++++++++++++++--- routes/api.php | 1 + 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/MediaController.php b/app/Http/Controllers/MediaController.php index 7042d04..930f3db 100644 --- a/app/Http/Controllers/MediaController.php +++ b/app/Http/Controllers/MediaController.php @@ -201,9 +201,31 @@ public function index(Request $request) }); } - return response()->json( - $query->orderBy('created_at', 'desc')->get() - ); + $query->orderBy('created_at', 'desc'); + + // Optional cap: ?count=10 returns only the first 10 items. + if ($request->filled('count')) { + $query->limit(max(1, (int) $request->input('count'))); + } + + return response()->json($query->get()); +} + +// NEWEST media, paginated (?per_page=, ?page=). Same visibility scope as index. +public function newest(Request $request) +{ + $perPage = (int) $request->input('per_page', 20); + $perPage = max(1, min($perPage, 100)); + + $media = Media::with(['image', 'detailImage', 'categories', 'subCategories', 'myNote', 'tags']) + ->where(function ($q) { + $q->where('visibility', 'public') + ->orWhere('user_id', auth()->id()); + }) + ->orderBy('created_at', 'desc') + ->paginate($perPage); + + return response()->json($media); } public function submitFeedback(Request $request, $mediaId) diff --git a/routes/api.php b/routes/api.php index 72d3904..5205588 100644 --- a/routes/api.php +++ b/routes/api.php @@ -223,6 +223,7 @@ ///media Route::get('/media/filters', [MediaController::class, 'filters']); Route::get('/media/popular', [MediaController::class, 'popular']); + Route::get('/media/newest', [MediaController::class, 'newest']); Route::get('/media/recently-played', [MediaController::class, 'recentlyPlayed']); Route::post('/media', [MediaController::class, 'store']); Route::get('/media', [MediaController::class, 'index']);