From 4de59861b7b10315b6d0b3cc082a6ce927ba11cd Mon Sep 17 00:00:00 2001
From: Anupama Sarjoshi
Date: Tue, 24 Oct 2023 10:42:25 +0100
Subject: [PATCH] Changing correctanswers to store column numbers
---
.../restore_qtype_oumatrix_plugin.class.php | 19 +-------
classes/column.php | 14 ------
db/install.xml | 2 +-
db/upgrade.php | 2 -
edit_oumatrix_form.php | 6 +--
lang/en/qtype_oumatrix.php | 2 +-
question.php | 18 +++----
questiontype.php | 47 ++++++++++---------
renderer.php | 12 ++---
tests/behat/export.feature | 2 +-
.../testquestion_multipleresponse.moodle.xml | 46 +++++++++---------
.../testquestion_singlechoice.moodle.xml | 35 +++++++-------
version.php | 2 +-
13 files changed, 86 insertions(+), 121 deletions(-)
diff --git a/backup/moodle2/restore_qtype_oumatrix_plugin.class.php b/backup/moodle2/restore_qtype_oumatrix_plugin.class.php
index d74c5ce..77e11f4 100644
--- a/backup/moodle2/restore_qtype_oumatrix_plugin.class.php
+++ b/backup/moodle2/restore_qtype_oumatrix_plugin.class.php
@@ -74,24 +74,7 @@ public function process_qtype_oumatrix_column(array $data): void {
* @param array $data
*/
public function process_qtype_oumatrix_row(array $data): void {
- $data = (object)$data;
-
- // Detect if the question is created or mapped.
- $questioncreated = $this->get_mappingid('question_created',
- $this->get_old_parentid('question'));
-
- // If the question has been created by restore, we need to update the correctanswers to store new column id's.
- if ($questioncreated) {
- // Adjust correct answers.
- $decodedanswers = json_decode($data->correctanswers, true);
- foreach ($decodedanswers as $columnid => $value) {
- $newcolumnid = $this->get_mappingid('qtype_oumatrix_columns', $columnid);
- $decodedanswers[$newcolumnid] = $value;
- unset($decodedanswers[$columnid]);
- }
- $data->correctanswers = json_encode($decodedanswers);
- }
- self::process_qtype_oumatrix_data_with_table_name((array)$data, 'qtype_oumatrix_rows');
+ self::process_qtype_oumatrix_data_with_table_name($data, 'qtype_oumatrix_rows');
}
/**
diff --git a/classes/column.php b/classes/column.php
index 4f387a0..a9357f2 100644
--- a/classes/column.php
+++ b/classes/column.php
@@ -52,18 +52,4 @@ public function __construct(int $questionid, int $number, string $name, int $id
$this->name = $name;
$this->id = $id;
}
-
- /**
- * Returns the array of columns by id's.
- *
- * @param array $columns
- * @return array
- */
- public static function get_column_ids(array $columns): array {
- $columnids = [];
- foreach ($columns as $column) {
- $columnids[$column->id] = $column;
- }
- return $columnids;
- }
}
diff --git a/db/install.xml b/db/install.xml
index 97e981b..f84f553 100644
--- a/db/install.xml
+++ b/db/install.xml
@@ -42,7 +42,7 @@
-
+
diff --git a/db/upgrade.php b/db/upgrade.php
index eef0059..1c221b2 100644
--- a/db/upgrade.php
+++ b/db/upgrade.php
@@ -24,8 +24,6 @@
defined('MOODLE_INTERNAL') || die();
-require_once(__DIR__.'/upgradelib.php');
-
/**
* Execute qtype_oumatrix upgrade from the given old version.
*
diff --git a/edit_oumatrix_form.php b/edit_oumatrix_form.php
index c153c8b..cabe146 100644
--- a/edit_oumatrix_form.php
+++ b/edit_oumatrix_form.php
@@ -258,15 +258,15 @@ private function data_preprocessing_rows($question) {
$question->rowname = [];
foreach ($question->rows as $index => $row) {
$question->rowname[$row->number - 1] = $row->name;
- $decodedanswers = json_decode($row->correctanswers, true);
+ $answerslist = explode(',', $row->correctanswers);
foreach ($question->columns as $key => $column) {
- if (array_key_exists($column->id, $decodedanswers)) {
+ if (in_array($column->number, $answerslist)) {
$columnvalue = 'a' . ($column->number);
if ($question->options->inputtype == 'single') {
$question->rowanswers[$row->number - 1] = $columnvalue;
} else {
$rowanswerslabel = "rowanswers" . $columnvalue;
- $question->{$rowanswerslabel}[$row->number - 1] = $decodedanswers[$column->id];
+ $question->{$rowanswerslabel}[$row->number - 1] = '1';
}
}
}
diff --git a/lang/en/qtype_oumatrix.php b/lang/en/qtype_oumatrix.php
index 76f7e19..4f34be0 100644
--- a/lang/en/qtype_oumatrix.php
+++ b/lang/en/qtype_oumatrix.php
@@ -77,4 +77,4 @@
$string['yougot1right'] = 'You have correctly selected one option.';
$string['yougotnright'] = 'You have correctly selected {$a->num} options';
$string['yougot1rightsubquestion'] = 'You have correctly answered one sub-question.';
-$string['yougotnrightsubquestion'] = 'You have correctly answered {$a->num} sub-question.';
+$string['yougotnrightsubquestion'] = 'You have correctly answered {$a->num} sub-questions.';
diff --git a/question.php b/question.php
index 7fb81d1..076813c 100644
--- a/question.php
+++ b/question.php
@@ -207,12 +207,11 @@ protected function field(int $rowkey): string {
public function get_correct_response(): ?array {
$response = [];
- $columnids = column::get_column_ids($this->columns);
foreach ($this->roworder as $key => $rownumber) {
$row = $this->rows[$rownumber];
- foreach ($row->correctanswers as $colkey => $answer) {
+ foreach ($row->correctanswers as $colnum => $answer) {
// Get the corresponding column number associated with the column key.
- $response[$this->field($key)] = $columnids[$colkey]->number;
+ $response[$this->field($key)] = $colnum;
}
}
return $response;
@@ -255,12 +254,10 @@ public function grade_response(array $response): array {
public function get_num_parts_right(array $response): array {
$numright = 0;
- $columnids = column::get_column_ids($this->columns);
foreach ($this->roworder as $key => $rownumber) {
$row = $this->rows[$rownumber];
- $column = $columnids[array_key_first($row->correctanswers)];
if (array_key_exists($this->field($key), $response) &&
- $response[$this->field($key)] == $column->number) {
+ array_key_exists($response[$this->field($key)], $row->correctanswers)) {
$numright++;
}
}
@@ -324,12 +321,11 @@ public function is_same_response(array $prevresponse, array $newresponse): bool
public function get_correct_response(): ?array {
$response = [];
- $columnids = column::get_column_ids($this->columns);
foreach ($this->roworder as $key => $rownumber) {
$row = $this->rows[$rownumber];
- foreach ($row->correctanswers as $colkey => $answer) {
+ foreach ($row->correctanswers as $colnum => $answer) {
// Get the corresponding column number associated with the column key.
- $response[$this->field($key, $columnids[$colkey]->number)] = $answer;
+ $response[$this->field($key, $colnum)] = $answer;
}
}
return $response;
@@ -401,7 +397,7 @@ public function get_num_grade_allornone(array $response): array {
foreach ($this->columns as $column) {
$reponsekey = $this->field($rowkey, $column->number);
if (array_key_exists($reponsekey, $response)) {
- if (array_key_exists($column->id, $row->correctanswers)) {
+ if (array_key_exists($column->number, $row->correctanswers)) {
// Add to the count of correct responses.
$rowrightresponse++;
} else {
@@ -435,7 +431,7 @@ public function get_num_parts_grade_partial(array $response): array {
if ($row->correctanswers != '' ) {
foreach ($this->columns as $column) {
$reponsekey = $this->field($rowkey, $column->number);
- if (array_key_exists($reponsekey, $response) && array_key_exists($column->id, $row->correctanswers)) {
+ if (array_key_exists($reponsekey, $response) && array_key_exists($column->number, $row->correctanswers)) {
$rightresponse++;
}
}
diff --git a/questiontype.php b/questiontype.php
index 1557a87..31fc1e8 100644
--- a/questiontype.php
+++ b/questiontype.php
@@ -110,7 +110,7 @@ public function save_columns(stdClass $question): array {
$column->number = $columnnumber;
$column->name = $question->columnname[$i];
$column->id = $DB->insert_record('qtype_oumatrix_columns', $column);
- $columnslist[] = $column;
+ $columnslist[$column->number] = $column;
$columnnumber++;
}
return $columnslist;
@@ -141,17 +141,18 @@ public function save_rows(stdClass $question, array $columnslist) {
// Prepare correct answers.
for ($c = 0; $c < count($columnslist); $c++) {
if ($question->inputtype == 'single') {
- $columnindex = preg_replace("/[^0-9]/", "", $question->rowanswers[$i]);
- $answerslist[$columnslist[$columnindex - 1]->id] = "1";
+ $columnnumber = preg_replace("/[^0-9]/", "", $question->rowanswers[$i]);
+ $answerslist[] = $columnnumber;
+ break;
} else {
$rowanswerslabel = "rowanswers" . 'a' . ($c + 1);
if (!isset($question->$rowanswerslabel) || !array_key_exists($i, $question->$rowanswerslabel)) {
continue;
}
- $answerslist[$columnslist[$c]->id] = $question->{$rowanswerslabel}[$i];
+ $answerslist[] = $c + 1;
}
}
- $questionrow->correctanswers = json_encode($answerslist);
+ $questionrow->correctanswers = implode(',',$answerslist);
$questionrow->feedback = $question->feedback[$i]['text'];
$questionrow->feedbackformat = FORMAT_HTML;
$questionrow->id = $DB->insert_record('qtype_oumatrix_rows', $questionrow);
@@ -219,12 +220,12 @@ protected function initialise_question_rows(question_definition $question, stdCl
$newrow = $this->make_row($row);
$correctanswers = [];
foreach ($questiondata->columns as $column) {
- if (array_key_exists($column->id, $newrow->correctanswers)) {
+ if (in_array($column->number, $newrow->correctanswers)) {
if ($questiondata->options->inputtype == 'single') {
$anslabel = 'a' . $column->number;
- $correctanswers[$column->id] = $anslabel;
+ $correctanswers[$column->number] = $anslabel;
} else {
- $correctanswers[$column->id] = $newrow->correctanswers[$column->id];
+ $correctanswers[$column->number] = '1';
}
}
}
@@ -241,7 +242,11 @@ protected function initialise_question_rows(question_definition $question, stdCl
*/
public function make_row(stdClass $rowdata): row {
return new row($rowdata->id, $rowdata->questionid, $rowdata->number, $rowdata->name,
- json_decode($rowdata->correctanswers, true), $rowdata->feedback, $rowdata->feedbackformat);
+ explode(',', $rowdata->correctanswers), $rowdata->feedback, $rowdata->feedbackformat);
+ }
+
+ protected function make_hint($hint) {
+ return question_hint_with_parts::load_from_record($hint);
}
public function delete_question($questionid, $contextid) {
@@ -283,8 +288,7 @@ public function get_total_number_of_choices(object $questiondata):? int {
public function get_num_correct_choices($questiondata) {
$numright = 0;
foreach ($questiondata->rows as $row) {
- $rowanwers = json_decode($row->correctanswers, true);
- $numright += count($rowanwers);
+ $numright += count((array)$row->correctanswers);
}
return $numright;
}
@@ -362,7 +366,7 @@ public function import_columns(qformat_xml $format, stdClass $question, array $c
static $indexno = 0;
$question->columns[$indexno]['name'] =
$format->import_text($format->getpath($column, ['#', 'text'], ''));
- $question->columns[$indexno]['id'] = $format->getpath($column, ['@', 'key'], $indexno);
+ $question->columns[$indexno]['number'] = $format->getpath($column, ['@', 'number'], $indexno);
$question->columnname[$indexno] =
$format->import_text($format->getpath($column, ['#', 'text'], ''));
@@ -373,23 +377,22 @@ public function import_columns(qformat_xml $format, stdClass $question, array $c
public function import_rows(qformat_xml $format, stdClass $question, array $rows) {
foreach ($rows as $row) {
static $indexno = 0;
- $question->rows[$indexno]['id'] = $format->getpath($row, ['@', 'key'], $indexno);
+ $question->rows[$indexno]['number'] = $format->getpath($row, ['@', 'number'], $indexno);
$question->rows[$indexno]['name'] =
$format->import_text($format->getpath($row, ['#', 'name', 0, '#', 'text'], ''));
$correctanswer = $format->getpath($row, ['#', 'correctanswers', 0, '#', 'text', 0, '#'], '');
- $decodedanswers = json_decode($correctanswer, true);
- foreach ($question->columns as $colindex => $col) {
- if (array_key_exists($col['id'], $decodedanswers)) {
+ $answerslist = explode(',', $correctanswer);
+ foreach ($question->columns as $col) {
+ if (in_array($col['number'], $answerslist)) {
// Import correct answers for single choice.
if ($question->inputtype == 'single') {
- // Assigning $colindex + 1 as answers are stored as 1,2 and so on.
- $question->rowanswers[$indexno] = ($colindex + 1);
+ $question->rowanswers[$indexno] = $col['number'];
break;
} else {
// Import correct answers for multiple choice.
- $rowanswerslabel = "rowanswers" . 'a' . ($colindex + 1);
- if (array_key_exists($col['id'], $decodedanswers)) {
+ $rowanswerslabel = "rowanswers" . 'a' . $col['number'];
+ if (in_array($col['number'], $answerslist)) {
$question->{$rowanswerslabel}[$indexno] = "1";
}
}
@@ -416,7 +419,7 @@ public function export_to_xml($question, qformat_xml $format, $extra = null) {
$output .= " \n";
ksort($question->columns);
foreach ($question->columns as $columnkey => $column) {
- $output .= " \n";
+ $output .= " number}\">\n";
$output .= $format->writetext($column->name, 4);
$output .= " \n";
}
@@ -428,7 +431,7 @@ public function export_to_xml($question, qformat_xml $format, $extra = null) {
ksort($question->rows);
$indent = 5;
foreach ($question->rows as $rowkey => $row) {
- $output .= " \n";
+ $output .= " number}\">\n";
$output .= " \n";
$output .= $format->writetext($row->name, $indent);
$output .= " \n";
diff --git a/renderer.php b/renderer.php
index 96835ec..8fa4526 100644
--- a/renderer.php
+++ b/renderer.php
@@ -54,7 +54,7 @@ abstract protected function get_input_id(question_attempt $qa, $value, $columnnu
protected function is_right(question_definition $question, $rowkey, $columnkey) {
$row = $question->rows[$rowkey];
foreach ($question->columns as $column) {
- if ($column->number == $columnkey && array_key_exists($column->id, $row->correctanswers)) {
+ if ($column->number == $columnkey && array_key_exists($column->number, $row->correctanswers)) {
return 1;
}
}
@@ -242,9 +242,8 @@ protected function get_input_id(question_attempt $qa, $value, $columnnumber) {
public function correct_response(question_attempt $qa) {
$question = $qa->get_question();
$right = [];
- $columnids = column::get_column_ids($question->columns);
foreach ($question->rows as $row) {
- $right[] = $row->name . ' → ' . $columnids[array_key_first($row->correctanswers)]->name;
+ $right[] = $row->name . ' → ' . $question->columns[array_key_first($row->correctanswers)]->name;
}
return $this->correct_choices($right);
}
@@ -276,14 +275,13 @@ protected function get_input_id(question_attempt $qa, $value, $columnnumber) {
public function correct_response(question_attempt $qa) {
$question = $qa->get_question();
- $columnids = column::get_column_ids($question->columns);
foreach ($question->rows as $row) {
// Get the correct row.
$rowanswer = $row->name . ' → ';
$answers = [];
if ($row->correctanswers != '') {
- foreach ($row->correctanswers as $columnkey => $notused) {
- $answers[] = $columnids[$columnkey]->name;
+ foreach ($row->correctanswers as $columnnumber => $notused) {
+ $answers[] = $question->columns[$columnnumber]->name;
}
$rowanswer .= implode(', ', $answers);
$rightanswers[] = $rowanswer;
@@ -300,7 +298,7 @@ protected function num_parts_correct(question_attempt $qa): string {
$a = new stdClass();
if ($qa->get_question()->grademethod == 'allnone') {
- list($a->num, $a->outof) = $qa->get_question()->get_num_parts_right($qa->get_last_qt_data());
+ list($a->num, $a->outof) = $qa->get_question()->get_num_grade_allornone($qa->get_last_qt_data());
if (is_null($a->outof)) {
return '';
}
diff --git a/tests/behat/export.feature b/tests/behat/export.feature
index f2b9ec7..11e08a4 100644
--- a/tests/behat/export.feature
+++ b/tests/behat/export.feature
@@ -27,7 +27,7 @@ Feature: Test exporting Numerical questions
When I am on the "Course 1" "core_question > course question export" page logged in as teacher
And I set the field "id_format_xml" to "1"
And I press "Export questions to file"
- Then following "click here" should download between "5500" and "5800" bytes
+ Then following "click here" should download between "5300" and "5600" bytes
# If the download step is the last in the scenario then we can sometimes run
# into the situation where the download page causes a http redirect but behat
# has already conducted its reset (generating an error). By putting a logout
diff --git a/tests/fixtures/testquestion_multipleresponse.moodle.xml b/tests/fixtures/testquestion_multipleresponse.moodle.xml
index f0a7e6a..4029ce9 100644
--- a/tests/fixtures/testquestion_multipleresponse.moodle.xml
+++ b/tests/fixtures/testquestion_multipleresponse.moodle.xml
@@ -1,6 +1,6 @@
-
+
OUMatrix multiple choice
@@ -9,7 +9,7 @@
Select the true statements for each of the materials by ticking the boxes in the table.
]]>
- This is general feedback
+ This is general feedback]]>
10
0.3333333
@@ -19,111 +19,111 @@
allnone
false
-
+
is a good conductor of electricity
-
+
is an insulator
-
+
can be magnetised
-
+
copper
-
+ 1
Copper is a good conductor of electricity.]]>
-
+
glass
-
+ 2
Glass is an insulator.]]>
-
+
iron
-
+ 1,3
Iron is a good conductor of electricity and can be magnetised.]]>
-
+
gold
-
+ 1
Gold is a good conductor of electricity.]]>
-
+
carbon
-
+ 1
Carbon is a good conductor of electricity.]]>
-
+
rubber
-
+ 2
Rubber is an insulator.]]>
-
+
silver
-
+ 1
Silver is a good conductor of electricity.]]>
-
+
nitrogen
-
+ 2
Nitrogen is an insulator.]]>
-
+
wood
-
+ 2
Wood is an insulator.]]>
diff --git a/tests/fixtures/testquestion_singlechoice.moodle.xml b/tests/fixtures/testquestion_singlechoice.moodle.xml
index c0c0963..02db719 100644
--- a/tests/fixtures/testquestion_singlechoice.moodle.xml
+++ b/tests/fixtures/testquestion_singlechoice.moodle.xml
@@ -1,6 +1,6 @@
-
+
OUMatrix single choice
@@ -9,7 +9,7 @@
Select the correct option for each of the animals and the family they belong to.]]>
- This is general feedback
+ This is general feedback]]>
6
0.3333333
@@ -19,78 +19,78 @@
partial
false
-
+
Canine
-
+
Feline
-
+
Tetrapod
-
+
New Guinea bockadam
-
+ 3
New Guinea bockadam belongs to Tetrapod family.]]>
-
+
German Shepherd
-
+ 1
German Shepherd belongs to Canine family.]]>
-
+
Bengal
-
+ 2
Bengal belongs to Feline falimiy.]]>
-
+
Andaman worm
-
+ 3
Andaman worm belongs to Tetrapod family.]]>
-
+
English Cocker Spaniel
-
+ 1
English Cocker Spaniel belongs to Canine family.]]>
-
+
Maine coon
-
+ 2
Maine coon belongs to Feline falimiy.]]>
@@ -112,6 +112,7 @@
Hint 2]]>
+
diff --git a/version.php b/version.php
index d4a38dc..32d2521 100644
--- a/version.php
+++ b/version.php
@@ -24,7 +24,7 @@
defined('MOODLE_INTERNAL') || die();
-$plugin->version = 2023081400;
+$plugin->version = 2023102300;
$plugin->release = '0.1.0';
$plugin->component = 'qtype_oumatrix';
$plugin->requires = 2023041800;