Checking in the code for the "improvements to the quiz results overview page"

project, commissioned by the University of York. Enjoy!
This commit is contained in:
defacer
2005-03-08 18:49:00 +00:00
parent f05512fd16
commit 526a130e50
2 changed files with 222 additions and 85 deletions
+198 -85
View File
@@ -1,72 +1,104 @@
<?php // $Id$
require_once($CFG->libdir.'/tablelib.php');
/// Overview report just displays a big table of all the attempts
class quiz_report extends quiz_default_report {
function display($quiz, $cm, $course) { /// This function just displays the report
global $CFG, $QUIZ_GRADE_METHOD, $del;
global $CFG, $SESSION, $db;
$strreallydel = addslashes(get_string('deleteattemptcheck','quiz'));
$strdeleteselected = get_string('deleteselected');
$strdeleteall = get_string('deleteall');
$strname = get_string("name");
$strattempts = get_string("attempts", "quiz");
$strreallydel = addslashes(get_string('deleteattemptcheck','quiz'));
$strnoattempts = get_string('noattempts','quiz');
$strbestgrade = $QUIZ_GRADE_METHOD[$quiz->grademethod];
$strtimeformat = get_string('strftimedatetime');
if (!empty($del)) { /// Some attempts need to be deleted
$action = optional_param('action', '');
if (record_exists('quiz_attempts', 'quiz', $quiz->id)) {
switch($action) {
case 'delete': /// Some attempts need to be deleted
if ($del == 'all'){ /// Delete all the attempts
$attempts = get_records('quiz_attempts','quiz',$quiz->id);
delete_records('quiz_attempts','quiz',$quiz->id);
delete_records('quiz_grades','quiz',$quiz->id);
if ($attempts) {
foreach ($attempts as $thisattempt){
delete_records('quiz_responses','attempt',$thisattempt->id);
}
$attemptids = isset($_POST['attemptid']) ? $_POST['attemptid'] : array();
if(!is_array($attemptids) || empty($attemptids)) {
break;
}
foreach($attemptids as $num => $attemptid) {
if(empty($attemptid)) {
unset($attemptids[$num]);
}
}
} else { /// Delete selected attempts
foreach($attemptids as $attemptid) {
if ($todelete = get_record('quiz_attempts', 'id', $attemptid)) {
$items = (array)data_submitted();
delete_records('quiz_attempts', 'id', $attemptid);
delete_records('quiz_responses', 'attempt', $attemptid);
unset($items['del']);
unset($items['id']);
// Search quiz_attempts for other instances by this user.
// If none, then delete record for this quiz, this user from quiz_grades
// else recalculate best grade
if ($items) {
foreach ($items as $attemptid) {
if ($todelete = get_record('quiz_attempts', 'id', $attemptid)) {
delete_records('quiz_attempts', 'id', $attemptid);
delete_records('quiz_responses', 'attempt', $attemptid);
// Search quiz_attempts for other instances by this user.
// If none, then delete record for this quiz, this user from quiz_grades
// else recalculate best grade
$userid = $todelete->userid;
if (!record_exists('quiz_attempts', 'userid', $userid, 'quiz',$quiz->id)) {
delete_records('quiz_grades', 'userid', $userid,'quiz',$quiz->id);
} else {
quiz_save_best_grade($quiz, $userid);
}
}
$userid = $todelete->userid;
if (!record_exists('quiz_attempts', 'userid', $userid, 'quiz', $quiz->id)) {
delete_records('quiz_grades', 'userid', $userid,'quiz', $quiz->id);
} else {
quiz_save_best_grade($quiz, $userid);
}
}
}
break;
}
if(!isset($SESSION->quiz_overview_table)) {
$SESSION->quiz_overview_table = array('noattempts' => false, 'teacherattempts' => true, 'detailedmarks' => false);
}
foreach($SESSION->quiz_overview_table as $option => $value) {
$urlparam = optional_param($option, NULL);
if($urlparam === NULL) {
$$option = $value;
}
else {
$$option = $SESSION->quiz_overview_table[$option] = $urlparam;
}
}
if (!$grades = quiz_get_grade_records($quiz)) {
print_heading($strnoattempts);
return true;
$tablecolumns = array('checkbox', 'picture', 'fullname', 'timefinish', 'duration', 'sumgrades');
$tableheaders = array(NULL, '', get_string('fullname'), get_string('attemptedon', 'quiz'), get_string('attemptduration', 'quiz'), get_string('grade', 'quiz').'/'.$quiz->grade);
if($detailedmarks) {
$questions = explode(',', $quiz->questions);
foreach($questions as $number => $questionid) {
$tablecolumns[] = '$'.$questionid;
$tableheaders[] = '#'.($number + 1);
}
}
$table = new flexible_table('mod-quiz-report-overview-report');
$table->define_columns($tablecolumns);
$table->define_headers($tableheaders);
$table->define_baseurl($CFG->wwwroot.'/mod/quiz/report.php?id='.$cm->id);
$table->sortable(true);
$table->collapsible(true);
$table->initialbars(true);
$table->column_suppress('picture');
$table->column_suppress('fullname');
$table->column_class('picture', 'picture');
$table->set_attribute('cellspacing', '0');
$table->set_attribute('id', 'attempts');
$table->set_attribute('class', 'generaltable generalbox');
// Start working -- this is necessary as soon as the niceties are over
$table->setup();
/// Check to see if groups are being used in this quiz
if ($groupmode = groupmode($course, $cm)) { // Groups are being used
$currentgroup = setup_and_print_groups($course, $groupmode, "report.php?id=$cm->id&amp;mode=overview");
@@ -78,54 +110,135 @@ class quiz_report extends quiz_default_report {
if ($currentgroup) {
$users = get_group_users($currentgroup);
}
$table->head = array("&nbsp;", $strname, $strattempts, "$strbestgrade /$quiz->grade");
$table->align = array("center", "left", "left", "center");
$table->wrap = array("nowrap", "nowrap", "nowrap", "nowrap");
$table->width = 10;
$table->size = array(10, "*", "80%", "*");
foreach ($grades as $grade) {
if ($currentgroup) {
if (empty($users[$grade->userid])) { /// Using groups, but this user not in group
continue;
}
}
$picture = print_user_picture($grade->userid, $course->id, $grade->picture, false, true);
if ($attempts = quiz_get_user_attempts($quiz->id, $grade->userid)) {
$userattempts = $this->quiz_get_user_attempts_list($quiz, $attempts, $grade->grade, $strtimeformat);
} else {
$userattempts = "";
}
$table->data[] = array ($picture,
"<a href=\"$CFG->wwwroot/user/view.php?id=$grade->userid&amp;course=$course->id\">".
fullname($grade).'</a>',
"$userattempts", format_float($grade->grade,$quiz->decimalpoints));
else {
$users = get_course_users($course->id);
}
//Embed script for warning
echo "\n<script language=\"javascript\" type=\"text/javascript\">\n<!--\nfunction delcheck(){\n ";
echo "if (confirm('$strreallydel')) {\n";
echo " document.delform.del.value='all';\n return true;\n";
echo " } else {\n";
echo " return false;\n }\n}\n";
echo "//-->\n</script>\n";
$onsub = "return confirm('$strreallydel')";
if(!$teacherattempts) {
$teachers = get_course_teachers($course->id);
if(!empty($teachers)) {
$keys = array_keys($teachers);
}
foreach($keys as $key) {
unset($users[$key]);
}
}
echo "<form method=\"post\" action=\"report.php\" name=\"delform\" onsubmit=\"$onsub\">\n";
echo "<input type=\"hidden\" name=\"del\" value=\"selection\" />\n";
echo "<input type=\"hidden\" name=\"id\" value=\"$cm->id\" />\n";
if(empty($users)) {
print_heading($strnoattempts);
return true;
}
print_table($table);
// Construct the SQL
if($where = $table->get_sql_where()) {
$where .= ' AND ';
}
if($sort = $table->get_sql_sort()) {
if(substr($sort, 0, 1) == '$') {
$qnum = intval(substr($sort, 1));
$where.= '('.sql_isnull('qr.question').' OR qr.question = '.$qnum.') AND ';
$sort = ' ORDER BY grade '.(strpos($sort, 'ASC')? 'ASC' : 'DESC');
}
else {
$sort = ' ORDER BY '.$sort;
}
}
$select = 'SELECT '.$db->Concat('u.id', '\'#\'', $db->IfNull('qa.attempt', '0')).' AS uvsa, u.id AS userid, u.firstname, u.lastname, u.picture, qa.id AS attempt, qa.sumgrades, qa.timefinish, qa.timefinish - qa.timestart AS duration ';
$group = 'GROUP BY uvsa';
$sql = 'FROM '.$CFG->prefix.'user u '.
'LEFT JOIN '.$CFG->prefix.'quiz_attempts qa ON u.id = qa.userid '.
'LEFT JOIN '.$CFG->prefix.'quiz_responses qr ON qr.attempt = qa.id '.
'WHERE '.$where.'u.id IN ('.implode(',', array_keys($users)).') AND ('.($noattempts ? sql_isnull('qa.quiz').' OR ' : '') . 'qa.quiz = '.$quiz->id.') ';
$total = count_records_sql('SELECT COUNT(DISTINCT('.$db->Concat('u.id', '\'#\'', $db->IfNull('qa.attempt', '0')).')) '.$sql);
$table->pagesize(10, $total);
if($table->get_page_start() !== '' && $table->get_page_size() !== '') {
$limit = ' '.sql_paging_limit($table->get_page_start(), $table->get_page_size());
}
else {
$limit = '';
}
$attempts = get_records_sql($select.$sql.$group.$sort.$limit);
if(!empty($attempts)) {
foreach ($attempts as $attempt) {
//There might be a more elegant way than using the <center> tag for this
echo "<center><input type=\"submit\" value=\"$strdeleteselected\" />&nbsp;";
echo "<input type=\"button\" value=\"$strdeleteall\" onclick=\"if(delcheck()){document.delform.submit()}\" />\n</center>\n";
echo "</form>\n";
$picture = print_user_picture($attempt->userid, $course->id, $attempt->picture, false, true);
$row = array(
'<input type="checkbox" name="attemptid[]" value="'.$attempt->attempt.'" />',
$picture,
'<a href="'.$CFG->wwwroot.'/user/view.php?id='.$attempt->userid.'&amp;course='.$course->id.'">'.fullname($attempt).'</a>',
empty($attempt->attempt) ? '-' : '<a href="review.php?q='.$quiz->id.'&amp;attempt='.$attempt->attempt.'">'.userdate($attempt->timefinish, $strtimeformat).'</a>',
empty($attempt->attempt) ? '-' : format_time($attempt->duration),
$attempt->sumgrades === NULL ? '-' : format_float($attempt->sumgrades / $quiz->sumgrades * $quiz->grade,$quiz->decimalpoints)
);
if($detailedmarks) {
if(empty($attempt->attempt)) {
foreach($questions as $question) {
$row[] = '-';
}
}
else {
$responses = get_records('quiz_responses', 'attempt', $attempt->attempt, 'question');
foreach($responses as $response) {
$row[] = $response->grade;
}
}
}
$table->add_data($row);
}
echo '<script type="text/javascript" src="'.$CFG->wwwroot.'/mod/quiz/report/overview/utility.js" />';
echo '<form id="attemptsform" method="post" action="report.php" onsubmit="var menu = document.getElementById(\'actionmenu\'); return confirm_if(menu.options[menu.selectedIndex].value == \'delete\', \''.$strreallydel.'\');">';
echo '<input type="hidden" name="id" value="'.$cm->id.'" />';
}
$table->print_html();
if(!empty($attempts)) {
//There might be a more elegant way than using the <center> tag for this
echo '<table id="commands">';
echo '<tr><td>';
echo '<a href="javascript:select_all();">'.get_string('selectall', 'quiz').'</a> / ';
echo '<a href="javascript:deselect_all();">'.get_string('selectnone', 'quiz').'</a> ';
echo '</td><td style="text-align: right;">';
$options = array('dummy' => ' ', 'delete' => get_string('delete'));
$menu = str_replace('<select', '<select id="actionmenu"', choose_from_menu($options, 'action', '', get_string('selectedattempts', 'quiz'), 'if(this.selectedIndex > 1) submitFormById(\'attemptsform\');', '', true));
echo $menu;
echo '</td></tr></table>';
//echo '<noscript id="noscriptactionmenu" style="display: inline;">';
//echo '<input type="submit" value="'.get_string('go').'" /></noscript>';
//echo '<script type="text/javascript">'."\n<!--\n".'document.getElementById("noscriptactionmenu").style.display = "none";'."\n-->\n".'</script>';
echo '</form>';
}
else {
print_heading(get_string('noattemptsmatchingfilter', 'quiz', strtolower($course->students)));
}
echo '<div class="controls">';
echo '<form method="report.php">';
echo '<p>'.get_string('displayoptions', 'quiz').': ';
echo '<input type="hidden" name="id" value="'.$cm->id.'" />';
echo '<input type="hidden" name="noattempts" value="0" />';
echo '<input type="hidden" name="teacherattempts" value="0" />';
echo '<input type="hidden" name="detailedmarks" value="0" />';
echo '<input type="checkbox" id="checknoattempts" name="noattempts" '.($noattempts?'checked="checked" ':'').'value="1" /> <label for="checknoattempts">'.get_string('shownoattempts', 'quiz').'</label> ';
echo '<input type="checkbox" id="checkteacherattempts" name="teacherattempts" '.($teacherattempts?'checked="checked" ':'').'value="1" /> <label for="checkteacherattempts">'.get_string('showteacherattempts', 'quiz').'</label> ';
echo '<input type="checkbox" id="checkdetailedmarks" name="detailedmarks" '.($detailedmarks?'checked="checked" ':'').'value="1" /> <label for="checkdetailedmarks">'.get_string('showdetailedmarks', 'quiz').'</label> ';
echo '<input type="submit" value="'.get_string('go').'" />';
echo '</p>';
echo '</form>';
echo '</div>';
return true;
}
+24
View File
@@ -0,0 +1,24 @@
function select_all() {
var inputs = document.getElementsByTagName('INPUT');
for(var i = 0; i < inputs.length; ++i) {
if(inputs[i].type == 'checkbox') {
inputs[i].checked = 'checked';
}
}
}
function deselect_all() {
var inputs = document.getElementsByTagName('INPUT');
for(var i = 0; i < inputs.length; ++i) {
if(inputs[i].type == 'checkbox') {
inputs[i].checked = '';
}
}
}
function confirm_if(expr, message) {
if(!expr) {
return true;
}
return confirm(message);
}