diff --git a/app/Http/Controllers/Admin/UserManagementController.php b/app/Http/Controllers/Admin/UserManagementController.php index 349ea43..160d1f7 100644 --- a/app/Http/Controllers/Admin/UserManagementController.php +++ b/app/Http/Controllers/Admin/UserManagementController.php @@ -6,6 +6,7 @@ use App\Http\Controllers\Controller; use App\Http\Requests\Admin\UpdateUserAdminStatusRequest; use App\Models\User; use Illuminate\Http\RedirectResponse; +use Illuminate\Support\Arr; use Inertia\Inertia; use Inertia\Response; @@ -24,8 +25,9 @@ class UserManagementController extends Controller public function update(UpdateUserAdminStatusRequest $request, User $user): RedirectResponse { + $validated = $request->validated(); $user->forceFill([ - 'is_admin' => $request->boolean('is_admin'), + 'is_admin' => Arr::get($validated, 'is_admin'), ])->save(); $status = $user->is_admin diff --git a/app/Http/Controllers/ProjectBacklogController.php b/app/Http/Controllers/ProjectBacklogController.php index 92958fb..54d6091 100644 --- a/app/Http/Controllers/ProjectBacklogController.php +++ b/app/Http/Controllers/ProjectBacklogController.php @@ -21,15 +21,18 @@ class ProjectBacklogController extends Controller public function index(Request $request, Project $project): Response { + $user = $request->user(); + abort_unless( - $this->projectPermissionService->userCanViewProject($request->user(), $project), + $this->projectPermissionService->userCanViewProject($user, $project), 403, ); + return Inertia::render('projects/Backlog', [ 'boardColumns' => $project->boardColumns()->get(), - 'canEditTickets' => $this->projectPermissionService->userHasPermission($request->user(), $project, 'edit'), - 'canCreateTickets' => $this->projectPermissionService->userHasPermission($request->user(), $project, 'create'), + 'canEditTickets' => $this->projectPermissionService->userHasPermission($user, $project, 'edit'), + 'canCreateTickets' => $this->projectPermissionService->userHasPermission($user, $project, 'create'), 'project' => $project, 'status' => session('status'), 'ticketPriorities' => $project->ticketPriorities()->get(), @@ -45,12 +48,15 @@ class ProjectBacklogController extends Controller public function store(StoreProjectTicketRequest $request, Project $project): RedirectResponse { + $user = $request->user(); + $validated = $request->validated(); + abort_unless( - $this->projectPermissionService->userHasPermission($request->user(), $project, 'create'), + $this->projectPermissionService->userHasPermission($user, $project, 'create'), 403, ); - $ticket = $this->createProjectTicket->handle($project, $request->validated(), $request->user()); + $ticket = $this->createProjectTicket->handle($project, $validated, $user); return to_route('projects.backlog.index', $project) ->with('status', "{$ticket->ticket_key} was added to the backlog."); diff --git a/app/Http/Controllers/ProjectBoardController.php b/app/Http/Controllers/ProjectBoardController.php index ca5a15b..e6bae65 100644 --- a/app/Http/Controllers/ProjectBoardController.php +++ b/app/Http/Controllers/ProjectBoardController.php @@ -9,6 +9,7 @@ use App\Models\Project; use App\Models\Ticket; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; +use Illuminate\Support\Arr; use Inertia\Inertia; use Inertia\Response; @@ -21,8 +22,10 @@ class ProjectBoardController extends Controller public function index(Request $request, Project $project): Response { + $user = $request->user(); + abort_unless( - $this->projectPermissionService->userCanViewProject($request->user(), $project), + $this->projectPermissionService->userCanViewProject($user, $project), 403, ); @@ -33,7 +36,7 @@ class ProjectBoardController extends Controller ->with(['ticketPriority', 'ticketType']), ]) ->get(), - 'canEditTickets' => $this->projectPermissionService->userHasPermission($request->user(), $project, 'edit'), + 'canEditTickets' => $this->projectPermissionService->userHasPermission($user, $project, 'edit'), 'project' => $project, 'status' => session('status'), ]); @@ -44,20 +47,28 @@ class ProjectBoardController extends Controller Project $project, Ticket $ticket, ): RedirectResponse { + $user = $request->user(); + abort_unless( - $this->projectPermissionService->userHasPermission($request->user(), $project, 'edit'), + $this->projectPermissionService->userHasPermission($user, $project, 'edit'), 403, ); + $validated = $request->validated(); + $boardColumnId = Arr::get($validated, 'board_column_id'); + $redirectRoute = Arr::get($validated, 'redirect_to') === 'backlog' + ? 'projects.backlog.index' + : 'projects.board.index'; + $destinationColumn = $project->boardColumns() - ->find($request->boardColumnId()); + ->find($boardColumnId); $originBoardColumnId = $ticket->board_column_id; $originLabel = $ticket->boardColumn?->name ?? 'Backlog'; $destinationLabel = $destinationColumn?->name ?? 'Backlog'; - if ($ticket->board_column_id === $request->boardColumnId()) { - return to_route($request->redirectRouteName(), $project) + if ($ticket->board_column_id === $boardColumnId) { + return to_route($redirectRoute, $project) ->with('status', "{$ticket->ticket_key} already belongs to {$destinationLabel}."); } @@ -67,7 +78,7 @@ class ProjectBoardController extends Controller $this->createTicketWorklogEntry->handle( $ticket->fresh(), - $request->user(), + $user, 'status_changed', "Moved from {$originLabel} to {$destinationLabel}.", [ @@ -82,7 +93,7 @@ class ProjectBoardController extends Controller ], ); - return to_route($request->redirectRouteName(), $project) + return to_route($redirectRoute, $project) ->with('status', "{$ticket->ticket_key} moved to {$destinationLabel}."); } } diff --git a/app/Http/Controllers/ProjectController.php b/app/Http/Controllers/ProjectController.php index dc2e63e..5fa0fb4 100644 --- a/app/Http/Controllers/ProjectController.php +++ b/app/Http/Controllers/ProjectController.php @@ -11,6 +11,7 @@ use App\Models\Team; use App\Models\User; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; +use Illuminate\Support\Arr; use Inertia\Inertia; use Inertia\Response; @@ -23,11 +24,13 @@ class ProjectController extends Controller public function index(Request $request): Response { + $user = $request->user(); + $projectQuery = Project::query() ->orderByDesc('id'); - if (! $request->user()->is_admin) { - $viewableProjectIds = $this->projectPermissionService->viewableProjectIds($request->user()); + if (! $user->is_admin) { + $viewableProjectIds = $this->projectPermissionService->viewableProjectIds($user); if ($viewableProjectIds === []) { return Inertia::render('projects/Index', [ @@ -60,21 +63,24 @@ class ProjectController extends Controller public function show(Request $request, Project $project): Response { + $user = $request->user(); + abort_unless( - $this->projectPermissionService->userCanViewProject($request->user(), $project), + $this->projectPermissionService->userCanViewProject($user, $project), 403, ); return Inertia::render('projects/Show', [ - 'canManageAccess' => $this->projectPermissionService->userCanManageProjectAccess($request->user(), $project), + 'canManageAccess' => $this->projectPermissionService->userCanManageProjectAccess($user, $project), 'project' => $project, ]); } public function access(Request $request, Project $project): Response { + $user = $request->user(); abort_unless( - $this->projectPermissionService->userCanManageProjectAccess($request->user(), $project), + $this->projectPermissionService->userCanManageProjectAccess($user, $project), 403, ); @@ -107,12 +113,16 @@ class ProjectController extends Controller Project $project, User $user, ): RedirectResponse { + abort_unless( $this->projectPermissionService->userCanManageProjectAccess($request->user(), $project), 403, ); - $this->projectPermissionService->syncUserPermissions($project, $user, $request->permissions()); + $validated = $request->validated(); + $permissions = Arr::get($validated, 'permissions', []); + + $this->projectPermissionService->syncUserPermissions($project, $user, $permissions); return to_route('projects.access', $project) ->with('status', "{$user->name} permissions were updated."); @@ -128,7 +138,10 @@ class ProjectController extends Controller 403, ); - $this->projectPermissionService->syncTeamPermissions($project, $team, $request->permissions()); + $validated = $request->validated(); + $permissions = Arr::get($validated, 'permissions', []); + + $this->projectPermissionService->syncTeamPermissions($project, $team, $permissions); return to_route('projects.access', $project) ->with('status', "{$team->name} permissions were updated."); diff --git a/app/Http/Controllers/ProjectRepositorySettingsController.php b/app/Http/Controllers/ProjectRepositorySettingsController.php index 49c009c..0ccd23a 100644 --- a/app/Http/Controllers/ProjectRepositorySettingsController.php +++ b/app/Http/Controllers/ProjectRepositorySettingsController.php @@ -13,6 +13,7 @@ use App\Models\User; use App\Models\UserGitConnection; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; +use Illuminate\Support\Arr; use Illuminate\Support\Collection; use Illuminate\Validation\ValidationException; use Inertia\Inertia; @@ -28,20 +29,21 @@ class ProjectRepositorySettingsController extends Controller public function show(Request $request, Project $project): Response { + $user = $request->user(); abort_unless( - $this->projectPermissionService->userCanManageProjectAccess($request->user(), $project), + $this->projectPermissionService->userCanManageProjectAccess($user, $project), 403, ); return Inertia::render('projects/settings/Repositories', [ - 'availableRepositorySources' => $this->availableRepositorySources($request->user()), + 'availableRepositorySources' => $this->availableRepositorySources($user), 'project' => $project, 'repositoryConnections' => $project->repositoryConnections() ->get() ->map(fn (RepositoryConnection $repositoryConnection): array => [ 'base_url' => $repositoryConnection->base_url, 'created_at' => $repositoryConnection->created_at?->toISOString(), - 'has_personal_access' => $this->hasPersonalAccess($request->user(), $repositoryConnection), + 'has_personal_access' => $this->hasPersonalAccess($user, $repositoryConnection), 'id' => $repositoryConnection->id, 'owner_name' => $repositoryConnection->owner_name, 'project_id' => $repositoryConnection->project_id, @@ -62,15 +64,20 @@ class ProjectRepositorySettingsController extends Controller StoreRepositoryConnectionRequest $request, Project $project, ): RedirectResponse { + $user = $request->user(); abort_unless( - $this->projectPermissionService->userCanManageProjectAccess($request->user(), $project), + $this->projectPermissionService->userCanManageProjectAccess($user, $project), 403, ); + $validated = $request->validated(); + $userGitConnectionId = Arr::get($validated, 'user_git_connection_id'); + $providerRepositoryId = Arr::get($validated, 'provider_repository_id'); + $repositoryAttributes = $this->repositoryAttributesForSelection( - $request->user(), - $request->userGitConnectionId(), - $request->providerRepositoryId(), + $user, + $userGitConnectionId, + $providerRepositoryId, ); $this->ensureRepositoryConnectionIsUnique($project, $repositoryAttributes); @@ -86,15 +93,22 @@ class ProjectRepositorySettingsController extends Controller Project $project, RepositoryConnection $repositoryConnection, ): RedirectResponse { + $user = $request->user(); + abort_unless( - $this->projectPermissionService->userCanManageProjectAccess($request->user(), $project), + $this->projectPermissionService->userCanManageProjectAccess($user, $project), 403, ); + + $validated = $request->validated(); + $userGitConnectionId = Arr::get($validated, 'user_git_connection_id'); + $providerRepositoryId = Arr::get($validated, 'provider_repository_id'); + $repositoryAttributes = $this->repositoryAttributesForSelection( - $request->user(), - $request->userGitConnectionId(), - $request->providerRepositoryId(), + $user, + $userGitConnectionId, + $providerRepositoryId, ); $this->ensureRepositoryConnectionIsUnique( diff --git a/app/Http/Controllers/ProjectTicketBranchController.php b/app/Http/Controllers/ProjectTicketBranchController.php index 067299e..a6656e3 100644 --- a/app/Http/Controllers/ProjectTicketBranchController.php +++ b/app/Http/Controllers/ProjectTicketBranchController.php @@ -14,6 +14,7 @@ use App\Models\Ticket; use App\Models\UserGitConnection; use Illuminate\Http\JsonResponse; use Illuminate\Http\RedirectResponse; +use Illuminate\Support\Arr; use Illuminate\Validation\ValidationException; use Throwable; @@ -30,17 +31,23 @@ class ProjectTicketBranchController extends Controller Project $project, Ticket $ticket, ): JsonResponse { + $user = $request->user(); + abort_unless( - $this->projectPermissionService->userHasPermission($request->user(), $project, 'edit'), + $this->projectPermissionService->userHasPermission($user, $project, 'edit'), 403, ); + $validated = $request->validated(); + $repositoryConnectionId = Arr::get($validated, 'repository_connection_id'); + $branchName = trim((string) Arr::get($validated, 'branch_name')); + $repositoryConnection = $this->projectRepositoryConnection( $project, - $request->repositoryConnectionId(), + $repositoryConnectionId, ); $userGitConnection = $this->matchingUserGitConnection( - $request->user()->id, + $user->id, $repositoryConnection, ); @@ -51,7 +58,7 @@ class ProjectTicketBranchController extends Controller ]); } - $syntaxMessage = $this->validateGitBranchName->message($request->branchName()); + $syntaxMessage = $this->validateGitBranchName->message($branchName); if ($syntaxMessage !== null) { return response()->json([ @@ -72,7 +79,7 @@ class ProjectTicketBranchController extends Controller ), ) ->contains( - fn (GitBranch $branch): bool => $branch->name === $request->branchName(), + fn (GitBranch $branch): bool => $branch->name === $branchName, ); } catch (Throwable) { return response()->json([ @@ -99,17 +106,26 @@ class ProjectTicketBranchController extends Controller Project $project, Ticket $ticket, ): RedirectResponse { + + $user = $request->user(); + abort_unless( - $this->projectPermissionService->userHasPermission($request->user(), $project, 'edit'), + $this->projectPermissionService->userHasPermission($user, $project, 'edit'), 403, ); + $validated = $request->validated(); + $repositoryConnectionId = Arr::get($validated, 'repository_connection_id'); + $branchName = trim((string) Arr::get($validated, 'branch_name')); + + + $repositoryConnection = $this->projectRepositoryConnection( $project, - $request->repositoryConnectionId(), + $repositoryConnectionId, ); $userGitConnection = $this->matchingUserGitConnection( - $request->user()->id, + $user->id, $repositoryConnection, ); @@ -119,7 +135,7 @@ class ProjectTicketBranchController extends Controller ]); } - $syntaxMessage = $this->validateGitBranchName->message($request->branchName()); + $syntaxMessage = $this->validateGitBranchName->message($branchName); if ($syntaxMessage !== null) { throw ValidationException::withMessages([ @@ -139,7 +155,7 @@ class ProjectTicketBranchController extends Controller ), ) ->contains( - fn (GitBranch $branch): bool => $branch->name === $request->branchName(), + fn (GitBranch $branch): bool => $branch->name === $branchName, ); } catch (Throwable) { throw ValidationException::withMessages([ @@ -166,7 +182,7 @@ class ProjectTicketBranchController extends Controller $userGitConnection->api_token, $repositoryConnection->owner_name, $repositoryConnection->repository_name, - $request->branchName(), + $branchName, $repository->defaultBranch, ); } catch (Throwable) { @@ -178,7 +194,7 @@ class ProjectTicketBranchController extends Controller return to_route('projects.tickets.show', [$project, $ticket]) ->with( 'status', - "{$request->branchName()} was created in {$repositoryConnection->repository_full_name}.", + "{$branchName} was created in {$repositoryConnection->repository_full_name}.", ); } diff --git a/app/Http/Controllers/ProjectTicketController.php b/app/Http/Controllers/ProjectTicketController.php index 63ba7b1..16ff9d9 100644 --- a/app/Http/Controllers/ProjectTicketController.php +++ b/app/Http/Controllers/ProjectTicketController.php @@ -14,6 +14,7 @@ use App\Models\TicketLink; use App\Models\User; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; +use Illuminate\Support\Arr; use Inertia\Inertia; use Inertia\Response; @@ -29,15 +30,17 @@ class ProjectTicketController extends Controller public function show(Request $request, Project $project, Ticket $ticket): Response { + $user = $request->user(); + abort_unless( - $this->projectPermissionService->userCanViewProject($request->user(), $project), + $this->projectPermissionService->userCanViewProject($user, $project), 403, ); $excludedParentIds = [$ticket->id, ...$this->descendantIds($ticket)]; return Inertia::render('projects/Ticket', [ - 'canEditTicket' => $this->projectPermissionService->userHasPermission($request->user(), $project, 'edit'), + 'canEditTicket' => $this->projectPermissionService->userHasPermission($user, $project, 'edit'), 'childTicketTree' => $this->buildChildTicketTree($ticket), 'linkedTickets' => $this->linkedTickets($ticket), 'parentTicketOptions' => Ticket::query() @@ -53,12 +56,12 @@ class ProjectTicketController extends Controller ]), 'project' => $project, 'repositoryBranches' => $this->resolveTicketBranchMatches->handle( - $request->user(), + $user, $project, $ticket, ), 'repositoryPullRequests' => $this->resolveTicketPullRequestMatches->handle( - $request->user(), + $user, $project, $ticket, ), @@ -97,16 +100,22 @@ class ProjectTicketController extends Controller Project $project, Ticket $ticket, ): RedirectResponse { + + $user = $request->user(); abort_unless( - $this->projectPermissionService->userHasPermission($request->user(), $project, 'edit'), + $this->projectPermissionService->userHasPermission($user, $project, 'edit'), 403, ); + $validated = $request->validated(); + $fieldValues = Arr::get($validated, 'field_values'); + $ticketAttributes = $request->ticketAttributes(); + $wasUpdated = $this->updateProjectTicket->handle( $ticket, - $request->user(), - $request->ticketAttributes(), - $request->fieldValues(), + $user, + $ticketAttributes, + $fieldValues, ); $statusMessage = $wasUpdated diff --git a/app/Http/Controllers/ProjectTicketLinkController.php b/app/Http/Controllers/ProjectTicketLinkController.php index 7dfebae3..da67c21 100644 --- a/app/Http/Controllers/ProjectTicketLinkController.php +++ b/app/Http/Controllers/ProjectTicketLinkController.php @@ -10,6 +10,7 @@ use App\Models\Ticket; use App\Models\TicketLink; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; +use Illuminate\Support\Arr; use Illuminate\Support\Facades\DB; class ProjectTicketLinkController extends Controller @@ -24,25 +25,31 @@ class ProjectTicketLinkController extends Controller Project $project, Ticket $ticket, ): RedirectResponse { + + $user = $request->user(); abort_unless( - $this->projectPermissionService->userHasPermission($request->user(), $project, 'edit'), + $this->projectPermissionService->userHasPermission($user, $project, 'edit'), 403, ); + $validated = $request->validated(); + $linkedTicketId = Arr::get($validated, 'linked_ticket_id'); + $ticketLinkTypeId = Arr::get($validated, 'ticket_link_type_id'); + $linkedTicket = Ticket::query() ->where('project_id', $project->id) - ->findOrFail($request->linkedTicketId()); + ->findOrFail($linkedTicketId); [$sourceTicketId, $targetTicketId] = $this->normalizeTicketPair($ticket->id, $linkedTicket->id); - $ticketLink = DB::transaction(function () use ($linkedTicket, $request, $sourceTicketId, $targetTicketId, $ticket): TicketLink { + $ticketLink = DB::transaction(function () use ($linkedTicket, $user, $ticketLinkTypeId, $sourceTicketId, $targetTicketId, $ticket): TicketLink { $ticketLink = TicketLink::query()->updateOrCreate( [ 'source_ticket_id' => $sourceTicketId, 'target_ticket_id' => $targetTicketId, ], [ - 'ticket_link_type_id' => $request->ticketLinkTypeId(), + 'ticket_link_type_id' => $ticketLinkTypeId, ], ); @@ -50,7 +57,7 @@ class ProjectTicketLinkController extends Controller $this->createTicketWorklogEntry->handle( $ticket, - $request->user(), + $user, 'link_updated', "Linked {$linkedTicket->ticket_key} as {$ticketLink->ticketLinkType->label}.", [ @@ -61,7 +68,7 @@ class ProjectTicketLinkController extends Controller $this->createTicketWorklogEntry->handle( $linkedTicket, - $request->user(), + $user, 'link_updated', "Linked {$ticket->ticket_key} as {$ticketLink->ticketLinkType->label}.", [ @@ -83,8 +90,10 @@ class ProjectTicketLinkController extends Controller Ticket $ticket, TicketLink $ticketLink, ): RedirectResponse { + + $user = $request->user(); abort_unless( - $this->projectPermissionService->userHasPermission($request->user(), $project, 'edit'), + $this->projectPermissionService->userHasPermission($user, $project, 'edit'), 403, ); @@ -101,12 +110,12 @@ class ProjectTicketLinkController extends Controller $label = $ticketLink->ticketLinkType->label; - DB::transaction(function () use ($label, $linkedTicket, $request, $ticket, $ticketLink): void { + DB::transaction(function () use ($label, $linkedTicket, $user, $ticket, $ticketLink): void { $ticketLink->delete(); $this->createTicketWorklogEntry->handle( $ticket, - $request->user(), + $user, 'link_removed', "Removed {$label} link to {$linkedTicket->ticket_key}.", [ @@ -117,7 +126,7 @@ class ProjectTicketLinkController extends Controller $this->createTicketWorklogEntry->handle( $linkedTicket, - $request->user(), + $user, 'link_removed', "Removed {$label} link to {$ticket->ticket_key}.", [ diff --git a/app/Http/Controllers/ProjectTicketMetadataSettingsController.php b/app/Http/Controllers/ProjectTicketMetadataSettingsController.php index 8826911..659fcca 100644 --- a/app/Http/Controllers/ProjectTicketMetadataSettingsController.php +++ b/app/Http/Controllers/ProjectTicketMetadataSettingsController.php @@ -16,6 +16,7 @@ use App\Models\TicketType; use Illuminate\Database\Eloquent\Model; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; +use Illuminate\Support\Arr; use Illuminate\Support\Collection; use Illuminate\Support\Facades\DB; use Inertia\Inertia; @@ -54,10 +55,15 @@ class ProjectTicketMetadataSettingsController extends Controller $this->abortUnlessCanManage($request, $project); $this->initializeProjectTicketMetadata->handle($project); - $ticketType = DB::transaction(function () use ($project, $request): TicketType { + $validated = $request->validated(); + $name = Arr::get($validated, 'name'); + $position = Arr::get($validated, 'position'); + + + $ticketType = DB::transaction(function () use ($project, $name, $position): TicketType { $ticketType = $project->ticketTypes()->create([ 'is_builtin' => false, - 'name' => $request->validated('name'), + 'name' => $name, 'position' => $project->ticketTypes()->count() + 1, 'system_key' => null, ]); @@ -65,7 +71,7 @@ class ProjectTicketMetadataSettingsController extends Controller $this->reorderModels( $project->ticketTypes()->whereKeyNot($ticketType->id)->get()->values(), $ticketType, - $request->position() ?? $project->ticketTypes()->count(), + $position ?? $project->ticketTypes()->count(), ); return $ticketType; @@ -83,15 +89,19 @@ class ProjectTicketMetadataSettingsController extends Controller $this->abortUnlessCanManage($request, $project); $this->initializeProjectTicketMetadata->handle($project); - DB::transaction(function () use ($project, $request, $ticketType): void { + $validated = $request->validated(); + $name = Arr::get($validated, 'name'); + $position = Arr::get($validated, 'position'); + + DB::transaction(function () use ($project, $name, $position, $ticketType): void { $ticketType->update([ - 'name' => $request->validated('name'), + 'name' => $name, ]); $this->reorderModels( $project->ticketTypes()->whereKeyNot($ticketType->id)->get()->values(), $ticketType, - $request->position(), + $position, ); }); @@ -121,16 +131,20 @@ class ProjectTicketMetadataSettingsController extends Controller { $this->abortUnlessCanManage($request, $project); - $ticketPriority = DB::transaction(function () use ($project, $request): TicketPriority { + $validated = $request->validated(); + $name = Arr::get($validated, 'name'); + $position = Arr::get($validated, 'position'); + + $ticketPriority = DB::transaction(function () use ($project, $name, $position): TicketPriority { $ticketPriority = $project->ticketPriorities()->create([ - 'name' => $request->validated('name'), + 'name' => $name, 'position' => $project->ticketPriorities()->count() + 1, ]); $this->reorderModels( $project->ticketPriorities()->whereKeyNot($ticketPriority->id)->get()->values(), $ticketPriority, - $request->position() ?? $project->ticketPriorities()->count(), + $position ?? $project->ticketPriorities()->count(), ); return $ticketPriority; @@ -147,15 +161,19 @@ class ProjectTicketMetadataSettingsController extends Controller ): RedirectResponse { $this->abortUnlessCanManage($request, $project); - DB::transaction(function () use ($project, $request, $ticketPriority): void { + $validated = $request->validated(); + $name = Arr::get($validated, 'name'); + $position = Arr::get($validated, 'position'); + + DB::transaction(function () use ($project, $name, $position, $ticketPriority): void { $ticketPriority->update([ - 'name' => $request->validated('name'), + 'name' => $name, ]); $this->reorderModels( $project->ticketPriorities()->whereKeyNot($ticketPriority->id)->get()->values(), $ticketPriority, - $request->position(), + $position, ); }); @@ -188,17 +206,22 @@ class ProjectTicketMetadataSettingsController extends Controller ): RedirectResponse { $this->abortUnlessCanManage($request, $project); - $ticketFieldDefinition = DB::transaction(function () use ($project, $request): TicketFieldDefinition { + $validated = $request->validated(); + $label = Arr::get($validated, 'label'); + $fieldType = Arr::get($validated, 'field_type'); + $position = Arr::get($validated, 'position'); + + $ticketFieldDefinition = DB::transaction(function () use ($project, $fieldType, $label): TicketFieldDefinition { $ticketFieldDefinition = $project->ticketFieldDefinitions()->create([ - 'field_type' => $request->validated('field_type'), - 'label' => $request->validated('label'), + 'field_type' => $fieldType, + 'label' => $label, 'position' => $project->ticketFieldDefinitions()->count() + 1, ]); $this->reorderModels( $project->ticketFieldDefinitions()->whereKeyNot($ticketFieldDefinition->id)->get()->values(), $ticketFieldDefinition, - $request->position() ?? $project->ticketFieldDefinitions()->count(), + $position ?? $project->ticketFieldDefinitions()->count(), ); return $ticketFieldDefinition; @@ -215,16 +238,21 @@ class ProjectTicketMetadataSettingsController extends Controller ): RedirectResponse { $this->abortUnlessCanManage($request, $project); - DB::transaction(function () use ($project, $request, $ticketFieldDefinition): void { + $validated = $request->validated(); + $label = Arr::get($validated, 'label'); + $fieldType = Arr::get($validated, 'field_type'); + $position = Arr::get($validated, 'position'); + + DB::transaction(function () use ($project, $fieldType, $label, $ticketFieldDefinition, $position): void { $ticketFieldDefinition->update([ - 'field_type' => $request->validated('field_type'), - 'label' => $request->validated('label'), + 'field_type' => $fieldType, + 'label' => $label, ]); $this->reorderModels( $project->ticketFieldDefinitions()->whereKeyNot($ticketFieldDefinition->id)->get()->values(), $ticketFieldDefinition, - $request->position(), + $position, ); }); @@ -253,18 +281,22 @@ class ProjectTicketMetadataSettingsController extends Controller public function storeLinkType(StoreProjectNamedSettingRequest $request, Project $project): RedirectResponse { + $validated = $request->validated(); + $name = Arr::get($validated, 'name'); + $position = Arr::get($validated, 'position'); + $this->abortUnlessCanManage($request, $project); - $ticketLinkType = DB::transaction(function () use ($project, $request): TicketLinkType { + $ticketLinkType = DB::transaction(function () use ($project, $position, $name): TicketLinkType { $ticketLinkType = $project->ticketLinkTypes()->create([ - 'label' => $request->validated('name'), + 'label' => $name, 'position' => $project->ticketLinkTypes()->count() + 1, ]); $this->reorderModels( $project->ticketLinkTypes()->whereKeyNot($ticketLinkType->id)->get()->values(), $ticketLinkType, - $request->position() ?? $project->ticketLinkTypes()->count(), + $position ?? $project->ticketLinkTypes()->count(), ); return $ticketLinkType; @@ -279,17 +311,22 @@ class ProjectTicketMetadataSettingsController extends Controller Project $project, TicketLinkType $ticketLinkType, ): RedirectResponse { + + $validated = $request->validated(); + $name = Arr::get($validated, 'name'); + $position = Arr::get($validated, 'position'); + $this->abortUnlessCanManage($request, $project); - DB::transaction(function () use ($project, $request, $ticketLinkType): void { + DB::transaction(function () use ($project, $name, $position, $ticketLinkType): void { $ticketLinkType->update([ - 'label' => $request->validated('name'), + 'label' => $name, ]); $this->reorderModels( $project->ticketLinkTypes()->whereKeyNot($ticketLinkType->id)->get()->values(), $ticketLinkType, - $request->position(), + $position, ); }); diff --git a/app/Http/Controllers/Settings/GitConnectionController.php b/app/Http/Controllers/Settings/GitConnectionController.php index c77362a..7b575b5 100644 --- a/app/Http/Controllers/Settings/GitConnectionController.php +++ b/app/Http/Controllers/Settings/GitConnectionController.php @@ -2,6 +2,7 @@ namespace App\Http\Controllers\Settings; +use App\Actions\Git\GitProviderKey; use App\Actions\Git\GitProviderManager; use App\Http\Controllers\Controller; use App\Http\Requests\Settings\StoreUserGitConnectionRequest; @@ -9,6 +10,7 @@ use App\Http\Requests\Settings\UpdateUserGitConnectionRequest; use App\Models\UserGitConnection; use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; +use Illuminate\Support\Arr; use Inertia\Inertia; use Inertia\Response; use Throwable; @@ -21,6 +23,7 @@ class GitConnectionController extends Controller public function edit(Request $request): Response { + return Inertia::render('settings/GitConnections', [ 'gitConnections' => $request->user()->gitConnections ->map(fn (UserGitConnection $gitConnection): array => [ @@ -42,11 +45,19 @@ class GitConnectionController extends Controller public function store(StoreUserGitConnectionRequest $request): RedirectResponse { + $validated = $request->validated(); + + $apiToken = Arr::get($validated, 'api_token'); + $baseUrl = Arr::get($validated, 'base_url'); + $provider = GitProviderKey::from(Arr::get($validated, 'provider')); + $user = $request->user(); + + try { - $gitProvider = $this->gitProviderManager->client($request->provider()); + $gitProvider = $this->gitProviderManager->client($provider); $authenticatedUser = $gitProvider->getAuthenticatedUser( - $request->baseUrl(), - $request->apiToken(), + $baseUrl, + $apiToken, ); } catch (Throwable) { return back() @@ -58,11 +69,11 @@ class GitConnectionController extends Controller UserGitConnection::query()->create([ 'account_login' => $authenticatedUser->login, 'account_name' => $authenticatedUser->name, - 'api_token' => $request->apiToken(), - 'base_url' => $request->baseUrl(), - 'provider' => $request->provider(), + 'api_token' => $apiToken, + 'base_url' => $baseUrl, + 'provider' => $provider, 'provider_user_id' => $authenticatedUser->providerUserId, - 'user_id' => $request->user()->id, + 'user_id' => $user->id, ]); return to_route('git-connections.edit') @@ -75,11 +86,18 @@ class GitConnectionController extends Controller ): RedirectResponse { $this->abortUnlessOwner($request, $gitConnection); + $validated = $request->validated(); + $apiToken = Arr::get($validated, 'api_token'); + $baseUrl = Arr::get($validated, 'base_url'); + $provider = GitProviderKey::from(Arr::get($validated, 'provider')); + + + try { - $gitProvider = $this->gitProviderManager->client($request->provider()); + $gitProvider = $this->gitProviderManager->client($provider); $authenticatedUser = $gitProvider->getAuthenticatedUser( - $request->baseUrl(), - $request->apiToken(), + $baseUrl, + $apiToken, ); } catch (Throwable) { return back() @@ -91,9 +109,9 @@ class GitConnectionController extends Controller $gitConnection->update([ 'account_login' => $authenticatedUser->login, 'account_name' => $authenticatedUser->name, - 'api_token' => $request->apiToken(), - 'base_url' => $request->baseUrl(), - 'provider' => $request->provider(), + 'api_token' => $apiToken, + 'base_url' => $baseUrl, + 'provider' => $provider, 'provider_user_id' => $authenticatedUser->providerUserId, ]); @@ -115,6 +133,7 @@ class GitConnectionController extends Controller private function abortUnlessOwner(Request $request, UserGitConnection $gitConnection): void { - abort_unless($gitConnection->user_id === $request->user()->id, 403); + $user = $request->user(); + abort_unless($gitConnection->user_id === $user->id, 403); } } diff --git a/app/Http/Controllers/Settings/ProfileController.php b/app/Http/Controllers/Settings/ProfileController.php index ab07fb9..9c57bcf 100644 --- a/app/Http/Controllers/Settings/ProfileController.php +++ b/app/Http/Controllers/Settings/ProfileController.php @@ -19,9 +19,12 @@ class ProfileController extends Controller */ public function edit(Request $request): Response { + $session = $request->session(); + $user = $request->user(); + return Inertia::render('settings/Profile', [ - 'mustVerifyEmail' => $request->user() instanceof MustVerifyEmail, - 'status' => $request->session()->get('status'), + 'mustVerifyEmail' => $user instanceof MustVerifyEmail, + 'status' => $session->get('status'), ]); } @@ -30,13 +33,15 @@ class ProfileController extends Controller */ public function update(ProfileUpdateRequest $request): RedirectResponse { - $request->user()->fill($request->validated()); - if ($request->user()->isDirty('email')) { - $request->user()->email_verified_at = null; + $user = $request->user(); + $user->fill($request->validated()); + + if ($user->isDirty('email')) { + $user->email_verified_at = null; } - $request->user()->save(); + $user->save(); return to_route('profile.edit'); } @@ -47,13 +52,14 @@ class ProfileController extends Controller public function destroy(ProfileDeleteRequest $request): RedirectResponse { $user = $request->user(); + $session = $request->session(); Auth::logout(); $user->delete(); - $request->session()->invalidate(); - $request->session()->regenerateToken(); + $session->invalidate(); + $session->regenerateToken(); return redirect('/'); } diff --git a/app/Http/Controllers/Settings/SecurityController.php b/app/Http/Controllers/Settings/SecurityController.php index 15ec8e3..4e47782 100644 --- a/app/Http/Controllers/Settings/SecurityController.php +++ b/app/Http/Controllers/Settings/SecurityController.php @@ -30,6 +30,7 @@ class SecurityController extends Controller implements HasMiddleware */ public function edit(TwoFactorAuthenticationRequest $request): Response { + $user = $request->user(); $props = [ 'canManageTwoFactor' => Features::canManageTwoFactorAuthentication(), ]; @@ -37,7 +38,7 @@ class SecurityController extends Controller implements HasMiddleware if (Features::canManageTwoFactorAuthentication()) { $request->ensureStateIsValid(); - $props['twoFactorEnabled'] = $request->user()->hasEnabledTwoFactorAuthentication(); + $props['twoFactorEnabled'] = $user->hasEnabledTwoFactorAuthentication(); $props['requiresConfirmation'] = Features::optionEnabled(Features::twoFactorAuthentication(), 'confirm'); } @@ -49,7 +50,9 @@ class SecurityController extends Controller implements HasMiddleware */ public function update(PasswordUpdateRequest $request): RedirectResponse { - $request->user()->update([ + $user = $request->user(); + + $user->update([ 'password' => $request->password, ]); diff --git a/app/Http/Controllers/TeamController.php b/app/Http/Controllers/TeamController.php index fa32843..68891d7 100644 --- a/app/Http/Controllers/TeamController.php +++ b/app/Http/Controllers/TeamController.php @@ -8,6 +8,7 @@ use App\Http\Requests\UpdateTeamMembersRequest; use App\Models\Team; use App\Models\User; use Illuminate\Http\RedirectResponse; +use Illuminate\Support\Arr; use Inertia\Inertia; use Inertia\Response; @@ -49,7 +50,11 @@ class TeamController extends Controller public function updateMembers(UpdateTeamMembersRequest $request, Team $team): RedirectResponse { - $this->projectPermissionService->syncTeamMembers($team, $request->userIds()); + $validated = $request->validated(); + + $userIds = Arr::get($validated, 'user_ids', []); + + $this->projectPermissionService->syncTeamMembers($team, $userIds); return to_route('admin.teams.index') ->with('status', "{$team->name} members were updated."); diff --git a/app/Http/Requests/MoveProjectTicketRequest.php b/app/Http/Requests/MoveProjectTicketRequest.php index 9aebb17..9a5a0b3 100644 --- a/app/Http/Requests/MoveProjectTicketRequest.php +++ b/app/Http/Requests/MoveProjectTicketRequest.php @@ -36,22 +36,4 @@ class MoveProjectTicketRequest extends FormRequest 'redirect_to' => ['required', 'string', Rule::in(['backlog', 'board'])], ]; } - - public function boardColumnId(): ?int - { - $boardColumnId = $this->validated('board_column_id'); - - if ($boardColumnId === null || $boardColumnId === '') { - return null; - } - - return (int) $boardColumnId; - } - - public function redirectRouteName(): string - { - return $this->validated('redirect_to') === 'backlog' - ? 'projects.backlog.index' - : 'projects.board.index'; - } } diff --git a/app/Http/Requests/Settings/StoreUserGitConnectionRequest.php b/app/Http/Requests/Settings/StoreUserGitConnectionRequest.php index dbddd2b..8e4e70c 100644 --- a/app/Http/Requests/Settings/StoreUserGitConnectionRequest.php +++ b/app/Http/Requests/Settings/StoreUserGitConnectionRequest.php @@ -17,6 +17,13 @@ class StoreUserGitConnectionRequest extends FormRequest { return $this->user() !== null; } + protected function prepareForValidation(): void + { + $this->merge([ + 'base_url' => $this->normalizedBaseUrl(), + 'provider' => Str::lower(trim((string) $this->input('provider'))), + ]); + } /** * Get the validation rules that apply to the request. @@ -42,30 +49,6 @@ class StoreUserGitConnectionRequest extends FormRequest ))], ]; } - - protected function prepareForValidation(): void - { - $this->merge([ - 'base_url' => $this->normalizedBaseUrl(), - 'provider' => Str::lower(trim((string) $this->input('provider'))), - ]); - } - - public function apiToken(): string - { - return (string) $this->validated('api_token'); - } - - public function baseUrl(): string - { - return (string) $this->validated('base_url'); - } - - public function provider(): GitProviderKey - { - return GitProviderKey::from((string) $this->validated('provider')); - } - private function normalizedBaseUrl(): string { $baseUrl = Str::of((string) $this->input('base_url')) diff --git a/app/Http/Requests/Settings/UpdateUserGitConnectionRequest.php b/app/Http/Requests/Settings/UpdateUserGitConnectionRequest.php index e73a97d..911fea2 100644 --- a/app/Http/Requests/Settings/UpdateUserGitConnectionRequest.php +++ b/app/Http/Requests/Settings/UpdateUserGitConnectionRequest.php @@ -19,6 +19,13 @@ class UpdateUserGitConnectionRequest extends FormRequest return $this->user() !== null; } + protected function prepareForValidation(): void + { + $this->merge([ + 'base_url' => $this->normalizedBaseUrl(), + 'provider' => Str::lower(trim((string) $this->input('provider'))), + ]); + } /** * Get the validation rules that apply to the request. * @@ -47,30 +54,6 @@ class UpdateUserGitConnectionRequest extends FormRequest ))], ]; } - - protected function prepareForValidation(): void - { - $this->merge([ - 'base_url' => $this->normalizedBaseUrl(), - 'provider' => Str::lower(trim((string) $this->input('provider'))), - ]); - } - - public function apiToken(): string - { - return (string) $this->validated('api_token'); - } - - public function baseUrl(): string - { - return (string) $this->validated('base_url'); - } - - public function provider(): GitProviderKey - { - return GitProviderKey::from((string) $this->validated('provider')); - } - private function normalizedBaseUrl(): string { $baseUrl = Str::of((string) $this->input('base_url')) diff --git a/app/Http/Requests/StoreProjectNamedSettingRequest.php b/app/Http/Requests/StoreProjectNamedSettingRequest.php index e15870a..137dbf2 100644 --- a/app/Http/Requests/StoreProjectNamedSettingRequest.php +++ b/app/Http/Requests/StoreProjectNamedSettingRequest.php @@ -28,14 +28,5 @@ class StoreProjectNamedSettingRequest extends FormRequest ]; } - public function position(): ?int - { - $position = $this->validated('position'); - if ($position === null) { - return null; - } - - return (int) $position; - } } diff --git a/app/Http/Requests/StoreProjectTicketBranchRequest.php b/app/Http/Requests/StoreProjectTicketBranchRequest.php index 208f9a9..d7dc682 100644 --- a/app/Http/Requests/StoreProjectTicketBranchRequest.php +++ b/app/Http/Requests/StoreProjectTicketBranchRequest.php @@ -27,14 +27,6 @@ class StoreProjectTicketBranchRequest extends FormRequest 'repository_connection_id' => ['required', 'integer', 'exists:repository_connections,id'], ]; } - - public function branchName(): string - { - return trim((string) $this->validated('branch_name')); - } - - public function repositoryConnectionId(): int - { - return (int) $this->validated('repository_connection_id'); - } } + + diff --git a/app/Http/Requests/StoreRepositoryConnectionRequest.php b/app/Http/Requests/StoreRepositoryConnectionRequest.php index f1e7357..d5ec8e2 100644 --- a/app/Http/Requests/StoreRepositoryConnectionRequest.php +++ b/app/Http/Requests/StoreRepositoryConnectionRequest.php @@ -28,13 +28,5 @@ class StoreRepositoryConnectionRequest extends FormRequest ]; } - public function providerRepositoryId(): string - { - return (string) $this->validated('provider_repository_id'); - } - public function userGitConnectionId(): int - { - return (int) $this->validated('user_git_connection_id'); - } } diff --git a/app/Http/Requests/StoreTicketFieldDefinitionRequest.php b/app/Http/Requests/StoreTicketFieldDefinitionRequest.php index 1932178..bd09cfa 100644 --- a/app/Http/Requests/StoreTicketFieldDefinitionRequest.php +++ b/app/Http/Requests/StoreTicketFieldDefinitionRequest.php @@ -31,14 +31,4 @@ class StoreTicketFieldDefinitionRequest extends FormRequest ]; } - public function position(): ?int - { - $position = $this->validated('position'); - - if ($position === null) { - return null; - } - - return (int) $position; - } } diff --git a/app/Http/Requests/StoreTicketLinkRequest.php b/app/Http/Requests/StoreTicketLinkRequest.php index 134eccb..50a299a 100644 --- a/app/Http/Requests/StoreTicketLinkRequest.php +++ b/app/Http/Requests/StoreTicketLinkRequest.php @@ -61,14 +61,4 @@ class StoreTicketLinkRequest extends FormRequest }, ]; } - - public function linkedTicketId(): int - { - return (int) $this->validated('linked_ticket_id'); - } - - public function ticketLinkTypeId(): int - { - return (int) $this->validated('ticket_link_type_id'); - } } diff --git a/app/Http/Requests/SyncProjectPermissionsRequest.php b/app/Http/Requests/SyncProjectPermissionsRequest.php index 7dfa672..ee397ee 100644 --- a/app/Http/Requests/SyncProjectPermissionsRequest.php +++ b/app/Http/Requests/SyncProjectPermissionsRequest.php @@ -28,20 +28,10 @@ class SyncProjectPermissionsRequest extends FormRequest 'permissions' => ['nullable', 'array'], 'permissions.*' => [ 'string', + 'distinct', Rule::in(ProjectPermissionService::permissions()), ], ]; } - /** - * @return array - */ - public function permissions(): array - { - return collect($this->validated('permissions', [])) - ->map(fn (mixed $permission): string => (string) $permission) - ->unique() - ->values() - ->all(); - } } diff --git a/app/Http/Requests/UpdateProjectNamedSettingRequest.php b/app/Http/Requests/UpdateProjectNamedSettingRequest.php index 84b8fe0..68800ad 100644 --- a/app/Http/Requests/UpdateProjectNamedSettingRequest.php +++ b/app/Http/Requests/UpdateProjectNamedSettingRequest.php @@ -28,8 +28,5 @@ class UpdateProjectNamedSettingRequest extends FormRequest ]; } - public function position(): int - { - return (int) $this->validated('position'); - } + } diff --git a/app/Http/Requests/UpdateProjectTicketRequest.php b/app/Http/Requests/UpdateProjectTicketRequest.php index 4a543df..02191cd 100644 --- a/app/Http/Requests/UpdateProjectTicketRequest.php +++ b/app/Http/Requests/UpdateProjectTicketRequest.php @@ -174,26 +174,6 @@ class UpdateProjectTicketRequest extends FormRequest return $attributes; } - /** - * @return array - */ - public function fieldValues(): array - { - /** @var array $fieldValues - */ - $fieldValues = $this->validated('field_values', []); - - return $fieldValues; - } - private function createsCycle(Ticket $ticket, Ticket $candidateParent): bool { $currentParent = $candidateParent; diff --git a/app/Http/Requests/UpdateRepositoryConnectionRequest.php b/app/Http/Requests/UpdateRepositoryConnectionRequest.php index e3d7389..48da785 100644 --- a/app/Http/Requests/UpdateRepositoryConnectionRequest.php +++ b/app/Http/Requests/UpdateRepositoryConnectionRequest.php @@ -28,13 +28,5 @@ class UpdateRepositoryConnectionRequest extends FormRequest ]; } - public function providerRepositoryId(): string - { - return (string) $this->validated('provider_repository_id'); - } - public function userGitConnectionId(): int - { - return (int) $this->validated('user_git_connection_id'); - } } diff --git a/app/Http/Requests/UpdateTeamMembersRequest.php b/app/Http/Requests/UpdateTeamMembersRequest.php index af3106d..680f1ab 100644 --- a/app/Http/Requests/UpdateTeamMembersRequest.php +++ b/app/Http/Requests/UpdateTeamMembersRequest.php @@ -25,19 +25,8 @@ class UpdateTeamMembersRequest extends FormRequest { return [ 'user_ids' => ['nullable', 'array'], - 'user_ids.*' => ['integer', Rule::exists('users', 'id')], + 'user_ids.*' => ['integer', 'distinct', Rule::exists('users', 'id')], ]; } - /** - * @return array - */ - public function userIds(): array - { - return collect($this->validated('user_ids', [])) - ->map(fn (mixed $userId): int => (int) $userId) - ->unique() - ->values() - ->all(); - } } diff --git a/app/Http/Requests/UpdateTicketFieldDefinitionRequest.php b/app/Http/Requests/UpdateTicketFieldDefinitionRequest.php index 29fff74..69147f0 100644 --- a/app/Http/Requests/UpdateTicketFieldDefinitionRequest.php +++ b/app/Http/Requests/UpdateTicketFieldDefinitionRequest.php @@ -31,8 +31,4 @@ class UpdateTicketFieldDefinitionRequest extends FormRequest ]; } - public function position(): int - { - return (int) $this->validated('position'); - } } diff --git a/app/Http/Requests/ValidateProjectTicketBranchRequest.php b/app/Http/Requests/ValidateProjectTicketBranchRequest.php index 94fc65e..92f4f2b 100644 --- a/app/Http/Requests/ValidateProjectTicketBranchRequest.php +++ b/app/Http/Requests/ValidateProjectTicketBranchRequest.php @@ -27,14 +27,4 @@ class ValidateProjectTicketBranchRequest extends FormRequest 'repository_connection_id' => ['required', 'integer', 'exists:repository_connections,id'], ]; } - - public function branchName(): string - { - return trim((string) $this->validated('branch_name')); - } - - public function repositoryConnectionId(): int - { - return (int) $this->validated('repository_connection_id'); - } }