Cloze questions child questions missing

Cloze questions child questions missing

by Susana L. -
Number of replies: 17
Hi, 

Moodle 3.1.

We are facing a new problem with cloze questions. Cloze questions were displaying fine when the students answered the quiz, and now  (1month later) the child questions are missing... we no longer can preview some of the cloze questions because we get an error: "This question is of a type that is not installed on your system. No processing is possible."

When we edit the questions we can see that the child questions were replaced with #1,#2,#3...

In the database on mdl_question_multianswer table we have the sequence field with comma separated values questions ids but we don't have those questions on mdl_question table.

Cant understand what happened to those child questions... How did they disappeared?

Anyone with anything similar? 

Thank you!



moodle=# select * from mdl_question_multianswer where question=131348;

  id  | question |          sequence           

------+----------+-----------------------------

 7555 |   131348 | 131349,131350,131351,131352

moodle=# select * from mdl_question where id=131349;

(0 rows)



Average of ratings: -
In reply to Susana L.

Re: Cloze questions child questions missing

by Rebecca Trynes -

I'm facing the exact same problem on Moodle 3.3.4, using a Postgres db.

A fix for this would be awesome. Is it in the Tracker anywhere?


Warning: Creating default object from empty value in.../moodle/question/type/multianswer/questiontype.php on line 209

Notice: Undefined property: stdClass::$qtype in .../moodle/question/type/multianswer/questiontype.php on line 210

etc,etc.

In reply to Susana L.

Re: Cloze questions child questions missing

by Rebecca Trynes -

After some investigation, I think I know exactly what is going on.

There is a page: 'Question Bank Consistency Check' that says that "For each question whose id is listed in question_multianswer.sequence, its question.parent field should equal question_multianswer.question."

When that isn't true, you get something like this:


wrong parent, multiple qma.questions referencing same sequence


So, if you deleted one of the q.parent questions above, all of those qma.question(s) listed against it, would then result in an error upon preview because all those questions in the qma.sequence column would have then been deleted from the database.

Currently, I have no fix for this, because if you try to update/edit any of those qma.questions, they still have exactly the same qma.sequence that is shared amongst other qma.questions. They don't then get their own set of subquestion sequence values. (Unlike when you create new multianswer/cloze questions in a non-stuffed up environment.)

This whole problem is a carry-over from Moodle 1.9. It keeps happening to us because teachers here keep importing the same stuffed course over and over and over.

Anyone with any insight into this problem, please help!!!

In reply to Rebecca Trynes

Re: Cloze questions child questions missing

by Rebecca Trynes -
Further testing on this confirms it...
  q. id        | q.parent | qma.question   |  qma. sequence

--------------+--------------+---------------+-------------------------
 2783831 | 7302100 5334552 | 2783831,2783832,2783833
 2783831 | 7302100 |  3756523 | 2783831,2783832,2783833
 2783831 | 7302100 |  3758257 | 2783831,2783832,2783833
 2783831 | 7302100 |  6473599 | 2783831,2783832,2783833
 2783831 | 7302100 |  7302100 | 2783831,2783832,2783833
 2783831 | 7302100 |  9878958 | 2783831,2783832,2783833
 2783832 | 7302100 |  5334552 | 2783831,2783832,2783833
 2783832 | 7302100 |  3756523 | 2783831,2783832,2783833
 2783832 | 7302100 |  3758257 | 2783831,2783832,2783833
 2783832 | 7302100 |  6473599 | 2783831,2783832,2783833
 2783832 | 7302100 |  7302100 | 2783831,2783832,2783833
 2783832 | 7302100 |  9878958 | 2783831,2783832,2783833
 2783833 | 7302100 |  5334552 | 2783831,2783832,2783833
 2783833 | 7302100 |  3756523 | 2783831,2783832,2783833
 2783833 | 7302100 |  3758257 | 2783831,2783832,2783833
 2783833 | 7302100 |  6473599 | 2783831,2783832,2783833
 2783833 | 7302100 |  7302100 | 2783831,2783832,2783833
 2783833 | 7302100 |  9878958 | 2783831,2783832,2783833
(18 rows)


