userSession->getUser(); if ($user === null) { throw new OCSPreconditionFailedException('Not logged in'); } return $user->getUID(); } #[NoAdminRequired] public function index(): DataResponse { $workflows = $this->workflowMapper->findAllForUser($this->currentUserId()); return new DataResponse(array_map(static fn (Workflow $w) => $w->jsonSerialize(), $workflows)); } /** * @param string[] $filterUserIds * @param int[] $filterLabelIds */ #[NoAdminRequired] public function create( string $title, int $boardId, int $sourceStackId, int $targetStackId, array $filterUserIds = [], array $filterLabelIds = [], bool $notifyEmail = false, bool $enabled = true, ): DataResponse { $this->validate($title, $boardId, $sourceStackId, $targetStackId); $workflow = new Workflow(); $workflow->setUserId($this->currentUserId()); $this->applyFields($workflow, $title, $boardId, $sourceStackId, $targetStackId, $filterUserIds, $filterLabelIds, $notifyEmail, $enabled); $workflow = $this->workflowMapper->insert($workflow); return new DataResponse($workflow->jsonSerialize(), Http::STATUS_CREATED); } /** * @param string[] $filterUserIds * @param int[] $filterLabelIds */ #[NoAdminRequired] public function update( int $id, string $title, int $boardId, int $sourceStackId, int $targetStackId, array $filterUserIds = [], array $filterLabelIds = [], bool $notifyEmail = false, bool $enabled = true, ): DataResponse { $this->validate($title, $boardId, $sourceStackId, $targetStackId); try { $workflow = $this->workflowMapper->findForUser($id, $this->currentUserId()); } catch (DoesNotExistException $e) { throw new OCSNotFoundException('Workflow not found'); } $this->applyFields($workflow, $title, $boardId, $sourceStackId, $targetStackId, $filterUserIds, $filterLabelIds, $notifyEmail, $enabled); $workflow = $this->workflowMapper->update($workflow); return new DataResponse($workflow->jsonSerialize()); } #[NoAdminRequired] public function destroy(int $id): DataResponse { try { $workflow = $this->workflowMapper->findForUser($id, $this->currentUserId()); } catch (DoesNotExistException $e) { throw new OCSNotFoundException('Workflow not found'); } $this->workflowMapper->delete($workflow); return new DataResponse([]); } #[NoAdminRequired] public function boards(): DataResponse { $this->assertDeck(); return new DataResponse($this->deckService->listBoardsForCurrentUser()); } #[NoAdminRequired] public function stacks(int $boardId): DataResponse { $this->assertDeck(); return new DataResponse($this->deckService->listStacks($boardId)); } #[NoAdminRequired] public function labels(int $boardId): DataResponse { $this->assertDeck(); return new DataResponse($this->deckService->listLabels($boardId)); } #[NoAdminRequired] public function participants(int $boardId): DataResponse { $this->assertDeck(); return new DataResponse($this->deckService->listParticipants($boardId)); } private function assertDeck(): void { $user = $this->userSession->getUser(); if ($user === null) { throw new OCSPreconditionFailedException('Not logged in'); } try { $this->deckService->assertDeckAvailable($user); } catch (DeckUnavailableException $e) { throw new OCSPreconditionFailedException('Deck is not available: ' . $e->getMessage()); } } private function validate(string $title, int $boardId, int $sourceStackId, int $targetStackId): void { if (trim($title) === '') { throw new OCSBadRequestException('Title must not be empty'); } if ($sourceStackId === $targetStackId) { throw new OCSBadRequestException('Source and target stack must differ'); } // Reject references to boards or stacks that are gone (or were never // the user's) instead of storing a workflow that can only fail later. // assertDeck() ran first, so an empty list here means "not there", // not "Deck is unreachable". $this->assertDeck(); $boardIds = array_map( static fn (array $board) => (int)$board['id'], $this->deckService->listBoardsForCurrentUser(), ); if (!in_array($boardId, $boardIds, true)) { throw new OCSBadRequestException('The selected board does not exist or is not accessible'); } $stackIds = array_map( static fn (array $stack) => (int)$stack['id'], $this->deckService->listStacks($boardId), ); if (!in_array($sourceStackId, $stackIds, true) || !in_array($targetStackId, $stackIds, true)) { throw new OCSBadRequestException('The selected stack does not exist on this board'); } } /** * @param string[] $filterUserIds * @param int[] $filterLabelIds */ private function applyFields( Workflow $workflow, string $title, int $boardId, int $sourceStackId, int $targetStackId, array $filterUserIds, array $filterLabelIds, bool $notifyEmail, bool $enabled, ): void { $workflow->setTitle($title); $workflow->setBoardId($boardId); $workflow->setSourceStackId($sourceStackId); $workflow->setTargetStackId($targetStackId); $workflow->setFilterUserIds($filterUserIds === [] ? null : json_encode(array_values($filterUserIds))); $workflow->setFilterLabelIds($filterLabelIds === [] ? null : json_encode(array_values($filterLabelIds))); $workflow->setNotifyEmail($notifyEmail); $workflow->setEnabled($enabled); } }