mirror of
https://github.com/moodle/moodle.git
synced 2025-01-18 22:08:20 +01:00
MDL-15092 "Quiz overview report won't display if there are more than 29 questions" fixed this by going back to the old way of fetching data for display in the table. However still use table JOINs when user wants to sort by question grade. The user can sort by a maximum of two columns at once so the JOINs will not exceed the limit.
This commit is contained in:
parent
c35f3afcf1
commit
181608b708
@ -166,20 +166,31 @@ class quiz_report_overview_table extends table_sql {
|
||||
}
|
||||
}
|
||||
function other_cols($colname, $attempt){
|
||||
static $gradedstatesbyattempt = null;
|
||||
if ($gradedstatesbyattempt === null){
|
||||
//get all the attempt ids we want to display on this page
|
||||
//or to export for download.
|
||||
$attemptids = array();
|
||||
foreach ($this->rawdata as $attempt){
|
||||
if ($attempt->attemptuniqueid > 0){
|
||||
$attemptids[] = $attempt->attemptuniqueid;
|
||||
}
|
||||
}
|
||||
$gradedstatesbyattempt = quiz_get_newgraded_states($attemptids, true, 'qs.id, qs.grade, qs.event, qs.question, qs.attempt');
|
||||
}
|
||||
if (preg_match('/^qsgrade([0-9]+)$/', $colname, $matches)){
|
||||
$questionid = $matches[1];
|
||||
$question = $this->questions[$questionid];
|
||||
$state = new object();
|
||||
$state->event = $attempt->{'qsevent'.$questionid};
|
||||
if (question_state_is_graded($state)) {
|
||||
$grade = quiz_rescale_grade($attempt->{'qsgrade'.$questionid}, $this->quiz);
|
||||
$stateforqinattempt = $gradedstatesbyattempt[$attempt->attemptuniqueid][$questionid];
|
||||
if (question_state_is_graded($stateforqinattempt)) {
|
||||
$grade = quiz_rescale_grade($stateforqinattempt->grade, $this->quiz);
|
||||
} else {
|
||||
$grade = '--';
|
||||
}
|
||||
if (!$this->is_downloading()) {
|
||||
$grade = $grade.'/'.quiz_rescale_grade($question->grade, $this->quiz);
|
||||
return link_to_popup_window('/mod/quiz/reviewquestion.php?state='.
|
||||
$attempt->{'qsid'.$questionid}.'&number='.$question->number,
|
||||
$stateforqinattempt->id.'&number='.$question->number,
|
||||
'reviewquestion', $grade, 450, 650, get_string('reviewresponse', 'quiz'),
|
||||
'none', true);
|
||||
} else {
|
||||
|
@ -177,15 +177,29 @@ class quiz_report extends quiz_default_report {
|
||||
}
|
||||
$table->set_count_sql("SELECT COUNT(1) FROM $from WHERE $where");
|
||||
|
||||
if ($detailedmarks) {
|
||||
// we want to display marks for all questions
|
||||
// Add extra sql to get question grades
|
||||
$from .= ' ';
|
||||
// we want to display marks for all questions
|
||||
foreach (array_keys($questions) as $qid) {
|
||||
$fields .= ", qs$qid.grade AS qsgrade$qid, qs$qid.event AS qsevent$qid, qs$qid.id AS qsid$qid";
|
||||
$from .= "LEFT JOIN {$CFG->prefix}question_sessions qns$qid ON qns$qid.attemptid = qa.uniqueid AND qns$qid.questionid = $qid ";
|
||||
$from .= "LEFT JOIN {$CFG->prefix}question_states qs$qid ON qs$qid.id = qns$qid.newgraded ";
|
||||
// Add table joins so we can sort by question grade
|
||||
// unfortunately can't join all tables necessary to fetch all grades
|
||||
// to get the state for one question per attempt row we must join two tables
|
||||
// and there is a limit to how many joins you can have in one query. In MySQL it
|
||||
// is 61. This means that when having more than 29 questions the query will fail.
|
||||
// So we join just the tables needed to sort the attempts.
|
||||
if($sort = $table->get_sql_sort()) {
|
||||
if (!$table->is_downloading() && $detailedmarks) {
|
||||
$from .= ' ';
|
||||
$sortparts = explode(',', $sort);
|
||||
$matches = array();
|
||||
foreach($sortparts as $sortpart) {
|
||||
$sortpart = trim($sortpart);
|
||||
if (preg_match('/^qsgrade([0-9]+)/', $sortpart, $matches)){
|
||||
$qid = intval($matches[1]);
|
||||
$fields .= ", qs$qid.grade AS qsgrade$qid, qs$qid.event AS qsevent$qid, qs$qid.id AS qsid$qid";
|
||||
$from .= "LEFT JOIN {$CFG->prefix}question_sessions qns$qid ON qns$qid.attemptid = qa.uniqueid AND qns$qid.questionid = $qid ";
|
||||
$from .= "LEFT JOIN {$CFG->prefix}question_states qs$qid ON qs$qid.id = qns$qid.newgraded ";
|
||||
} else {
|
||||
$newsort[] = $sortpart;
|
||||
}
|
||||
}
|
||||
$select .= ' ';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -11,11 +11,11 @@ define('QUIZ_REPORT_ATTEMPTS_ALL_STUDENTS', 3);
|
||||
* 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){
|
||||
function quiz_get_newgraded_states($attemptids, $idxattemptq = true, $fields='qs.*'){
|
||||
global $CFG;
|
||||
if ($attemptids){
|
||||
$attemptidlist = join($attemptids, ',');
|
||||
$gradedstatesql = "SELECT qs.* FROM " .
|
||||
$gradedstatesql = "SELECT $fields FROM " .
|
||||
"{$CFG->prefix}question_sessions qns, " .
|
||||
"{$CFG->prefix}question_states qs " .
|
||||
"WHERE qns.attemptid IN ($attemptidlist) AND " .
|
||||
|
Loading…
x
Reference in New Issue
Block a user