diff --git a/lib/Controller/ApiController.php b/lib/Controller/ApiController.php index 848155601..096cf5e45 100644 --- a/lib/Controller/ApiController.php +++ b/lib/Controller/ApiController.php @@ -894,7 +894,7 @@ public function reorderQuestions(int $formId, array $newOrder): DataResponse { * @param int $formId id of the form * @param int $questionId id of the question * @param list $optionTexts the new option text - * @param string|null $optionType the new option type (e.g. 'row') + * @param string|null $optionType the new option type (e.g. 'row'), defaults to 'choice' * @return DataResponse, array{}> Returns a DataResponse containing the added options * @throws OCSBadRequestException This question is not part ot the given form * @throws OCSForbiddenException This form is archived and can not be modified @@ -908,7 +908,7 @@ public function reorderQuestions(int $formId, array $newOrder): DataResponse { #[NoAdminRequired()] #[BruteForceProtection(action: 'form')] #[ApiRoute(verb: 'POST', url: '/api/v3/forms/{formId}/questions/{questionId}/options')] - public function newOption(int $formId, int $questionId, array $optionTexts, ?string $optionType = null): DataResponse { + public function newOption(int $formId, int $questionId, array $optionTexts, ?string $optionType = 'choice'): DataResponse { $this->logger->debug('Adding new options: formId: {formId}, questionId: {questionId}, text: {text}, optionType: {optionType}', [ 'formId' => $formId, 'questionId' => $questionId, diff --git a/lib/Migration/Version050300Date20260716000000.php b/lib/Migration/Version050300Date20260716000000.php new file mode 100644 index 000000000..c5becf402 --- /dev/null +++ b/lib/Migration/Version050300Date20260716000000.php @@ -0,0 +1,67 @@ +getTable('forms_v2_options'); + $changed = false; + + if ($table->hasColumn('option_type')) { + $column = $table->getColumn('option_type'); + if ($column->getDefault() === null) { + $column->setDefault('choice'); + $changed = true; + } + } + + return $changed ? $schema : null; + } + + /** + * @param IOutput $output + * @param Closure(): ISchemaWrapper $schemaClosure + * @param array $options + */ + public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void { + $qbUpdate = $this->db->getQueryBuilder(); + + $qbUpdate->update('forms_v2_options') + ->set('option_type', $qbUpdate->createNamedParameter('choice')) + ->where($qbUpdate->expr()->isNull('option_type')) + ->executeStatement(); + } +} diff --git a/openapi.json b/openapi.json index 5bedb6c5d..f9eb1da32 100644 --- a/openapi.json +++ b/openapi.json @@ -2702,8 +2702,8 @@ "optionType": { "type": "string", "nullable": true, - "default": null, - "description": "the new option type (e.g. 'row')" + "default": "choice", + "description": "the new option type (e.g. 'row'), defaults to 'choice'" } } } diff --git a/tests/Integration/Api/ApiV3Test.php b/tests/Integration/Api/ApiV3Test.php index a4f4328d2..e869016b2 100644 --- a/tests/Integration/Api/ApiV3Test.php +++ b/tests/Integration/Api/ApiV3Test.php @@ -497,17 +497,17 @@ public static function dataGetFullForm() { [ 'text' => 'Option 1', 'order' => 1, - 'optionType' => null, + 'optionType' => 'choice', ], [ 'text' => 'Option 2', 'order' => 2, - 'optionType' => null, + 'optionType' => 'choice', ], [ 'text' => '', 'order' => 3, - 'optionType' => null, + 'optionType' => 'choice', ] ], 'accept' => [], @@ -1027,7 +1027,9 @@ public static function dataCreateNewOption() { // 'questionId' => Done dynamically below. 'text' => 'A new Option.', 'order' => 4, - 'optionType' => null, + // Non-grid questions default to the 'choice' option type + // when none is provided. + 'optionType' => 'choice', ] ] ];