Files
back-meditation/app/Http/Controllers/MusicCategoryController.php

174 lines
6.2 KiB
PHP

<?php
namespace App\Http\Controllers;
use App\Models\MusicPlaylist;
use App\Models\MusicCategory;
use App\Traits\HandlesImageUpload;
use Illuminate\Support\Str;
use Illuminate\Http\Request;
class MusicCategoryController extends Controller
{
use HandlesImageUpload;
public function index()
{
$categories = MusicCategory::with(['image', 'playlists' => function($q) {
$q->where('is_active', true)->orderBy('order');
}])->where('is_active', true)->orderBy('order')->get();
return response()->json($categories);
}
public function store(Request $request)
{
try {
$data = $request->validate([
'name' => 'required|string|max:255',
'description' => 'nullable|string',
'image_id' => 'nullable|exists:images,id',
'image' => 'nullable|file|extensions:jpg,jpeg,png,gif,webp,bmp,svg|max:8192',
'order' => 'nullable|integer',
'is_active' => 'nullable|boolean',
]);
// An uploaded image file takes precedence over a provided image_id.
$data['image_id'] = $this->uploadedImageId($request) ?? ($data['image_id'] ?? null);
// Check for duplicate name
$slug = Str::slug($data['name']);
$existingCategory = MusicCategory::where('slug', $slug)->first();
if ($existingCategory) {
return response()->json([
'message' => 'A category with this name already exists',
'errors' => [
'name' => ['The category name "' . $data['name'] . '" is already taken. Please use a different name.']
]
], 422);
}
// Optional: Check for duplicate name with case-insensitive comparison
$existingName = MusicCategory::whereRaw('LOWER(name) = ?', [strtolower($data['name'])])->first();
if ($existingName) {
return response()->json([
'message' => 'A category with a similar name already exists',
'errors' => [
'name' => ['Category "' . $existingName->name . '" already exists. Please use a different name.']
]
], 422);
}
$data['slug'] = $slug;
$category = MusicCategory::create($data);
return response()->json([
'message' => 'Category created successfully',
'category' => $category->load('image')
], 201);
} catch (\Illuminate\Database\QueryException $e) {
// Handle database duplicate entry error (if unique constraint exists)
if ($e->errorInfo[1] == 1062) { // MySQL duplicate entry error code
return response()->json([
'message' => 'A category with this name already exists',
'errors' => [
'name' => ['The category name must be unique.']
]
], 422);
}
return response()->json([
'message' => 'An error occurred while creating the category',
'error' => $e->getMessage()
], 500);
}
}
public function show($id)
{
$category = MusicCategory::with(['image', 'playlists' => function($q) {
$q->with(['image', 'musics' => function($q2) {
$q2->where('music.is_active', true)->with('image')->orderBy('music_playlist.order');
}])->where('is_active', true)->orderBy('order');
}])->findOrFail($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,
'name' => $category->name,
'description' => $category->description,
'icon_url' => $category->image?->url,
'type' => 'playlist',
],
'sub_categories' => $category->subcategories->map(fn ($sub) => [
'sub_category' => [
'id' => $sub->id,
'name' => $sub->name,
'description' => $sub->description,
'image_url' => $sub->image?->url,
],
'playlists' => $sub->playlists->each(fn ($p) => $p->append('duration')),
])->values(),
]);
}
public function update(Request $request, $id)
{
$category = MusicCategory::findOrFail($id);
$data = $request->validate([
'name' => 'sometimes|string|max:255',
'description' => 'nullable|string',
'image_id' => 'nullable|exists:images,id',
'image' => 'nullable|file|extensions:jpg,jpeg,png,gif,webp,bmp,svg|max:8192',
'order' => 'nullable|integer',
'is_active' => 'nullable|boolean',
]);
if (isset($data['name'])) {
$data['slug'] = Str::slug($data['name']);
}
// An uploaded image file takes precedence over a provided image_id.
if (($uploadedImageId = $this->uploadedImageId($request)) !== null) {
$data['image_id'] = $uploadedImageId;
}
$category->update($data);
return response()->json([
'message' => 'Category updated successfully',
'category' => $category->load('image')
]);
}
public function destroy($id)
{
$category = MusicCategory::findOrFail($id);
$category->delete();
return response()->json(['message' => 'Category deleted successfully']);
}
}