Moodle
  1. Moodle
  2. MDL-11081

Course restore doesn't restore students' quiz results correctly and the restore function also breaks OTHER course areas quizzes!

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Blocker Blocker
    • Resolution: Fixed
    • Affects Version/s: 1.6.5, 1.7, 1.7.1, 1.7.2, 1.8, 1.8.1, 1.8.2
    • Fix Version/s: 1.6.6, 1.7.3, 1.8.3, 1.9
    • Component/s: Quiz
    • Labels:
      None
    • Environment:
      Postgres 8.2.0, PHP 4.3.9, Mdl 1.6.5+
    • Database:
      Any
    • Affected Branches:
      MOODLE_16_STABLE, MOODLE_17_STABLE, MOODLE_18_STABLE
    • Fixed Branches:
      MOODLE_16_STABLE, MOODLE_17_STABLE, MOODLE_18_STABLE, MOODLE_19_STABLE
    • Rank:
      28638

      Description

      When a teacher (with normal user rights, not admin) makes a backup of his course and when he tries to restore the zip-file on the same or different server (deleting the newly created course area first before adding data to it), quiz results are not restored correctly. The main problem: when a teacher goes to any of the restored course areas's quizzes and looks at the "show all attempts" page, the teacher is able to see the quiz scores for each student but when the teacher clicks the individual attempt's score (in order to see the student's question sheet), moodle gives the following error:

      "This question has been deleted. Please contact your teacher"

      Here's the working and non-working course areas html source codes:

      THE WORKING MOODLE COURSE AREA (NOT RESTORED)
      #############################################
      <div id="q8315" class="que multichoice clearfix">
      <div class="info">
      <span class="no">1</span>
      <span class="edit"><a target="editquestion" title="Muokkaa " href="http://moodle-server.it.helsinki.fi/moodle/question/question.php?inpopup=1&id=8315" onclick="return openpopup('/question/question.php?inpopup=1&id=8315', 'editquestion', '', 0);"><img src="http://moodle-server.it.helsinki.fi/moodle/pix/t/edit.gif" border="0" alt="Muokkaa " /></a></span>
      <div class="grade">
      Pistettä: 1 </div>

      </div>
      <div class="content">
      <div class="qtext">
      Mikä on se tietokoneen osa
      ##############################################

      THE NONWORKING RESTORED AREA
      ############################
      <div id="q8330" class="que missingtype clearfix">
      <div class="info">
      <span class="no">4</span>
      <span class="edit"><a target="editquestion" title="Muokkaa " href="http://moodle-server.it.helsinki.fi/moodle-test/question/question.php?inpopup=1&id=8330" onclick="return openpopup('/question/question.php?inpopup=1&id=8330', 'editquestion', '', 0);"><img src="http://moodle-server.it.helsinki.fi/moodle-test/pix/t/edit.gif" border="0" alt="Muokkaa " /></a></span>
      <div class="grade">
      Pistettä: 1 </div>

      </div>
      <div class="content">
      <div class="qtext">
      This question has been deleted. Please contact your teacher</div>
      ###############################

      When I look at our production db (=postgres), I can find the question (id=8315) in the db but when I look at our test server's db (=postgres too) and the restored course area's question with the id=8330, I get nothing:

      => select name from mdl_question where id ='8330';
      name
      ------
      (0 rows)

      When I look at the course backup file (the zip) and the xml inside it, I can see the question with the id=8330 correctly there. Here's a sample of what's in the xml:

      ################
      <QUESTION>
      <ID>8330</ID>
      <PARENT>0</PARENT>
      <NAME>Jotta voisit hallita tiedostojasi ja... mikä on hakemisto?</NAME>
      <QUESTIONTEXT><span lang="fi">Jotta voisit hallita tiedostojasi ja hakemistojasi järkevästi, ja jotta löytäisit haluamasi tiedon nopeasti, sinun on hyvä tuntea hakemistojen ja tiedostojen välinen ero. Mikä on hakemisto (valitse 2)?</span><span lang="en">For you to be able to manage your files and directories sensibly, and find your stored information quickly, you should know the difference between directories and files. What is a directory? </span><span lang="sv">För att du skall kunna ha kontroll över dina filer och kataloger (eng. directory) och för att du snabbt skall kunna hitta det du behöver, är det viktigt att du vet vad som skiljer kataloger och filer åt. Vad är en katalog?</span></QUESTIONTEXT>
      <QUESTIONTEXTFORMAT>1</QUESTIONTEXTFORMAT>
      <IMAGE></IMAGE>
      <DEFAULTGRADE>1</DEFAULTGRADE>
      <PENALTY>0.1</PENALTY>
      <QTYPE>multichoice</QTYPE>
      <LENGTH>1</LENGTH>
      <STAMP>moody.it.helsinki.fi+070130070706+0qkUex</STAMP>
      <VERSION>moodle-server.it.helsinki.fi+070705130325+SQTi3T</VERSION>
      <HIDDEN>0</HIDDEN>
      <MULTICHOICE>
      <LAYOUT>0</LAYOUT>
      <ANSWERS>25988,25989,25990,25991</ANSWERS>
      <SINGLE>0</SINGLE>
      <SHUFFLEANSWERS>1</SHUFFLEANSWERS>
      </MULTICHOICE>
      <ANSWERS>
      <ANSWER>
      <ID>25988</ID>
      <ANSWER_TEXT><span lang="fi">Digitaaliseen muotoon tallennettu data, esimerkiksi asiakirja, valokuva, piirros tai vaikkapa taulukko.</span><span lang="sv">En slags mapp, där jag arkiverar t.ex. dokument, fotografier, teckningar och tabeller som jag har sparat i digitalformat.</span><span lang="en">A sort of folder where you store e.g. documents, photographs, drawings and tables in digital form.</span></ANSWER_TEXT>
      <FRACTION>-0.5</FRACTION>
      <FEEDBACK><span lang="fi">Väärin.</span><span lang="sv">Fel.</span><span lang="en">Wrong.</span></FEEDBACK>
      </ANSWER>
      <ANSWER>
      <ID>25989</ID>
      <ANSWER_TEXT><span lang="fi">Ohjelma, joka sisältää käyttäjän tiedot kuten nimen ja salasanan.</span><span lang="sv">Ett program som innehåller uppgifter om användaren, såsom namn och lösenord.</span><span lang="en">A program that contains user information, such as name and password. </span></ANSWER_TEXT>
      <FRACTION>-0.5</FRACTION>
      <FEEDBACK><span lang="fi">Väärin.</span><span lang="sv">Fel.</span><span lang="en">Wrong.</span></FEEDBACK>
      </ANSWER>
      <ANSWER>
      <ID>25990</ID>
      <ANSWER_TEXT><span lang="fi">Eräänlainen mappi, johon arkistoidaan esimerkiksi digitaaliseen muotoon tallennettuja asiakirjoja, valokuvia, piirroksia, taulukkoja tms.</span><span lang="sv">Data, t.ex. ett dokument, ett fotografi, en teckning eller en tabell, som jag har sparat i digitalformat.</span><span lang="en">Data stored in digital form, such as a document, a photograph, a drawing or a table.</span></ANSWER_TEXT>
      <FRACTION>0.5</FRACTION>
      <FEEDBACK><span lang="fi">Oikein.</span><span lang="sv">Rätt.</span><span lang="en">Right.</span></FEEDBACK>
      </ANSWER>
      <ANSWER>
      <ID>25991</ID>
      <ANSWER_TEXT><span lang="fi">Synonyymi tallennuksessa käytetylle "kansio"-käsitteelle.</span><span lang="sv">Ett synonym för begreppet "mapp" som används då man sparar.</span><span lang="en">A synonym to the concept 'folder' used in storing.</span></ANSWER_TEXT>
      <FRACTION>0.5</FRACTION>
      <FEEDBACK><span lang="fi">Oikein.</span><span lang="sv">Rätt.</span><span lang="en">Right.</span></FEEDBACK>
      </ANSWER>
      </ANSWERS>
      </QUESTION>
      ################

      To me it seems that the restore feature does something really wrong. In fact, we were forced to go back to our backups and restore the whole production server's db to the state prior to the user-made course restore -episode because the user-made restore didn't only restore the course area unsuccessfully but it also:

      1) destroyed the quiz results data (same error message: "This question has been deleted. Please contact your teacher") in OTHER course areas!
      2) altered quizzes in OTHER course areas (in our production site) so that the quizzes no longer had questions inside them and the question scores disappeared.

      I had to comment out the restore function from the <site-url>/files/files.php for now. The problem seems to persist since I can reproduce it in our test server with the same problematic results.

      Help truly appreciated!!!

      Olli S. / FINLAND

      1. lib.patch
        0.9 kB
        Janne Mikkonen

        Issue Links

          Activity

          Hide
          Janne Mikkonen added a comment -

          I've changed this issue since it's a show stopper for all versions at least from 1.6.x up. Quiz is missing code that handles used instances of questions (published) from other courses. I'll try to send in some patches.

          Show
          Janne Mikkonen added a comment - I've changed this issue since it's a show stopper for all versions at least from 1.6.x up. Quiz is missing code that handles used instances of questions (published) from other courses. I'll try to send in some patches.
          Hide
          Janne Mikkonen added a comment -

          This is a unified form patch for Moodle_16_stable (/mod/quiz/lib.php), but the same code can be used in other versions too.

          (patch -u lib.php lib.patch)

          Show
          Janne Mikkonen added a comment - This is a unified form patch for Moodle_16_stable (/mod/quiz/lib.php), but the same code can be used in other versions too. (patch -u lib.php lib.patch)
          Hide
          Olli Salo added a comment -

          I installed Janne's patch to our test site and ran some tests. At least to me it seemed to work just fine, no errors whatsoever. Restoring a course from a zip no longer deleted questions, the quiz categories were there correctly and other course areas' quizzes didn't get broken...

          As this bug is pretty severe, some extra testing might be a good idea, though.

          Awesome job from Janne - thx!

          Olli Salo / FINLAND

          Show
          Olli Salo added a comment - I installed Janne's patch to our test site and ran some tests. At least to me it seemed to work just fine, no errors whatsoever. Restoring a course from a zip no longer deleted questions, the quiz categories were there correctly and other course areas' quizzes didn't get broken... As this bug is pretty severe, some extra testing might be a good idea, though. Awesome job from Janne - thx! Olli Salo / FINLAND
          Hide
          Tim Hunt added a comment -

          This patch is a big step forwards, but it is not 100% right.

          It fails to consider the case of a random question. When you have a random question and a student attempts a quiz, some other question from the same category, or from a sub-category, gets linked to the quiz too, via the question_states table, and this link is in a form that it is quite hard to work out with SQL.

          Here is an improved patch:

          Index: mod/quiz/lib.php
          ===================================================================
          RCS file: /cvsroot/moodle/moodle/mod/quiz/lib.php,v
          retrieving revision 1.276
          diff -u -r1.276 lib.php
          — mod/quiz/lib.php 10 Sep 2007 11:07:39 -0000 1.276
          +++ mod/quiz/lib.php 13 Sep 2007 17:04:46 -0000
          @@ -821,11 +821,25 @@
          /**

          • Returns an array of names of quizzes that use this question
            *
          • * TODO: write this
          • @param object $questionid
          • @return array of strings
            */
            function quiz_question_list_instances($questionid) {
            + global $CFG;
            +
            + // TODO: we should also consider other questions that are used by
            + // random questions in this quiz, but that is very hard.
            +
            + $sql = "SELECT q.id, q.name
            + FROM {$CFG->prefix}quiz q
            + INNER JOIN
            + {$CFG->prefix}quiz_question_instances qqi
            + ON q.id = qqi.quiz
            + WHERE qqi.question = '$questionid'";
            +
            + if ($instances = get_records_sql_menu($sql)) { + return $instances; + }

            return array();
            }

          Show
          Tim Hunt added a comment - This patch is a big step forwards, but it is not 100% right. It fails to consider the case of a random question. When you have a random question and a student attempts a quiz, some other question from the same category, or from a sub-category, gets linked to the quiz too, via the question_states table, and this link is in a form that it is quite hard to work out with SQL. Here is an improved patch: Index: mod/quiz/lib.php =================================================================== RCS file: /cvsroot/moodle/moodle/mod/quiz/lib.php,v retrieving revision 1.276 diff -u -r1.276 lib.php — mod/quiz/lib.php 10 Sep 2007 11:07:39 -0000 1.276 +++ mod/quiz/lib.php 13 Sep 2007 17:04:46 -0000 @@ -821,11 +821,25 @@ /** Returns an array of names of quizzes that use this question * * TODO: write this @param object $questionid @return array of strings */ function quiz_question_list_instances($questionid) { + global $CFG; + + // TODO: we should also consider other questions that are used by + // random questions in this quiz, but that is very hard. + + $sql = "SELECT q.id, q.name + FROM {$CFG->prefix}quiz q + INNER JOIN + {$CFG->prefix}quiz_question_instances qqi + ON q.id = qqi.quiz + WHERE qqi.question = '$questionid'"; + + if ($instances = get_records_sql_menu($sql)) { + return $instances; + } return array(); }
          Hide
          Tim Hunt added a comment -

          Despite the limitation, this patch is a major step forwards, so I have committed it.

          (Apologies that pasting the diff into the previous comment did not work very well.)

          Show
          Tim Hunt added a comment - Despite the limitation, this patch is a major step forwards, so I have committed it. (Apologies that pasting the diff into the previous comment did not work very well.)
          Hide
          Tim Hunt added a comment -

          The TODO in the above code is basically MDL-5780.

          Show
          Tim Hunt added a comment - The TODO in the above code is basically MDL-5780 .

            People

            • Votes:
              6 Vote for this issue
              Watchers:
              6 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: