if ($detailedmarks) {
// we want to display marks for all questions
- // Start by getting all questions
- $questionlist = quiz_questions_in_quiz($quiz->questions);
- $questionids = explode(',', $questionlist);
- $sql = "SELECT q.*, i.grade AS maxgrade, i.id AS instance".
- " FROM {$CFG->prefix}question q,".
- " {$CFG->prefix}quiz_question_instances i".
- " WHERE i.quiz = '$quiz->id' AND q.id = i.question".
- " AND q.id IN ($questionlist)";
- if (!$questions = get_records_sql($sql)) {
- print_error('No questions found');
- }
- $number = 1;
- foreach ($questionids as $key => $id) {
- if ($questions[$id]->length) {
- // Only print questions of non-zero length
- $tablecolumns[] = '$'.$id;
- $tableheaders[] = '#'.$number;
- $questions[$id]->number = $number;
- $number += $questions[$id]->length;
- } else {
- // get rid of zero length questions
- unset($questions[$id]);
- unset($questionids[$key]);
- }
+ $questions = quiz_report_load_questions($quiz);
+ foreach ($questions as $id => $question) {
+ // Ignore questions of zero length
+ $tablecolumns[] = '$'.$id;
+ $tableheaders[] = '#'.$question->number;
}
}
-
if ($hasfeedback) {
$tablecolumns[] = 'feedbacktext';
$tableheaders[] = get_string('feedback', 'quiz');
$headers[] = get_string('grade', 'quiz').'/'.$quiz->grade;
}
if($detailedmarks) {
- foreach ($questionids as $id) {
- $headers[] = '#'.$questions[$id]->number;
+ foreach ($questions as $question) {
+ $headers[] = '#'.$question->number;
}
}
if ($hasfeedback) {
$headers[] = get_string('grade', 'quiz').'/'.$quiz->grade;
}
if($detailedmarks) {
- foreach ($questionids as $id) {
- $headers[] = '#'.$questions[$id]->number;
+ foreach ($questions as $question) {
+ $headers[] = '#'.$question->number;
}
}
if ($hasfeedback) {
$headers .= "\t".get_string('grade', 'quiz')."/".$quiz->grade;
}
if($detailedmarks) {
- foreach ($questionids as $id) {
- $headers .= "\t#".$questions[$id]->number;
+ foreach ($questions as $question) {
+ $headers .= "\t#".$question->number;
}
}
if ($hasfeedback) {
// don't need to do this expensive call if we are listing all attempts though.
if ( $noattempts != 3 ) {
if (empty($currentgroup)) {
-
// all users who can attempt quizzes
$allowed = join(',',array_keys(get_users_by_capability($context, 'mod/quiz:attempt','','','','','','',false)));
} else {
$newsort[] = $sortpart;
}
}
-
// Reconstruct the sort string
$sort = ' ORDER BY '.implode(', ', $newsort);
}
if(!empty($attempts) || !empty($noattempts)) {
if ($attempts) {
if($detailedmarks) {
+ //get all the attempt ids we want to display on this page
+ //or to export for download.
$attemptids = array();
foreach ($attempts as $attempt){
$attemptids[] = $attempt->attemptuniqueid;
}
- $attemptidlist = join($attemptids, ',');
- $questionidlist = join($questionids, ',');
- $detailledgradedsql = "SELECT qs.id as qsid, qqi.question, qs.grade, qs.event, qs.attempt, qqi.grade as qqigrade, qns.newgraded FROM " .
- "{$CFG->prefix}quiz_question_instances qqi, " .
- "{$CFG->prefix}question_sessions qns " .
- "LEFT JOIN {$CFG->prefix}question_states qs " .
- "ON qs.attempt IN ($attemptidlist) AND " .
- "qns.newgraded = qs.id " .
- "WHERE qqi.question = qs.question AND " .
- "qqi.quiz = $quiz->id";
- $detailledgrades = get_records_sql($detailledgradedsql);
+ $gradedstatesbyattempt = quiz_get_newgraded_states($attemptids);
}
foreach ($attempts as $attempt) {
$picture = print_user_picture($attempt->userid, $course->id, $attempt->picture, false, true);
}
if($detailedmarks) {
- //get the detailled grade data for this attempt
- $attemptdetailledgrades = array();
- foreach ($detailledgrades as $detailledgrade){
- if ($detailledgrade->attempt == $attempt->attemptuniqueid){
- $attemptdetailledgrades[$detailledgrade->question] = $detailledgrade;
- }
- }
-
if(empty($attempt->attempt)) {
- foreach($questionids as $questionid) {
+ foreach($questions as $question) {
$row[] = '-';
}
} else {
- foreach($questionids as $questionid) {
- if (question_state_is_graded($attemptdetailledgrades[$questionid])) {
- $grade = number_format($attemptdetailledgrades[$questionid]->grade, $quiz->decimalpoints);
- $grade = $grade.'/'.number_format($attemptdetailledgrades[$questionid]->qqigrade, $quiz->decimalpoints);
+ foreach($questions as $questionid => $question) {
+ $stateforqinattempt = $gradedstatesbyattempt[$attempt->attemptuniqueid][$questionid];
+ if (question_state_is_graded($stateforqinattempt)) {
+ $grade = quiz_rescale_grade($stateforqinattempt->grade, $quiz);
+ $grade = $grade;
} else {
- $grade = '--'.'/'.number_format($attemptdetailledgrades[$questionid]->qqigrade, $quiz->decimalpoints);
+ $grade = '--';
}
if (!$download) {
+ $grade = $grade.'/'.quiz_rescale_grade($question->grade, $quiz);
$row[] = link_to_popup_window('/mod/quiz/reviewquestion.php?state='.
- $attemptdetailledgrades[$questionid]->qsid.'&number='.$questions[$questionid]->number,
+ $stateforqinattempt->id.'&number='.$question->number,
'reviewquestion', $grade, 450, 650, $strreviewquestion, 'none', true);
} else {
$row[] = $grade;
<?php
define('QUIZ_REPORT_DEFAULT_PAGE_SIZE', 30);
+/**
+ * Get newest graded state or newest state for a number of attempts. Pass in the
+ * uniqueid field from quiz_attempt table not the id. Use question_state_is_graded
+ * function to check that the question is actually graded.
+ */
+function quiz_get_newgraded_states($attemptids, $idxattemptq = true){
+ global $CFG;
+ $attemptidlist = join($attemptids, ',');
+ $gradedstatesql = "SELECT qs.* FROM " .
+ "{$CFG->prefix}question_sessions qns, " .
+ "{$CFG->prefix}question_states qs " .
+ "WHERE qns.attemptid IN ($attemptidlist) AND " .
+ "qns.newgraded = qs.id";
+ $gradedstates = get_records_sql($gradedstatesql);
+ if ($idxattemptq){
+ $gradedstatesbyattempt = array();
+ foreach ($gradedstates as $gradedstate){
+ if (!isset($gradedstatesbyattempt[$gradedstate->attempt])){
+ $gradedstatesbyattempt[$gradedstate->attempt] = array();
+ }
+ $gradedstatesbyattempt[$gradedstate->attempt][$gradedstate->question] = $gradedstate;
+ }
+ return $gradedstatesbyattempt;
+ } else {
+ return $gradedstates;
+ }
+}
+/**
+ * Load the question data necessary in the reports.
+ * - Remove description questions.
+ * - Order questions in order that they are in the quiz
+ * - Add question numbers.
+ * - Add grade from quiz_questions_instance
+ */
+function quiz_report_load_questions($quiz){
+ global $CFG;
+ $questionlist = quiz_questions_in_quiz($quiz->questions);
+ //In fact in most cases the id IN $questionlist below is redundant
+ //since we are also doing a JOIN on the qqi table. But will leave it in
+ //since this double check will probably do no harm.
+ if (!$questions = get_records_sql("SELECT q.*, qqi.grade " .
+ "FROM {$CFG->prefix}question q, " .
+ "{$CFG->prefix}quiz_question_instances qqi " .
+ "WHERE q.id IN ($questionlist) AND " .
+ "qqi.question = q.id AND " .
+ "qqi.quiz =".$quiz->id)) {
+ print_error('No questions found');
+ }
+ //Now we have an array of questions from a quiz we work out there question nos and remove
+ //questions with zero length ie. description questions etc.
+ //also put questions in order.
+ $number = 1;
+ $realquestions = array();
+ $questionids = explode(',', $questionlist);
+ foreach ($questionids as $id) {
+ if ($questions[$id]->length) {
+ // Ignore questions of zero length
+ $realquestions[$id] = $questions[$id];
+ $realquestions[$id]->number = $number;
+ $number += $questions[$id]->length;
+ }
+ }
+ return $realquestions;
+}
?>
\ No newline at end of file