mirror of
https://github.com/moodle/moodle.git
synced 2025-08-05 00:46:50 +02:00
Merged from stable
This commit is contained in:
parent
cb998489a2
commit
fc44ee0de8
17 changed files with 307 additions and 414 deletions
|
@ -216,13 +216,13 @@
|
|||
// list of questions needed by page
|
||||
$pagelist = quiz_questions_on_page($attempt->layout, $page);
|
||||
|
||||
// add all questions that are on the submitted form
|
||||
if ($newattempt) {
|
||||
$questionlist = $attempt->layout;
|
||||
$questionlist = quiz_questions_in_quiz($attempt->layout);
|
||||
} else {
|
||||
$questionlist = $pagelist;
|
||||
}
|
||||
|
||||
// add all questions that are on the submitted form
|
||||
if ($questionids) {
|
||||
$questionlist .= ','.$questionids;
|
||||
}
|
||||
|
@ -253,6 +253,13 @@
|
|||
error('Could not restore question sessions');
|
||||
}
|
||||
|
||||
// Save all the newly created states
|
||||
if ($newattempt) {
|
||||
foreach ($questions as $i => $question) {
|
||||
quiz_save_question_session($questions[$i], $states[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Process form data /////////////////////////////////////////////////
|
||||
|
||||
|
@ -370,13 +377,16 @@
|
|||
|
||||
/// Print the attempt number or preview heading
|
||||
if ($isteacher) {
|
||||
print_heading(get_string('previewquiz', 'quiz'));
|
||||
print_heading(get_string('previewquiz', 'quiz', format_string($quiz->name)));
|
||||
unset($buttonoptions);
|
||||
$buttonoptions['q'] = $quiz->id;
|
||||
$buttonoptions['forcenew'] = true;
|
||||
echo '<center>';
|
||||
print_single_button($CFG->wwwroot.'/mod/quiz/attempt.php', $buttonoptions, get_string('startagain', 'quiz'));
|
||||
echo '</center>';
|
||||
if ($quiz->popup) {
|
||||
notify(get_string('popupnotice', 'quiz'));
|
||||
}
|
||||
} else {
|
||||
print_heading($strattemptnum);
|
||||
}
|
||||
|
@ -434,14 +444,6 @@
|
|||
quiz_save_question_session($questions[$i], $states[$i]);
|
||||
$number += $questions[$i]->length;
|
||||
}
|
||||
if ($newattempt) {
|
||||
$questionlist = explode(',', $attempt->layout);
|
||||
foreach ($questionlist as $i) {
|
||||
if ($i != 0) {
|
||||
quiz_save_question_session($questions[$i], $states[$i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Print the submit buttons
|
||||
|
||||
|
|
|
@ -932,7 +932,7 @@
|
|||
fwrite ($bf,full_tag("ID",8,false,$newest_state->id));
|
||||
fwrite ($bf,full_tag("QUESTIONID",8,false,$newest_state->questionid));
|
||||
fwrite ($bf,full_tag("NEWEST",8,false,$newest_state->newest));
|
||||
fwrite ($bf,full_tag("NEWESTGRADED",8,false,$newest_state->newestgraded));
|
||||
fwrite ($bf,full_tag("NEWGRADED",8,false,$newest_state->newgraded));
|
||||
fwrite ($bf,full_tag("SUMPENALTY",8,false,$newest_state->sumpenalty));
|
||||
//End newest_state
|
||||
$status =fwrite ($bf,end_tag("NEWEST_STATE",7,true));
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
-- http://www.phpmyadmin.net
|
||||
--
|
||||
-- Host: localhost
|
||||
-- Generation Time: May 25, 2005 at 06:50 AM
|
||||
-- Generation Time: Jun 05, 2005 at 04:32 PM
|
||||
-- Server version: 4.0.15
|
||||
-- PHP Version: 4.3.3
|
||||
--
|
||||
-- Database: `upgrading`
|
||||
-- Database: `moodle15`
|
||||
--
|
||||
|
||||
-- --------------------------------------------------------
|
||||
|
@ -399,7 +399,7 @@ CREATE TABLE prefix_quiz_rqp (
|
|||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `prefix_quiz_rqp_states`
|
||||
-- Table structure for table `prefix_quiz_rqp_servers`
|
||||
--
|
||||
|
||||
CREATE TABLE prefix_quiz_rqp_servers (
|
||||
|
@ -414,7 +414,7 @@ CREATE TABLE prefix_quiz_rqp_servers (
|
|||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `mdl_quiz_rqp_states`
|
||||
-- Table structure for table `prefix_quiz_rqp_states`
|
||||
--
|
||||
|
||||
CREATE TABLE prefix_quiz_rqp_states (
|
||||
|
@ -429,15 +429,12 @@ CREATE TABLE prefix_quiz_rqp_states (
|
|||
-- --------------------------------------------------------
|
||||
|
||||
--
|
||||
-- Table structure for table `prefix_quiz_rqp_type`
|
||||
-- Table structure for table `prefix_quiz_rqp_types`
|
||||
--
|
||||
|
||||
CREATE TABLE prefix_quiz_rqp_types (
|
||||
id int(10) unsigned NOT NULL auto_increment,
|
||||
name varchar(255) NOT NULL default '',
|
||||
rendering_server varchar(255) NOT NULL default '',
|
||||
cloning_server varchar(255) NOT NULL default '',
|
||||
flags tinyint(3) NOT NULL default '0',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY name (name)
|
||||
) TYPE=MyISAM COMMENT='RQP question types and the servers to be used to process the';
|
||||
|
|
|
@ -408,14 +408,13 @@ if (self.name == 'editquestion') {
|
|||
if (! $cm = get_coursemodule_from_instance("quiz", $modform->instance, $course->id)) {
|
||||
error("Course Module ID was incorrect");
|
||||
}
|
||||
notify("$strattemptsexist<br /><a href=\"report.php?mode=overview&id=$cm->id\">$strviewallanswers ($usercount $strusers)</a>");
|
||||
|
||||
echo "<center>\n";
|
||||
echo "$strattemptsexist<br /><a href=\"report.php?mode=overview&id=$cm->id\">$strviewallanswers ($usercount $strusers)</a>";
|
||||
echo "<form target=\"_parent\" method=\"get\" action=\"$CFG->wwwroot/mod/quiz/edit.php\">\n";
|
||||
echo " <input type=\"hidden\" name=\"courseid\" value=\"$course->id\" />\n";
|
||||
echo " <input type=\"submit\" value=\"".get_string("editcatquestions", "quiz")."\" />\n";
|
||||
echo "</form>";
|
||||
echo "</center>\n";
|
||||
echo "</center><br/ >\n";
|
||||
|
||||
$sumgrades = quiz_print_question_list($modform, false, $SESSION->quiz_showbreaks);
|
||||
if (!set_field('quiz', 'sumgrades', $sumgrades, 'id', $modform->instance)) {
|
||||
|
|
|
@ -247,7 +247,7 @@ class quiz_default_questiontype {
|
|||
// The default implementation attaches all answers for this question
|
||||
if (!$question->options->answers = get_records('quiz_answers', 'question',
|
||||
$question->id)) {
|
||||
notify('Error: Missing question answers!');
|
||||
//notify('Error: Missing question answers!');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -1349,39 +1349,43 @@ function quiz_save_question_session(&$question, &$state) {
|
|||
$state->answer = isset($state->responses['']) ? $state->responses[''] : '';
|
||||
|
||||
// Save the state
|
||||
unset($state->id);
|
||||
if (!$state->id = insert_record('quiz_states', $state)) {
|
||||
unset($state->id);
|
||||
unset($state->answer);
|
||||
return false;
|
||||
}
|
||||
unset($state->answer);
|
||||
|
||||
// this is the most recent state
|
||||
if (!record_exists('quiz_newest_states', 'attemptid',
|
||||
$state->attempt, 'questionid', $question->id)) {
|
||||
$new->attemptid = $state->attempt;
|
||||
$new->questionid = $question->id;
|
||||
$new->newest = $state->id;
|
||||
$new->newgraded = $state->id;
|
||||
$new->sumpenalty = $state->sumpenalty;
|
||||
if (!insert_record('quiz_newest_states', $new)) {
|
||||
error('Could not insert entry in quiz_newest_states');
|
||||
}
|
||||
if (isset($state->update)) {
|
||||
update_record('quiz_states', $state);
|
||||
} else {
|
||||
set_field('quiz_newest_states', 'newest', $state->id, 'attemptid',
|
||||
$state->attempt, 'questionid', $question->id);
|
||||
}
|
||||
if (quiz_state_is_graded($state)) {
|
||||
// this is also the most recent graded state
|
||||
if ($newest = get_record('quiz_newest_states', 'attemptid',
|
||||
if (!$state->id = insert_record('quiz_states', $state)) {
|
||||
unset($state->id);
|
||||
unset($state->answer);
|
||||
return false;
|
||||
}
|
||||
|
||||
// this is the most recent state
|
||||
if (!record_exists('quiz_newest_states', 'attemptid',
|
||||
$state->attempt, 'questionid', $question->id)) {
|
||||
$newest->newgraded = $state->id;
|
||||
$newest->sumpenalty = $state->sumpenalty;
|
||||
update_record('quiz_newest_states', $newest);
|
||||
$new->attemptid = $state->attempt;
|
||||
$new->questionid = $question->id;
|
||||
$new->newest = $state->id;
|
||||
$new->newgraded = $state->id;
|
||||
$new->sumpenalty = $state->sumpenalty;
|
||||
if (!insert_record('quiz_newest_states', $new)) {
|
||||
error('Could not insert entry in quiz_newest_states');
|
||||
}
|
||||
} else {
|
||||
set_field('quiz_newest_states', 'newest', $state->id, 'attemptid',
|
||||
$state->attempt, 'questionid', $question->id);
|
||||
}
|
||||
if (quiz_state_is_graded($state)) {
|
||||
// this is also the most recent graded state
|
||||
if ($newest = get_record('quiz_newest_states', 'attemptid',
|
||||
$state->attempt, 'questionid', $question->id)) {
|
||||
$newest->newgraded = $state->id;
|
||||
$newest->sumpenalty = $state->sumpenalty;
|
||||
update_record('quiz_newest_states', $newest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unset($state->answer);
|
||||
|
||||
// Save the question type specific state information and responses
|
||||
if (!$QUIZ_QTYPES[$question->qtype]->save_session_and_responses(
|
||||
$question, $state)) {
|
||||
|
@ -1465,98 +1469,92 @@ function quiz_extract_responses($questions, $responses, $defaultevent) {
|
|||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* For a given question instance we walk the complete history of states for
|
||||
* each user and recalculate the grades as we go along.
|
||||
* For a given question in an attempt we walk the complete history of states
|
||||
* and recalculate the grades as we go along.
|
||||
*
|
||||
* This is used when a question in an existing quiz is changed and old student
|
||||
* responses need to be marked with the new version of a question.
|
||||
*
|
||||
* TODO: Finish documenting this
|
||||
* @return boolean Indicates success/failure
|
||||
* @param object $question A question object
|
||||
* @param array $quizlist An array of quiz ids, in which the question should
|
||||
* be regraded. If quizlist == 'all' all quizzes are affected
|
||||
* @param object $question A question object
|
||||
* @param object $attempt The attempt, in which the question needs to be regraded.
|
||||
* @param object $quiz Optional. The quiz object that the attempt corresponds to.
|
||||
* @param boolean $verbose Optional. Whether to print progress information or not.
|
||||
*/
|
||||
function quiz_regrade_question_in_quizzes($question, $quizlist) {
|
||||
|
||||
// Disable until tested
|
||||
return;
|
||||
|
||||
if (empty($quizlist)) {
|
||||
return;
|
||||
function quiz_regrade_question_in_attempt($question, $attempt, $quiz=false, $verbose=false) {
|
||||
if (!$quiz && !($quiz = get_record('quiz', 'id', $attempt->quiz))) {
|
||||
$verbose && notify("Regrading of quiz #{$attempt->quiz} failed; " .
|
||||
"Couldn't load quiz record from database!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($quizlist == 'all') { // assume that all quizzes are affected
|
||||
// fetch a list of all the quizzes using this question
|
||||
if (! $instances = (array)get_records('quiz_question_instances',
|
||||
'question', $question->id, '', 'id, quiz')) {
|
||||
// No instances were found, so it successfully regraded all of them
|
||||
return true;
|
||||
}
|
||||
$quizlist = array_map(create_function('$val', 'return $val->quiz;'), $instances);
|
||||
unset($instances);
|
||||
}
|
||||
if ($states = get_records_select('quiz_states',
|
||||
"attempt = '{$attempt->id}' AND question = '{$question->id}'", 'seq_number ASC')) {
|
||||
$states = array_values($states);
|
||||
|
||||
// Get all affected quizzes
|
||||
$quizlist = implode(',', $quizlist);
|
||||
if (! $quizzes = get_records_list('quiz', 'id', $quizlist)) {
|
||||
error('Couldn\'t get quizzes for regrading!');
|
||||
}
|
||||
$attempt->sumgrades -= $states[count($states)-1]->grade;
|
||||
|
||||
foreach ($quizzes as $quiz) {
|
||||
// All the attempts that need to be changed
|
||||
if (! $attempts = get_records('quiz_attempts', 'quiz', $quiz->id)) {
|
||||
continue;
|
||||
}
|
||||
$attempts = array_values($attempts);
|
||||
if (! $instance = get_record('quiz_question_instances',
|
||||
'quiz', $quiz->id, 'question', $question->id)) {
|
||||
error("Couldn't get question instance for regrading!");
|
||||
}
|
||||
$question->maxgrade = $instance->grade;
|
||||
for ($i = 0; $i < count($attempts); $i++) {
|
||||
if ($states = get_records_select('quiz_states',
|
||||
"attempt = '{$attempts[$i]->id}' ".
|
||||
"AND question = '{$question->id}'",
|
||||
'seq_number ASC')) {
|
||||
$states = array_values($states);
|
||||
// Initialise the replaystate
|
||||
$state = clone($states[0]);
|
||||
quiz_restore_state($question, $state);
|
||||
$state->sumpenalty = 0.0;
|
||||
$state->raw_grade = 0;
|
||||
$state->grade = 0;
|
||||
$state->responses = array(''=>'');
|
||||
$state->event = QUIZ_EVENTOPEN;
|
||||
$replaystate = clone($state);
|
||||
$replaystate->last_graded = $state;
|
||||
|
||||
$attempts[$i]->sumgrades -= $states[count($states)-1]->grade;
|
||||
$changed = 0;
|
||||
for($j = 0; $j < count($states); $j++) {
|
||||
quiz_restore_state($question, $states[$j]);
|
||||
$action = new stdClass;
|
||||
$action->responses = $states[$j]->responses;
|
||||
$action->timestamp = $states[$j]->timestamp;
|
||||
|
||||
// Initialise the replaystate
|
||||
quiz_restore_state($question, $states[0]);
|
||||
$replaystate = clone($states[0]);
|
||||
$replaystate->last_graded = clone($states[0]);
|
||||
for($j = 1; $j < count($states); $j++) {
|
||||
quiz_restore_state($question, $states[$j]);
|
||||
$action = new stdClass;
|
||||
$action->responses = $states[$j]->responses;
|
||||
// Close the last state of a finished attempt
|
||||
if (((count($states) - 1) === $j) && ($attempts[$i]->timefinish > 0)) {
|
||||
$action->event = QUIZ_EVENTCLOSE;
|
||||
// Close the last state of a finished attempt
|
||||
if (((count($states) - 1) === $j) && ($attempt->timefinish > 0)) {
|
||||
$action->event = QUIZ_EVENTCLOSE;
|
||||
|
||||
// Grade instead of closing, quiz_process_responses will then
|
||||
// work out whether to close it
|
||||
} else if (QUIZ_EVENTCLOSE == $states[$j]->event) {
|
||||
$action->event = QUIZ_EVENTGRADE;
|
||||
// Grade instead of closing, quiz_process_responses will then
|
||||
// work out whether to close it
|
||||
} else if (QUIZ_EVENTCLOSE == $states[$j]->event) {
|
||||
$action->event = QUIZ_EVENTGRADE;
|
||||
|
||||
// By default take the event that was saved in the database
|
||||
} else {
|
||||
$action->event = $states[$j]->event;
|
||||
}
|
||||
|
||||
// Reprocess (regrade) responses
|
||||
quiz_process_responses($question, $replaystate, $action, $quiz,
|
||||
$attempts[$i]);
|
||||
$replaystate->id = $states[$j]->id;
|
||||
update_record('quiz_states', $replaystate);
|
||||
}
|
||||
update_record('quiz_attempts', $attempts[$i]);
|
||||
quiz_save_best_grade($quiz, $attempts[$i]->userid);
|
||||
// By default take the event that was saved in the database
|
||||
} else {
|
||||
$action->event = $states[$j]->event;
|
||||
}
|
||||
// Reprocess (regrade) responses
|
||||
if (!quiz_process_responses($question, $replaystate, $action, $quiz,
|
||||
$attempt)) {
|
||||
$verbose && notify("Couldn't regrade state #{$state->id}!");
|
||||
}
|
||||
if ((float)$replaystate->raw_grade != (float)$states[$j]->raw_grade) {
|
||||
$changed++;
|
||||
|
||||
}
|
||||
$replaystate->id = $states[$j]->id;
|
||||
$replaystate->update = true;
|
||||
quiz_save_question_session($question, $replaystate);
|
||||
}
|
||||
if ($verbose) {
|
||||
if ($changed) {
|
||||
link_to_popup_window ('/mod/quiz/reviewquestion.php?attempt='.$attempt->id.'&question='.$question->id,
|
||||
'reviewquestion', ' #'.$attempt->id, 450, 550, get_string('reviewresponse', 'quiz'));
|
||||
update_record('quiz_attempts', $attempt);
|
||||
} else {
|
||||
echo ' #'.$attempt->id;
|
||||
}
|
||||
echo "\n"; flush(); ob_flush();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2244,7 +2242,7 @@ if (!$grade = get_record('quiz_grades', 'quiz', $quiz->id, 'userid', $userid)) {
|
|||
}
|
||||
|
||||
/**
|
||||
* TODO: document this
|
||||
* Save the overall grade for a user at a quiz in the quiz_grades table
|
||||
*
|
||||
* @return boolean Indicates success or failure.
|
||||
* @param object $quiz The quiz for which the best grade is to be calculated
|
||||
|
@ -2269,11 +2267,12 @@ function quiz_save_best_grade($quiz, $userid=null) {
|
|||
// Calculate the best grade
|
||||
$bestgrade = quiz_calculate_best_grade($quiz, $attempts);
|
||||
$bestgrade = (($bestgrade / $quiz->sumgrades) * $quiz->grade);
|
||||
$bestgrade = round($bestgrade, $quiz->decimalpoints);
|
||||
|
||||
// Save the best grade in the database
|
||||
if ($grade = get_record('quiz_grades', 'quiz', $quiz->id, 'userid',
|
||||
$userid)) {
|
||||
$grade->grade = round($bestgrade, $quiz->decimalpoints);
|
||||
$grade->grade = $bestgrade;
|
||||
$grade->timemodified = time();
|
||||
if (!update_record('quiz_grades', $grade)) {
|
||||
notify('Could not update best grade');
|
||||
|
@ -2282,7 +2281,7 @@ function quiz_save_best_grade($quiz, $userid=null) {
|
|||
} else {
|
||||
$grade->quiz = $quiz->id;
|
||||
$grade->userid = $userid;
|
||||
$grade->grade = round($bestgrade, $quiz->decimalpoints);
|
||||
$grade->grade = $bestgrade;
|
||||
$grade->timemodified = time();
|
||||
if (!insert_record('quiz_grades', $grade)) {
|
||||
notify('Could not insert new best grade');
|
||||
|
@ -2292,9 +2291,14 @@ function quiz_save_best_grade($quiz, $userid=null) {
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calculate the overall grade for a quiz given a number of attempts by a particular user.
|
||||
*
|
||||
* @return float The overall grade
|
||||
* @param object $quiz The quiz for which the best grade is to be calculated
|
||||
* @param array $attempts An array of all the attempts of the user at the quiz
|
||||
*/
|
||||
function quiz_calculate_best_grade($quiz, $attempts) {
|
||||
/// Calculate the best grade for a quiz given a number of attempts by a particular user.
|
||||
|
||||
switch ($quiz->grademethod) {
|
||||
|
||||
|
@ -2331,9 +2335,16 @@ function quiz_calculate_best_grade($quiz, $attempts) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the attempt with the best grade for a quiz
|
||||
*
|
||||
* Which attempt is the best depends on $quiz->grademethod. If the grade
|
||||
* method is GRADEAVERAGE then this function simply returns the last attempt.
|
||||
* @return object The attempt with the best grade
|
||||
* @param object $quiz The quiz for which the best grade is to be calculated
|
||||
* @param array $attempts An array of all the attempts of the user at the quiz
|
||||
*/
|
||||
function quiz_calculate_best_attempt($quiz, $attempts) {
|
||||
/// Return the attempt with the best grade for a quiz
|
||||
|
||||
switch ($quiz->grademethod) {
|
||||
|
||||
|
|
|
@ -256,7 +256,7 @@
|
|||
set_field('quiz_newest_states', 'questionid', $question->id, 'attemptid', $attempt->id, 'questionid', $oldquestionid);
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Now do anything question-type specific that is required to replace the question
|
||||
// For example questions that use the quiz_answers table to hold part of their question will
|
||||
// have to recode the answer ids in the states
|
||||
|
@ -272,11 +272,12 @@
|
|||
}
|
||||
|
||||
if (empty($question->errors) && $QUIZ_QTYPES[$qtype]->finished_edit_wizard($form)) {
|
||||
// DISABLED AUTOMATIC REGRADING
|
||||
// Automagically regrade all attempts (and states) in the affected quizzes
|
||||
if (!empty($replaceinquiz)) {
|
||||
$QUIZ_QTYPES[$question->qtype]->get_question_options($question);
|
||||
quiz_regrade_question_in_quizzes($question, $replaceinquiz);
|
||||
}
|
||||
//if (!empty($replaceinquiz)) {
|
||||
// $QUIZ_QTYPES[$question->qtype]->get_question_options($question);
|
||||
// quiz_regrade_question_in_quizzes($question, $replaceinquiz);
|
||||
//}
|
||||
redirect("edit.php");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -368,7 +368,8 @@ class quiz_calculated_qtype extends quiz_dataset_dependent_questiontype {
|
|||
}
|
||||
|
||||
// Get answers
|
||||
$answers = $question->options->answers;
|
||||
// the next line is hacked to get rid of the PHP notice until this gets fixed properly
|
||||
$answers = (isset($question->options->answers)) ? $question->options->answers : null;
|
||||
$stranswers = get_string('answer', 'quiz');
|
||||
$strmin = get_string('min', 'quiz');
|
||||
$strmax = get_string('max', 'quiz');
|
||||
|
@ -378,26 +379,28 @@ class quiz_calculated_qtype extends quiz_dataset_dependent_questiontype {
|
|||
$state->responses = array();
|
||||
$state->options = new stdClass;
|
||||
$virtualqtype = $this->get_virtual_qtype();
|
||||
foreach ($answers as $answer) {
|
||||
$calculated = quiz_qtype_calculated_calculate_answer(
|
||||
$answer->answer, $data, $answer->tolerance,
|
||||
$answer->tolerancetype, $answer->correctanswerlength,
|
||||
$answer->correctanswerformat, $unit);
|
||||
$state->responses[''] = $calculated->answer;
|
||||
$virtualqtype->get_tolerance_interval($question, $state);
|
||||
$calculated->min = $state->options->min;
|
||||
$calculated->max = $state->options->max;
|
||||
if ($calculated->min === '') {
|
||||
// This should mean that something is wrong
|
||||
$errors .= " -$calculated->answer";
|
||||
$stranswers .= $delimiter;
|
||||
} else {
|
||||
$stranswers .= $delimiter.$calculated->answer;
|
||||
if ($answers) {
|
||||
foreach ($answers as $answer) {
|
||||
$calculated = quiz_qtype_calculated_calculate_answer(
|
||||
$answer->answer, $data, $answer->tolerance,
|
||||
$answer->tolerancetype, $answer->correctanswerlength,
|
||||
$answer->correctanswerformat, $unit);
|
||||
$state->responses[''] = $calculated->answer;
|
||||
$virtualqtype->get_tolerance_interval($question, $state);
|
||||
$calculated->min = $state->options->min;
|
||||
$calculated->max = $state->options->max;
|
||||
if ($calculated->min === '') {
|
||||
// This should mean that something is wrong
|
||||
$errors .= " -$calculated->answer";
|
||||
$stranswers .= $delimiter;
|
||||
} else {
|
||||
$stranswers .= $delimiter.$calculated->answer;
|
||||
}
|
||||
$strmin .= $delimiter.$calculated->min;
|
||||
$strmax .= $delimiter.$calculated->max;
|
||||
|
||||
$delimiter = ', ';
|
||||
}
|
||||
$strmin .= $delimiter.$calculated->min;
|
||||
$strmax .= $delimiter.$calculated->max;
|
||||
|
||||
$delimiter = ', ';
|
||||
}
|
||||
return "$stranswers<br/>$strmin<br/>$strmax<br/>$errors";
|
||||
}
|
||||
|
|
|
@ -239,7 +239,7 @@ class quiz_multichoice_qtype extends quiz_default_questiontype {
|
|||
|
||||
$answers = &$question->options->answers;
|
||||
$correctanswers = $this->get_correct_responses($question, $state);
|
||||
$readonly = empty($options->readonly) ? '' : 'disabled="disabled"';
|
||||
$readonly = empty($options->readonly) ? '' : 'readonly="readonly"';
|
||||
|
||||
$formatoptions = new stdClass;
|
||||
$formatoptions->para = false;
|
||||
|
|
|
@ -246,7 +246,7 @@ class quiz_numerical_qtype extends quiz_shortanswer_qtype {
|
|||
|
||||
$answers = &$question->options->answers;
|
||||
$correctanswers = $this->get_correct_responses($question, $state);
|
||||
$readonly = empty($options->readonly) ? '' : 'disabled="disabled"';
|
||||
$readonly = empty($options->readonly) ? '' : 'readonly="readonly"';
|
||||
$nameprefix = $question->name_prefix;
|
||||
|
||||
/// Print question text and media
|
||||
|
|
|
@ -7,13 +7,7 @@
|
|||
/// QUESTION TYPE CLASS //////////////////
|
||||
class quiz_random_qtype extends quiz_default_questiontype {
|
||||
|
||||
var $possiblerandomqtypes = array(SHORTANSWER,
|
||||
NUMERICAL,
|
||||
MULTICHOICE,
|
||||
MATCH,
|
||||
// RANDOMSAMATCH,// Can cause unexpected outcomes
|
||||
TRUEFALSE,
|
||||
MULTIANSWER);
|
||||
var $excludedtypes = array(RANDOM, RANDOMSAMATCH);
|
||||
|
||||
// Carries questions available as randoms sorted by category
|
||||
// This array is used when needed only
|
||||
|
@ -52,8 +46,7 @@ class quiz_random_qtype extends quiz_default_questiontype {
|
|||
// Need to fetch random questions from category $question->category"
|
||||
// (Note: $this refers to the questiontype, not the question.)
|
||||
global $CFG;
|
||||
$possiblerandomqtypes = "'"
|
||||
. implode("','", $this->possiblerandomqtypes) . "'";
|
||||
$excludedtypes = implode(',', $this->excludedtypes);
|
||||
if ($question->questiontext == "1") {
|
||||
// recurse into subcategories
|
||||
$categorylist = quiz_categorylist($question->category);
|
||||
|
@ -65,7 +58,7 @@ class quiz_random_qtype extends quiz_default_questiontype {
|
|||
WHERE category IN ($categorylist)
|
||||
AND parent = '0'
|
||||
AND id NOT IN ($quiz->questionsinuse)
|
||||
AND qtype IN ($possiblerandomqtypes)");
|
||||
AND qtype NOT IN ($excludedtypes)");
|
||||
$this->catrandoms[$question->category] =
|
||||
draw_rand_array($this->catrandoms[$question->category],
|
||||
count($this->catrandoms[$question->category])); // from bug 1889
|
||||
|
@ -80,13 +73,6 @@ class quiz_random_qtype extends quiz_default_questiontype {
|
|||
global $QUIZ_QTYPES;
|
||||
$QUIZ_QTYPES[$wrappedquestion->qtype]
|
||||
->get_question_options($wrappedquestion);
|
||||
|
||||
// Backup the original state of the random question
|
||||
// And change the $state to match the wrapped question. This
|
||||
// is sensible, because so the wrapped question's state gets
|
||||
// put through all the generic processing.
|
||||
$state->options->state = clone($state);
|
||||
$state->question = $wrappedquestion->id;
|
||||
$QUIZ_QTYPES[$wrappedquestion->qtype]
|
||||
->create_session_and_responses($wrappedquestion,
|
||||
$state, $quiz, $attempt);
|
||||
|
@ -97,38 +83,53 @@ class quiz_random_qtype extends quiz_default_questiontype {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
notify(get_string('toomanyrandom', 'quiz', $question->category));
|
||||
return false;
|
||||
$question->questiontext = '<span class="notifyproblem">'.
|
||||
get_string('toomanyrandom', 'quiz', $question->category). '</span>';
|
||||
$question->qtype = DESCRIPTION;
|
||||
$state->responses = array('' => '');
|
||||
return true;
|
||||
}
|
||||
|
||||
function restore_session_and_responses(&$question, &$state) {
|
||||
/// The raw response records for random questions come in two flavours:
|
||||
/// ---- 1 ----
|
||||
/// For responses stored by Moodle version 1.5 and later the answer
|
||||
/// field has the pattern random#-* where the # part is the numeric
|
||||
/// question id of the actual question shown in the quiz attempt
|
||||
/// and * represents the student response to that actual question.
|
||||
/// ---- 2 ----
|
||||
/// For responses stored by older Moodle versions - the answer field is
|
||||
/// simply the question id of the actual question. The student response
|
||||
/// to the actual question is stored in a separate response record.
|
||||
/// -----------------------
|
||||
/// This means that prior to Moodle version 1.5, random questions needed
|
||||
/// two response records for storing the response to a single question.
|
||||
/// From version 1.5 and later the question type random works like all
|
||||
/// the other question types in that it now only needs one response
|
||||
/// record per question.
|
||||
global $QUIZ_QTYPES;
|
||||
if(!$randomstate = get_record('quiz_states', 'question',
|
||||
$question->id, 'attempt', $state->attempt)) {
|
||||
return false;
|
||||
if (!ereg('^random([0-9]+)-(.*)$', $state->responses[''], $answerregs)) {
|
||||
// this must be an old-style state which stores only the id for the wrapped question
|
||||
if (!$wrappedquestion = get_record('quiz_questions', 'id', $state->responses[''])) {
|
||||
error("Can not find wrapped question $state->responses['']");
|
||||
}
|
||||
// In the old model the actual response was stored in a separate entry in
|
||||
// the state table
|
||||
if (!$state->responses[''] = get_field('quiz_states', 'answer', 'attempt', $state->attempt, 'question', $wrappedquestion->id)) {
|
||||
error("Wrapped state missing");
|
||||
}
|
||||
} else {
|
||||
if (!$wrappedquestion = get_record('quiz_questions', 'id', $answerregs[1])) {
|
||||
return false;
|
||||
}
|
||||
$state->responses[''] = $answerregs[2];
|
||||
}
|
||||
|
||||
if (!$wrappedquestion = get_record('quiz_questions', 'id',
|
||||
$randomstate->answer)) {
|
||||
return false;
|
||||
}
|
||||
$state->question = $wrappedquestion->id;
|
||||
|
||||
if (!$QUIZ_QTYPES[$wrappedquestion->qtype]
|
||||
->get_question_options($wrappedquestion)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We need to set responses[''] to whatever was saved in the most recent
|
||||
// state of the wrapped question.
|
||||
if(!$wrappedstates = get_records_select('quiz_states',
|
||||
"question = $wrappedquestion->id AND attempt = $state->attempt",
|
||||
'seq_number DESC')) {
|
||||
return false;
|
||||
}
|
||||
$wrappedstates = array_values($wrappedstates);
|
||||
$state->responses = array('' => $wrappedstates[0]->answer);
|
||||
|
||||
if (!$QUIZ_QTYPES[$wrappedquestion->qtype]
|
||||
->restore_session_and_responses($wrappedquestion, $state)) {
|
||||
return false;
|
||||
|
@ -136,21 +137,12 @@ class quiz_random_qtype extends quiz_default_questiontype {
|
|||
$wrappedquestion->name_prefix = $question->name_prefix;
|
||||
$wrappedquestion->maxgrade = $question->maxgrade;
|
||||
$state->options->question = &$wrappedquestion;
|
||||
$state->options->state = &$randomstate;
|
||||
return true;
|
||||
}
|
||||
|
||||
function save_session_and_responses(&$question, &$state) {
|
||||
global $QUIZ_QTYPES;
|
||||
$wrappedquestion = &$state->options->question;
|
||||
$randomstate = &$state->options->state;
|
||||
|
||||
// We need to save the randomstate manually, because we can only process
|
||||
// one response record automatically
|
||||
if (empty($randomstate->id)) {
|
||||
$randomstate->answer = $wrappedquestion->id;
|
||||
$randomstate->id = insert_record('quiz_states', $randomstate);
|
||||
}
|
||||
|
||||
// Trick the wrapped question into pretending to be the random one.
|
||||
$realqid = $wrappedquestion->id;
|
||||
|
@ -158,6 +150,21 @@ class quiz_random_qtype extends quiz_default_questiontype {
|
|||
$QUIZ_QTYPES[$wrappedquestion->qtype]
|
||||
->save_session_and_responses($wrappedquestion, $state);
|
||||
|
||||
// Read what the wrapped question has just set the answer field to
|
||||
// (if anything)
|
||||
$response = get_field('quiz_states', 'answer', 'id', $state->id);
|
||||
if(false === $response) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Prefix the answer field...
|
||||
$response = "random$realqid-$response";
|
||||
|
||||
// ... and save it again.
|
||||
if (!set_field('quiz_states', 'answer', $response, 'id', $state->id)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Restore the real id
|
||||
$wrappedquestion->id = $realqid;
|
||||
return true;
|
||||
|
@ -193,34 +200,7 @@ class quiz_random_qtype extends quiz_default_questiontype {
|
|||
$QUIZ_QTYPES[$wrappedquestion->qtype]
|
||||
->print_question($wrappedquestion, $state, $number, $quiz, $options);
|
||||
}
|
||||
/*
|
||||
function print_question_grading_details(&$question, &$state, $quiz,
|
||||
$options) {
|
||||
global $QUIZ_QTYPES;
|
||||
$wrappedquestion = &$state->options->question;
|
||||
$QUIZ_QTYPES[$wrappedquestion->qtype]
|
||||
->print_question_grading_details($wrappedquestion, $state, $quiz,
|
||||
$options);
|
||||
}
|
||||
|
||||
function print_question_formulation_and_controls(&$question, &$state, $quiz,
|
||||
$options) {
|
||||
global $QUIZ_QTYPES;
|
||||
$wrappedquestion = &$state->options->question;
|
||||
$QUIZ_QTYPES[$wrappedquestion->qtype]
|
||||
->print_question_formulation_and_controls($wrappedquestion, $state,
|
||||
$quiz, $options);
|
||||
}
|
||||
|
||||
function print_question_submit_buttons(&$question, &$state, $quiz,
|
||||
$options) {
|
||||
global $QUIZ_QTYPES;
|
||||
$wrappedquestion = &$state->options->question;
|
||||
$QUIZ_QTYPES[$wrappedquestion->qtype]
|
||||
->print_question_submit_buttons($wrappedquestion, $state, $quiz,
|
||||
$options);
|
||||
}
|
||||
*/
|
||||
function grade_responses(&$question, &$state, $quiz) {
|
||||
global $QUIZ_QTYPES;
|
||||
$wrappedquestion = &$state->options->question;
|
||||
|
@ -255,173 +235,7 @@ class quiz_random_qtype extends quiz_default_questiontype {
|
|||
return $QUIZ_QTYPES[$wrappedquestion->qtype]
|
||||
->print_question_form_end($wrappedquestion, $state, $quizid);
|
||||
}
|
||||
/*
|
||||
function convert_to_response_answer_field($questionresponse) {
|
||||
global $QUIZ_QTYPES;
|
||||
|
||||
foreach ($questionresponse as $key => $response) {
|
||||
if (ereg('[^0-9][0-9]+random$', $key)) {
|
||||
unset($questionresponse[$key]);
|
||||
$randomquestion = get_record('quiz_questions',
|
||||
'id', $response);
|
||||
return "random$response-"
|
||||
.$QUIZ_QTYPES[$randomquestion->qtype]
|
||||
->convert_to_response_answer_field($questionresponse);
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
|
||||
function create_response($question, $nameprefix, $questionsinuse) {
|
||||
// It's for question types like RANDOMSAMATCH and RANDOM that
|
||||
// the true power of the pattern with this function comes to the surface.
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
*/
|
||||
/*
|
||||
function print_question_formulation_and_controls($question,
|
||||
$quiz, $readonly, $answers, $correctanswers, $nameprefix) {
|
||||
global $QUIZ_QTYPES;
|
||||
|
||||
// Get the wrapped question...
|
||||
if ($actualquestion = $this->get_wrapped_question($question,
|
||||
$nameprefix)) {
|
||||
echo '<input type="hidden" name="' . $nameprefix
|
||||
. '" value="' . $actualquestion->id . '" />';
|
||||
return $QUIZ_QTYPES[$actualquestion->qtype]
|
||||
->print_question_formulation_and_controls($actualquestion,
|
||||
$quiz, $readonly, $answers, $correctanswers,
|
||||
quiz_qtype_nameprefix($actualquestion, $nameprefix));
|
||||
} else {
|
||||
echo '<p>' . get_string('random', 'quiz') . '</p>';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function get_wrapped_question($question, $nameprefix) {
|
||||
if (!empty($question->response[$nameprefix])
|
||||
and $actualquestion = get_record('quiz_questions',
|
||||
'id', $question->response[$nameprefix])) {
|
||||
$actualquestion->response = $question->response;
|
||||
unset($actualquestion->response[$nameprefix]);
|
||||
$actualquestion->maxgrade = $question->maxgrade;
|
||||
return $actualquestion;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function grade_response($question, $nameprefix) {
|
||||
global $QUIZ_QTYPES;
|
||||
|
||||
// Get the wrapped question...
|
||||
if ($actualquestion = $this->get_wrapped_question($question,
|
||||
$nameprefix)) {
|
||||
return $QUIZ_QTYPES[$actualquestion->qtype]->grade_response(
|
||||
$actualquestion,
|
||||
quiz_qtype_nameprefix($actualquestion, $nameprefix));
|
||||
} else {
|
||||
$result->grade = 0.0;
|
||||
$result->answers = array();
|
||||
$result->correctanswers = array();
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
function extract_response($rawresponse, $nameprefix) {
|
||||
global $QUIZ_QTYPES;
|
||||
|
||||
/// The raw response records for random questions come in two flavours:
|
||||
/// ---- 1 ----
|
||||
/// For responses stored by Moodle version 1.5 and later the answer
|
||||
/// field has the pattern random#-* where the # part is the numeric
|
||||
/// question id of the actual question shown in the quiz attempt
|
||||
/// and * represents the student response to that actual question.
|
||||
/// ---- 2 ----
|
||||
/// For responses stored by older Moodle versions - the answer field is
|
||||
/// simply the question id of the actual question. The student response
|
||||
/// to the actual question is stored in a separate response record.
|
||||
/// -----------------------
|
||||
/// This means that prior to Moodle version 1.5, random questions needed
|
||||
/// two response records for storing the response to a single question.
|
||||
/// From version 1.5 and later the question type random works like all
|
||||
/// the other question types in that it now only needs one response
|
||||
/// record per question.
|
||||
/// Because updating the old response records to fit the new response
|
||||
/// record format could need hours of CPU time and the equivalent
|
||||
/// amount of down time for the Moodle site and because a response
|
||||
/// storage with two response formats for random question only effect
|
||||
/// this function, where the response record is translated, this
|
||||
/// function is now able to handle both types of response record.
|
||||
|
||||
|
||||
// Pick random question id from the answer field in a way that
|
||||
/// works for both formats:
|
||||
if (!ereg('^(random)?([0-9]+)(-(.*))?$', $rawresponse->answer, $answerregs)) {
|
||||
error("The answer value '$rawresponse->answer' for the response with "
|
||||
."id=$rawresponse->id to the random question "
|
||||
."$rawresponse->question is malformated."
|
||||
." - No response can be extracted!");
|
||||
}
|
||||
$randomquestionid = $answerregs[2];
|
||||
|
||||
if ($randomquestion = get_record('quiz_questions',
|
||||
'id', $randomquestionid)) {
|
||||
|
||||
if ($answerregs[1] && $answerregs[3]) {
|
||||
// The raw response is formatted according to
|
||||
// Moodle version 1.5 or later
|
||||
$randomresponse = $rawresponse;
|
||||
$randomresponse->question = $randomquestionid;
|
||||
$randomresponse->answer = $answerregs[4];
|
||||
|
||||
} else if ($randomresponse = get_record
|
||||
('quiz_responses', 'question', $rawresponse->answer,
|
||||
'attempt', $rawresponse->attempt)) {
|
||||
// The response was stored by an older version of Moodle
|
||||
// :-)
|
||||
|
||||
} else {
|
||||
notify("Error: Cannot find response to random question $randomquestionid");
|
||||
unset($randomresponse);
|
||||
}
|
||||
|
||||
if (isset($randomresponse)) {
|
||||
/// The prefered case:
|
||||
/// There is a random question and a response field, from
|
||||
/// which the response array can be extracted:
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
/// Instead: workaround by creating a new response:
|
||||
$response = $QUIZ_QTYPES[$randomquestion->qtype]
|
||||
->create_response($randomquestion,
|
||||
quiz_qtype_nameprefix($randomquestion, $nameprefix),
|
||||
"$rawresponse->question,$randomquestionid");
|
||||
// (That last argument is instead of $questionsinuse.
|
||||
// It is not correct but it would be very messy to
|
||||
// determine the correct value, while very few
|
||||
// question types actually use it and they who do have
|
||||
// good chances to execute properly anyway.)
|
||||
}
|
||||
$response[$nameprefix] = $randomquestionid;
|
||||
//return $response;
|
||||
return '';
|
||||
} else {
|
||||
notify("Error: Unable to find random question $rawresponse->question");
|
||||
/// No new random question is picked as this is probably
|
||||
/// not what the moodle user has in mind anyway
|
||||
return array();
|
||||
}
|
||||
}
|
||||
}
|
||||
//// END OF CLASS ////
|
||||
|
||||
|
|
|
@ -205,8 +205,17 @@ class quiz_rqp_qtype extends quiz_default_questiontype {
|
|||
$options->persistent_data = $state->options->persistent_data;
|
||||
$options->template_vars =
|
||||
quiz_rqp_implode($state->options->template_vars);
|
||||
if (!insert_record('quiz_rqp_states', $options)) {
|
||||
return false;
|
||||
if ($state->update) {
|
||||
if (!$options->id = get_field('quiz_rqp_states', 'id', 'stateid', $state->id)) {
|
||||
return false;
|
||||
}
|
||||
if (!update_record('quiz_rqp_states', $options)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!insert_record('quiz_rqp_states', $options)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -104,7 +104,7 @@ class quiz_shortanswer_qtype extends quiz_default_questiontype {
|
|||
|
||||
$answers = &$question->options->answers;
|
||||
$correctanswers = $this->get_correct_responses($question, $state);
|
||||
$readonly = empty($options->readonly) ? '' : 'disabled="disabled"';
|
||||
$readonly = empty($options->readonly) ? '' : 'readonly="readonly"';
|
||||
$nameprefix = $question->name_prefix;
|
||||
|
||||
/// Print question text and media
|
||||
|
|
|
@ -120,7 +120,7 @@ class quiz_truefalse_qtype extends quiz_default_questiontype {
|
|||
|
||||
$answers = &$question->options->answers;
|
||||
$correctanswers = $this->get_correct_responses($question, $state);
|
||||
$readonly = $options->readonly ? ' disabled="disabled"' : '';
|
||||
$readonly = $options->readonly ? ' readonly="readonly"' : '';
|
||||
|
||||
// Print question formulation
|
||||
echo format_text($question->questiontext,
|
||||
|
|
|
@ -12,10 +12,64 @@ class quiz_report extends quiz_default_report {
|
|||
/// Print header
|
||||
$this->print_header_and_tabs($cm, $course, $quiz, $reportmode="regrade");
|
||||
|
||||
notify('Not yet implemented');
|
||||
/// Fetch all attempts
|
||||
if (!$attempts = get_records_select('quiz_attempts', "quiz = '$quiz->id' AND preview = 0")) {
|
||||
print_heading(get_string('noattempts', 'quiz'));
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Fetch all questions
|
||||
$sql = "SELECT q.*, i.grade AS maxgrade FROM {$CFG->prefix}quiz_questions q,
|
||||
{$CFG->prefix}quiz_question_instances i
|
||||
WHERE i.quiz = $quiz->id
|
||||
AND i.question = q.id";
|
||||
|
||||
if (! $questions = get_records_sql($sql)) {
|
||||
error("Failed to get questions for regrading!");
|
||||
}
|
||||
quiz_get_question_options($questions);
|
||||
|
||||
/// Print heading
|
||||
print_heading(get_string('regradingquiz', 'quiz', $quiz));
|
||||
echo '<center>';
|
||||
print_string('regradedisplayexplanation', 'quiz');
|
||||
echo '<center>';
|
||||
|
||||
/// Loop through all questions and all attempts and regrade while printing progress info
|
||||
foreach ($questions as $question) {
|
||||
echo '<b>'.get_string('regradingquestion', 'quiz', $question->name).'</b> '.get_string('attempts', 'quiz').": \n";
|
||||
foreach ($attempts as $attempt) {
|
||||
quiz_regrade_question_in_attempt($question, $attempt, $quiz, true);
|
||||
}
|
||||
echo '<br/ >';
|
||||
// the following makes sure that the output is sent immediately.
|
||||
flush();ob_flush();
|
||||
}
|
||||
|
||||
/// Loop through all questions and recalculate $attempt->sumgrade
|
||||
$attemptschanged = 0;
|
||||
foreach ($attempts as $attempt) {
|
||||
$sumgrades = 0;
|
||||
$questionids = explode(',', quiz_questions_in_quiz($attempt->layout));
|
||||
foreach($questionids as $questionid) {
|
||||
$lastgradedid = get_field('quiz_newest_states', 'newgraded', 'attemptid', $attempt->id, 'questionid', $questionid);
|
||||
$sumgrades += get_field('quiz_states', 'grade', 'id', $lastgradedid);
|
||||
}
|
||||
if ($attempt->sumgrades != $sumgrades) {
|
||||
$attemptschanged++;
|
||||
set_field('quiz_attempts', 'sumgrades', $sumgrades, 'id', $attempt->id);
|
||||
}
|
||||
}
|
||||
|
||||
/// Update the overall quiz grades
|
||||
if ($grades = get_records('quiz_grades', 'quiz', $quiz->id)) {
|
||||
foreach($grades as $grade) {
|
||||
quiz_save_best_grade($quiz, $grade->userid);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
?>
|
|
@ -1420,6 +1420,9 @@
|
|||
//This function restores the quiz_attempts
|
||||
function quiz_attempts_restore_mods($quiz_id,$info,$restore) {
|
||||
|
||||
notify("Restoring quiz without user attempts. Restoring of user attempts will be implemented in Moodle 1.5.1");
|
||||
return true;
|
||||
|
||||
global $CFG;
|
||||
|
||||
$status = true;
|
||||
|
@ -1761,7 +1764,7 @@
|
|||
return $status;
|
||||
}
|
||||
|
||||
//This function restores the quiz_states
|
||||
//This function restores the quiz_rqp_states
|
||||
function quiz_rqp_states_restore_mods($state_id,$info,$restore) {
|
||||
|
||||
global $CFG;
|
||||
|
|
|
@ -18,8 +18,7 @@
|
|||
$stateid = optional_param('state', 0, PARAM_INT); // state id
|
||||
$attemptid = optional_param('attempt', 0, PARAM_INT); // attempt id
|
||||
$questionid = optional_param('question', 0, PARAM_INT); // attempt id
|
||||
|
||||
$number = required_param('number', PARAM_INT); // question number
|
||||
$number = optional_param('number', 0, PARAM_INT); // question number
|
||||
|
||||
if ($stateid) {
|
||||
if (! $state = get_record('quiz_states', 'id', $stateid)) {
|
||||
|
|
|
@ -113,13 +113,14 @@
|
|||
// This is all the teacher will get
|
||||
if ($isteacher) {
|
||||
|
||||
$attemptcount = count_records('quiz_attempts', 'quiz', $quiz->id, 'preview', 0);
|
||||
if ($attemptcount = count_records('quiz_attempts', 'quiz', $quiz->id, 'preview', 0)) {
|
||||
|
||||
$strviewallanswers = get_string("viewallanswers", "quiz", $attemptcount);
|
||||
$usercount = count_records_select('quiz_attempts', "quiz = '$quiz->id' AND preview = '0'", 'COUNT(DISTINCT userid)');
|
||||
$strusers = $course->students;
|
||||
|
||||
notify("<a href=\"report.php?mode=overview&id=$cm->id\">$strviewallanswers ($usercount $strusers)</a>");
|
||||
$strviewallanswers = get_string("viewallanswers", "quiz", $attemptcount);
|
||||
$usercount = count_records_select('quiz_attempts', "quiz = '$quiz->id' AND preview = '0'", 'COUNT(DISTINCT userid)');
|
||||
$strusers = $course->students;
|
||||
|
||||
notify("<a href=\"report.php?mode=overview&id=$cm->id\">$strviewallanswers ($usercount $strusers)</a>");
|
||||
}
|
||||
print_footer($course);
|
||||
exit;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue