diff --git a/mod/quiz/report/overview/report.php b/mod/quiz/report/overview/report.php index 33e0993fdff..f6f7ba60513 100644 --- a/mod/quiz/report/overview/report.php +++ b/mod/quiz/report/overview/report.php @@ -118,33 +118,13 @@ class quiz_report extends quiz_default_report { 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'); @@ -213,8 +193,8 @@ class quiz_report extends quiz_default_report { $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) { @@ -266,8 +246,8 @@ class quiz_report extends quiz_default_report { $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) { @@ -295,8 +275,8 @@ class quiz_report extends quiz_default_report { $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) { @@ -309,7 +289,6 @@ class quiz_report extends quiz_default_report { // 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 { @@ -383,7 +362,6 @@ class quiz_report extends quiz_default_report { $newsort[] = $sortpart; } } - // Reconstruct the sort string $sort = ' ORDER BY '.implode(', ', $newsort); } @@ -423,21 +401,13 @@ class quiz_report extends quiz_default_report { 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); @@ -499,29 +469,23 @@ class quiz_report extends quiz_default_report { } 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; diff --git a/mod/quiz/report/reportlib.php b/mod/quiz/report/reportlib.php index f08f332bb44..bba51ae37c0 100644 --- a/mod/quiz/report/reportlib.php +++ b/mod/quiz/report/reportlib.php @@ -1,3 +1,67 @@ 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