Merged from MOODLE_15_STABLE: Fixing bug 4303 - quiz reports dying on large enrolments - getting all users into an array and imploding it into an IN() replaced with joins. This changes the functionality SLIGHTLY in two ways - 1. show students with no attempts now JUST shows students with no attempts, rather than both. Show students with no attempts is now disabled for the site course as is not really relevant and could be ridiculously large

This commit is contained in:
mjollnir_ 2005-11-15 22:23:43 +00:00
parent 9edf8e04e5
commit 39a2761465
3 changed files with 88 additions and 94 deletions

View File

@ -384,6 +384,7 @@ $string['showdetailedmarks'] = 'Show mark details';
$string['showfeedback'] = 'After answering, show feedback?';
$string['showhidden'] = 'Also show old questions';
$string['shownoattempts'] = 'Show students with no attempts';
$string['shownoattemptsonly'] = 'Show only students with no attempts';
$string['showteacherattempts'] = 'Show teacher attempts';
$string['shuffleanswers'] = 'Shuffle answers';
$string['shufflequestions'] = 'Shuffle questions';

View File

@ -40,19 +40,6 @@ class quiz_report extends quiz_default_report {
$currentgroup = false;
}
/// Get all users: students
if ($currentgroup) {
$users = get_group_students($currentgroup);
}
else {
$users = get_course_students($course->id);
}
if(empty($users)) {
print_heading($strnoattempts);
return true;
}
// set Table and Analysis stats options
if(!isset($SESSION->quiz_analysis_table)) {
$SESSION->quiz_analysis_table = array('attemptselection' => 0, 'lowmarklimit' => 0, 'pagesize' => 10);
@ -96,9 +83,12 @@ class quiz_report extends quiz_default_report {
}
$sql = 'SELECT qa.* FROM '.$CFG->prefix.'user u '.
'LEFT JOIN '.$CFG->prefix.'quiz_attempts qa ON u.id = qa.userid '.
'WHERE u.id IN ('.implode(',', array_keys($users)).') AND ( qa.quiz = '.$quiz->id.') '. // ULPGC ecastro
' AND ( qa.sumgrades >= '.$scorelimit.' ) ';
'JOIN '.$CFG->prefix.'quiz_attempts qa ON u.id = qa.userid ';
if (!empty($currentgroup)) {
$sql .= ' JOIN '.$CFG->prefix.'groups_members gm ON u.id = gm.userid AND gm.groupid = '.$currentgroup;
}
$sql .= ' WHERE qa.quiz = '.$quiz->id. // ULPGC ecastro
' AND ( qa.sumgrades >= '.$scorelimit.' ) ';
// ^^^^^^ es posible seleccionar aquí TODOS los quizzes, como quiere Jussi,
// pero habría que llevar la cuenta ed cada quiz para restaura las preguntas (quizquestions, states)
/// Fetch the attempts

View File

@ -78,35 +78,6 @@ class quiz_report extends quiz_default_report {
$currentgroup = false;
}
/// Get all students
if ($currentgroup) {
$users = get_group_students($currentgroup);
}
else {
$users = get_course_students($course->id);
}
if($users === false) {
$users = array();
}
else {
$users = array_keys($users);
}
// Uncomment the following if desired: if there are people with attempts but they have been unenrolled
// since making those attempts, count them in as well. DO NOT count course teachers.
// Problem with this code: includes users from ALL groups, see bug 3995
//$userswithattempts = get_records_sql('SELECT DISTINCT qa.userid AS id, qa.userid FROM '.$CFG->prefix.'quiz_attempts qa LEFT JOIN '.$CFG->prefix.'user_teachers ut ON qa.userid = ut.userid AND ut.course = '.$course->id.' WHERE ut.id IS NULL AND quiz = '.$quiz->id);
//if(!empty($userswithattempts)) {
// $unenrolledusers = array_diff(array_keys($userswithattempts), $users);
// $users = array_merge($users, $unenrolledusers);
//}
if(empty($users)) {
print_heading($strnoattempts);
return true;
}
/// Set table options
if(!isset($SESSION->quiz_overview_table)) {
$SESSION->quiz_overview_table = array('noattempts' => false, 'detailedmarks' => false, 'pagesize' => 10);
@ -178,7 +149,6 @@ class quiz_report extends quiz_default_report {
$table->sortable(true);
$table->collapsible(true);
$table->initialbars(count($users)>20);
$table->column_suppress('picture');
$table->column_suppress('fullname');
@ -270,24 +240,48 @@ class quiz_report extends quiz_default_report {
// Construct the SQL
$select = 'SELECT '.$db->Concat('u.id', '\'#\'', $db->IfNull('qa.attempt', '0')).' AS uniqueid, qa.id AS attempt, qa.uniqueid as attemptuniqueid, u.id AS userid, u.firstname, u.lastname, u.picture, '.
'qa.sumgrades, qa.timefinish, qa.timestart, qa.timefinish - qa.timestart AS duration ';
$from = 'FROM '.$CFG->prefix.'user u LEFT JOIN '.$CFG->prefix.'quiz_attempts qa ON (u.id = qa.userid AND qa.quiz = '.$quiz->id.') ';
$where = 'WHERE u.id IN ('.implode(',', $users).') ';
// Add extra limits if we 're not interested in students without attempts
if(!$noattempts) {
$where .= 'AND '.$db->IfNull('qa.attempt', '0').' != 0 ';
$select = 'SELECT '.$db->Concat('u.id', '\'#\'', $db->IfNull('qa.guestemail','\'\''), '\'#\'', $db->IfNull('qa.attempt', '0')).' AS uniqueid, '.
'qa.id AS attempt, u.id AS userid, u.firstname, u.lastname, u.picture, '.
'qa.sumgrades, qa.timefinish, qa.timestart, qa.timefinish - qa.timestart AS duration, qa.guestemail ';
if ($course->id != SITEID) { // this is too complicated, so just do it for each of the four cases.
if (!empty($currentgroup) && empty($noattempts)) {
$from = 'FROM '.$CFG->prefix.'user u JOIN '.$CFG->prefix.'user_students us ON us.userid = u.id JOIN '.$CFG->prefix.'groups_members gm ON u.id = gm.userid '.
'JOIN '.$CFG->prefix.'quiz_attempts qa ON u.id = qa.userid AND qa.quiz = '.$quiz->id;
$where = ' WHERE us.course = '.$course->id.' AND gm.groupid = '.$currentgroup;
} else if (!empty($currentgroup) && !empty($noattempts)) {
$from = 'FROM '.$CFG->prefix.'user u JOIN '.$CFG->prefix.'user_students us ON us.userid = u.id JOIN '.$CFG->prefix.'groups_members gm ON u.id = gm.userid '.
'LEFT JOIN '.$CFG->prefix.'quiz_attempts qa ON u.id = qa.userid AND qa.quiz = '.$quiz->id;
$where = ' WHERE us.course = '.$course->id.' AND gm.groupid = '.$currentgroup.' AND qa.userid IS NULL';
} else if (empty($currentgroup) && empty($noattempts)) {
$from = 'FROM '.$CFG->prefix.'user u JOIN '.$CFG->prefix.'quiz_attempts qa ON u.id = qa.userid ';
$where = ' WHERE qa.quiz = '.$quiz->id;
} else if (empty($currentgroup) && !empty($noattempts)) {
$from = 'FROM '.$CFG->prefix.'user u JOIN '.$CFG->prefix.'user_students us ON us.userid = u.id LEFT JOIN '.$CFG->prefix.'quiz_attempts qa ON u.id = qa.userid AND qa.quiz = '.$quiz->id;
$where = ' WHERE us.course = '.$course->id.' AND qa.userid IS NULL';
}
$countsql = 'SELECT COUNT(DISTINCT('.$db->Concat('u.id', '\'#\'', $db->IfNull('qa.guestemail','\'\''), '\'#\'', $db->IfNull('qa.attempt', '0')).')) '.$from.$where;
} else {
if (empty($noattempts)) {
$from = 'FROM '.$CFG->prefix.'user u JOIN '.$CFG->prefix.'quiz_attempts qa ON u.id = qa.userid ';
$where = ' WHERE qa.quiz = '.$quiz->id;
$countsql = 'SELECT COUNT(DISTINCT('.$db->Concat('u.id', '\'#\'', 'qa.guestemail', '\'#\'', $db->IfNull('qa.attempt', '0')).')) '.$from.$where;
}
}
if (!$download) {
// Add extra limits due to initials bar
if($table->get_sql_where()) {
$where .= 'AND '.$table->get_sql_where();
$where .= ' AND '.$table->get_sql_where();
}
// Count the records NOW, before funky question grade sorting messes up $from
$total = count_records_sql('SELECT COUNT(DISTINCT('.$db->Concat('u.id', '\'#\'', $db->IfNull('qa.attempt', '0')).')) '.$from.$where);
if (!empty($countsql)) {
$totalinitials = count_records_sql($countsql);
if ($table->get_sql_where()) {
$countsql .= ' AND '.$table->get_sql_where();
}
$total = count_records_sql($countsql);
}
// Add extra limits due to sorting by question grade
if($sort = $table->get_sql_sort()) {
@ -336,11 +330,18 @@ class quiz_report extends quiz_default_report {
}
/// Fetch the attempts
$attempts = get_records_sql($select.$from.$where.$sort.$limit);
if (!empty($from)) { // if we're in the site course and displaying no attempts, it makes no sense to do the query.
$attempts = get_records_sql($select.$from.$where.$sort.$limit);
} else {
$attempts = array();
}
/// Build table rows
if(!empty($attempts)) {
if (!$download) {
$table->initialbars($totalinitials>20);
}
if(!empty($attempts) || !empty($noattempts)) {
foreach ($attempts as $attempt) {
@ -434,19 +435,19 @@ class quiz_report extends quiz_default_report {
$table->print_html();
/// Print "Select all" etc.
echo '<table id="commands">';
echo '<tr><td>';
echo '<a href="javascript:select_all_in(\'DIV\',null,\'tablecontainer\');">'.get_string('selectall', 'quiz').'</a> / ';
echo '<a href="javascript:deselect_all_in(\'DIV\',null,\'tablecontainer\');">'.get_string('selectnone', 'quiz').'</a> ';
echo '&nbsp;&nbsp;';
$options = array('delete' => get_string('delete'));
echo choose_from_menu($options, 'action', '', get_string('withselected', 'quiz'), 'if(this.selectedIndex > 0) submitFormById(\'attemptsform\');', '', true);
echo '<noscript id="noscriptmenuaction" style="display: inline;">';
echo '<input type="submit" value="'.get_string('go').'" /></noscript>';
echo '<script type="text/javascript">'."\n<!--\n".'document.getElementById("noscriptmenuaction").style.display = "none";'."\n-->\n".'</script>';
echo '</td></tr></table>';
if (!empty($attempts)) {
echo '<table id="commands">';
echo '<tr><td>';
echo '<a href="javascript:select_all_in(\'DIV\',null,\'tablecontainer\');">'.get_string('selectall', 'quiz').'</a> / ';
echo '<a href="javascript:deselect_all_in(\'DIV\',null,\'tablecontainer\');">'.get_string('selectnone', 'quiz').'</a> ';
echo '&nbsp;&nbsp;';
$options = array('delete' => get_string('delete'));
echo choose_from_menu($options, 'action', '', get_string('withselected', 'quiz'), 'if(this.selectedIndex > 0) submitFormById(\'attemptsform\');', '', true);
echo '<noscript id="noscriptmenuaction" style="display: inline;">';
echo '<input type="submit" value="'.get_string('go').'" /></noscript>';
echo '<script type="text/javascript">'."\n<!--\n".'document.getElementById("noscriptmenuaction").style.display = "none";'."\n-->\n".'</script>';
echo '</td></tr></table>';
}
/// Close form
echo '</form></div>';
/// Print display options
@ -464,10 +465,10 @@ class quiz_report extends quiz_default_report {
echo '<td><input type="text" id="pagesize" name="pagesize" size="1" value="'.$pagesize.'" /></td>';
echo '</tr>';
echo '<tr align="left">';
echo '<td colspan="2"><input type="checkbox" id="checknoattempts" name="noattempts" '.($noattempts?'checked="checked" ':'').'value="1" /> <label for="checknoattempts">'.get_string('shownoattempts', 'quiz').'</label> ';
echo '<td colspan="2"><input type="checkbox" id="checknoattempts" name="noattempts" '.($noattempts?'checked="checked" ':'').'value="1" /> <label for="checknoattempts">'.get_string('shownoattemptsonly', 'quiz').'</label> ';
echo '</td></tr>';
echo '<tr align="left">';
echo '<td colspan="2"><input type="checkbox" id="checkdetailedmarks" name="detailedmarks" '.($detailedmarks?'checked="checked" ':'').'value="1" /> <label for="checkdetailedmarks">'.get_string('showdetailedmarks', 'quiz').'</label> ';
echo '<td colspan="2"><input type="checkbox" id="checkdetailedmarks" name="detailedmarks" '.($detailedmarks?'checked="checked" ':'').'value="1" '.(($course->id == SITEID) ? ' disabled="disabled"' : '') .' /> <label for="checkdetailedmarks">'.get_string('showdetailedmarks', 'quiz').'</label> ';
echo '</td></tr>';
echo '<tr><td colspan="2" align="center">';
echo '<input type="submit" value="'.get_string('go').'" />';
@ -475,26 +476,28 @@ class quiz_report extends quiz_default_report {
echo '</form>';
echo '</div>';
echo "\n";
echo '<table align="center"><tr>';
unset($options);
$options["id"] = "$cm->id";
$options["q"] = "$quiz->id";
$options["mode"] = "overview";
$options['sesskey'] = sesskey();
$options["noheader"] = "yes";
echo '<td>';
$options["download"] = "Excel";
print_single_button("report.php", $options, get_string("downloadexcel"));
echo "</td>\n";
echo '<td>';
$options["download"] = "CSV";
print_single_button('report.php', $options, get_string("downloadtext"));
echo "</td>\n";
echo "<td>";
helpbutton("download", get_string("download","quiz"), "quiz");
echo "</td>\n";
echo '</tr></table>';
if (!empty($attempts)) {
echo '<table align="center"><tr>';
unset($options);
$options["id"] = "$cm->id";
$options["q"] = "$quiz->id";
$options["mode"] = "overview";
$options['sesskey'] = sesskey();
$options["noheader"] = "yes";
echo '<td>';
$options["download"] = "Excel";
print_single_button("report.php", $options, get_string("downloadexcel"));
echo "</td>\n";
echo '<td>';
$options["download"] = "CSV";
print_single_button('report.php', $options, get_string("downloadtext"));
echo "</td>\n";
echo "<td>";
helpbutton("download", get_string("download","quiz"), "quiz");
echo "</td>\n";
echo '</tr></table>';
}
}
elseif ($download == 'Excel') {
$workbook->close();