-
Bug
-
Resolution: Fixed
-
Major
-
1.9.8, 1.9.10, 1.9.11
-
Linux x86_64, PHP 5.3.3
-
MySQL
-
MOODLE_19_STABLE
-
MOODLE_19_STABLE
-
When restoring random questions states in 1.9, the question column in the question_states tables gets assigned the wrong value. The defect is in function restore_recode_answer in question/type/random/questiontype.php.
That function gets an object reference $state parameter from the caller (which is function question_states_restore_mods in question/restorelib.php). The function then assigns the reference to another variable and proceeds to modify the referent, which is the question_state that the caller is about to insert into the database. Here are a couple of lines from restore_recode_answer.
$newstate = $state;
$newstate->question = $wrapped->new_id;
The fix could be as simple as changing the first line to
$newstate = clone($state);
Here is what this looks like in databases using fresh installs...
The source system has the following:
mysql> select id, name, qtype from mdl_question;
------------------------------------------------------------
id | name | qtype |
------------------------------------------------------------
1 | sky color | shortanswer |
2 | grass color | shortanswer |
3 | Random Question (Default for Random Question) | random |
------------------------------------------------------------
mysql> select attempt, question, answer from mdl_question_states where seq_number=2;
------------------------------
attempt | question | answer |
------------------------------
11 | 3 | random2-green |
------------------------------
After backing up and restoring in another fresh database, we get this:
mysql> select id, name, qtype from mdl_question where id in (1,2,3);
------------------------------------------------------------
id | name | qtype |
------------------------------------------------------------
1 | sky color | shortanswer |
2 | grass color | shortanswer |
3 | Random Question (Default for Random Question) | random |
------------------------------------------------------------
mysql> select attempt, question, answer from mdl_question_states where seq_number=2 and attempt=2;
------------------------------
attempt | question | answer |
------------------------------
2 | 2 | random2-green |
------------------------------
Note that the value of the question column is '2' rather than '3'. The correct question id is '3' because that is the id of the random question on the quiz. The 'random2' in the answer is correct because question 2 was actually question randomly presented to the user. The faulty logic, however, incorrectly results in using the id embedded in the answer as the question value.
After changing the code to use the clone function, we get something that looks like this, which appears to be correct.
mysql> select id, name, qtype from mdl_question where id in (28,29,30);
------------------------------------------------------------
id | name | qtype |
------------------------------------------------------------
28 | sky color | shortanswer |
29 | grass color | shortanswer |
30 | Random Question (Default for Random Question) | random |
------------------------------------------------------------
mysql> select attempt, question, answer from mdl_question_states where seq_number=2 and attempt=20;
-------------------------------
attempt | question | answer |
-------------------------------
20 | 30 | random29-green |
-------------------------------
I don't know all the implications of this defect, but this is how we noticed it. We are migrating courses from 1.9 to 2.0 by
1) backing up from 1.9 production,
2) restoring into a 1.9 "migration" instance,
3) upgrading the migration instance to 2.0,
4) backing up the course from the 2.0 migration instance, and
5) restoring the course into 2.0 production.
On the transitory migration instance, even though we have corrupt data due to this defect, we have not noticed any issues. Our problem appears when we backup and restore the upgraded course to complete the migration. On the production 2.0 system, the quiz review displays the wrong random questions; the questions it displays are typically not even in the pool of questions for that random question. Although some warnings appeared during the 2.0 backup or restore, their significance was unclear because the actual data corruption occurs in the 1.9 restore.