Uploaded image for project: 'Moodle'
  1. Moodle
  2. MDL-24814

Teachers' ability to submit students' open quiz attempts

    Details

    • Type: Improvement
    • Status: Reopened
    • Priority: 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

      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.

        Gliffy Diagrams

          Issue Links

            Activity

            Hide
            timhunt Tim Hunt added a comment -

            Please search for existing issues before creating yet another duplicate.

            Show
            timhunt Tim Hunt added a comment - Please search for existing issues before creating yet another duplicate.
            Hide
            timhunt 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
            timhunt 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
            drex 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
            drex 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
            aolley 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
            aolley 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
            timhunt 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
            timhunt 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
            tlevi Tony Levi added a comment -

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

            Show
            tlevi Tony Levi added a comment - Well, could always tack on a 'manuallyclosed' field in the DB or similar?
            Hide
            amjadsqu 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
            amjadsqu 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
            margaretmfleck 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
            margaretmfleck 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
            timhunt 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
            timhunt 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
            pjfish06 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
            pjfish06 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
            pjfish06 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
            pjfish06 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
            timhunt Tim Hunt added a comment -

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

            Show
            timhunt Tim Hunt added a comment - Yes. That is about the best that is available until this is fixed properly.
            Hide
            justinlitalien 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
            justinlitalien 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
            timhunt Tim Hunt added a comment -

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

            Show
            timhunt Tim Hunt added a comment - Thanks, but this issue is now only relevant to Moodle 2.3, where things changed in this area.
            Hide
            paaskynen 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
            paaskynen 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
            haristephenkumar 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
            haristephenkumar 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
            timhunt 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
            timhunt 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
            kisa-chan 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
            kisa-chan 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
            vicden 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
            vicden 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?
            Hide
            rex Rex Lorenzo added a comment -

            Just ran into this problem as well. Extending the quiz due date didn't work and increasing the attempts to 2 and then reattempting the quiz as a student was too much work.

            The fix I did was get the quiz attempt (by clicking on "Review Attempt" and then copying the "attempt" id in the URL).

            Then go the database and lookup the entry for the attempt in mdl_quiz_attempts and change the state from "abandoned" to "finished". Then go to the quiz grading screen, select the attempts that weren't grade and re-grade them.

            Would like to see Tania's patch incorporated, but it is for Moodle 2.3 and not sure if it would merge in cleanly to 2.7+.

            Show
            rex Rex Lorenzo added a comment - Just ran into this problem as well. Extending the quiz due date didn't work and increasing the attempts to 2 and then reattempting the quiz as a student was too much work. The fix I did was get the quiz attempt (by clicking on "Review Attempt" and then copying the "attempt" id in the URL). Then go the database and lookup the entry for the attempt in mdl_quiz_attempts and change the state from "abandoned" to "finished". Then go to the quiz grading screen, select the attempts that weren't grade and re-grade them. Would like to see Tania's patch incorporated, but it is for Moodle 2.3 and not sure if it would merge in cleanly to 2.7+.

              People

              • Votes:
                26 Vote for this issue
                Watchers:
                23 Start watching this issue

                Dates

                • Created:
                  Updated: