user(); $space = DB::transaction(function () use ($user, $request): Space { $space = $user->ownedSpaces()->create([ 'name' => $request->validated('name'), 'personal' => false, ]); app(CreateDefaultCategories::class)->handle($user, $space); return $space; }); $user->forceFill(['current_space_id' => $space->id])->save(); return back(); } /** * Rename a space (owner only; the personal space name is fixed). */ public function update(UpdateSpaceRequest $request, Space $space): RedirectResponse { $space->update(['name' => $request->validated('name')]); return back(); } /** * Delete a space the user owns. The personal space is permanent, and a space * that still holds accounts must be emptied first — financial data is never * deleted implicitly. */ public function destroy(Request $request, Space $space): RedirectResponse { $user = $request->user(); abort_unless( ! $space->personal && $space->owner_id === $user->id && Feature::for($user)->active(Spaces::class), 403, ); if ($space->accounts()->exists()) { return back()->with('error', __('Remove or move this space\'s accounts before deleting it.')); } if ($user->current_space_id === $space->id) { $user->forceFill(['current_space_id' => $user->personalSpace->id])->save(); } $space->delete(); return back(); } /** * Switch the active space. Any space the user owns or belongs to is allowed; * the personal space is always reachable so this never requires the flag. */ public function select(Request $request, Space $space): RedirectResponse { $user = $request->user(); abort_unless($space->hasMember($user), 403); $user->forceFill(['current_space_id' => $space->id])->save(); return back(); } }