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); } }