From: jamiesensei Date: Sat, 3 May 2008 13:06:49 +0000 (+0000) Subject: MDL-14677 "should rescale the grades displayed for each question in the detailed... X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=2badf2e6ecbe4a26a8fccba81deeeedb53453389;p=moodle.git MDL-14677 "should rescale the grades displayed for each question in the detailed marks view of the overview report so that all grades add up to the sum total grade" used quiz_rescale_grades function to rescale the grade properly before displaying it. Also this patch includes some general clean up and refactoring of overview report. --- diff --git a/mod/quiz/report/overview/report.php b/mod/quiz/report/overview/report.php index 33e0993fdf..f6f7ba6051 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 f08f332bb4..bba51ae37c 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