221 lines
7.8 KiB
PHP
221 lines
7.8 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\Guild;
|
|
use App\Models\GuildMember;
|
|
use App\Models\GuildMessage;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Illuminate\Support\Str;
|
|
|
|
class GuildActionController extends Controller
|
|
{
|
|
private function generateInviteCode(): string
|
|
{
|
|
do {
|
|
$code = strtoupper(Str::random(8));
|
|
} while (Guild::where('invite_code', $code)->exists());
|
|
return $code;
|
|
}
|
|
|
|
public function store(Request $request)
|
|
{
|
|
$user = $request->user();
|
|
if (!$user) return response()->json(['message' => 'Unauthenticated'], 401);
|
|
|
|
if (GuildMember::where('user_id', $user->id)->exists()) {
|
|
return response()->json(['message' => 'Du bist bereits in einer Gilde.'], 422);
|
|
}
|
|
|
|
$validated = $request->validate([
|
|
'name' => ['required', 'string', 'min:3', 'max:40', 'unique:guilds,name'],
|
|
'tag' => ['required', 'string', 'min:2', 'max:6', 'regex:/^[A-Za-z0-9]{2,6}$/'],
|
|
'description' => ['nullable', 'string', 'max:500'],
|
|
'logo' => ['nullable', 'file', 'image', 'max:2048'],
|
|
]);
|
|
|
|
$tag = strtoupper($validated['tag']);
|
|
if (Guild::where('tag', $tag)->exists()) {
|
|
return response()->json(['errors' => ['tag' => ['Dieses Tag ist bereits vergeben.']]], 422);
|
|
}
|
|
|
|
$logoUrl = null;
|
|
if ($request->hasFile('logo') && $request->file('logo')->isValid()) {
|
|
$path = $request->file('logo')->store('guild-logos', 'public');
|
|
$logoUrl = Storage::url($path);
|
|
}
|
|
|
|
$guild = Guild::create([
|
|
'name' => $validated['name'],
|
|
'tag' => $tag,
|
|
'logo_url' => $logoUrl,
|
|
'description' => isset($validated['description']) ? strip_tags($validated['description']) : null,
|
|
'owner_id' => $user->id,
|
|
'invite_code' => $this->generateInviteCode(),
|
|
'points' => 0,
|
|
'members_count' => 1,
|
|
]);
|
|
|
|
GuildMember::create([
|
|
'guild_id' => $guild->id,
|
|
'user_id' => $user->id,
|
|
'role' => 'owner',
|
|
'joined_at' => now(),
|
|
]);
|
|
|
|
GuildMessage::create([
|
|
'guild_id' => $guild->id,
|
|
'user_id' => $user->id,
|
|
'type' => 'system',
|
|
'message' => 'hat die Gilde gegründet 🎉',
|
|
]);
|
|
|
|
return response()->json(['success' => true, 'data' => $guild], 201);
|
|
}
|
|
|
|
public function join(Request $request)
|
|
{
|
|
$user = $request->user();
|
|
if (!$user) return response()->json(['message' => 'Unauthenticated'], 401);
|
|
|
|
if (GuildMember::where('user_id', $user->id)->exists()) {
|
|
return response()->json(['message' => 'Du bist bereits in einer Gilde.'], 422);
|
|
}
|
|
|
|
$data = $request->validate([
|
|
'invite_code' => ['required', 'string', 'min:4', 'max:16'],
|
|
]);
|
|
|
|
$guild = Guild::where('invite_code', strtoupper($data['invite_code']))->first();
|
|
if (!$guild) {
|
|
return response()->json(['message' => 'Ungültiger Einladungscode.'], 422);
|
|
}
|
|
|
|
GuildMember::create([
|
|
'guild_id' => $guild->id,
|
|
'user_id' => $user->id,
|
|
'role' => 'member',
|
|
'joined_at' => now(),
|
|
]);
|
|
|
|
$guild->increment('members_count');
|
|
|
|
GuildMessage::create([
|
|
'guild_id' => $guild->id,
|
|
'user_id' => $user->id,
|
|
'type' => 'system',
|
|
'message' => 'ist der Gilde beigetreten 👋',
|
|
]);
|
|
|
|
return response()->json(['success' => true], 200);
|
|
}
|
|
|
|
public function leave(Request $request)
|
|
{
|
|
$user = $request->user();
|
|
if (!$user) return response()->json(['message' => 'Unauthenticated'], 401);
|
|
|
|
$member = GuildMember::where('user_id', $user->id)->first();
|
|
if (!$member) return response()->json(['message' => 'Du bist in keiner Gilde.'], 422);
|
|
|
|
// Owner cannot leave — must disband or transfer first
|
|
if ($member->role === 'owner') {
|
|
return response()->json(['message' => 'Als Owner kannst du die Gilde nicht verlassen. Lösche die Gilde oder übertrage den Besitz.'], 422);
|
|
}
|
|
|
|
$guildId = $member->guild_id;
|
|
$member->delete();
|
|
Guild::where('id', $guildId)->decrement('members_count');
|
|
|
|
return response()->json(['success' => true], 200);
|
|
}
|
|
|
|
public function kick(Request $request)
|
|
{
|
|
$user = $request->user();
|
|
if (!$user) return response()->json(['message' => 'Unauthenticated'], 401);
|
|
|
|
$data = $request->validate([
|
|
'user_id' => ['required', 'integer'],
|
|
]);
|
|
|
|
$actor = GuildMember::where('user_id', $user->id)->first();
|
|
if (!$actor || !in_array($actor->role, ['owner', 'officer'])) {
|
|
return response()->json(['message' => 'Keine Berechtigung.'], 403);
|
|
}
|
|
|
|
$target = GuildMember::where('user_id', $data['user_id'])
|
|
->where('guild_id', $actor->guild_id)
|
|
->first();
|
|
|
|
if (!$target) return response()->json(['message' => 'Mitglied nicht gefunden.'], 404);
|
|
if ($target->role === 'owner') return response()->json(['message' => 'Den Owner kannst du nicht kicken.'], 422);
|
|
|
|
$target->delete();
|
|
Guild::where('id', $actor->guild_id)->decrement('members_count');
|
|
|
|
return response()->json(['success' => true], 200);
|
|
}
|
|
|
|
public function update(Request $request)
|
|
{
|
|
$user = $request->user();
|
|
if (!$user) return response()->json(['message' => 'Unauthenticated'], 401);
|
|
|
|
$member = GuildMember::where('user_id', $user->id)->first();
|
|
if (!$member || !in_array($member->role, ['owner', 'officer'])) {
|
|
return response()->json(['message' => 'Keine Berechtigung.'], 403);
|
|
}
|
|
|
|
$validated = $request->validate([
|
|
'description' => ['sometimes', 'nullable', 'string', 'max:500'],
|
|
'name' => ['sometimes', 'string', 'min:3', 'max:40'],
|
|
'tag' => ['sometimes', 'string', 'min:2', 'max:6', 'regex:/^[A-Za-z0-9]{2,6}$/'],
|
|
'logo' => ['sometimes', 'nullable', 'file', 'image', 'max:2048'],
|
|
]);
|
|
|
|
$guild = Guild::findOrFail($member->guild_id);
|
|
|
|
if ($request->hasFile('logo') && $request->file('logo')->isValid()) {
|
|
// Delete old logo if stored locally
|
|
if ($guild->logo_url && str_contains($guild->logo_url, '/storage/')) {
|
|
$oldPath = str_replace('/storage/', 'public/', $guild->logo_url);
|
|
Storage::delete($oldPath);
|
|
}
|
|
$path = $request->file('logo')->store('guild-logos', 'public');
|
|
$guild->logo_url = Storage::url($path);
|
|
}
|
|
|
|
if (isset($validated['description'])) {
|
|
$guild->description = strip_tags($validated['description']);
|
|
}
|
|
if (isset($validated['name'])) {
|
|
$guild->name = $validated['name'];
|
|
}
|
|
if (isset($validated['tag'])) {
|
|
$guild->tag = strtoupper($validated['tag']);
|
|
}
|
|
|
|
$guild->save();
|
|
|
|
return response()->json(['success' => true, 'data' => $guild], 200);
|
|
}
|
|
|
|
public function regenerateInvite(Request $request)
|
|
{
|
|
$user = $request->user();
|
|
if (!$user) return response()->json(['message' => 'Unauthenticated'], 401);
|
|
|
|
$member = GuildMember::where('user_id', $user->id)->first();
|
|
if (!$member || !in_array($member->role, ['owner', 'officer'])) {
|
|
return response()->json(['message' => 'Keine Berechtigung.'], 403);
|
|
}
|
|
|
|
$guild = Guild::findOrFail($member->guild_id);
|
|
$guild->update(['invite_code' => $this->generateInviteCode()]);
|
|
|
|
return response()->json(['invite_code' => $guild->invite_code], 200);
|
|
}
|
|
}
|