Skip to content

Commit 700fe5e

Browse files
committed
make question endpoints openapi compatible
Signed-off-by: Christian Hartmann <[email protected]>
1 parent 5927ca2 commit 700fe5e

File tree

2 files changed

+88
-42
lines changed

2 files changed

+88
-42
lines changed

lib/Controller/ApiController.php

Lines changed: 65 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@
7777
/**
7878
* @psalm-import-type FormsPartialForm from ResponseDefinitions
7979
* @psalm-import-type FormsForm from ResponseDefinitions
80+
* @psalm-import-type FormsQuestion from ResponseDefinitions
81+
* @psalm-import-type FormsOption from ResponseDefinitions
8082
*/
8183
class ApiController extends OCSController {
8284
private ?IUser $currentUser;
@@ -367,10 +369,10 @@ public function deleteForm(int $formId): DataResponse {
367369
/**
368370
* Read all questions (including options)
369371
*
370-
* @param int $formId FormId
371-
* @return DataResponse
372-
* @throws OCSBadRequestException
373-
* @throws OCSForbiddenException
372+
* @param int $formId the form id
373+
* @return DataResponse<array<FormQuestion>, Http::STATUS_OK, array<>>
374+
* @throws OCSForbiddenException User has no permissions to get this form
375+
* @throws OCSNotFoundException Could not find form
374376
*/
375377
#[CORS()]
376378
#[NoAdminRequired()]
@@ -380,7 +382,7 @@ public function getQuestions(int $formId): DataResponse {
380382
$form = $this->formMapper->findById($formId);
381383
} catch (IMapperException $e) {
382384
$this->logger->debug('Could not find form');
383-
throw new OCSBadRequestException();
385+
throw new OCSNotFoundException();
384386
}
385387

386388
if (!$this->formsService->hasUserAccess($form)) {
@@ -398,9 +400,10 @@ public function getQuestions(int $formId): DataResponse {
398400
*
399401
* @param int $formId FormId
400402
* @param int $questionId QuestionId
401-
* @return DataResponse
402-
* @throws OCSBadRequestException
403-
* @throws OCSForbiddenException
403+
* @return DataResponse<FormQuestion, Http::STATUS_OK, array<>>
404+
* @throws OCSBadRequestException Question doesn\'t belong to given Form
405+
* @throws OCSForbiddenException User has no permissions to get this form
406+
* @throws OCSNotFoundException Could not find form
404407
*/
405408
#[CORS()]
406409
#[NoAdminRequired()]
@@ -410,7 +413,7 @@ public function getQuestion(int $formId, int $questionId): DataResponse {
410413
$form = $this->formMapper->findById($formId);
411414
} catch (IMapperException $e) {
412415
$this->logger->debug('Could not find form');
413-
throw new OCSBadRequestException();
416+
throw new OCSNotFoundException();
414417
}
415418

416419
if (!$this->formsService->hasUserAccess($form)) {
@@ -421,7 +424,7 @@ public function getQuestion(int $formId, int $questionId): DataResponse {
421424
$question = $this->formsService->getQuestion($questionId);
422425

423426
if ($question['formId'] !== $formId) {
424-
throw new OCSBadRequestException('Question doesn\'t belong to given Form');
427+
throw new OCSBadRequestException('Question doesn\'t belong to given form');
425428
}
426429

427430
return new DataResponse($question);
@@ -433,10 +436,14 @@ public function getQuestion(int $formId, int $questionId): DataResponse {
433436
* @param int $formId the form id
434437
* @param string $type the new question type
435438
* @param string $text the new question title
436-
* @param int $fromId (optional) id of the question that should be cloned
437-
* @return DataResponse
438-
* @throws OCSBadRequestException
439-
* @throws OCSForbiddenException
439+
* @param ?int $fromId (optional) id of the question that should be cloned
440+
* @return DataResponse<FormQuestion, Http::STATUS_CREATED, array<>>
441+
* @throws OCSBadRequestException Invalid type
442+
* @throws OCSBadRequestException Datetime question type no longer supported
443+
* @throws OCSForbiddenException User has no permissions to get this form
444+
* @throws OCSForbiddenException This form is archived and can not be modified
445+
* @throws OCSNotFoundException Could not find form
446+
* @throws OCSNotFoundException Could not find question
440447
*/
441448
#[CORS()]
442449
#[NoAdminRequired()]
@@ -530,19 +537,26 @@ public function newQuestion(int $formId, ?string $type = null, string $text = ''
530537

531538
$this->formMapper->update($form);
532539

533-
return new DataResponse($response);
540+
return new DataResponse($response, Http::STATUS_CREATED);
534541
}
535542

536543
/**
537-
* Writes the given key-value pairs into Database.
538-
* Key 'order' should only be changed by reorderQuestions() and is not allowed here.
544+
* Writes the given key-value pairs into Database
545+
* Key `order` should only be changed by reorderQuestions() and is not allowed here
539546
*
540547
* @param int $formId the form id
541548
* @param int $questionId id of question to update
542-
* @param array $keyValuePairs Array of key=>value pairs to update.
543-
* @return DataResponse
544-
* @throws OCSBadRequestException
545-
* @throws OCSForbiddenException
549+
* @param array<string, mixed> $keyValuePairs Array of key=>value pairs to update.
550+
* @return DataResponse<int id, Http::STATUS_OK, array<>>
551+
* @throws OCSBadRequestException Question doesn\'t belong to given Form
552+
* @throws OCSBadRequestException Invalid extraSettings, will not update.
553+
* @throws OCSForbiddenException Empty keyValuePairs, will not update
554+
* @throws OCSForbiddenException Not allowed to update `id` or `formId`
555+
* @throws OCSForbiddenException Please use reorderQuestions() to change order
556+
* @throws OCSForbiddenException This form is archived and can not be modified
557+
* @throws OCSForbiddenException User has no permissions to get this form
558+
* @throws OCSNotFoundException Could not find form
559+
* @throws OCSNotFoundException Could not find question
546560
*/
547561
#[CORS()]
548562
#[NoAdminRequired()]
@@ -558,7 +572,7 @@ public function updateQuestion(int $formId, int $questionId, array $keyValuePair
558572
$question = $this->questionMapper->findById($questionId);
559573
} catch (IMapperException $e) {
560574
$this->logger->debug('Could not find question');
561-
throw new OCSBadRequestException('Could not find question');
575+
throw new OCSNotFoundException('Could not find question');
562576
}
563577

564578
if ($question->getFormId() !== $formId) {
@@ -568,19 +582,19 @@ public function updateQuestion(int $formId, int $questionId, array $keyValuePair
568582
$form = $this->getFormIfAllowed($formId);
569583
if ($this->formsService->isFormArchived($form)) {
570584
$this->logger->debug('This form is archived and can not be modified');
571-
throw new OCSForbiddenException();
585+
throw new OCSForbiddenException('This form is archived and can not be modified');
572586
}
573587

574588
// Don't allow empty array
575589
if (sizeof($keyValuePairs) === 0) {
576590
$this->logger->info('Empty keyValuePairs, will not update.');
577-
throw new OCSForbiddenException();
591+
throw new OCSBacRequestException('This form is archived and can not be modified');
578592
}
579593

580594
//Don't allow to change id or formId
581595
if (key_exists('id', $keyValuePairs) || key_exists('formId', $keyValuePairs)) {
582596
$this->logger->debug('Not allowed to update \'id\' or \'formId\'');
583-
throw new OCSForbiddenException();
597+
throw new OCSForbiddenException('Not allowed to update \'id\' or \'formId\'');
584598
}
585599

586600
// Don't allow to reorder here
@@ -609,9 +623,12 @@ public function updateQuestion(int $formId, int $questionId, array $keyValuePair
609623
*
610624
* @param int $formId the form id
611625
* @param int $questionId the question id
612-
* @return DataResponse
613-
* @throws OCSBadRequestException
614-
* @throws OCSForbiddenException
626+
* @return DataResponse<int id, Http::STATUS_OK, array<>>
627+
* @throws OCSBadRequestException Question doesn\'t belong to given Form
628+
* @throws OCSForbiddenException This form is archived and can not be modified
629+
* @throws OCSForbiddenException User has no permissions to get this form
630+
* @throws OCSNotFoundException Could not find form
631+
* @throws OCSNotFoundException Could not find question
615632
*/
616633
#[CORS()]
617634
#[NoAdminRequired()]
@@ -625,7 +642,7 @@ public function deleteQuestion(int $formId, int $questionId): DataResponse {
625642
$question = $this->questionMapper->findById($questionId);
626643
} catch (IMapperException $e) {
627644
$this->logger->debug('Could not find question');
628-
throw new OCSBadRequestException('Could not find question');
645+
throw new OCSNotFoundException('Could not find question');
629646
}
630647

631648
if ($question->getFormId() !== $formId) {
@@ -635,7 +652,7 @@ public function deleteQuestion(int $formId, int $questionId): DataResponse {
635652
$form = $this->getFormIfAllowed($formId);
636653
if ($this->formsService->isFormArchived($form)) {
637654
$this->logger->debug('This form is archived and can not be modified');
638-
throw new OCSForbiddenException();
655+
throw new OCSForbiddenException('This form is archived and can not be modified');
639656
}
640657

641658
// Store Order of deleted Question
@@ -661,13 +678,19 @@ public function deleteQuestion(int $formId, int $questionId): DataResponse {
661678
}
662679

663680
/**
664-
* Updates the Order of all Questions of a Form.
681+
* Updates the Order of all Questions of a Form
665682
*
666683
* @param int $formId Id of the form to reorder
667-
* @param array<int, int> $newOrder Array of Question-Ids in new order.
668-
* @return DataResponse
669-
* @throws OCSBadRequestException
670-
* @throws OCSForbiddenException
684+
* @param array<string, int> $newOrder Array of Question-Ids in new order.
685+
* @return DataResponse<array<int, int>, Http::STATUS_OK, array<>>
686+
* @throws OCSBadRequestException The given array contains duplicates
687+
* @throws OCSBadRequestException The length of the given array does not match the number of stored questions
688+
* @throws OCSBadRequestException Question doesn\'t belong to given Form
689+
* @throws OCSBadRequestException One question has already been marked as deleted
690+
* @throws OCSForbiddenException This form is archived and can not be modified
691+
* @throws OCSForbiddenException User has no permissions to get this form
692+
* @throws OCSNotFoundException Could not find form
693+
* @throws OCSNotFoundException Could not find question
671694
*/
672695
#[CORS()]
673696
#[NoAdminRequired()]
@@ -681,7 +704,7 @@ public function reorderQuestions(int $formId, array $newOrder): DataResponse {
681704
$form = $this->getFormIfAllowed($formId);
682705
if ($this->formsService->isFormArchived($form)) {
683706
$this->logger->debug('This form is archived and can not be modified');
684-
throw new OCSForbiddenException();
707+
throw new OCSForbiddenException('This form is archived and can not be modified');
685708
}
686709

687710
// Check if array contains duplicates
@@ -705,27 +728,27 @@ public function reorderQuestions(int $formId, array $newOrder): DataResponse {
705728
try {
706729
$questions[$arrayKey] = $this->questionMapper->findById($questionId);
707730
} catch (IMapperException $e) {
708-
$this->logger->debug('Could not find question. Id: {questionId}', [
731+
$this->logger->debug('Could not find question {questionId}', [
709732
'questionId' => $questionId
710733
]);
711-
throw new OCSBadRequestException();
734+
throw new OCSNotFoundException('Could not find question');
712735
}
713736

714737
// Abort if a question is not part of the Form.
715738
if ($questions[$arrayKey]->getFormId() !== $formId) {
716-
$this->logger->debug('This Question is not part of the given Form: questionId: {questionId}', [
739+
$this->logger->debug('This Question is not part of the given form: {questionId}', [
717740
'questionId' => $questionId
718741
]);
719-
throw new OCSBadRequestException();
742+
throw new OCSBadRequestException('Question doesn\'t belong to given Form');
720743
}
721744

722745
// Abort if a question is already marked as deleted (order==0)
723746
$oldOrder = $questions[$arrayKey]->getOrder();
724747
if ($oldOrder === 0) {
725-
$this->logger->debug('This Question has already been marked as deleted: Id: {questionId}', [
748+
$this->logger->debug('This question has already been marked as deleted: Id: {questionId}', [
726749
'questionId' => $questions[$arrayKey]->getId()
727750
]);
728-
throw new OCSBadRequestException();
751+
throw new OCSBadRequestException('One question has already been marked as deleted');
729752
}
730753

731754
// Only set order, if it changed.

lib/ResponseDefinitions.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
* "shares": array<FormsShare>,
4444
* "submissions": array<FormsSubmission>,
4545
* }
46+
*
4647
* @psalm-type FormsPartialForm = array{
4748
* "id": int,
4849
* "hash": string,
@@ -52,6 +53,28 @@
5253
* "partial": bool true,
5354
* "state": int
5455
* }
56+
*
57+
* @psalm-type FormsQuestion = array{
58+
* "id": int,
59+
* "formId": int,
60+
* "order": int,
61+
* "type": string,
62+
* "isRequired": bool,
63+
* "text": string,
64+
* "name": string,
65+
* "options": array<FormsOption>,
66+
* "accept": array<FormsQuestionFileType>,
67+
* "extraSettings": stdClass
68+
* }
69+
*
70+
* @psalm-type FormsOption = array{
71+
* "id": int,
72+
* "questionId": int,
73+
* "text": string,
74+
* "order": ?int
75+
* }
76+
*
77+
* @psalm-type FormsQuestionFileType = string
5578
*/
5679
class ResponseDefinitions {
5780
}

0 commit comments

Comments
 (0)