168 lines
5.2 KiB
PHP
168 lines
5.2 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\Rank;
|
|
use Illuminate\Http\JsonResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Storage;
|
|
|
|
class RankController extends Controller
|
|
{
|
|
private function ensureAdmin(Request $request): ?JsonResponse
|
|
{
|
|
$user = $request->user();
|
|
if (!$user || !$user->roles()->where(column: 'name', operator: 'ROLE_ADMIN')->exists()) {
|
|
return response()->json(data: ['message' => 'Forbidden'], status: 403);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public function index(Request $request): JsonResponse
|
|
{
|
|
$ranks = Rank::query()
|
|
->orderBy('name')
|
|
->get()
|
|
->map(fn (Rank $rank) => [
|
|
'id' => $rank->id,
|
|
'name' => $rank->name,
|
|
'badge_type' => $rank->badge_type,
|
|
'badge_text' => $rank->badge_text,
|
|
'color' => $rank->color,
|
|
'badge_image_url' => $rank->badge_image_path
|
|
? Storage::url($rank->badge_image_path)
|
|
: null,
|
|
]);
|
|
|
|
return response()->json($ranks);
|
|
}
|
|
|
|
public function store(Request $request): JsonResponse
|
|
{
|
|
if ($error = $this->ensureAdmin($request)) {
|
|
return $error;
|
|
}
|
|
|
|
$data = $request->validate([
|
|
'name' => ['required', 'string', 'max:100', 'unique:ranks,name'],
|
|
'badge_type' => ['nullable', 'in:text,image,none'],
|
|
'badge_text' => ['nullable', 'string', 'max:40'],
|
|
'color' => ['nullable', 'string', 'max:20', 'regex:/^#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/'],
|
|
]);
|
|
|
|
$badgeType = $data['badge_type'] ?? 'text';
|
|
$badgeText = $badgeType === 'text'
|
|
? ($data['badge_text'] ?? $data['name'])
|
|
: null;
|
|
if ($badgeType === 'none') {
|
|
$badgeText = null;
|
|
}
|
|
|
|
$rank = Rank::create([
|
|
'name' => $data['name'],
|
|
'badge_type' => $badgeType,
|
|
'badge_text' => $badgeText,
|
|
'color' => $data['color'] ?? null,
|
|
]);
|
|
|
|
return response()->json([
|
|
'id' => $rank->id,
|
|
'name' => $rank->name,
|
|
'badge_type' => $rank->badge_type,
|
|
'badge_text' => $rank->badge_text,
|
|
'color' => $rank->color,
|
|
'badge_image_url' => null,
|
|
], 201);
|
|
}
|
|
|
|
public function update(Request $request, Rank $rank): JsonResponse
|
|
{
|
|
if ($error = $this->ensureAdmin($request)) {
|
|
return $error;
|
|
}
|
|
|
|
$data = $request->validate([
|
|
'name' => ['required', 'string', 'max:100', "unique:ranks,name,{$rank->id}"],
|
|
'badge_type' => ['nullable', 'in:text,image,none'],
|
|
'badge_text' => ['nullable', 'string', 'max:40'],
|
|
'color' => ['nullable', 'string', 'max:20', 'regex:/^#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/'],
|
|
]);
|
|
|
|
$badgeType = $data['badge_type'] ?? $rank->badge_type ?? 'text';
|
|
$badgeText = $badgeType === 'text'
|
|
? ($data['badge_text'] ?? $rank->badge_text ?? $data['name'])
|
|
: null;
|
|
if ($badgeType === 'none') {
|
|
$badgeText = null;
|
|
}
|
|
$color = array_key_exists('color', $data) ? $data['color'] : $rank->color;
|
|
|
|
if ($badgeType !== 'image' && $rank->badge_image_path) {
|
|
Storage::disk('public')->delete($rank->badge_image_path);
|
|
$rank->badge_image_path = null;
|
|
}
|
|
|
|
$rank->update([
|
|
'name' => $data['name'],
|
|
'badge_type' => $badgeType,
|
|
'badge_text' => $badgeText,
|
|
'color' => $color,
|
|
]);
|
|
|
|
return response()->json([
|
|
'id' => $rank->id,
|
|
'name' => $rank->name,
|
|
'badge_type' => $rank->badge_type,
|
|
'badge_text' => $rank->badge_text,
|
|
'color' => $rank->color,
|
|
'badge_image_url' => $rank->badge_image_path
|
|
? Storage::url($rank->badge_image_path)
|
|
: null,
|
|
]);
|
|
}
|
|
|
|
public function destroy(Request $request, Rank $rank): JsonResponse
|
|
{
|
|
if ($error = $this->ensureAdmin($request)) {
|
|
return $error;
|
|
}
|
|
|
|
if ($rank->badge_image_path) {
|
|
Storage::disk('public')->delete($rank->badge_image_path);
|
|
}
|
|
|
|
$rank->delete();
|
|
|
|
return response()->json(null, 204);
|
|
}
|
|
|
|
public function uploadBadgeImage(Request $request, Rank $rank): JsonResponse
|
|
{
|
|
if ($error = $this->ensureAdmin($request)) {
|
|
return $error;
|
|
}
|
|
|
|
$data = $request->validate([
|
|
'file' => ['required', 'image', 'mimes:jpg,jpeg,png,gif,webp', 'max:2048'],
|
|
]);
|
|
|
|
if ($rank->badge_image_path) {
|
|
Storage::disk('public')->delete($rank->badge_image_path);
|
|
}
|
|
|
|
$path = $data['file']->store('rank-badges', 'public');
|
|
$rank->badge_type = 'image';
|
|
$rank->badge_text = null;
|
|
$rank->badge_image_path = $path;
|
|
$rank->save();
|
|
|
|
return response()->json([
|
|
'id' => $rank->id,
|
|
'badge_type' => $rank->badge_type,
|
|
'badge_text' => $rank->badge_text,
|
|
'badge_image_url' => Storage::url($path),
|
|
]);
|
|
}
|
|
}
|