Differences Between: [Versions 311 and 402] [Versions 311 and 403]
1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * Library code used by quiz cron. 19 * 20 * @package mod_quiz 21 * @copyright 2012 the Open University 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 26 defined('MOODLE_INTERNAL') || die(); 27 28 require_once($CFG->dirroot . '/mod/quiz/locallib.php'); 29 30 31 /** 32 * This class holds all the code for automatically updating all attempts that have 33 * gone over their time limit. 34 * 35 * @copyright 2012 the Open University 36 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 37 */ 38 class mod_quiz_overdue_attempt_updater { 39 40 /** 41 * Do the processing required. 42 * @param int $timenow the time to consider as 'now' during the processing. 43 * @param int $processto only process attempt with timecheckstate longer ago than this. 44 * @return array with two elements, the number of attempt considered, and how many different quizzes that was. 45 */ 46 public function update_overdue_attempts($timenow, $processto) { 47 global $DB; 48 49 $attemptstoprocess = $this->get_list_of_overdue_attempts($processto); 50 51 $course = null; 52 $quiz = null; 53 $cm = null; 54 55 $count = 0; 56 $quizcount = 0; 57 foreach ($attemptstoprocess as $attempt) { 58 try { 59 60 // If we have moved on to a different quiz, fetch the new data. 61 if (!$quiz || $attempt->quiz != $quiz->id) { 62 $quiz = $DB->get_record('quiz', array('id' => $attempt->quiz), '*', MUST_EXIST); 63 $cm = get_coursemodule_from_instance('quiz', $attempt->quiz); 64 $quizcount += 1; 65 } 66 67 // If we have moved on to a different course, fetch the new data. 68 if (!$course || $course->id != $quiz->course) { 69 $course = $DB->get_record('course', array('id' => $quiz->course), '*', MUST_EXIST); 70 } 71 72 // Make a specialised version of the quiz settings, with the relevant overrides. 73 $quizforuser = clone($quiz); 74 $quizforuser->timeclose = $attempt->usertimeclose; 75 $quizforuser->timelimit = $attempt->usertimelimit; 76 77 // Trigger any transitions that are required. 78 $attemptobj = new quiz_attempt($attempt, $quizforuser, $cm, $course); 79 $attemptobj->handle_if_time_expired($timenow, false); 80 $count += 1; 81 82 } catch (moodle_exception $e) { 83 // If an error occurs while processing one attempt, don't let that kill cron. 84 mtrace("Error while processing attempt {$attempt->id} at {$attempt->quiz} quiz:"); 85 mtrace($e->getMessage()); 86 mtrace($e->getTraceAsString()); 87 // Close down any currently open transactions, otherwise one error 88 // will stop following DB changes from being committed. 89 $DB->force_transaction_rollback(); 90 } 91 } 92 93 $attemptstoprocess->close(); 94 return array($count, $quizcount); 95 } 96 97 /** 98 * @return moodle_recordset of quiz_attempts that need to be processed because time has 99 * passed. The array is sorted by courseid then quizid. 100 */ 101 public function get_list_of_overdue_attempts($processto) { 102 global $DB; 103 104 105 // SQL to compute timeclose and timelimit for each attempt: 106 $quizausersql = quiz_get_attempt_usertime_sql( 107 "iquiza.state IN ('inprogress', 'overdue') AND iquiza.timecheckstate <= :iprocessto"); 108 109 // This query should have all the quiz_attempts columns. 110 return $DB->get_recordset_sql(" 111 SELECT quiza.*, 112 quizauser.usertimeclose, 113 quizauser.usertimelimit 114 115 FROM {quiz_attempts} quiza 116 JOIN {quiz} quiz ON quiz.id = quiza.quiz 117 JOIN ( $quizausersql ) quizauser ON quizauser.id = quiza.id 118 119 WHERE quiza.state IN ('inprogress', 'overdue') 120 AND quiza.timecheckstate <= :processto 121 ORDER BY quiz.course, quiza.quiz", 122 123 array('processto' => $processto, 'iprocessto' => $processto)); 124 } 125 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body