/** * Update the final grades for all attempts. This method is used following * a regrade. * @param object $quiz the quiz settings. * @param array $userids only update scores for these userids. * @param array $attemptids attemptids only update scores for these attempt ids. */ protected function update_overall_grades($quiz) { quiz_update_all_attempt_sumgrades($quiz); quiz_update_all_final_grades($quiz); quiz_update_grades($quiz); }
// Update the database. $DB->set_field('quiz', 'questions', $quiz->questions, array('id' => $quiz->id)); $deletepreviews = true; } // If rescaling is required save the new maximum. $maxgrade = unformat_float(optional_param('maxgrade', -1, PARAM_RAW)); if ($maxgrade >= 0) { quiz_set_grade($maxgrade, $quiz); } if ($deletepreviews) { quiz_delete_previews($quiz); } if ($recomputesummarks) { quiz_update_sumgrades($quiz); quiz_update_all_attempt_sumgrades($quiz); quiz_update_all_final_grades($quiz); quiz_update_grades($quiz, 0, true); } redirect($afteractionurl); } $questionbank->process_actions($thispageurl, $cm); // End of process commands ===================================================== $PAGE->requires->yui2_lib('container'); $PAGE->requires->yui2_lib('dragdrop'); $PAGE->requires->skip_link_to('questionbank', get_string('skipto', 'access', get_string('questionbank', 'question'))); $PAGE->requires->skip_link_to('quizcontentsblock', get_string('skipto', 'access', get_string('questionsinthisquiz', 'quiz'))); $PAGE->set_title(get_string('editingquizx', 'quiz', format_string($quiz->name))); $PAGE->set_heading($course->fullname); $node = $PAGE->settingsnav->find('mod_quiz_edit', navigation_node::TYPE_SETTING); if ($node) { $node->make_active();
/** * 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; }
/** * Given an object containing all the necessary data, * (defined by the form in mod_form.php) this function * will update an existing instance with new data. * * @param object $quiz the data that came from the form. * @return mixed true on success, false or a string error message on failure. */ function quiz_update_instance($quiz, $mform) { global $CFG, $DB; require_once $CFG->dirroot . '/mod/quiz/locallib.php'; // Process the options from the form. $result = quiz_process_options($quiz); if ($result && is_string($result)) { return $result; } // Get the current value, so we can see what changed. $oldquiz = $DB->get_record('quiz', array('id' => $quiz->instance)); // We need two values from the existing DB record that are not in the form, // in some of the function calls below. $quiz->sumgrades = $oldquiz->sumgrades; $quiz->grade = $oldquiz->grade; // Repaginate, if asked to. if (!$quiz->shufflequestions && !empty($quiz->repaginatenow)) { $quiz->questions = quiz_repaginate(quiz_clean_layout($oldquiz->questions, true), $quiz->questionsperpage); } unset($quiz->repaginatenow); // Update the database. $quiz->id = $quiz->instance; $DB->update_record('quiz', $quiz); // Do the processing required after an add or an update. quiz_after_add_or_update($quiz); if ($oldquiz->grademethod != $quiz->grademethod) { quiz_update_all_final_grades($quiz); quiz_update_grades($quiz); } $quizdateschanged = $oldquiz->timelimit != $quiz->timelimit || $oldquiz->timeclose != $quiz->timeclose || $oldquiz->graceperiod != $quiz->graceperiod; if ($quizdateschanged) { quiz_update_open_attempts(array('quizid' => $quiz->id)); } // Delete any previous preview attempts. quiz_delete_previews($quiz); return true; }
/** * Recalculate grades for any affected quiz. * @global moodle_database $DB * @param array $data array with attributes, like 'tableName' * @param array $ids ids of the table to be updated, and so, to update quiz grades. */ protected function updateQuizzes($data, $ids, &$actionLog) { if (empty($ids)) { // if no ids... do nothing. return; } global $DB; $idsstr = "'" . implode("', '", $ids) . "'"; $sqlQuizzes = "\n SELECT * FROM {quiz} q\n WHERE EXISTS (\n SELECT * FROM {" . $data['tableName'] . "} WHERE id IN ({$idsstr}) AND quiz=q.id\n )\n "; $quizzes = $DB->get_records_sql($sqlQuizzes); if ($quizzes) { $actionLog[] = get_string('qa_grades', 'tool_mergeusers', implode(', ', array_keys($quizzes))); foreach ($quizzes as $quiz) { // https://moodle.org/mod/forum/discuss.php?d=258979 // recalculate grades for affected quizzes. quiz_update_all_final_grades($quiz); } } }
/** * Given an object containing all the necessary data, * (defined by the form in mod_form.php) this function * will update an existing instance with new data. * * @param object $quiz the data that came from the form. * @return mixed true on success, false or a string error message on failure. */ function quiz_update_instance($quiz, $mform) { global $CFG, $DB; // Process the options from the form. $result = quiz_process_options($quiz); if ($result && is_string($result)) { return $result; } $oldquiz = $DB->get_record('quiz', array('id' => $quiz->instance)); // Repaginate, if asked to. if (!$quiz->shufflequestions && !empty($quiz->repaginatenow)) { require_once($CFG->dirroot . '/mod/quiz/locallib.php'); $quiz->questions = quiz_repaginate(quiz_clean_layout($oldquiz->questions, true), $quiz->questionsperpage); } unset($quiz->repaginatenow); // Update the database. $quiz->id = $quiz->instance; $DB->update_record('quiz', $quiz); // Do the processing required after an add or an update. quiz_after_add_or_update($quiz); if ($oldquiz->grademethod != $quiz->grademethod) { require_once($CFG->dirroot . '/mod/quiz/locallib.php'); $quiz->sumgrades = $oldquiz->sumgrades; $quiz->grade = $oldquiz->grade; quiz_update_all_final_grades($quiz); quiz_update_grades($quiz); } // Delete any previous preview attempts. quiz_delete_previews($quiz); return true; }