Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QE-513: tempId for newly created objects #3594

Merged
merged 19 commits into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions application/libraries/Api/Command/V1/SurveyPatch.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,14 @@ public function run(Request $request)
PatcherSurvey::class
);
try {
$patcher->applyPatch($patch, ['id' => $id]);
$returnedData = $patcher->applyPatch($patch, ['id' => $id]);
} catch (ObjectPatchException $e) {
return $this->responseFactory->makeErrorBadRequest(
$e->getMessage()
);
}

return $this->responseFactory
->makeSuccess(true);
->makeSuccess($returnedData);
}
}
106 changes: 83 additions & 23 deletions application/libraries/Api/Command/V1/SurveyPatch/OpHandlerAnswer.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,42 +54,50 @@ public function canHandle(OpInterface $op): bool
* "id" is the qid, so we are only allowing answers for a single question in
* the patch.
* Attention: Currently all answers not provided in the patch
* will be deleted by the service.
* All existing answers are needed independently from "update" or "create".
* will be deleted by the service. Doesn't matter if
* create or update was chosen
* You could also mix updated and newly created answers in one patch.
* The difference is that new created answers need "tempId"
* and updated answers need the "aid" provided.
* The OpHandler doesn't care if you choose create or update as "op"!!!
*
* Example for "update":
* {
* "patch": [{
* "entity": "answer",
* "op": "create", // "update"
* "id": "726", // qid(!)
* "op": "update",
* "id": "809",
* "props": {
* "0": {
* "code": "XX01",
* "sortOrder": 0,
* "aid": 465,
* "code": "AO01",
* "sortOrder": 2,
* "assessmentValue": 0,
* "scaleId": 0,
* "scaleId": 1,
* "l10ns": {
* "de": {
* "answer": "antwort1",
* "answer": "ANTW1 scale 1",
* "language": "de"
* },
* "en": {
* "answer": "answer1",
* "answer": "ANS1 scale 1",
* "language": "en"
* }
* }
* },
* "1": {
* "code": "YY02",
* "sortOrder": 1,
* "aid": 467,
* "code": "AO02",
* "sortOrder": 3,
* "assessmentValue": 0,
* "scaleId": 0,
* "scaleId": 1,
* "l10ns": {
* "de": {
* "answer": "antwort1.2",
* "answer": "ANTW2 scale 1",
* "language": "de"
* },
* "en": {
* "answer": "answer1.2",
* "answer": "ANS2 scale 1",
* "language": "en"
* }
* }
Expand All @@ -99,30 +107,82 @@ public function canHandle(OpInterface $op): bool
* ]
* }
*
* Example for "create":
* {
* "patch": [{
* "entity": "answer",
* "op": "create",
* "id": "809",
* "props": {
* "0": {
* "tempId": "222",
* "code": "AO11",
* "sortOrder": 4,
* "assessmentValue": 0,
* "scaleId": 1,
* "l10ns": {
* "de": {
* "answer": "ANTW11 scale 1",
* "language": "de"
* },
* "en": {
* "answer": "ANS11 scale 1",
* "language": "en"
* }
* }
* },
* "1": {
* "tempId": "223",
* "code": "AO12",
* "sortOrder": 5,
* "assessmentValue": 0,
* "scaleId": 1,
* "l10ns": {
* "de": {
* "answer": "ANTW12 scale 1",
* "language": "de"
* },
* "en": {
* "answer": "ANS12 scale 1",
* "language": "en"
* }
* }
* }
* }
* }
* ]
* }
* @param OpInterface $op
* @return void
* @return array
* @throws OpHandlerException
* @throws \DI\DependencyException
* @throws \DI\NotFoundException
* @throws \LimeSurvey\Models\Services\Exception\NotFoundException
* @throws \LimeSurvey\Models\Services\Exception\PermissionDeniedException
* @throws \LimeSurvey\Models\Services\Exception\PersistErrorException
*/
public function handle(OpInterface $op): void
public function handle(OpInterface $op): array
{
$question = $this->questionService->getQuestionBySidAndQid(
$this->getSurveyIdFromContext($op),
$op->getEntityId()
);
$preparedData = $this->prepareAnswers(
$op,
$op->getProps(),
$this->transformerAnswer,
$this->transformerAnswerL10n,
['answer', 'answerL10n']
);
$this->answersService->save(
$question,
$this->prepareAnswers(
$op,
$op->getProps(),
$this->transformerAnswer,
$this->transformerAnswerL10n,
['answer', 'answerL10n']
)
$preparedData
);

return $this->getSubQuestionNewIdMapping(
$question,
$preparedData,
true
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,29 +81,30 @@ public function canHandle(OpInterface $op): bool
* "mandatory": false,
* "relevance": "1",
* "encrypted": false,
* "save_as_default": false
* "save_as_default": false,
kevin-foster-uk marked this conversation as resolved.
Show resolved Hide resolved
* "tempId": "XXX321"
* },
* "questionL10n": {
* "en": {
* "question": "Array Question",
* "help": "Help text"
* },
* "de-informal": {
* "de": {
* "question": "Array ger",
* "help": "help ger"
* }
* },
* "attributes": {
* "dualscale_headerA": {
* "de-informal": {
* "de": {
* "value": "A ger"
* },
* "en": {
* "value": "A"
* }
* },
* "dualscale_headerB": {
* "de-informal": {
* "de": {
* "value": "B ger"
* },
* "en": {
Expand All @@ -122,6 +123,7 @@ public function canHandle(OpInterface $op): bool
* "sortOrder": 0,
* "assessmentValue": 0,
* "scaleId": 0,
* "tempId": "111",
* "l10ns": {
* "de": {
* "answer": "antwort1",
Expand All @@ -138,6 +140,7 @@ public function canHandle(OpInterface $op): bool
* "sortOrder": 1,
* "assessmentValue": 0,
* "scaleId": 0,
* "tempId": "112",
* "l10ns": {
* "de": {
* "answer": "antwort1.2",
Expand All @@ -155,8 +158,9 @@ public function canHandle(OpInterface $op): bool
* "title": "SQ001",
* "sortOrder": 0,
* "relevance": "1",
* "tempId": "113",
* "l10ns": {
* "de-informal": {
* "de": {
* "question": "subger1",
* "language": "de"
* },
Expand All @@ -170,8 +174,9 @@ public function canHandle(OpInterface $op): bool
* "title": "SQ002",
* "sortOrder": 1,
* "relevance": "1",
* "tempId": "114",
* "l10ns": {
* "de-informal": {
* "de": {
* "question": "subger2",
* "language": "de"
* },
Expand All @@ -188,25 +193,59 @@ public function canHandle(OpInterface $op): bool
* }
*
* @param OpInterface $op
* @return void
* @return array
* @throws OpHandlerException
* @throws \DI\DependencyException
* @throws \DI\NotFoundException
* @throws \LimeSurvey\Models\Services\Exception\NotFoundException
* @throws \LimeSurvey\Models\Services\Exception\PermissionDeniedException
* @throws \LimeSurvey\Models\Services\Exception\PersistErrorException
*/
public function handle(OpInterface $op): void
public function handle(OpInterface $op): array
{
$diContainer = \LimeSurvey\DI::getContainer();
$questionService = $diContainer->get(
QuestionAggregateService::class
);
$transformedProps = $this->prepareData($op);
if (
is_array($transformedProps) &&
array_key_exists(
'question',
$transformedProps
)
) {
$tempId = $this->extractTempId($transformedProps['question']);
kevin-foster-uk marked this conversation as resolved.
Show resolved Hide resolved
$diContainer = \LimeSurvey\DI::getContainer();
$questionService = $diContainer->get(
QuestionAggregateService::class
);

$questionService->save(
$this->getSurveyIdFromContext($op),
$this->prepareData($op)
);
$question = $questionService->save(
$this->getSurveyIdFromContext($op),
$transformedProps
);
} else {
throw new OpHandlerException(
sprintf(
'no question entity provided within props for %s with id "%s"',
$this->entity,
print_r($op->getEntityId(), true)
)
);
}

return [
'questionsMap' => [
'tempId' => $tempId,
'qid' => $question->qid
],
$this->getSubQuestionNewIdMapping(
$question,
$transformedProps['subquestions']
),
$this->getSubQuestionNewIdMapping(
$question,
$transformedProps['answeroptions'],
true
)
];
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,19 +70,19 @@ public function canHandle(OpInterface $op): bool
* @param OpInterface $op
* @throws OpHandlerException
*/
public function handle(OpInterface $op): void
public function handle(OpInterface $op): array
{
switch (true) {
case $this->isUpdateOperation:
$this->update($op);
break;
case $this->isCreateOperation:
$this->create($op);
break;
return $this->create($op);
case $this->isDeleteOperation:
$this->delete($op);
break;
}
return [];
}

/**
Expand Down Expand Up @@ -210,6 +210,7 @@ private function update(OpInterface $op)
* "op": "create",
* "props":{
* "questionGroup": {
* "tempId": 777,
* "randomizationGroup": "",
* "gRelevance": ""
* },
Expand All @@ -235,19 +236,27 @@ private function update(OpInterface $op)
*
* @param OpInterface $op
* @param QuestionGroupService $groupService
* @return void
* @return array
* @throws OpHandlerException
* @throws \LimeSurvey\Models\Services\Exception\NotFoundException
* @throws \LimeSurvey\Models\Services\Exception\PersistErrorException
*/
private function create(OpInterface $op)
private function create(OpInterface $op): array
{
$surveyId = $this->getSurveyIdFromContext($op);
$transformedProps = $this->getTransformedProps($op);
$this->questionGroupService->createGroup(
$tempId = $this->extractTempId($transformedProps['questionGroup']);
$questionGroup = $this->questionGroupService->createGroup(
$surveyId,
$transformedProps
);
$questionGroup->refresh();
return [
'questionGroupsMap' => [
'tempId' => $tempId,
'gid' => $questionGroup->gid
]
];
}

/**
Expand Down