validate([ 'type' => 'required|string|in:music,media,playlist', 'id' => 'required|integer', ]); $model = $this->getModel($request->type, $request->id); if (!$model) { return response()->json([ 'message' => 'Item not found' ], 404); } $result = $model->addLike(); return response()->json([ 'message' => 'Item liked successfully', 'is_liked' => true, 'likes_count' => $model->likes_count ]); } /** * Unlike an item */ public function unlike(Request $request) { $request->validate([ 'type' => 'required|string|in:music,media,playlist', 'id' => 'required|integer', ]); $model = $this->getModel($request->type, $request->id); if (!$model) { return response()->json([ 'message' => 'Item not found' ], 404); } $result = $model->removeLike(); return response()->json([ 'message' => 'Item unliked successfully', 'is_liked' => false, 'likes_count' => $model->likes_count ]); } /** * Toggle like status */ public function toggleLike(Request $request) { $request->validate([ 'type' => 'required|string|in:music,media,playlist', 'id' => 'required|integer', ]); $model = $this->getModel($request->type, $request->id); if (!$model) { return response()->json([ 'message' => 'Item not found' ], 404); } $result = $model->toggleLike(); return response()->json([ 'message' => $result ? 'Item liked successfully' : 'Item unliked successfully', 'is_liked' => $model->is_liked, 'likes_count' => $model->likes_count ]); } /** * Get all liked items for the authenticated user */ public function myLikedItems(Request $request) { $type = $request->get('type'); // Optional filter by type (music or media) $query = Like::with(['likeable' => fn (MorphTo $m) => $m->morphWith([ \App\Models\Media::class => ['image', 'detailImage', 'categories', 'subCategories', 'tags'], \App\Models\Music::class => ['image', 'playlists', 'tags'], \App\Models\MusicPlaylist::class => ['image', 'detailImage', 'categories', 'subcategories'], ])]) ->where('user_id', auth()->id()); if ($type) { $modelClass = $this->getModelClass($type); $query->where('likeable_type', $modelClass); } $likedItems = $query->latest()->paginate(20); return response()->json([ 'data' => $likedItems, 'total' => $likedItems->total(), 'types' => [ 'music' => 'App\\Models\\Music', 'media' => 'App\\Models\\Media', 'playlist' => 'App\\Models\\MusicPlaylist', ] ]); // Transform the response // $transformedItems = $likedItems->map(function ($likeItem) { // $item = $likeItem->likeable; // if (!$item) return null; // $baseData = [ // 'like_id' => $likeItem->id, // 'liked_at' => $likeItem->created_at, // 'type' => class_basename($likeItem->likeable_type), // 'is_liked' => true, // ]; // // Add type-specific data // if ($item instanceof \App\Models\Music) { // return array_merge($baseData, [ // 'id' => $item->id, // 'title' => $item->title, // 'artist' => $item->artist, // 'duration' => $item->duration_formatted ?? $item->duration, // 'image_url' => $item->image_url, // 'likes_count' => $item->likes_count, // 'type_display' => 'music' // ]); // } elseif ($item instanceof \App\Models\Media) { // return array_merge($baseData, [ // 'id' => $item->id, // 'title' => $item->title, // 'caption' => $item->caption, // 'media_type' => $item->type, // 'duration' => $item->duration, // 'image_url' => $item->image->url ?? null, // 'likes_count' => $item->likes_count, // 'type_display' => 'media' // ]); // } // return $baseData; // })->filter(); // return response()->json([ // 'data' => $transformedItems, // 'total' => $likedItems->total(), // 'current_page' => $likedItems->currentPage(), // 'last_page' => $likedItems->lastPage(), // 'per_page' => $likedItems->perPage(), // ]); } /** * Check if specific item is liked by user */ public function checkLiked(Request $request) { $request->validate([ 'type' => 'required|string|in:music,media,playlist', 'id' => 'required|integer', ]); $model = $this->getModel($request->type, $request->id); if (!$model) { return response()->json([ 'message' => 'Item not found' ], 404); } return response()->json([ 'is_liked' => $model->is_liked, 'likes_count' => $model->likes_count ]); } /** * Get top liked items */ public function topLiked(Request $request) { $type = $request->get('type', 'music'); // Default to music $limit = $request->get('limit', 10); $modelClass = $this->getModelClass($type); $items = $modelClass::with(['image']) ->withCount('likes') ->where(function($query) use ($modelClass) { if (property_exists($modelClass, 'type')) { $query->where('type', 'public'); } if (property_exists($modelClass, 'visibility')) { $query->where('visibility', 'public'); } }) ->orderBy('likes_count', 'desc') ->limit($limit) ->get(); return response()->json([ 'data' => $items, 'type' => $type, 'total' => $items->count() ]); } private function getModel($type, $id) { $modelClass = $this->getModelClass($type); return $modelClass::find($id); } private function getModelClass($type) { $models = [ 'music' => \App\Models\Music::class, 'media' => \App\Models\Media::class, 'playlist' => \App\Models\MusicPlaylist::class, ]; return $models[$type] ?? null; } }