From a5503611ad366eac8352c5d06be4ce2bca74b91e Mon Sep 17 00:00:00 2001 From: Angel Fernando Quiroz Campos Date: Tue, 25 Feb 2020 17:52:56 -0500 Subject: [PATCH] MigrationMoodle: Add task for gapselect questions - refs BT#15992 --- plugin/migrationmoodle/admin.php | 1 + plugin/migrationmoodle/lang/english.php | 1 + .../src/Loader/QuestionGapselectLoader.php | 37 ++++++++ .../src/Task/QuestionGapselectTask.php | 89 +++++++++++++++++++ .../Property/QuestionGapselectAnswer.php | 77 ++++++++++++++++ .../src/Transformer/Property/QuestionType.php | 2 +- 6 files changed, 206 insertions(+), 1 deletion(-) create mode 100644 plugin/migrationmoodle/src/Loader/QuestionGapselectLoader.php create mode 100644 plugin/migrationmoodle/src/Task/QuestionGapselectTask.php create mode 100644 plugin/migrationmoodle/src/Transformer/Property/QuestionGapselectAnswer.php diff --git a/plugin/migrationmoodle/admin.php b/plugin/migrationmoodle/admin.php index 12e7c2ada1..903992cc6f 100644 --- a/plugin/migrationmoodle/admin.php +++ b/plugin/migrationmoodle/admin.php @@ -74,6 +74,7 @@ $menu = [ 'question_multi_choice_multiple', 'questions_true_false', 'question_short_answer', + 'question_gapselect', ], 'course_modules_scorm' => [ 'scorm_scoes', diff --git a/plugin/migrationmoodle/lang/english.php b/plugin/migrationmoodle/lang/english.php index 575f987bec..6cae005e60 100644 --- a/plugin/migrationmoodle/lang/english.php +++ b/plugin/migrationmoodle/lang/english.php @@ -60,3 +60,4 @@ $strings['UsersScormsProgressTask'] = 'Scorm progress'; $strings['UsersLearnPathsTask'] = 'Learn paths views of users'; $strings['UsersLearnPathsSectionsTask'] = 'Learn paths sections views of users'; $strings['QuizzesScoresTask'] = 'Update quiz scores in learn path'; +$strings['QuestionGapselectTask'] = 'Answers for gapselect questions'; diff --git a/plugin/migrationmoodle/src/Loader/QuestionGapselectLoader.php b/plugin/migrationmoodle/src/Loader/QuestionGapselectLoader.php new file mode 100644 index 0000000000..87666f5e23 --- /dev/null +++ b/plugin/migrationmoodle/src/Loader/QuestionGapselectLoader.php @@ -0,0 +1,37 @@ +read($incomingData['quiz_id']); + + $question = \Question::read($incomingData['question_id'], $courseInfo); + $question->setTitle(get_lang('FillBlanks')); + $question->weighting = $incomingData['score']; + + $answer = new \Answer($incomingData['question_id'], $incomingData['c_id'], $exercise); + $answer->createAnswer($incomingData['answer'], 0, $incomingData['comment'], 0, 1); + $answer->save(); + + $question->save($exercise); + + return $question->id; + } +} diff --git a/plugin/migrationmoodle/src/Task/QuestionGapselectTask.php b/plugin/migrationmoodle/src/Task/QuestionGapselectTask.php new file mode 100644 index 0000000000..db4478fa8c --- /dev/null +++ b/plugin/migrationmoodle/src/Task/QuestionGapselectTask.php @@ -0,0 +1,89 @@ + LoadedCoursesFilterExtractor::class, + 'query' => "SELECT + qa.id, + qa.question, + GROUP_CONCAT( + CONCAT(qa.feedback, '==>>', qa.answer) ORDER BY qa.id ASC SEPARATOR '@||@' + ) answers, + qq.questiontext, + qs.maxmark, + qg.correctfeedback, + q.id quiz_id, + q.course + FROM mdl_question_answers qa + INNER JOIN mdl_question qq ON qa.question = qq.id + INNER JOIN mdl_question_gapselect qg ON qq.id = qg.questionid + INNER JOIN mdl_quiz_slots qs ON qq.id = qs.questionid + INNER JOIN mdl_quiz q ON qs.quizid = q.id + WHERE qq.qtype = 'gapselect' + GROUP BY q.id, qq.id + ORDER BY q.id, qq.id" + ]; + } + + /** + * @inheritDoc + */ + public function getTransformConfiguration() + { + return [ + 'class' => BaseTransformer::class, + 'map' => [ + 'c_id' => [ + 'class' => LoadedCourseLookup::class, + 'properties' => ['course'], + ], + 'quiz_id' => [ + 'class' => LoadedQuizLookup::class, + 'properties' => ['quiz_id'], + ], + 'question_id' => [ + 'class' => LoadedQuestionLookup::class, + 'properties' => ['question'], + ], + 'answer' => [ + 'class' => QuestionGapselectAnswer::class, + 'properties' => ['answers', 'questiontext', 'maxmark'], + ], + 'score' => 'maxmark', + 'comment' => 'correctfeedback', + ], + ]; + } + + /** + * @inheritDoc + */ + public function getLoadConfiguration() + { + return [ + 'class' => QuestionGapselectLoader::class, + ]; + } +} diff --git a/plugin/migrationmoodle/src/Transformer/Property/QuestionGapselectAnswer.php b/plugin/migrationmoodle/src/Transformer/Property/QuestionGapselectAnswer.php new file mode 100644 index 0000000000..1dcbaabe03 --- /dev/null +++ b/plugin/migrationmoodle/src/Transformer/Property/QuestionGapselectAnswer.php @@ -0,0 +1,77 @@ + $groupAndOption) { + $position = $zeroPosition + 1; + + list($group, $option) = explode('==>>', $groupAndOption); + + $positionsByGroup[$position] = $group; + $groups[$group][$position] = $option; + } + + $blanks = []; + + foreach ($positionsByGroup as $option => $group) { + if ($option === 1) { + $blanks[] = '['.implode($groups[$group], '|').']'; + + continue; + } + + $baz = $groups[$group]; + + unset($baz[$option]); + + $baz = [$groups[$group][$option]] + $baz; + + $blanks[] = '['.implode($baz, '|').']'; + } + + $countBlanks = 0; + + foreach ($blanks as $zeroPosition => $blank) { + $countBlank = 0; + $position = $zeroPosition + 1; + $questionText = str_replace("[[$position]]", $blank, $questionText, $countBlank); + + $countBlanks += $countBlank; + } + + $individualScore = $score / $countBlanks; + $scores = []; + + for ($i = 0; $i < $countBlanks - 1; $i++) { + $scores[] = $individualScore; + } + + $scores[] = $score - array_sum($scores); + + $inputs = str_repeat('300,', $countBlanks - 1).'300'; + + return "$questionText::".implode(',', $scores).":$inputs:0@"; + } +} diff --git a/plugin/migrationmoodle/src/Transformer/Property/QuestionType.php b/plugin/migrationmoodle/src/Transformer/Property/QuestionType.php index 452bb0725d..ee72520e74 100644 --- a/plugin/migrationmoodle/src/Transformer/Property/QuestionType.php +++ b/plugin/migrationmoodle/src/Transformer/Property/QuestionType.php @@ -36,6 +36,7 @@ class QuestionType implements TransformPropertyInterface return MATCHING_DRAGGABLE; case 'shortanswer': case 'numerical': + case 'gapselect': return FILL_IN_BLANKS; case 'essay': return FREE_ANSWER; @@ -48,7 +49,6 @@ class QuestionType implements TransformPropertyInterface case 'ddimageortext': case 'multianswer': case 'randomsamatch': - case 'gapselect': case 'description': throw new \Exception("Question type \"$qtype\" not supported in question \"$id\"."); }