mirror of
https://github.com/moodle/moodle.git
synced 2025-02-15 21:36:58 +01:00
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:
parent
9edf8e04e5
commit
39a2761465
@ -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';
|
||||
|
@ -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
|
||||
|
@ -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 ' ';
|
||||
$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 ' ';
|
||||
$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();
|
||||
|
Loading…
x
Reference in New Issue
Block a user