/** * Removes all grades from gradebook * @param int $courseid * @param string optional type */ function quiz_reset_gradebook($courseid, $type = '') { global $CFG; $sql = "SELECT q.*, cm.idnumber as cmidnumber, q.course as courseid\n FROM {$CFG->prefix}quiz q, {$CFG->prefix}course_modules cm, {$CFG->prefix}modules m\n WHERE m.name='quiz' AND m.id=cm.module AND cm.instance=q.id AND q.course={$courseid}"; if ($quizs = get_records_sql($sql)) { foreach ($quizs as $quiz) { quiz_grade_item_update($quiz, 'reset'); } } }
/** * The quiz grade is the score that student's results are marked out of. When it * changes, the corresponding data in quiz_grades and quiz_feedback needs to be * rescaled. * * @param float $newgrade the new maximum grade for the quiz. * @param object $quiz the quiz we are updating. Passed by reference so its grade field can be updated too. * @return boolean indicating success or failure. */ function quiz_set_grade($newgrade, &$quiz) { // This is potentially expensive, so only do it if necessary. if (abs($quiz->grade - $newgrade) < 1.0E-7) { // Nothing to do. return true; } // Use a transaction, so that on those databases that support it, this is safer. begin_sql(); // Update the quiz table. $success = set_field('quiz', 'grade', $newgrade, 'id', $quiz->instance); // Rescaling the other data is only possible if the old grade was non-zero. if ($quiz->grade > 1.0E-7) { global $CFG; $factor = $newgrade / $quiz->grade; $quiz->grade = $newgrade; // Update the quiz_grades table. $timemodified = time(); $success = $success && execute_sql("\n UPDATE {$CFG->prefix}quiz_grades\n SET grade = {$factor} * grade, timemodified = {$timemodified}\n WHERE quiz = {$quiz->id}\n ", false); // Update the quiz_feedback table. $success = $success && execute_sql("\n UPDATE {$CFG->prefix}quiz_feedback\n SET mingrade = {$factor} * mingrade, maxgrade = {$factor} * maxgrade\n WHERE quizid = {$quiz->id}\n ", false); } // update grade item and send all grades to gradebook quiz_grade_item_update($quiz); quiz_update_grades($quiz); if ($success) { return commit_sql(); } else { rollback_sql(); return false; } }
/** * The quiz grade is the maximum that student's results are marked out of. When it * changes, the corresponding data in quiz_grades and quiz_feedback needs to be * rescaled. After calling this function, you probably need to call * quiz_update_all_attempt_sumgrades, quiz_update_all_final_grades and * quiz_update_grades. * * @param float $newgrade the new maximum grade for the quiz. * @param object $quiz the quiz we are updating. Passed by reference so its * grade field can be updated too. * @return bool indicating success or failure. */ function quiz_set_grade($newgrade, $quiz) { global $DB; // This is potentially expensive, so only do it if necessary. if (abs($quiz->grade - $newgrade) < 1e-7) { // Nothing to do. return true; } $oldgrade = $quiz->grade; $quiz->grade = $newgrade; // Use a transaction, so that on those databases that support it, this is safer. $transaction = $DB->start_delegated_transaction(); // Update the quiz table. $DB->set_field('quiz', 'grade', $newgrade, array('id' => $quiz->instance)); if ($oldgrade < 1) { // If the old grade was zero, we cannot rescale, we have to recompute. // We also recompute if the old grade was too small to avoid underflow problems. quiz_update_all_final_grades($quiz); } else { // We can rescale the grades efficiently. $timemodified = time(); $DB->execute(" UPDATE {quiz_grades} SET grade = ? * grade, timemodified = ? WHERE quiz = ? ", array($newgrade/$oldgrade, $timemodified, $quiz->id)); } if ($oldgrade > 1e-7) { // Update the quiz_feedback table. $factor = $newgrade/$oldgrade; $DB->execute(" UPDATE {quiz_feedback} SET mingrade = ? * mingrade, maxgrade = ? * maxgrade WHERE quizid = ? ", array($factor, $factor, $quiz->id)); } // Update grade item and send all grades to gradebook. quiz_grade_item_update($quiz); quiz_update_grades($quiz); $transaction->allow_commit(); return true; }
/** * Removes all grades from gradebook * * @param int $courseid * @param string optional type */ function quiz_reset_gradebook($courseid, $type='') { global $CFG, $DB; $quizzes = $DB->get_records_sql(" SELECT q.*, cm.idnumber as cmidnumber, q.course as courseid FROM {modules} m JOIN {course_modules} cm ON m.id = cm.module JOIN {quiz} q ON cm.instance = q.id WHERE m.name = 'quiz' AND cm.course = ?", array($courseid)); foreach ($quizzes as $quiz) { quiz_grade_item_update($quiz, 'reset'); } }
/** * The quiz grade is the maximum that student's results are marked out of. When it * changes, the corresponding data in quiz_grades and quiz_feedback needs to be * rescaled. After calling this function, you probably need to call * quiz_update_all_attempt_sumgrades, quiz_update_all_final_grades and * quiz_update_grades. * * @param float $newgrade the new maximum grade for the quiz. * @param object $quiz the quiz we are updating. Passed by reference so its * grade field can be updated too. * @return bool indicating success or failure. */ function quiz_set_grade($newgrade, $quiz) { global $DB; // This is potentially expensive, so only do it if necessary. if (abs($quiz->grade - $newgrade) < 1e-7) { // Nothing to do. return true; } // Use a transaction, so that on those databases that support it, this is safer. $transaction = $DB->start_delegated_transaction(); // Update the quiz table. $DB->set_field('quiz', 'grade', $newgrade, array('id' => $quiz->instance)); // Rescaling the other data is only possible if the old grade was non-zero. if ($quiz->grade > 1e-7) { global $CFG; $factor = $newgrade/$quiz->grade; $quiz->grade = $newgrade; // Update the quiz_grades table. $timemodified = time(); $DB->execute(" UPDATE {quiz_grades} SET grade = ? * grade, timemodified = ? WHERE quiz = ? ", array($factor, $timemodified, $quiz->id)); // Update the quiz_feedback table. $DB->execute(" UPDATE {quiz_feedback} SET mingrade = ? * mingrade, maxgrade = ? * maxgrade WHERE quizid = ? ", array($factor, $factor, $quiz->id)); } // update grade item and send all grades to gradebook quiz_grade_item_update($quiz); quiz_update_grades($quiz); $transaction->allow_commit(); return true; }
/** * Removes all grades from gradebook * * @global stdClass * @global object * @param int $courseid * @param string optional type */ function quiz_reset_gradebook($courseid, $type='') { global $CFG, $DB; $sql = "SELECT q.*, cm.idnumber as cmidnumber, q.course as courseid FROM {quiz} q, {course_modules} cm, {modules} m WHERE m.name='quiz' AND m.id=cm.module AND cm.instance=q.id AND q.course=?"; if ($quizs = $DB->get_records_sql($sql, array($courseid))) { foreach ($quizs as $quiz) { quiz_grade_item_update($quiz, 'reset'); } } }
/** * This function is called at the end of quiz_add_instance * and quiz_update_instance, to do the common processing. * * @param object $quiz the quiz object. */ function quiz_after_add_or_update($quiz) { // Save the feedback delete_records('quiz_feedback', 'quizid', $quiz->id); for ($i = 0; $i <= $quiz->feedbackboundarycount; $i += 1) { $feedback = new stdClass(); $feedback->quizid = $quiz->id; $feedback->feedbacktext = $quiz->feedbacktext[$i]; $feedback->mingrade = $quiz->feedbackboundaries[$i]; $feedback->maxgrade = $quiz->feedbackboundaries[$i - 1]; if (!insert_record('quiz_feedback', $feedback, false)) { return "Could not save quiz feedback."; } } // Update the events relating to this quiz. // This is slightly inefficient, deleting the old events and creating new ones. However, // there are at most two events, and this keeps the code simpler. if ($events = get_records_select('event', "modulename = 'quiz' and instance = '{$quiz->id}'")) { foreach ($events as $event) { delete_event($event->id); } } $event = new stdClass(); $event->description = $quiz->intro; $event->courseid = $quiz->course; $event->groupid = 0; $event->userid = 0; $event->modulename = 'quiz'; $event->instance = $quiz->id; $event->timestart = $quiz->timeopen; $event->timeduration = $quiz->timeclose - $quiz->timeopen; $event->visible = instance_is_visible('quiz', $quiz); $event->eventtype = 'open'; if ($quiz->timeclose and $quiz->timeopen and $event->timeduration <= QUIZ_MAX_EVENT_LENGTH) { // Single event for the whole quiz. $event->name = $quiz->name; add_event($event); } else { // Separate start and end events. $event->timeduration = 0; if ($quiz->timeopen) { $event->name = $quiz->name . ' (' . get_string('quizopens', 'quiz') . ')'; add_event($event); unset($event->id); // So we can use the same object for the close event. } if ($quiz->timeclose) { $event->name = $quiz->name . ' (' . get_string('quizcloses', 'quiz') . ')'; $event->timestart = $quiz->timeclose; $event->eventtype = 'close'; add_event($event); } } //update related grade item quiz_grade_item_update(stripslashes_recursive($quiz)); }