153 lines
4.6 KiB
PHP
153 lines
4.6 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\Category;
|
|
use App\Traits\StoresUploads;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Illuminate\Validation\Rule;
|
|
|
|
class CategoryController extends Controller
|
|
{
|
|
use StoresUploads;
|
|
|
|
public function index(Request $request)
|
|
{
|
|
$query = Category::query()->withCount('subcategories');
|
|
|
|
if ($request->filled('type')) {
|
|
$query->where('type', $request->input('type'));
|
|
}
|
|
|
|
if ($request->boolean('with_subcategories')) {
|
|
$query->with('subcategories');
|
|
}
|
|
|
|
return response()->json(
|
|
$query->orderBy('name')->get()
|
|
);
|
|
}
|
|
|
|
public function store(Request $request)
|
|
{
|
|
$data = $request->validate([
|
|
'name' => [
|
|
'required',
|
|
'string',
|
|
'max:255',
|
|
Rule::unique('categories', 'name')->where('type', $request->input('type', Category::TYPE_MEDIA)),
|
|
],
|
|
'type' => ['nullable', Rule::in(Category::TYPES)],
|
|
'description' => 'nullable|string',
|
|
'icon' => 'nullable|file|extensions:jpg,jpeg,png,gif,webp,bmp,svg|max:8192',
|
|
]);
|
|
|
|
$category = Category::create([
|
|
'name' => $data['name'],
|
|
'type' => $data['type'] ?? Category::TYPE_MEDIA,
|
|
'description' => $data['description'] ?? null,
|
|
'icon' => $request->hasFile('icon')
|
|
? $this->storeUpload($request->file('icon'), 'categories/icons')
|
|
: null,
|
|
]);
|
|
|
|
return response()->json([
|
|
'message' => 'Category created successfully',
|
|
'category' => $category,
|
|
], 201);
|
|
}
|
|
|
|
public function show($id)
|
|
{
|
|
$category = Category::with('subcategories')->withCount('subcategories')->findOrFail($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,
|
|
'name' => $category->name,
|
|
'description' => $category->description,
|
|
'icon_url' => $category->icon_url,
|
|
'type' => $category->type,
|
|
],
|
|
'sub_categories' => $category->subcategories->map(fn ($sub) => [
|
|
'sub_category' => [
|
|
'id' => $sub->id,
|
|
'name' => $sub->name,
|
|
'description' => $sub->description,
|
|
],
|
|
'medias' => $sub->media,
|
|
])->values(),
|
|
]);
|
|
}
|
|
|
|
public function update(Request $request, $id)
|
|
{
|
|
$category = Category::findOrFail($id);
|
|
|
|
$targetType = $request->input('type', $category->type);
|
|
|
|
$data = $request->validate([
|
|
'name' => [
|
|
'sometimes',
|
|
'string',
|
|
'max:255',
|
|
Rule::unique('categories', 'name')
|
|
->where('type', $targetType)
|
|
->ignore($category->id),
|
|
],
|
|
'type' => ['nullable', Rule::in(Category::TYPES)],
|
|
'description' => 'nullable|string',
|
|
'icon' => 'nullable|file|extensions:jpg,jpeg,png,gif,webp,bmp,svg|max:8192',
|
|
]);
|
|
|
|
if (array_key_exists('type', $data) && $data['type'] !== null) {
|
|
$category->type = $data['type'];
|
|
}
|
|
if (array_key_exists('name', $data)) {
|
|
$category->name = $data['name'];
|
|
}
|
|
if (array_key_exists('description', $data)) {
|
|
$category->description = $data['description'];
|
|
}
|
|
if ($request->hasFile('icon')) {
|
|
if ($category->icon) {
|
|
Storage::disk('public')->delete($category->icon);
|
|
}
|
|
$category->icon = $this->storeUpload($request->file('icon'), 'categories/icons');
|
|
}
|
|
|
|
$category->save();
|
|
|
|
return response()->json([
|
|
'message' => 'Category updated successfully',
|
|
'category' => $category,
|
|
]);
|
|
}
|
|
|
|
public function destroy($id)
|
|
{
|
|
$category = Category::findOrFail($id);
|
|
|
|
if ($category->icon) {
|
|
Storage::disk('public')->delete($category->icon);
|
|
}
|
|
|
|
$category->delete();
|
|
|
|
return response()->json(['message' => 'Category deleted successfully']);
|
|
}
|
|
}
|