function xmldb_quiz_upgrade($oldversion = 0) { global $CFG, $THEME, $db; $result = true; /// And upgrade begins here. For each one, you'll need one /// block of code similar to the next one. Please, delete /// this comment lines once this file start handling proper /// upgrade code. if ($result && $oldversion < 2007022800) { /// Ensure that there are not existing duplicate entries in the database. $duplicateunits = get_records_select('question_numerical_units', "id > (SELECT MIN(iqnu.id)\n FROM {$CFG->prefix}question_numerical_units iqnu\n WHERE iqnu.question = {$CFG->prefix}question_numerical_units.question AND\n iqnu.unit = {$CFG->prefix}question_numerical_units.unit)", '', 'id'); if ($duplicateunits) { delete_records_select('question_numerical_units', 'id IN (' . implode(',', array_keys($duplicateunits)) . ')'); } /// Define index question-unit (unique) to be added to question_numerical_units $table = new XMLDBTable('question_numerical_units'); $index = new XMLDBIndex('question-unit'); $index->setAttributes(XMLDB_INDEX_UNIQUE, array('question', 'unit')); /// Launch add index question-unit $result = $result && add_index($table, $index); } if ($result && $oldversion < 2007070200) { /// Changing precision of field timelimit on table quiz to (10) $table = new XMLDBTable('quiz'); $field = new XMLDBField('timelimit'); $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0', 'timemodified'); /// Launch change of precision for field timelimit $result = $result && change_field_precision($table, $field); } if ($result && $oldversion < 2007072200) { require_once $CFG->dirroot . '/mod/quiz/lib.php'; // too much debug output $db->debug = false; quiz_update_grades(); $db->debug = true; } // Separate control for when overall feedback is displayed, independant of the question feedback settings. if ($result && $oldversion < 2007072600) { // Adjust the quiz review options so that overall feedback is displayed whenever feedback is. $result = $result && execute_sql('UPDATE ' . $CFG->prefix . 'quiz SET review = ' . sql_bitor(sql_bitand('review', sql_bitnot(QUIZ_REVIEW_OVERALLFEEDBACK)), sql_bitor(sql_bitand('review', QUIZ_REVIEW_FEEDBACK & QUIZ_REVIEW_IMMEDIATELY) . ' * 65536', sql_bitor(sql_bitand('review', QUIZ_REVIEW_FEEDBACK & QUIZ_REVIEW_OPEN) . ' * 16384', sql_bitand('review', QUIZ_REVIEW_FEEDBACK & QUIZ_REVIEW_CLOSED) . ' * 4096')))); // Same adjustment to the defaults for new quizzes. $result = $result && set_config('quiz_review', $CFG->quiz_review & ~QUIZ_REVIEW_OVERALLFEEDBACK | ($CFG->quiz_review & QUIZ_REVIEW_FEEDBACK & QUIZ_REVIEW_IMMEDIATELY) << 16 | ($CFG->quiz_review & QUIZ_REVIEW_FEEDBACK & QUIZ_REVIEW_OPEN) << 14 | ($CFG->quiz_review & QUIZ_REVIEW_FEEDBACK & QUIZ_REVIEW_CLOSED) << 12); } //===== 1.9.0 upgrade line ======// return $result; }
/** * 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); }
$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(); }
/** * Save the overall grade for a user at a quiz in the quiz_grades table * * @param object $quiz The quiz for which the best grade is to be calculated and then saved. * @param integer $userid The userid to calculate the grade for. Defaults to the current user. * @return boolean Indicates success or failure. */ function quiz_save_best_grade($quiz, $userid = null) { global $USER; if (empty($userid)) { $userid = $USER->id; } // Get all the attempts made by the user if (!($attempts = quiz_get_user_attempts($quiz->id, $userid))) { notify('Could not find any user attempts'); return false; } // Calculate the best grade $bestgrade = quiz_calculate_best_grade($quiz, $attempts); $bestgrade = quiz_rescale_grade($bestgrade, $quiz); // Save the best grade in the database if ($grade = get_record('quiz_grades', 'quiz', $quiz->id, 'userid', $userid)) { $grade->grade = $bestgrade; $grade->timemodified = time(); if (!update_record('quiz_grades', $grade)) { notify('Could not update best grade'); return false; } } else { $grade->quiz = $quiz->id; $grade->userid = $userid; $grade->grade = $bestgrade; $grade->timemodified = time(); if (!insert_record('quiz_grades', $grade)) { notify('Could not insert new best grade'); return false; } } quiz_update_grades($quiz, $userid); return true; }
/** * Update grades in central gradebook * * @param object $quiz null means all quizs * @param int $userid specific user only, 0 mean all */ function quiz_update_grades($quiz = null, $userid = 0, $nullifnone = true) { global $CFG; if (!function_exists('grade_update')) { //workaround for buggy PHP versions require_once $CFG->libdir . '/gradelib.php'; } if ($quiz != null) { if ($grades = quiz_get_user_grades($quiz, $userid)) { quiz_grade_item_update($quiz, $grades); } else { if ($userid and $nullifnone) { $grade = new object(); $grade->userid = $userid; $grade->rawgrade = NULL; quiz_grade_item_update($quiz, $grade); } else { quiz_grade_item_update($quiz); } } } else { $sql = "SELECT a.*, cm.idnumber as cmidnumber, a.course as courseid\n FROM {$CFG->prefix}quiz a, {$CFG->prefix}course_modules cm, {$CFG->prefix}modules m\n WHERE m.name='quiz' AND m.id=cm.module AND cm.instance=a.id"; if ($rs = get_recordset_sql($sql)) { while ($quiz = rs_fetch_next_record($rs)) { if ($quiz->grade != 0) { quiz_update_grades($quiz, 0, false); } else { quiz_grade_item_update($quiz); } } rs_close($rs); } } }
/** * Save the overall grade for a user at a quiz in the quiz_grades table * * @param object $quiz The quiz for which the best grade is to be calculated and then saved. * @param int $userid The userid to calculate the grade for. Defaults to the current user. * @param array $attempts The attempts of this user. Useful if you are * looping through many users. Attempts can be fetched in one master query to * avoid repeated querying. * @return bool Indicates success or failure. */ function quiz_save_best_grade($quiz, $userid = null, $attempts = array()) { global $DB, $OUTPUT, $USER; if (empty($userid)) { $userid = $USER->id; } if (!$attempts) { // Get all the attempts made by the user. $attempts = quiz_get_user_attempts($quiz->id, $userid); } // Calculate the best grade. $bestgrade = quiz_calculate_best_grade($quiz, $attempts); $bestgrade = quiz_rescale_grade($bestgrade, $quiz, false); // Save the best grade in the database. if (is_null($bestgrade)) { $DB->delete_records('quiz_grades', array('quiz' => $quiz->id, 'userid' => $userid)); } else if ($grade = $DB->get_record('quiz_grades', array('quiz' => $quiz->id, 'userid' => $userid))) { $grade->grade = $bestgrade; $grade->timemodified = time(); $DB->update_record('quiz_grades', $grade); } else { $grade = new stdClass(); $grade->quiz = $quiz->id; $grade->userid = $userid; $grade->grade = $bestgrade; $grade->timemodified = time(); $DB->insert_record('quiz_grades', $grade); } quiz_update_grades($quiz, $userid); }
/** * Update all grades in gradebook. */ function quiz_upgrade_grades() { global $DB; $sql = "SELECT COUNT('x') FROM {quiz} a, {course_modules} cm, {modules} m WHERE m.name='quiz' AND m.id=cm.module AND cm.instance=a.id"; $count = $DB->count_records_sql($sql); $sql = "SELECT a.*, cm.idnumber AS cmidnumber, a.course AS courseid FROM {quiz} a, {course_modules} cm, {modules} m WHERE m.name='quiz' AND m.id=cm.module AND cm.instance=a.id"; $rs = $DB->get_recordset_sql($sql); if ($rs->valid()) { $pbar = new progress_bar('quizupgradegrades', 500, true); $i=0; foreach ($rs as $quiz) { $i++; upgrade_set_timeout(60*5); // Set up timeout, may also abort execution. quiz_update_grades($quiz, 0, false); $pbar->update($i, $count, "Updating Quiz grades ($i/$count)."); } } $rs->close(); }
/** * 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; // 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); // Repaginate, if asked to. if (!empty($quiz->repaginatenow)) { quiz_repaginate_questions($quiz->id, $quiz->questionsperpage); } return true; }
/** * Save the overall grade for a user at a quiz in the quiz_grades table * * @param object $quiz The quiz for which the best grade is to be calculated and then saved. * @param integer $userid The userid to calculate the grade for. Defaults to the current user. * @param array $attempts The attempts of this user. Useful if you are * looping through many users. Attempts can be fetched in one master query to * avoid repeated querying. * @return boolean Indicates success or failure. */ function quiz_save_best_grade($quiz, $userid = null, $attempts = array()) { global $DB; global $USER, $OUTPUT; if (empty($userid)) { $userid = $USER->id; } if (!$attempts) { // Get all the attempts made by the user if (!($attempts = quiz_get_user_attempts($quiz->id, $userid))) { echo $OUTPUT->notification('Could not find any user attempts'); return false; } } // Calculate the best grade $bestgrade = quiz_calculate_best_grade($quiz, $attempts); $bestgrade = quiz_rescale_grade($bestgrade, $quiz, false); // Save the best grade in the database if ($grade = $DB->get_record('quiz_grades', array('quiz' => $quiz->id, 'userid' => $userid))) { $grade->grade = $bestgrade; $grade->timemodified = time(); $DB->update_record('quiz_grades', $grade); } else { $grade->quiz = $quiz->id; $grade->userid = $userid; $grade->grade = $bestgrade; $grade->timemodified = time(); $DB->insert_record('quiz_grades', $grade); } quiz_update_grades($quiz, $userid); return true; }