Editing the first qma.question before deleting the parent question looks like this:

Before deleting parent question

Then, I went and deleted the parent question 7302100, went to edit the same question, and got this:

After deleting the parent question


The question still exists in the mdl_question and mdl_question_multianswer tables in the database:

 

SELECT * FROM mdl_question WHERE id = 5334552;


  id    | category | parent | name |                                            questiontext                                            | questiontextformat | generalfeedback | defaultmark |  penalty  |    qtype    | length |                 stamp                 |                version                | hidden | timecreated | timemodified | createdby | modifiedby | generalfeedbackformat
---------+----------+--------+------+----------------------------------------------------------------------------------------------------+--------------------+-----------------+-------------+-----------+-------------+--------+---------------------------------------+---------------------------------------+--------+-------------+--------------+-----------+------------+-----------------------
 5334552 |   346831 |      0 | Q04  | <p>Using the diagram below and the following calculations.</p>                                    +|                  1 |                 |   3.0000000 | 0.0000000 | multianswer |      1 | eldev8.cit.edu.au+130427090228+klCquZ | eldev8.cit.edu.au+150518092645+R7SkDm |      0 |  1367053348 |   1431941205 |    108526 |     108526 |                     1
         |          |        |      | <p><img src="https://moodle.org/pluginfile.php/134/mod_forum/post/1485481/series.parallel%206.4.png" alt="" width="332" height="250" /></p>     +|                    |                 |             |           |             |        |                                       |                                       |        |             |              |           |            |
         |          |        |      | <p>Note:  R1 = 2.6k Ω...R2 = 4k Ω...R3 = 8k Ω....R4 = 600 Ω...R5 = 2.4k Ω...R6 = 12k Ω</p>        +|                    |                 |             |           |             |        |                                       |                                       |        |             |              |           |            |
         |          |        |      | <p>Supply voltage 620 V</p>                                                                       +|                    |                 |             |           |             |        |                                       |                                       |        |             |              |           |            |
         |          |        |      | <p>Question (a)  Calculate the total equivalent resistance of the circuit...Answer{#1} k ohm's</p>+|                    |                 |             |           |             |        |                                       |                                       |        |             |              |           |            |
         |          |        |      | <p>Question (b)  Calculate the total circuit current...Answer{#2} amps</p>                        +|                    |                 |             |           |             |        |                                       |                                       |        |             |              |           |            |
         |          |        |      | <p>Question (c)  Calculate the current through R4...Answer{#3} amp</p>                            +|                    |                 |             |           |             |        |                                       |                                       |        |             |              |           |            |
         |          |        |      | <p> </p>                                                                                           |                    |                 |             |           |             |        |                                       |                                       |        |             |              |           |            |
(1 row)



SELECT * FROM mdl_question_multianswer WHERE question = 5334552;


   id   | question |        sequence
--------+----------+-------------------------
 115404 |  5334552 | 2783831,2783832,2783833
(1 row)


But now the sequence questions don't exist:


SELECT * FROM mdl_question WHERE id = 2783831;


 id | category | parent | name | questiontext | questiontextformat | generalfeedback | defaultmark | penalty | qtype | length | stamp | version | hidden | timecreated | timemodified | createdby | modifiedby | generalfeedbackformat
----+----------+--------+------+--------------+--------------------+-----------------+-------------+---------+-------+--------+-------+---------+--------+-------------+--------------+-----------+------------+-----------------------
(0 rows)

In reply to Rebecca Trynes

Re: Cloze questions child questions missing

by Rebecca Trynes -
I also edited the broken question with the correct Cloze sytnax, and the database updated the question with new sequence question ids.

Before editing:
SELECT * FROM mdl_question_multianswer WHERE question IN ('5334552','3756523','3758257','6473599','9878958');

   id        | question |        sequence
------------+--------------+-------------------------
  78806 |  3756523 | 2783831,2783832,2783833
  79139 |  3758257 | 2783831,2783832,2783833
 115404 |  5334552 | 2783831,2783832,2783833
 161761 |  6473599 | 2783831,2783832,2783833
 289632 |  9878958 | 2783831,2783832,2783833
(5 rows)

After editing:
SELECT * FROM mdl_question_multianswer WHERE question IN ('5334552','3756523','3758257','6473599','9878958');
   id       | question  | sequence
-----------+---------------+----------------------------
  78806 |  3756523 | 2783831,2783832,2783833
  79139 |  3758257 | 2783831,2783832,2783833
 115404 |  5334552 | 10390351,10390352,10390353
 161761 |  6473599 | 2783831,2783832,2783833
 289632 |  9878958 | 2783831,2783832,2783833
(5 rows)

So it looks like the fix is pretty simple once that dodgy parent is deleted. IF you know what the cloze sytax should be!
Don't know how you'd fix this for multiple questions all at once, however.
In reply to Rebecca Trynes

Re: Cloze questions child questions missing

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

I must admit that I have not real all of your posts in detail. However, it seems that you have a reasonably good understanding of how it should work, I think.

I don't entirely undertand what your tables of numbers mean. When you give the output from an SQL query, it can be helpful if you also give the SQL that was run.

Let my say how it is supposed to work, for a question that is set up right. (You can verify this by creating a new Cloze question, and seeing what is added to the database.) For simplicity, our example question will be

Type A {1:SHORTANSWER:=A}. Type B {1:SHORTANSWER:=B}.

Then the contents of mdl_question will be: (Note, irrelevant columns omitted.)

id category parent name questiontext defaultmark penalty qtype length
10736 2 0 Simple Cloze <p>Type A {#1}. Type B {#2}.<br></p> 2 0.3333333 multianswer 1
10737 2 10736 Simple Cloze {1:SHORTANSWER:=A} 1 0 shortanswer 1
10738 2 10736 Simple Cloze {1:SHORTANSWER:=B} 1 0 shortanswer 1

and the contents of mdl_question_multianswer will be:

id question sequence
1 10736 10737,10738

I hope that simple exampel makes it clear how it is supposed to work in general.

In reply to Tim Hunt

Re: Cloze questions child questions missing

by Rebecca Trynes -
Indeed, Tim, that's how it should be!

The query that I ran to get the tables was the query from the Question bank consistency page that I mentioned in a previous post:

SELECT * FROM mdl_question q
    JOIN mdl_question_multianswer qma ON POSITION(',' || q.id || ',' IN ',' || qma.sequence || ',') > 0
WHERE qma.question <> q.parent


The result of mine showed that there were multiple questions in the question_multianswer.question column all referencing the SAME sequence of questions. Not great. Another query I ran showed me all the sequences with no value, or a whole bunch of ,,,,.


I'm currently working on a script that will fix these errors, but it may be a while in coming. And, it might be a bit ambitious!

I'm going to try and fix ALL the issues for multianswer questions in one script. I'll post the help text for the script when I've got it properly worked out on what I think it should do. The hard part will be working out HOW to make it do what I want it to do!

In reply to Rebecca Trynes

Re: Cloze questions child questions missing

by Rebecca Trynes -

This is the script I'm hoping to develop. Questions/comments/suggestions welcome!

---------------------------------------------------------------------------------------------------------------------------------------------

This is a multi-step script that does the following...

Checks and fixes questions in the mdl_question_multianswer table in the DB for incorrect/invalid sequences;
i.e. sequence is null, or ',,,,' (no subquestions listed, or only commas), or multiple questions in the
mdl_question_multianswer.question column share the same sequence questions.

It does this by checking the DB for:
- empty sequences in question_multianswer.sequence
- duplicate sequences in question_multianswer.sequence (the values in here could be
  shuffled around, so the order is not important, just that the sequence questions are listed in
  another sequence).

To correct the problem of DUPLICATE sequences, it will:
- identify the parent question that the sequences belong to, and then
- duplicate each of the sequence questions for that parent,
- assign the newly duplicated question ids to the sequence of one of the duplicate questions
  so that question now has its own unique sequence questions listed, and
- make sure the sequence questions all have the correct parent

e.g. Checking a known duplicate sequence:

SELECT qma.question,qma.sequence,q.id,q.parent
FROM mdl_question_multianswer qma
    JOIN mdl_question q ON POSITION(',' || q.id || ',' IN ',' || qma.sequence || ',') > 0
WHERE qma.sequence = '2783831,2783832,2783833';

 question |        sequence                         |   id           | parent
--------------+-----------------------------------------+--------------+---------
  5334552 | 2783831,2783832,2783833 | 2783831 | 3758257
  3756523 | 2783831,2783832,2783833 | 2783831 | 3758257
  3758257 | 2783831,2783832,2783833 | 2783831 | 3758257
  6473599 | 2783831,2783832,2783833 | 2783831 | 3758257
  7302100 | 2783831,2783832,2783833 | 2783831 | 3758257
  9878958 | 2783831,2783832,2783833 | 2783831 | 3758257

The above result shows all the matching qma.questions with q.id 2783831 (the first question in the sequence).
Ideally, there should only be one result for this sequence:

 question |        sequence                         |   id            | parent
--------------+-----------------------------------------+---------------+---------
  3758257 | 2783831,2783832,2783833 | 2783831 | 3758257

If all the questions in the first column were correct, they would look more like
(taking just the first question in the sequence as an example):

 question |        sequence                         |   id            | parent
--------------+-----------------------------------------+---------------+---------
  5334552 | 5334553,5334554,5334555 | 5334553 | 5334552
  3756523 | 3756524,3756525,3756526 | 3756524 | 3756523
  3758257 | 2783831,2783832,2783833 | 2783831 | 3758257
  6473599 | 6473600,6473601,6473602 | 6473600 | 6473599
  7302100 | 7302101,7302102,7302103 | 7302101 | 7302100
  9878958 | 9878959,9878960,9878961 | 9878959 | 9878958

 
To correct all questions with an EMPTY/INVALID sequence, it will:
- identify if the questions with an empty/invalid sequence exist somewhere else in the database,
  and if those other questions have a valid sequence
- duplicate the sequence questions in the valid sequence and then,
- assign those new question.id(s) to the question_multianswer.sequence column of the DB
  for the broken questions

If no duplicate question with a valid sequence exists in the database, it will:
- delete the questions if they are not used in a quiz??? Maybe? Maybe not. Maybe just do the next step?
- if in a quiz, it will assign a filler sequence to the question so that the question may
  be manually edited, and then report on which questions need to be fixed.
  (To fix the question: Go into the course with the broken question, edit the question to contain
  the correct syntax, click the 'validate questions' button and save.
  New sequence questions should then be created in the database, and the question will now have a
  valid sequence).

In reply to Rebecca Trynes

Re: Cloze questions child questions missing

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

That looks like a correct approach to writing the script.

Note, there is a question in questionlib.php that will really delete a question if not used, and otherwise only hide it. So, you could call that, and then check to see if the question is gone or hidden, before replacing with a placeholder question.

I hope you can test your script on a copy of your live site before running it for real.

If you can work out exactly where these broken questions are coming from, that would be helpful. (They are almost certainly coming from bugs in backup/restore, but what, exactly is the situation the triggers the bug?)

In reply to Tim Hunt

Re: Cloze questions child questions missing

by Rebecca Trynes -

Yes, I tried that delete question function, but it left about 4,300 questions still in existence! That's why I'm now trying to fix them instead.

Yes, I'm testing it on my development server. No way would I do it on the live version until fully tested! I'd be drawn and quartered :P

As to where it's coming from, I can tell you that now: Moodle 1.9 courses that have been restored/imported over and over into new ones and never fixed! Sigh. Where THAT original bug came from, I don't know. All I know is that it keeps perpetuating itself.

Thanks for your time, Tim. smile I appreciate it.

In reply to Tim Hunt

Re: Cloze questions child questions missing

by Rebecca Trynes -
,

Hi Tim (or anyone able to help),

I'm at the stage where I need to duplicate the sequence questions for these multi-answer questions but I'm not sure how to go about it.

Is there a function somewhere that can duplicate all of the sequence questions and everything relating to them? (I don't need the 'parent' question, as that is fine. I just need new/uniquely id'ed sequence questions and every location they're required).

Alternatively, is anyone able to tell me ALL the tables these sequence questions would need to have an entry in?

I've got:

  • mdl_question
  • mdl_question_answers
  • mdl_question_multianswer (sequence question ids should be the values in 'sequence')
  • mdl_qtype_multichoice_options

Are there any others?

I've tried to manually insert entries for a few questions but it didn't work. I'll try again and let you know the error I'm getting, but for now, can anyone help? Did I miss a table?

When I run question_bank::load_question($question), I get a number of array elements which come from the above tables, but then there's this:

    object(qtype_multichoice)#140 (1)
      ["fileoptions":protected]=>
      array(3) {
        ["subdirs"]=>
        bool(true)
        ["maxfiles"]=>
        int(-1)
        ["maxbytes"]=>
        int(0)
      }
    }

I have no idea where this is coming from and feel like I probably need it to make these questions work.

Any help would be greatly appreciated!

In reply to Rebecca Trynes

Re: Cloze questions child questions missing

by Rebecca Trynes -

Okay, so that is coming from moodle/questiontypebase.php

class question_type {
protected $fileoptions = array(
'subdirs' => true,
'maxfiles' => -1,
'maxbytes' => 0,
);

Do I need to worry about it?

In reply to Rebecca Trynes

Re: Cloze questions child questions missing

by Rebecca Trynes -

Well, hey, I tried again and it actually worked! Yay!

I still don't know if there's a function I can use to do it quickly and easily, but I know how to do it by writing my own SQL query/insert/updates :P

For anyone interested, it does involve those tables mentioned, but also:

  • mdl_question_numerical
  • mdl_question_shortanswer
  • etc...
depending on the question type. Now to write the code!
In reply to Rebecca Trynes

Re: Cloze questions child questions missing

by Tim Hunt -
Picture of Core developers Picture of Documentation writers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

I think you have worked it out.

I don't really understand why you need to do this though.

In reply to Rebecca Trynes

Re: Cloze questions child questions missing

by Jordi Pujol-Ahulló -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

Hi Rebecca!

In our production Moodle we faced this problem with lots of cloze questions being affected.

What was the result of your efforts on trying to solve this? Once removed, should it be possible to recover the original status with some backup being restored? We have deleted all courses from an old academic year (about < 3300 courses) and the effect could be important. We are now realising on the magnitude of the problem.

Is there any issue related into the Moodle Tracker about this problem?

Thanks for your time,

Jordi

In reply to Jordi Pujol-Ahulló

Re: Cloze questions child questions missing

by Rebecca Trynes -

Hi Jordi,

I developed an admin cli script that tries to fix the broken questions where it can (it's not sanctioned by Moodle, so use with caution!). I haven't worked out what to do with the others yet. Probably just delete them if they're not being used.

I have the script, and an explanation on what it does, on github: https://github.com/Trynes/fix_moodle_cloze_questions

There is also a Moodle Tracker for this issue, yes: https://tracker.moodle.org/browse/MDL-54724

I hope this helps!

Bec

Average of ratings: Useful (1)
In reply to Rebecca Trynes

Re: Cloze questions child questions missing

by Jordi Pujol-Ahulló -
Picture of Core developers Picture of Particularly helpful Moodlers Picture of Peer reviewers Picture of Plugin developers

Thanks for the information, Rebecca.

In our case, we are able to recover cloze questions because of an old database with all questions on it, and recovering all records from all question type tables related to them.

We detected that the problem was with the column "parent" on the question table, that pointed out to the same value, so that, after several imports, year after year, of the course and all its question bank, deleting the oldest course made all subsequent courses not to work properly.

We are restoring all these questions to make them work. Then, we'll need to be sure that deleting any course does not affect to the other courses tha imported the content from this one, year after year.

We'll take a look at the script if this may be useful for us.

Regards,

Jordi

In reply to Rebecca Trynes

Re: Cloze questions child questions missing

by Miro Iliaš -

Dear Rebecca, 

thanks for your excellent work ! 

Unfortunately, me as ordinary teacher and Moodle user, without admin rights, I have no way to utilize your script  for fixing fishy cloze questions in my courses...