Moodle
  1. Moodle
  2. MDL-24814

Teachers' ability to submit students' open quiz attempts

    Details

    • Type: Improvement Improvement
    • Status: Reopened
    • Priority: Minor Minor
    • Resolution: Unresolved
    • Affects Version/s: 1.9.9, 2.3.2
    • Fix Version/s: DEV backlog
    • Component/s: Quiz
    • Environment:
      Linux RedHat
    • Database:
      MySQL
    • Affected Branches:
      MOODLE_19_STABLE, MOODLE_23_STABLE
    • Rank:
      13195

      Description

      It happens quit often that, students close their quiz attempt after saving their answers without clicking on "Submit" icon. That will make the attempt open and ungraded. Teachers will face lots of problems in closing these attempt to allow the system to grade them.

      Therefore, it would be a great idea if the teacher has the capability to submit the students' opened attempts.

        Issue Links

          Activity

          Hide
          Tim Hunt added a comment -

          Please search for existing issues before creating yet another duplicate.

          Show
          Tim Hunt added a comment - Please search for existing issues before creating yet another duplicate.
          Hide
          Tim Hunt added a comment -

          OK, so now that MDL-3030 it is clear that it did not cover this functionality, I am reopening this issue. There is more discussion in MDL-32883.

          The proposed implementation is

          In the quiz grades and responses reports, add a button 'Submit selected attempts' next to 'Regrade selected attempts' and 'Delete selected attempts'. Making that button work is quite easy.

          The tricky bit would be that if the teacher clicks the button when the student has the quiz open, the next time the student does anything (navigates or submits a question) they will get a fatal error. We would have to detect that situation, and explain what is happening to the student, and I can't quite see how to do that. UI suggestions welcome.

          Show
          Tim Hunt added a comment - OK, so now that MDL-3030 it is clear that it did not cover this functionality, I am reopening this issue. There is more discussion in MDL-32883 . The proposed implementation is In the quiz grades and responses reports, add a button 'Submit selected attempts' next to 'Regrade selected attempts' and 'Delete selected attempts'. Making that button work is quite easy. The tricky bit would be that if the teacher clicks the button when the student has the quiz open, the next time the student does anything (navigates or submits a question) they will get a fatal error. We would have to detect that situation, and explain what is happening to the student, and I can't quite see how to do that. UI suggestions welcome.
          Hide
          Mark Drechsler added a comment -

          Thanks Tim,

          Much appreciated.

          What I don't know about is the code issues you're referring to - I'll circulate at work and see if I can get any suggestions for UI or code options.

          Again, thanks for making the effort to understand the issue and re-open this.

          Cheers,

          Mark.

          Show
          Mark Drechsler added a comment - Thanks Tim, Much appreciated. What I don't know about is the code issues you're referring to - I'll circulate at work and see if I can get any suggestions for UI or code options. Again, thanks for making the effort to understand the issue and re-open this. Cheers, Mark.
          Hide
          Adam Olley added a comment -

          >We would have to detect that situation, and explain what is happening to the student, and I can't quite see how to do that. UI suggestions welcome.

          I've not yet looked at the code for this nor attempted to do it and see what happens currently error-wise. But is there some reason when a student is progressing through a quiz that at the point where it normally would throw a fatal error (due to attempt now being closed) that it can't simply display a nice generic message instead describing possible reasons why they can't progress? "This attempt has been closed. This may be due to blah blah or blah" (you get the idea).

          Show
          Adam Olley added a comment - >We would have to detect that situation, and explain what is happening to the student, and I can't quite see how to do that. UI suggestions welcome. I've not yet looked at the code for this nor attempted to do it and see what happens currently error-wise. But is there some reason when a student is progressing through a quiz that at the point where it normally would throw a fatal error (due to attempt now being closed) that it can't simply display a nice generic message instead describing possible reasons why they can't progress? "This attempt has been closed. This may be due to blah blah or blah" (you get the idea).
          Hide
          Tim Hunt added a comment -

          Well, the code path to worry about is after the student does something on attempt.php, which causes a post to processattempt.php.

          And sadly, MDL-3030 just made processattempt.php more spaghetti-like. We really must find a way to refactor it some-time. But, at the moment, if something else has submitted the quiz between the attempt.php page-load in the POST to processattempt.php, then we will hit

          // If the attempt is already closed, send them to the review page.
          if ($attemptobj->is_finished()) {
              throw new moodle_quiz_exception($attemptobj->get_quizobj(),
                      'attemptalreadyclosed', null, $attemptobj->review_url());
          }
          

          (Currently, this can only happen if the student is doing something inadvisable or malicious, like having the quiz open in two different browser windows simultaneously, which is why we don't worry much about what happens.)

          The danger with a message like "This attempt has been closed. This may be due to blah blah or blah" is that it there are many different possible explanations, and if you only list a few, and someone hits the error for a completely different reason, it is totally confusing.

          Anyway, I am sure this is soluble, given time.

          Show
          Tim Hunt added a comment - Well, the code path to worry about is after the student does something on attempt.php, which causes a post to processattempt.php. And sadly, MDL-3030 just made processattempt.php more spaghetti-like. We really must find a way to refactor it some-time. But, at the moment, if something else has submitted the quiz between the attempt.php page-load in the POST to processattempt.php, then we will hit // If the attempt is already closed, send them to the review page. if ($attemptobj->is_finished()) { throw new moodle_quiz_exception($attemptobj->get_quizobj(), 'attemptalreadyclosed', null , $attemptobj->review_url()); } (Currently, this can only happen if the student is doing something inadvisable or malicious, like having the quiz open in two different browser windows simultaneously, which is why we don't worry much about what happens.) The danger with a message like "This attempt has been closed. This may be due to blah blah or blah" is that it there are many different possible explanations, and if you only list a few, and someone hits the error for a completely different reason, it is totally confusing. Anyway, I am sure this is soluble, given time.
          Hide
          Tony Levi added a comment -

          Well, could always tack on a 'manuallyclosed' field in the DB or similar?

          Show
          Tony Levi added a comment - Well, could always tack on a 'manuallyclosed' field in the DB or similar?
          Hide
          Amjad Mohammed added a comment - - edited

          Hi everyone

          Thanks for reopening this track. Any ways, I do not think there are usually many open attempts to e added in the quiz grades and responses reports. I would suggest adding a "Force Student Attempt" button in attempt preview page, where teacher can preview the student's attempt and submit the attempt if the quiz is closed or quiz duration is over. I suggest the coding will be something like that:

          IF (attempt status is open) {
          IF (quiz is closed) OR (attempt duration is over)

          { Button("Force Student Attempt…"); }

          }

          Yours
          Amjad Al-Tobi

          Show
          Amjad Mohammed added a comment - - edited Hi everyone Thanks for reopening this track. Any ways, I do not think there are usually many open attempts to e added in the quiz grades and responses reports. I would suggest adding a "Force Student Attempt" button in attempt preview page, where teacher can preview the student's attempt and submit the attempt if the quiz is closed or quiz duration is over. I suggest the coding will be something like that: IF (attempt status is open) { IF (quiz is closed) OR (attempt duration is over) { Button("Force Student Attempt…"); } } Yours Amjad Al-Tobi
          Hide
          Margaret Fleck added a comment -

          I agree with the person who said it's only a small number of students on any given quiz, but doing workarounds for them sucks down a lot of course staff time. An important point here is that students can't see the right answers unless they have submitted a quiz. Aside from students who have done the quiz and forgotten to submit, we also have students who were excused from taking the quiz e.g. due to illness. So it would be best if it's possible to force a submit, even if they have done no work on the quiz and consequently get a grade of 0, so that students can review the correct answers.

          Show
          Margaret Fleck added a comment - I agree with the person who said it's only a small number of students on any given quiz, but doing workarounds for them sucks down a lot of course staff time. An important point here is that students can't see the right answers unless they have submitted a quiz. Aside from students who have done the quiz and forgotten to submit, we also have students who were excused from taking the quiz e.g. due to illness. So it would be best if it's possible to force a submit, even if they have done no work on the quiz and consequently get a grade of 0, so that students can review the correct answers.
          Hide
          Tim Hunt added a comment -

          Please note that MDL-3030 is done in Moodle 2.3. That has the option to have Moodle automatically submit the quiz when the time expires. No intervention is required by the teacher at all.

          This issue is about the few time where you manually want to submit some attempts, but not all.

          There is another but about allowing students who have not attempted the quiz at all to see a review page.

          Show
          Tim Hunt added a comment - Please note that MDL-3030 is done in Moodle 2.3. That has the option to have Moodle automatically submit the quiz when the time expires. No intervention is required by the teacher at all. This issue is about the few time where you manually want to submit some attempts, but not all. There is another but about allowing students who have not attempted the quiz at all to see a review page.
          Hide
          Susan Mangan added a comment - - edited

          What is a workaround for manually submit a student's attempt now? We are running v.2.3 I tried re-opening the quiz so there was no end date, changed the setting to automatically submit open attempts and then re-graded. But the open attempts are still open. I seem to recall I could log in as a student in the previous version and then submit, after opening the quiz up again but it seems I can no longer do this.

          Show
          Susan Mangan added a comment - - edited What is a workaround for manually submit a student's attempt now? We are running v.2.3 I tried re-opening the quiz so there was no end date, changed the setting to automatically submit open attempts and then re-graded. But the open attempts are still open. I seem to recall I could log in as a student in the previous version and then submit, after opening the quiz up again but it seems I can no longer do this.
          Hide
          Susan Mangan added a comment -

          I managed to submit a student's quiz by:

          • opening up the quiz (by changing the closed date to future date)
          • allowed 2 attempts at the quiz
          • set attempts to build on last
          • set grading option to Highest grade
          • logged in as a student
          • re-attempted the quiz
          • submitted quiz

          (you can then either delete the first attempt or set the quiz to only display highest graded attempts)

          If there is an easier way, please let me know! Thanks!

          Show
          Susan Mangan added a comment - I managed to submit a student's quiz by: opening up the quiz (by changing the closed date to future date) allowed 2 attempts at the quiz set attempts to build on last set grading option to Highest grade logged in as a student re-attempted the quiz submitted quiz (you can then either delete the first attempt or set the quiz to only display highest graded attempts) If there is an easier way, please let me know! Thanks!
          Hide
          Tim Hunt added a comment -

          Yes. That is about the best that is available until this is fixed properly.

          Show
          Tim Hunt added a comment - Yes. That is about the best that is available until this is fixed properly.
          Hide
          Justin Litalien added a comment -

          Hi folks, for Moodle 2.2 I've shortened Susan's process down a few steps:

          1) Create a user override for Joe Student (extend the due date)
          2) Impersonate Joe Student
          3) Visit quiz, continue attempt, and submit
          4) Remove user override

          This seems to be working just fine at the moment. We'll be moving to 2.3 in a few months, so we're hoping this doesn't occur too frequently!

          Cheers...

          Show
          Justin Litalien added a comment - Hi folks, for Moodle 2.2 I've shortened Susan's process down a few steps: 1) Create a user override for Joe Student (extend the due date) 2) Impersonate Joe Student 3) Visit quiz, continue attempt, and submit 4) Remove user override This seems to be working just fine at the moment. We'll be moving to 2.3 in a few months, so we're hoping this doesn't occur too frequently! Cheers...
          Hide
          Tim Hunt added a comment -

          Thanks, but this issue is now only relevant to Moodle 2.3, where things changed in this area.

          Show
          Tim Hunt added a comment - Thanks, but this issue is now only relevant to Moodle 2.3, where things changed in this area.
          Hide
          Paul Nijbakker added a comment -

          This issue is topical in courses that have continuous enrolment, which makes end dates for quizzes impractical. If the teacher also chooses not to set a timer, so as to allow students as much time as they need, this force submit would be a good thing to have (given that open attempts do not show, for instance, correct answers to the reviewing teacher).

          Show
          Paul Nijbakker added a comment - This issue is topical in courses that have continuous enrolment, which makes end dates for quizzes impractical. If the teacher also chooses not to set a timer, so as to allow students as much time as they need, this force submit would be a good thing to have (given that open attempts do not show, for instance, correct answers to the reviewing teacher).
          Hide
          hari stephen kumar added a comment -

          +1 on the proposed solution of: "In the quiz grades and responses reports, add a button 'Submit selected attempts' next to 'Regrade selected attempts' and 'Delete selected attempts'."

          Tim, with regard to the tricky bit you mentioned, i.e. what to tell the student, I believe Moodle 2.3's assignments system provides one possible approach. In Moodle 2.3 assignments, as an instructor I can manually click on a particular student's submission and select "Prevent submission changes". When I do this, what the student sees is that the submission is closed: they can see their own submission, but they do not see an "Edit submission" or "Add submission" button, and there is no explanation.

          I believe for quizzes too something analogous could be acceptable: the student sees basically whatever it is that any other student sees for an attempt that has been successfully submitted (whether by them or by the instructor). If an explanation is at all necessary, it could be something brief like: "Attempt manually submitted by instructor. Contact instructor for details."

          Just my $0.02 – I use quizzes frequently and I do run into this scenario at least a few times each semester, with at least a few students who simply forgot to click the submit button or otherwise had some kind of issue requiring me to manually "close" their attempt (and I end up having to do a lot of strange workarounds to give them credit).

          Show
          hari stephen kumar added a comment - +1 on the proposed solution of: "In the quiz grades and responses reports, add a button 'Submit selected attempts' next to 'Regrade selected attempts' and 'Delete selected attempts'." Tim, with regard to the tricky bit you mentioned, i.e. what to tell the student, I believe Moodle 2.3's assignments system provides one possible approach. In Moodle 2.3 assignments, as an instructor I can manually click on a particular student's submission and select "Prevent submission changes". When I do this, what the student sees is that the submission is closed: they can see their own submission, but they do not see an "Edit submission" or "Add submission" button, and there is no explanation. I believe for quizzes too something analogous could be acceptable: the student sees basically whatever it is that any other student sees for an attempt that has been successfully submitted (whether by them or by the instructor). If an explanation is at all necessary, it could be something brief like: "Attempt manually submitted by instructor. Contact instructor for details." Just my $0.02 – I use quizzes frequently and I do run into this scenario at least a few times each semester, with at least a few students who simply forgot to click the submit button or otherwise had some kind of issue requiring me to manually "close" their attempt (and I end up having to do a lot of strange workarounds to give them credit).
          Hide
          Tim Hunt added a comment -

          This issue was assigned to me automatically, however I will not be able to work on this issue in the immediate future. In order to create a truer sense of the state of this issue and to allow other developers to have chance to become involved, I am removing myself as the assignee of this issue.

          For more information, see http://docs.moodle.org/dev/Changes_to_issue_assignment

          Show
          Tim Hunt added a comment - This issue was assigned to me automatically, however I will not be able to work on this issue in the immediate future. In order to create a truer sense of the state of this issue and to allow other developers to have chance to become involved, I am removing myself as the assignee of this issue. For more information, see http://docs.moodle.org/dev/Changes_to_issue_assignment
          Hide
          Tania Ramirez added a comment -

          This actually happened a lot in our case, so I had to create a buttom so the teacher can close all the attempts he/she choose

          at /mod/quiz/report/overview/overview_table.php I added

          echo '<input type="submit" name="close" value="Cerrar intentos seleccionados"/>'; 
          

          inside the submit_buttons() function

          and at /mod/quiz/report/overview/report.php I added

          if (optional_param('close', 0, PARAM_BOOL) && confirm_sesskey()) {
                          if ($attemptids = optional_param_array('attemptid', array(), PARAM_INT)) {
                              $this->close_attempts($quiz, $cm, false, $groupstudents, $attemptids);
                              redirect($redirecturl, '', 5);
                          }
                      }
          

          Inside the process_actions() function

          and the new function

              protected function close_attempts($quiz, $cm, $dryrun = false,
                      $groupstudents = array(), $attemptids = array()) {
                  global $CFG, $USER, $DB;
                  require_once($CFG->dirroot . "/user/externallib.php");
          
                  $where = "quiz = ? AND preview = 0";
                  $params = array($quiz->id);
                  //obtiene los estudiantes del grupo si es que lo hay
                  if ($groupstudents) {
                      list($usql, $uparams) = $DB->get_in_or_equal($groupstudents);
                      $where .= " AND userid $usql";
                      $params = array_merge($params, $uparams);
                  }
                  //obtiene los ids de los intentos
                  if ($attemptids) {
                      list($asql, $aparams) = $DB->get_in_or_equal($attemptids);
                      $where .= " AND id $asql";
                      $params = array_merge($params, $aparams);
                  }
                  //obtiene los intentos de la BD
                  $attempts = $DB->get_records_select('quiz_attempts', $where, $params);
                  if (!$attempts) {
                      return;
                  }
          
                  foreach ($attempts as $attempt) {        
                      if ($attempt->state !='finished') {
                      $timestamp = time();
                      $transaction = $DB->start_delegated_transaction();
                      $attempt->quba= question_engine::load_questions_usage_by_activity($attempt->uniqueid);
                      $attempt->quba->process_all_actions($timestamp);
                      $attempt->quba->finish_all_questions($timestamp);
          
                      question_engine::save_questions_usage_by_activity($attempt->quba);
          
                      $attempt->timemodified = $timestamp;
                      $attempt->timefinish = $timestamp;
                      $attempt->sumgrades = $attempt->quba->get_total_mark();
                      $attempt->state = 'finished';
                      $DB->update_record('quiz_attempts', $attempt);
                      // Get student name
                      $studentid = $attempt->userid;
                      $studentwhere = "id = $studentid";
                      $students = $DB->get_records_select('user', $studentwhere);
                      foreach ($students as $student) {
                          //agregado para que el mensaje del log no sea mayor a 40 caracteres
                          $mensaje = '';
                          if ($student->idnumber != NULL) {
                              $mensaje = $student->idnumber;
                          } else {
                              $nombre = $student->firstname.' '.$student->lastname;
                              if (strlen($nombre) > 23 ) {
                                  $mensaje = substr($nombre,0,23);
                              } else
                                  $mensaje = $nombre;
                          }
                          // Log the end of this attempt.
                          add_to_log($quiz->course, 'quiz', 
                                  'close attempt of '.$mensaje,
                                  'review.php?attempt='.$attempt->id, $quiz->name, $cm->id);
                          //
                      }
                      $transaction->allow_commit();           
                      }
                      else                
                          continue;
                  }
              }
          

          before the regrade_attempts_needing_it() function (sorry for the spanish comments)

          Hope this can help

          Show
          Tania Ramirez added a comment - This actually happened a lot in our case, so I had to create a buttom so the teacher can close all the attempts he/she choose at /mod/quiz/report/overview/overview_table.php I added echo '<input type="submit" name="close" value="Cerrar intentos seleccionados"/>'; inside the submit_buttons() function and at /mod/quiz/report/overview/report.php I added if (optional_param('close', 0, PARAM_BOOL) && confirm_sesskey()) { if ($attemptids = optional_param_array('attemptid', array(), PARAM_INT)) { $this->close_attempts($quiz, $cm, false, $groupstudents, $attemptids); redirect($redirecturl, '', 5); } } Inside the process_actions() function and the new function protected function close_attempts($quiz, $cm, $dryrun = false, $groupstudents = array(), $attemptids = array()) { global $CFG, $USER, $DB; require_once($CFG->dirroot . "/user/externallib.php"); $where = "quiz = ? AND preview = 0"; $params = array($quiz->id); //obtiene los estudiantes del grupo si es que lo hay if ($groupstudents) { list($usql, $uparams) = $DB->get_in_or_equal($groupstudents); $where .= " AND userid $usql"; $params = array_merge($params, $uparams); } //obtiene los ids de los intentos if ($attemptids) { list($asql, $aparams) = $DB->get_in_or_equal($attemptids); $where .= " AND id $asql"; $params = array_merge($params, $aparams); } //obtiene los intentos de la BD $attempts = $DB->get_records_select('quiz_attempts', $where, $params); if (!$attempts) { return; } foreach ($attempts as $attempt) { if ($attempt->state !='finished') { $timestamp = time(); $transaction = $DB->start_delegated_transaction(); $attempt->quba= question_engine::load_questions_usage_by_activity($attempt->uniqueid); $attempt->quba->process_all_actions($timestamp); $attempt->quba->finish_all_questions($timestamp); question_engine::save_questions_usage_by_activity($attempt->quba); $attempt->timemodified = $timestamp; $attempt->timefinish = $timestamp; $attempt->sumgrades = $attempt->quba->get_total_mark(); $attempt->state = 'finished'; $DB->update_record('quiz_attempts', $attempt); // Get student name $studentid = $attempt->userid; $studentwhere = "id = $studentid"; $students = $DB->get_records_select('user', $studentwhere); foreach ($students as $student) { //agregado para que el mensaje del log no sea mayor a 40 caracteres $mensaje = ''; if ($student->idnumber != NULL) { $mensaje = $student->idnumber; } else { $nombre = $student->firstname.' '.$student->lastname; if (strlen($nombre) > 23 ) { $mensaje = substr($nombre,0,23); } else $mensaje = $nombre; } // Log the end of this attempt. add_to_log($quiz->course, 'quiz', 'close attempt of '.$mensaje, 'review.php?attempt='.$attempt->id, $quiz->name, $cm->id); // } $transaction->allow_commit(); } else continue; } } before the regrade_attempts_needing_it() function (sorry for the spanish comments) Hope this can help
          Hide
          Vicke Denniston added a comment -

          We are having the issue in 2.5, and unfortunately can't add any code as we are hosted. Has there been any move made to fix this?

          Show
          Vicke Denniston added a comment - We are having the issue in 2.5, and unfortunately can't add any code as we are hosted. Has there been any move made to fix this?

            People

            • Votes:
              18 Vote for this issue
              Watchers:
              16 Start watching this issue

              Dates

              • Created:
                Updated: